xref: /linux/arch/x86/kernel/cpu/sgx/virt.c (revision 570f7e331f5febb30f1384817463c7e42b65ca7d)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Device driver to expose SGX enclave memory to KVM guests.
4  *
5  * Copyright(c) 2021 Intel Corporation.
6  */
7 
8 #include <linux/kvm_types.h>
9 #include <linux/miscdevice.h>
10 #include <linux/mm.h>
11 #include <linux/mman.h>
12 #include <linux/pagemap.h>
13 #include <linux/sched/mm.h>
14 #include <linux/sched/signal.h>
15 #include <linux/slab.h>
16 #include <linux/xarray.h>
17 #include <asm/sgx.h>
18 #include <uapi/asm/sgx.h>
19 
20 #include "encls.h"
21 #include "sgx.h"
22 
23 struct sgx_vepc {
24 	struct xarray page_array;
25 	struct mutex lock;
26 };
27 
28 /*
29  * Temporary SECS pages that cannot be EREMOVE'd due to having child in other
30  * virtual EPC instances, and the lock to protect it.
31  */
32 static struct mutex zombie_secs_pages_lock;
33 static struct list_head zombie_secs_pages;
34 
35 static int __sgx_vepc_fault(struct sgx_vepc *vepc,
36 			    struct vm_area_struct *vma, unsigned long addr)
37 {
38 	struct sgx_epc_page *epc_page;
39 	unsigned long index, pfn;
40 	int ret;
41 
42 	WARN_ON(!mutex_is_locked(&vepc->lock));
43 
44 	/* Calculate index of EPC page in virtual EPC's page_array */
45 	index = linear_page_index(vma, addr);
46 
47 	epc_page = xa_load(&vepc->page_array, index);
48 	if (epc_page)
49 		return 0;
50 
51 	epc_page = sgx_alloc_epc_page(vepc, false);
52 	if (IS_ERR(epc_page))
53 		return PTR_ERR(epc_page);
54 
55 	ret = xa_err(xa_store(&vepc->page_array, index, epc_page, GFP_KERNEL));
56 	if (ret)
57 		goto err_free;
58 
59 	pfn = PFN_DOWN(sgx_get_epc_phys_addr(epc_page));
60 
61 	ret = vmf_insert_pfn(vma, addr, pfn);
62 	if (ret != VM_FAULT_NOPAGE) {
63 		ret = -EFAULT;
64 		goto err_delete;
65 	}
66 
67 	return 0;
68 
69 err_delete:
70 	xa_erase(&vepc->page_array, index);
71 err_free:
72 	sgx_free_epc_page(epc_page);
73 	return ret;
74 }
75 
76 static vm_fault_t sgx_vepc_fault(struct vm_fault *vmf)
77 {
78 	struct vm_area_struct *vma = vmf->vma;
79 	struct sgx_vepc *vepc = vma->vm_private_data;
80 	int ret;
81 
82 	mutex_lock(&vepc->lock);
83 	ret = __sgx_vepc_fault(vepc, vma, vmf->address);
84 	mutex_unlock(&vepc->lock);
85 
86 	if (!ret)
87 		return VM_FAULT_NOPAGE;
88 
89 	if (ret == -EBUSY && (vmf->flags & FAULT_FLAG_ALLOW_RETRY)) {
90 		mmap_read_unlock(vma->vm_mm);
91 		return VM_FAULT_RETRY;
92 	}
93 
94 	return VM_FAULT_SIGBUS;
95 }
96 
97 static const struct vm_operations_struct sgx_vepc_vm_ops = {
98 	.fault = sgx_vepc_fault,
99 };
100 
101 static int sgx_vepc_mmap(struct file *file, struct vm_area_struct *vma)
102 {
103 	struct sgx_vepc *vepc = file->private_data;
104 
105 	if (!(vma->vm_flags & VM_SHARED))
106 		return -EINVAL;
107 
108 	vma->vm_ops = &sgx_vepc_vm_ops;
109 	/* Don't copy VMA in fork() */
110 	vm_flags_set(vma, VM_PFNMAP | VM_IO | VM_DONTDUMP | VM_DONTCOPY);
111 	vma->vm_private_data = vepc;
112 
113 	return 0;
114 }
115 
116 static int sgx_vepc_remove_page(struct sgx_epc_page *epc_page)
117 {
118 	/*
119 	 * Take a previously guest-owned EPC page and return it to the
120 	 * general EPC page pool.
121 	 *
122 	 * Guests can not be trusted to have left this page in a good
123 	 * state, so run EREMOVE on the page unconditionally.  In the
124 	 * case that a guest properly EREMOVE'd this page, a superfluous
125 	 * EREMOVE is harmless.
126 	 */
127 	return __eremove(sgx_get_epc_virt_addr(epc_page));
128 }
129 
130 static int sgx_vepc_free_page(struct sgx_epc_page *epc_page)
131 {
132 	int ret = sgx_vepc_remove_page(epc_page);
133 	if (ret) {
134 		/*
135 		 * Only SGX_CHILD_PRESENT is expected, which is because of
136 		 * EREMOVE'ing an SECS still with child, in which case it can
137 		 * be handled by EREMOVE'ing the SECS again after all pages in
138 		 * virtual EPC have been EREMOVE'd. See comments in below in
139 		 * sgx_vepc_release().
140 		 *
141 		 * The user of virtual EPC (KVM) needs to guarantee there's no
142 		 * logical processor is still running in the enclave in guest,
143 		 * otherwise EREMOVE will get SGX_ENCLAVE_ACT which cannot be
144 		 * handled here.
145 		 */
146 		WARN_ONCE(ret != SGX_CHILD_PRESENT, EREMOVE_ERROR_MESSAGE,
147 			  ret, ret);
148 		return ret;
149 	}
150 
151 	sgx_free_epc_page(epc_page);
152 	return 0;
153 }
154 
155 static long sgx_vepc_remove_all(struct sgx_vepc *vepc)
156 {
157 	struct sgx_epc_page *entry;
158 	unsigned long index;
159 	long failures = 0;
160 
161 	xa_for_each(&vepc->page_array, index, entry) {
162 		int ret = sgx_vepc_remove_page(entry);
163 		if (ret) {
164 			if (ret == SGX_CHILD_PRESENT) {
165 				/* The page is a SECS, userspace will retry.  */
166 				failures++;
167 			} else {
168 				/*
169 				 * Report errors due to #GP or SGX_ENCLAVE_ACT; do not
170 				 * WARN, as userspace can induce said failures by
171 				 * calling the ioctl concurrently on multiple vEPCs or
172 				 * while one or more CPUs is running the enclave.  Only
173 				 * a #PF on EREMOVE indicates a kernel/hardware issue.
174 				 */
175 				WARN_ON_ONCE(encls_faulted(ret) &&
176 					     ENCLS_TRAPNR(ret) != X86_TRAP_GP);
177 				return -EBUSY;
178 			}
179 		}
180 		cond_resched();
181 	}
182 
183 	/*
184 	 * Return the number of SECS pages that failed to be removed, so
185 	 * userspace knows that it has to retry.
186 	 */
187 	return failures;
188 }
189 
190 static int sgx_vepc_release(struct inode *inode, struct file *file)
191 {
192 	struct sgx_vepc *vepc = file->private_data;
193 	struct sgx_epc_page *epc_page, *tmp, *entry;
194 	unsigned long index;
195 
196 	LIST_HEAD(secs_pages);
197 
198 	xa_for_each(&vepc->page_array, index, entry) {
199 		/*
200 		 * Remove all normal, child pages.  sgx_vepc_free_page()
201 		 * will fail if EREMOVE fails, but this is OK and expected on
202 		 * SECS pages.  Those can only be EREMOVE'd *after* all their
203 		 * child pages. Retries below will clean them up.
204 		 */
205 		if (sgx_vepc_free_page(entry))
206 			continue;
207 
208 		xa_erase(&vepc->page_array, index);
209 		cond_resched();
210 	}
211 
212 	/*
213 	 * Retry EREMOVE'ing pages.  This will clean up any SECS pages that
214 	 * only had children in this 'epc' area.
215 	 */
216 	xa_for_each(&vepc->page_array, index, entry) {
217 		epc_page = entry;
218 		/*
219 		 * An EREMOVE failure here means that the SECS page still
220 		 * has children.  But, since all children in this 'sgx_vepc'
221 		 * have been removed, the SECS page must have a child on
222 		 * another instance.
223 		 */
224 		if (sgx_vepc_free_page(epc_page))
225 			list_add_tail(&epc_page->list, &secs_pages);
226 
227 		xa_erase(&vepc->page_array, index);
228 		cond_resched();
229 	}
230 
231 	/*
232 	 * SECS pages are "pinned" by child pages, and "unpinned" once all
233 	 * children have been EREMOVE'd.  A child page in this instance
234 	 * may have pinned an SECS page encountered in an earlier release(),
235 	 * creating a zombie.  Since some children were EREMOVE'd above,
236 	 * try to EREMOVE all zombies in the hopes that one was unpinned.
237 	 */
238 	mutex_lock(&zombie_secs_pages_lock);
239 	list_for_each_entry_safe(epc_page, tmp, &zombie_secs_pages, list) {
240 		/*
241 		 * Speculatively remove the page from the list of zombies,
242 		 * if the page is successfully EREMOVE'd it will be added to
243 		 * the list of free pages.  If EREMOVE fails, throw the page
244 		 * on the local list, which will be spliced on at the end.
245 		 */
246 		list_del(&epc_page->list);
247 
248 		if (sgx_vepc_free_page(epc_page))
249 			list_add_tail(&epc_page->list, &secs_pages);
250 		cond_resched();
251 	}
252 
253 	if (!list_empty(&secs_pages))
254 		list_splice_tail(&secs_pages, &zombie_secs_pages);
255 	mutex_unlock(&zombie_secs_pages_lock);
256 
257 	xa_destroy(&vepc->page_array);
258 	kfree(vepc);
259 
260 	sgx_dec_usage_count();
261 	return 0;
262 }
263 
264 static int __sgx_vepc_open(struct inode *inode, struct file *file)
265 {
266 	struct sgx_vepc *vepc;
267 
268 	vepc = kzalloc_obj(struct sgx_vepc);
269 	if (!vepc)
270 		return -ENOMEM;
271 	mutex_init(&vepc->lock);
272 	xa_init(&vepc->page_array);
273 
274 	file->private_data = vepc;
275 
276 	return 0;
277 }
278 
279 static int sgx_vepc_open(struct inode *inode, struct file *file)
280 {
281 	int ret;
282 
283 	ret = sgx_inc_usage_count();
284 	if (ret)
285 		return ret;
286 
287 	ret =  __sgx_vepc_open(inode, file);
288 	if (ret) {
289 		sgx_dec_usage_count();
290 		return ret;
291 	}
292 
293 	return 0;
294 }
295 
296 static long sgx_vepc_ioctl(struct file *file,
297 			   unsigned int cmd, unsigned long arg)
298 {
299 	struct sgx_vepc *vepc = file->private_data;
300 
301 	switch (cmd) {
302 	case SGX_IOC_VEPC_REMOVE_ALL:
303 		if (arg)
304 			return -EINVAL;
305 		return sgx_vepc_remove_all(vepc);
306 
307 	default:
308 		return -ENOTTY;
309 	}
310 }
311 
312 static const struct file_operations sgx_vepc_fops = {
313 	.owner		= THIS_MODULE,
314 	.open		= sgx_vepc_open,
315 	.unlocked_ioctl	= sgx_vepc_ioctl,
316 	.compat_ioctl	= sgx_vepc_ioctl,
317 	.release	= sgx_vepc_release,
318 	.mmap		= sgx_vepc_mmap,
319 };
320 
321 static struct miscdevice sgx_vepc_dev = {
322 	.minor		= MISC_DYNAMIC_MINOR,
323 	.name		= "sgx_vepc",
324 	.nodename	= "sgx_vepc",
325 	.fops		= &sgx_vepc_fops,
326 };
327 
328 int __init sgx_vepc_init(void)
329 {
330 	/* SGX virtualization requires KVM to work */
331 	if (!cpu_feature_enabled(X86_FEATURE_VMX))
332 		return -ENODEV;
333 
334 	INIT_LIST_HEAD(&zombie_secs_pages);
335 	mutex_init(&zombie_secs_pages_lock);
336 
337 	return misc_register(&sgx_vepc_dev);
338 }
339 
340 /**
341  * sgx_virt_ecreate() - Run ECREATE on behalf of guest
342  * @pageinfo:	Pointer to PAGEINFO structure
343  * @secs:	Userspace pointer to SECS page
344  * @trapnr:	trap number injected to guest in case of ECREATE error
345  *
346  * Run ECREATE on behalf of guest after KVM traps ECREATE for the purpose
347  * of enforcing policies of guest's enclaves, and return the trap number
348  * which should be injected to guest in case of any ECREATE error.
349  *
350  * Return:
351  * -  0:	ECREATE was successful.
352  * - <0:	on error.
353  */
354 int sgx_virt_ecreate(struct sgx_pageinfo *pageinfo, void __user *secs,
355 		     int *trapnr)
356 {
357 	int ret;
358 
359 	/*
360 	 * @secs is an untrusted, userspace-provided address.  It comes from
361 	 * KVM and is assumed to be a valid pointer which points somewhere in
362 	 * userspace.  This can fault and call SGX or other fault handlers when
363 	 * userspace mapping @secs doesn't exist.
364 	 *
365 	 * Add a WARN() to make sure @secs is already valid userspace pointer
366 	 * from caller (KVM), who should already have handled invalid pointer
367 	 * case (for instance, made by malicious guest).  All other checks,
368 	 * such as alignment of @secs, are deferred to ENCLS itself.
369 	 */
370 	if (WARN_ON_ONCE(!access_ok(secs, PAGE_SIZE)))
371 		return -EINVAL;
372 
373 	__uaccess_begin();
374 	ret = __ecreate(pageinfo, (void *)secs);
375 	__uaccess_end();
376 
377 	if (encls_faulted(ret)) {
378 		*trapnr = ENCLS_TRAPNR(ret);
379 		return -EFAULT;
380 	}
381 
382 	/* ECREATE doesn't return an error code, it faults or succeeds. */
383 	WARN_ON_ONCE(ret);
384 	return 0;
385 }
386 EXPORT_SYMBOL_FOR_KVM(sgx_virt_ecreate);
387 
388 static int __sgx_virt_einit(void __user *sigstruct, void __user *token,
389 			    void __user *secs)
390 {
391 	int ret;
392 
393 	/*
394 	 * Make sure all userspace pointers from caller (KVM) are valid.
395 	 * All other checks deferred to ENCLS itself.  Also see comment
396 	 * for @secs in sgx_virt_ecreate().
397 	 */
398 #define SGX_EINITTOKEN_SIZE	304
399 	if (WARN_ON_ONCE(!access_ok(sigstruct, sizeof(struct sgx_sigstruct)) ||
400 			 !access_ok(token, SGX_EINITTOKEN_SIZE) ||
401 			 !access_ok(secs, PAGE_SIZE)))
402 		return -EINVAL;
403 
404 	__uaccess_begin();
405 	ret = __einit((void *)sigstruct, (void *)token, (void *)secs);
406 	__uaccess_end();
407 
408 	return ret;
409 }
410 
411 /**
412  * sgx_virt_einit() - Run EINIT on behalf of guest
413  * @sigstruct:		Userspace pointer to SIGSTRUCT structure
414  * @token:		Userspace pointer to EINITTOKEN structure
415  * @secs:		Userspace pointer to SECS page
416  * @lepubkeyhash:	Pointer to guest's *virtual* SGX_LEPUBKEYHASH MSR values
417  * @trapnr:		trap number injected to guest in case of EINIT error
418  *
419  * Run EINIT on behalf of guest after KVM traps EINIT. If SGX_LC is available
420  * in host, SGX driver may rewrite the hardware values at wish, therefore KVM
421  * needs to update hardware values to guest's virtual MSR values in order to
422  * ensure EINIT is executed with expected hardware values.
423  *
424  * Return:
425  * -  0:	EINIT was successful.
426  * - <0:	on error.
427  */
428 int sgx_virt_einit(void __user *sigstruct, void __user *token,
429 		   void __user *secs, u64 *lepubkeyhash, int *trapnr)
430 {
431 	int ret;
432 
433 	if (!cpu_feature_enabled(X86_FEATURE_SGX_LC)) {
434 		ret = __sgx_virt_einit(sigstruct, token, secs);
435 	} else {
436 		preempt_disable();
437 
438 		sgx_update_lepubkeyhash(lepubkeyhash);
439 
440 		ret = __sgx_virt_einit(sigstruct, token, secs);
441 		preempt_enable();
442 	}
443 
444 	/* Propagate up the error from the WARN_ON_ONCE in __sgx_virt_einit() */
445 	if (ret == -EINVAL)
446 		return ret;
447 
448 	if (encls_faulted(ret)) {
449 		*trapnr = ENCLS_TRAPNR(ret);
450 		return -EFAULT;
451 	}
452 
453 	return ret;
454 }
455 EXPORT_SYMBOL_FOR_KVM(sgx_virt_einit);
456