x86/sgx: Wipe out EREMOVE from sgx_free_epc_page()
[linux-2.6-microblaze.git] / arch / x86 / kernel / cpu / sgx / ioctl.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*  Copyright(c) 2016-20 Intel Corporation. */
3
4 #include <asm/mman.h>
5 #include <linux/mman.h>
6 #include <linux/delay.h>
7 #include <linux/file.h>
8 #include <linux/hashtable.h>
9 #include <linux/highmem.h>
10 #include <linux/ratelimit.h>
11 #include <linux/sched/signal.h>
12 #include <linux/shmem_fs.h>
13 #include <linux/slab.h>
14 #include <linux/suspend.h>
15 #include "driver.h"
16 #include "encl.h"
17 #include "encls.h"
18
19 static struct sgx_va_page *sgx_encl_grow(struct sgx_encl *encl)
20 {
21         struct sgx_va_page *va_page = NULL;
22         void *err;
23
24         BUILD_BUG_ON(SGX_VA_SLOT_COUNT !=
25                 (SGX_ENCL_PAGE_VA_OFFSET_MASK >> 3) + 1);
26
27         if (!(encl->page_cnt % SGX_VA_SLOT_COUNT)) {
28                 va_page = kzalloc(sizeof(*va_page), GFP_KERNEL);
29                 if (!va_page)
30                         return ERR_PTR(-ENOMEM);
31
32                 va_page->epc_page = sgx_alloc_va_page();
33                 if (IS_ERR(va_page->epc_page)) {
34                         err = ERR_CAST(va_page->epc_page);
35                         kfree(va_page);
36                         return err;
37                 }
38
39                 WARN_ON_ONCE(encl->page_cnt % SGX_VA_SLOT_COUNT);
40         }
41         encl->page_cnt++;
42         return va_page;
43 }
44
45 static void sgx_encl_shrink(struct sgx_encl *encl, struct sgx_va_page *va_page)
46 {
47         encl->page_cnt--;
48
49         if (va_page) {
50                 sgx_encl_free_epc_page(va_page->epc_page);
51                 list_del(&va_page->list);
52                 kfree(va_page);
53         }
54 }
55
56 static int sgx_encl_create(struct sgx_encl *encl, struct sgx_secs *secs)
57 {
58         struct sgx_epc_page *secs_epc;
59         struct sgx_va_page *va_page;
60         struct sgx_pageinfo pginfo;
61         struct sgx_secinfo secinfo;
62         unsigned long encl_size;
63         struct file *backing;
64         long ret;
65
66         va_page = sgx_encl_grow(encl);
67         if (IS_ERR(va_page))
68                 return PTR_ERR(va_page);
69         else if (va_page)
70                 list_add(&va_page->list, &encl->va_pages);
71         /* else the tail page of the VA page list had free slots. */
72
73         /* The extra page goes to SECS. */
74         encl_size = secs->size + PAGE_SIZE;
75
76         backing = shmem_file_setup("SGX backing", encl_size + (encl_size >> 5),
77                                    VM_NORESERVE);
78         if (IS_ERR(backing)) {
79                 ret = PTR_ERR(backing);
80                 goto err_out_shrink;
81         }
82
83         encl->backing = backing;
84
85         secs_epc = sgx_alloc_epc_page(&encl->secs, true);
86         if (IS_ERR(secs_epc)) {
87                 ret = PTR_ERR(secs_epc);
88                 goto err_out_backing;
89         }
90
91         encl->secs.epc_page = secs_epc;
92
93         pginfo.addr = 0;
94         pginfo.contents = (unsigned long)secs;
95         pginfo.metadata = (unsigned long)&secinfo;
96         pginfo.secs = 0;
97         memset(&secinfo, 0, sizeof(secinfo));
98
99         ret = __ecreate((void *)&pginfo, sgx_get_epc_virt_addr(secs_epc));
100         if (ret) {
101                 ret = -EIO;
102                 goto err_out;
103         }
104
105         if (secs->attributes & SGX_ATTR_DEBUG)
106                 set_bit(SGX_ENCL_DEBUG, &encl->flags);
107
108         encl->secs.encl = encl;
109         encl->base = secs->base;
110         encl->size = secs->size;
111         encl->attributes = secs->attributes;
112         encl->attributes_mask = SGX_ATTR_DEBUG | SGX_ATTR_MODE64BIT | SGX_ATTR_KSS;
113
114         /* Set only after completion, as encl->lock has not been taken. */
115         set_bit(SGX_ENCL_CREATED, &encl->flags);
116
117         return 0;
118
119 err_out:
120         sgx_encl_free_epc_page(encl->secs.epc_page);
121         encl->secs.epc_page = NULL;
122
123 err_out_backing:
124         fput(encl->backing);
125         encl->backing = NULL;
126
127 err_out_shrink:
128         sgx_encl_shrink(encl, va_page);
129
130         return ret;
131 }
132
133 /**
134  * sgx_ioc_enclave_create() - handler for %SGX_IOC_ENCLAVE_CREATE
135  * @encl:       An enclave pointer.
136  * @arg:        The ioctl argument.
137  *
138  * Allocate kernel data structures for the enclave and invoke ECREATE.
139  *
140  * Return:
141  * - 0:         Success.
142  * - -EIO:      ECREATE failed.
143  * - -errno:    POSIX error.
144  */
145 static long sgx_ioc_enclave_create(struct sgx_encl *encl, void __user *arg)
146 {
147         struct sgx_enclave_create create_arg;
148         void *secs;
149         int ret;
150
151         if (test_bit(SGX_ENCL_CREATED, &encl->flags))
152                 return -EINVAL;
153
154         if (copy_from_user(&create_arg, arg, sizeof(create_arg)))
155                 return -EFAULT;
156
157         secs = kmalloc(PAGE_SIZE, GFP_KERNEL);
158         if (!secs)
159                 return -ENOMEM;
160
161         if (copy_from_user(secs, (void __user *)create_arg.src, PAGE_SIZE))
162                 ret = -EFAULT;
163         else
164                 ret = sgx_encl_create(encl, secs);
165
166         kfree(secs);
167         return ret;
168 }
169
170 static struct sgx_encl_page *sgx_encl_page_alloc(struct sgx_encl *encl,
171                                                  unsigned long offset,
172                                                  u64 secinfo_flags)
173 {
174         struct sgx_encl_page *encl_page;
175         unsigned long prot;
176
177         encl_page = kzalloc(sizeof(*encl_page), GFP_KERNEL);
178         if (!encl_page)
179                 return ERR_PTR(-ENOMEM);
180
181         encl_page->desc = encl->base + offset;
182         encl_page->encl = encl;
183
184         prot = _calc_vm_trans(secinfo_flags, SGX_SECINFO_R, PROT_READ)  |
185                _calc_vm_trans(secinfo_flags, SGX_SECINFO_W, PROT_WRITE) |
186                _calc_vm_trans(secinfo_flags, SGX_SECINFO_X, PROT_EXEC);
187
188         /*
189          * TCS pages must always RW set for CPU access while the SECINFO
190          * permissions are *always* zero - the CPU ignores the user provided
191          * values and silently overwrites them with zero permissions.
192          */
193         if ((secinfo_flags & SGX_SECINFO_PAGE_TYPE_MASK) == SGX_SECINFO_TCS)
194                 prot |= PROT_READ | PROT_WRITE;
195
196         /* Calculate maximum of the VM flags for the page. */
197         encl_page->vm_max_prot_bits = calc_vm_prot_bits(prot, 0);
198
199         return encl_page;
200 }
201
202 static int sgx_validate_secinfo(struct sgx_secinfo *secinfo)
203 {
204         u64 perm = secinfo->flags & SGX_SECINFO_PERMISSION_MASK;
205         u64 pt   = secinfo->flags & SGX_SECINFO_PAGE_TYPE_MASK;
206
207         if (pt != SGX_SECINFO_REG && pt != SGX_SECINFO_TCS)
208                 return -EINVAL;
209
210         if ((perm & SGX_SECINFO_W) && !(perm & SGX_SECINFO_R))
211                 return -EINVAL;
212
213         /*
214          * CPU will silently overwrite the permissions as zero, which means
215          * that we need to validate it ourselves.
216          */
217         if (pt == SGX_SECINFO_TCS && perm)
218                 return -EINVAL;
219
220         if (secinfo->flags & SGX_SECINFO_RESERVED_MASK)
221                 return -EINVAL;
222
223         if (memchr_inv(secinfo->reserved, 0, sizeof(secinfo->reserved)))
224                 return -EINVAL;
225
226         return 0;
227 }
228
229 static int __sgx_encl_add_page(struct sgx_encl *encl,
230                                struct sgx_encl_page *encl_page,
231                                struct sgx_epc_page *epc_page,
232                                struct sgx_secinfo *secinfo, unsigned long src)
233 {
234         struct sgx_pageinfo pginfo;
235         struct vm_area_struct *vma;
236         struct page *src_page;
237         int ret;
238
239         /* Deny noexec. */
240         vma = find_vma(current->mm, src);
241         if (!vma)
242                 return -EFAULT;
243
244         if (!(vma->vm_flags & VM_MAYEXEC))
245                 return -EACCES;
246
247         ret = get_user_pages(src, 1, 0, &src_page, NULL);
248         if (ret < 1)
249                 return -EFAULT;
250
251         pginfo.secs = (unsigned long)sgx_get_epc_virt_addr(encl->secs.epc_page);
252         pginfo.addr = encl_page->desc & PAGE_MASK;
253         pginfo.metadata = (unsigned long)secinfo;
254         pginfo.contents = (unsigned long)kmap_atomic(src_page);
255
256         ret = __eadd(&pginfo, sgx_get_epc_virt_addr(epc_page));
257
258         kunmap_atomic((void *)pginfo.contents);
259         put_page(src_page);
260
261         return ret ? -EIO : 0;
262 }
263
264 /*
265  * If the caller requires measurement of the page as a proof for the content,
266  * use EEXTEND to add a measurement for 256 bytes of the page. Repeat this
267  * operation until the entire page is measured."
268  */
269 static int __sgx_encl_extend(struct sgx_encl *encl,
270                              struct sgx_epc_page *epc_page)
271 {
272         unsigned long offset;
273         int ret;
274
275         for (offset = 0; offset < PAGE_SIZE; offset += SGX_EEXTEND_BLOCK_SIZE) {
276                 ret = __eextend(sgx_get_epc_virt_addr(encl->secs.epc_page),
277                                 sgx_get_epc_virt_addr(epc_page) + offset);
278                 if (ret) {
279                         if (encls_failed(ret))
280                                 ENCLS_WARN(ret, "EEXTEND");
281
282                         return -EIO;
283                 }
284         }
285
286         return 0;
287 }
288
289 static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long src,
290                              unsigned long offset, struct sgx_secinfo *secinfo,
291                              unsigned long flags)
292 {
293         struct sgx_encl_page *encl_page;
294         struct sgx_epc_page *epc_page;
295         struct sgx_va_page *va_page;
296         int ret;
297
298         encl_page = sgx_encl_page_alloc(encl, offset, secinfo->flags);
299         if (IS_ERR(encl_page))
300                 return PTR_ERR(encl_page);
301
302         epc_page = sgx_alloc_epc_page(encl_page, true);
303         if (IS_ERR(epc_page)) {
304                 kfree(encl_page);
305                 return PTR_ERR(epc_page);
306         }
307
308         va_page = sgx_encl_grow(encl);
309         if (IS_ERR(va_page)) {
310                 ret = PTR_ERR(va_page);
311                 goto err_out_free;
312         }
313
314         mmap_read_lock(current->mm);
315         mutex_lock(&encl->lock);
316
317         /*
318          * Adding to encl->va_pages must be done under encl->lock.  Ditto for
319          * deleting (via sgx_encl_shrink()) in the error path.
320          */
321         if (va_page)
322                 list_add(&va_page->list, &encl->va_pages);
323
324         /*
325          * Insert prior to EADD in case of OOM.  EADD modifies MRENCLAVE, i.e.
326          * can't be gracefully unwound, while failure on EADD/EXTEND is limited
327          * to userspace errors (or kernel/hardware bugs).
328          */
329         ret = xa_insert(&encl->page_array, PFN_DOWN(encl_page->desc),
330                         encl_page, GFP_KERNEL);
331         if (ret)
332                 goto err_out_unlock;
333
334         ret = __sgx_encl_add_page(encl, encl_page, epc_page, secinfo,
335                                   src);
336         if (ret)
337                 goto err_out;
338
339         /*
340          * Complete the "add" before doing the "extend" so that the "add"
341          * isn't in a half-baked state in the extremely unlikely scenario
342          * the enclave will be destroyed in response to EEXTEND failure.
343          */
344         encl_page->encl = encl;
345         encl_page->epc_page = epc_page;
346         encl->secs_child_cnt++;
347
348         if (flags & SGX_PAGE_MEASURE) {
349                 ret = __sgx_encl_extend(encl, epc_page);
350                 if (ret)
351                         goto err_out;
352         }
353
354         sgx_mark_page_reclaimable(encl_page->epc_page);
355         mutex_unlock(&encl->lock);
356         mmap_read_unlock(current->mm);
357         return ret;
358
359 err_out:
360         xa_erase(&encl->page_array, PFN_DOWN(encl_page->desc));
361
362 err_out_unlock:
363         sgx_encl_shrink(encl, va_page);
364         mutex_unlock(&encl->lock);
365         mmap_read_unlock(current->mm);
366
367 err_out_free:
368         sgx_encl_free_epc_page(epc_page);
369         kfree(encl_page);
370
371         return ret;
372 }
373
374 /**
375  * sgx_ioc_enclave_add_pages() - The handler for %SGX_IOC_ENCLAVE_ADD_PAGES
376  * @encl:       an enclave pointer
377  * @arg:        a user pointer to a struct sgx_enclave_add_pages instance
378  *
379  * Add one or more pages to an uninitialized enclave, and optionally extend the
380  * measurement with the contents of the page. The SECINFO and measurement mask
381  * are applied to all pages.
382  *
383  * A SECINFO for a TCS is required to always contain zero permissions because
384  * CPU silently zeros them. Allowing anything else would cause a mismatch in
385  * the measurement.
386  *
387  * mmap()'s protection bits are capped by the page permissions. For each page
388  * address, the maximum protection bits are computed with the following
389  * heuristics:
390  *
391  * 1. A regular page: PROT_R, PROT_W and PROT_X match the SECINFO permissions.
392  * 2. A TCS page: PROT_R | PROT_W.
393  *
394  * mmap() is not allowed to surpass the minimum of the maximum protection bits
395  * within the given address range.
396  *
397  * The function deinitializes kernel data structures for enclave and returns
398  * -EIO in any of the following conditions:
399  *
400  * - Enclave Page Cache (EPC), the physical memory holding enclaves, has
401  *   been invalidated. This will cause EADD and EEXTEND to fail.
402  * - If the source address is corrupted somehow when executing EADD.
403  *
404  * Return:
405  * - 0:         Success.
406  * - -EACCES:   The source page is located in a noexec partition.
407  * - -ENOMEM:   Out of EPC pages.
408  * - -EINTR:    The call was interrupted before data was processed.
409  * - -EIO:      Either EADD or EEXTEND failed because invalid source address
410  *              or power cycle.
411  * - -errno:    POSIX error.
412  */
413 static long sgx_ioc_enclave_add_pages(struct sgx_encl *encl, void __user *arg)
414 {
415         struct sgx_enclave_add_pages add_arg;
416         struct sgx_secinfo secinfo;
417         unsigned long c;
418         int ret;
419
420         if (!test_bit(SGX_ENCL_CREATED, &encl->flags) ||
421             test_bit(SGX_ENCL_INITIALIZED, &encl->flags))
422                 return -EINVAL;
423
424         if (copy_from_user(&add_arg, arg, sizeof(add_arg)))
425                 return -EFAULT;
426
427         if (!IS_ALIGNED(add_arg.offset, PAGE_SIZE) ||
428             !IS_ALIGNED(add_arg.src, PAGE_SIZE))
429                 return -EINVAL;
430
431         if (!add_arg.length || add_arg.length & (PAGE_SIZE - 1))
432                 return -EINVAL;
433
434         if (add_arg.offset + add_arg.length - PAGE_SIZE >= encl->size)
435                 return -EINVAL;
436
437         if (copy_from_user(&secinfo, (void __user *)add_arg.secinfo,
438                            sizeof(secinfo)))
439                 return -EFAULT;
440
441         if (sgx_validate_secinfo(&secinfo))
442                 return -EINVAL;
443
444         for (c = 0 ; c < add_arg.length; c += PAGE_SIZE) {
445                 if (signal_pending(current)) {
446                         if (!c)
447                                 ret = -ERESTARTSYS;
448
449                         break;
450                 }
451
452                 if (need_resched())
453                         cond_resched();
454
455                 ret = sgx_encl_add_page(encl, add_arg.src + c, add_arg.offset + c,
456                                         &secinfo, add_arg.flags);
457                 if (ret)
458                         break;
459         }
460
461         add_arg.count = c;
462
463         if (copy_to_user(arg, &add_arg, sizeof(add_arg)))
464                 return -EFAULT;
465
466         return ret;
467 }
468
469 static int __sgx_get_key_hash(struct crypto_shash *tfm, const void *modulus,
470                               void *hash)
471 {
472         SHASH_DESC_ON_STACK(shash, tfm);
473
474         shash->tfm = tfm;
475
476         return crypto_shash_digest(shash, modulus, SGX_MODULUS_SIZE, hash);
477 }
478
479 static int sgx_get_key_hash(const void *modulus, void *hash)
480 {
481         struct crypto_shash *tfm;
482         int ret;
483
484         tfm = crypto_alloc_shash("sha256", 0, CRYPTO_ALG_ASYNC);
485         if (IS_ERR(tfm))
486                 return PTR_ERR(tfm);
487
488         ret = __sgx_get_key_hash(tfm, modulus, hash);
489
490         crypto_free_shash(tfm);
491         return ret;
492 }
493
494 static int sgx_encl_init(struct sgx_encl *encl, struct sgx_sigstruct *sigstruct,
495                          void *token)
496 {
497         u64 mrsigner[4];
498         int i, j, k;
499         void *addr;
500         int ret;
501
502         /*
503          * Deny initializing enclaves with attributes (namely provisioning)
504          * that have not been explicitly allowed.
505          */
506         if (encl->attributes & ~encl->attributes_mask)
507                 return -EACCES;
508
509         /*
510          * Attributes should not be enforced *only* against what's available on
511          * platform (done in sgx_encl_create) but checked and enforced against
512          * the mask for enforcement in sigstruct. For example an enclave could
513          * opt to sign with AVX bit in xfrm, but still be loadable on a platform
514          * without it if the sigstruct->body.attributes_mask does not turn that
515          * bit on.
516          */
517         if (sigstruct->body.attributes & sigstruct->body.attributes_mask &
518             sgx_attributes_reserved_mask)
519                 return -EINVAL;
520
521         if (sigstruct->body.miscselect & sigstruct->body.misc_mask &
522             sgx_misc_reserved_mask)
523                 return -EINVAL;
524
525         if (sigstruct->body.xfrm & sigstruct->body.xfrm_mask &
526             sgx_xfrm_reserved_mask)
527                 return -EINVAL;
528
529         ret = sgx_get_key_hash(sigstruct->modulus, mrsigner);
530         if (ret)
531                 return ret;
532
533         mutex_lock(&encl->lock);
534
535         /*
536          * ENCLS[EINIT] is interruptible because it has such a high latency,
537          * e.g. 50k+ cycles on success. If an IRQ/NMI/SMI becomes pending,
538          * EINIT may fail with SGX_UNMASKED_EVENT so that the event can be
539          * serviced.
540          */
541         for (i = 0; i < SGX_EINIT_SLEEP_COUNT; i++) {
542                 for (j = 0; j < SGX_EINIT_SPIN_COUNT; j++) {
543                         addr = sgx_get_epc_virt_addr(encl->secs.epc_page);
544
545                         preempt_disable();
546
547                         for (k = 0; k < 4; k++)
548                                 wrmsrl(MSR_IA32_SGXLEPUBKEYHASH0 + k, mrsigner[k]);
549
550                         ret = __einit(sigstruct, token, addr);
551
552                         preempt_enable();
553
554                         if (ret == SGX_UNMASKED_EVENT)
555                                 continue;
556                         else
557                                 break;
558                 }
559
560                 if (ret != SGX_UNMASKED_EVENT)
561                         break;
562
563                 msleep_interruptible(SGX_EINIT_SLEEP_TIME);
564
565                 if (signal_pending(current)) {
566                         ret = -ERESTARTSYS;
567                         goto err_out;
568                 }
569         }
570
571         if (ret & ENCLS_FAULT_FLAG) {
572                 if (encls_failed(ret))
573                         ENCLS_WARN(ret, "EINIT");
574
575                 ret = -EIO;
576         } else if (ret) {
577                 pr_debug("EINIT returned %d\n", ret);
578                 ret = -EPERM;
579         } else {
580                 set_bit(SGX_ENCL_INITIALIZED, &encl->flags);
581         }
582
583 err_out:
584         mutex_unlock(&encl->lock);
585         return ret;
586 }
587
588 /**
589  * sgx_ioc_enclave_init() - handler for %SGX_IOC_ENCLAVE_INIT
590  * @encl:       an enclave pointer
591  * @arg:        userspace pointer to a struct sgx_enclave_init instance
592  *
593  * Flush any outstanding enqueued EADD operations and perform EINIT.  The
594  * Launch Enclave Public Key Hash MSRs are rewritten as necessary to match
595  * the enclave's MRSIGNER, which is caculated from the provided sigstruct.
596  *
597  * Return:
598  * - 0:         Success.
599  * - -EPERM:    Invalid SIGSTRUCT.
600  * - -EIO:      EINIT failed because of a power cycle.
601  * - -errno:    POSIX error.
602  */
603 static long sgx_ioc_enclave_init(struct sgx_encl *encl, void __user *arg)
604 {
605         struct sgx_sigstruct *sigstruct;
606         struct sgx_enclave_init init_arg;
607         void *token;
608         int ret;
609
610         if (!test_bit(SGX_ENCL_CREATED, &encl->flags) ||
611             test_bit(SGX_ENCL_INITIALIZED, &encl->flags))
612                 return -EINVAL;
613
614         if (copy_from_user(&init_arg, arg, sizeof(init_arg)))
615                 return -EFAULT;
616
617         /*
618          * 'sigstruct' must be on a page boundary and 'token' on a 512 byte
619          * boundary.  kmalloc() will give this alignment when allocating
620          * PAGE_SIZE bytes.
621          */
622         sigstruct = kmalloc(PAGE_SIZE, GFP_KERNEL);
623         if (!sigstruct)
624                 return -ENOMEM;
625
626         token = (void *)((unsigned long)sigstruct + PAGE_SIZE / 2);
627         memset(token, 0, SGX_LAUNCH_TOKEN_SIZE);
628
629         if (copy_from_user(sigstruct, (void __user *)init_arg.sigstruct,
630                            sizeof(*sigstruct))) {
631                 ret = -EFAULT;
632                 goto out;
633         }
634
635         /*
636          * A legacy field used with Intel signed enclaves. These used to mean
637          * regular and architectural enclaves. The CPU only accepts these values
638          * but they do not have any other meaning.
639          *
640          * Thus, reject any other values.
641          */
642         if (sigstruct->header.vendor != 0x0000 &&
643             sigstruct->header.vendor != 0x8086) {
644                 ret = -EINVAL;
645                 goto out;
646         }
647
648         ret = sgx_encl_init(encl, sigstruct, token);
649
650 out:
651         kfree(sigstruct);
652         return ret;
653 }
654
655 /**
656  * sgx_ioc_enclave_provision() - handler for %SGX_IOC_ENCLAVE_PROVISION
657  * @encl:       an enclave pointer
658  * @arg:        userspace pointer to a struct sgx_enclave_provision instance
659  *
660  * Allow ATTRIBUTE.PROVISION_KEY for an enclave by providing a file handle to
661  * /dev/sgx_provision.
662  *
663  * Return:
664  * - 0:         Success.
665  * - -errno:    Otherwise.
666  */
667 static long sgx_ioc_enclave_provision(struct sgx_encl *encl, void __user *arg)
668 {
669         struct sgx_enclave_provision params;
670         struct file *file;
671
672         if (copy_from_user(&params, arg, sizeof(params)))
673                 return -EFAULT;
674
675         file = fget(params.fd);
676         if (!file)
677                 return -EINVAL;
678
679         if (file->f_op != &sgx_provision_fops) {
680                 fput(file);
681                 return -EINVAL;
682         }
683
684         encl->attributes_mask |= SGX_ATTR_PROVISIONKEY;
685
686         fput(file);
687         return 0;
688 }
689
690 long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
691 {
692         struct sgx_encl *encl = filep->private_data;
693         int ret;
694
695         if (test_and_set_bit(SGX_ENCL_IOCTL, &encl->flags))
696                 return -EBUSY;
697
698         switch (cmd) {
699         case SGX_IOC_ENCLAVE_CREATE:
700                 ret = sgx_ioc_enclave_create(encl, (void __user *)arg);
701                 break;
702         case SGX_IOC_ENCLAVE_ADD_PAGES:
703                 ret = sgx_ioc_enclave_add_pages(encl, (void __user *)arg);
704                 break;
705         case SGX_IOC_ENCLAVE_INIT:
706                 ret = sgx_ioc_enclave_init(encl, (void __user *)arg);
707                 break;
708         case SGX_IOC_ENCLAVE_PROVISION:
709                 ret = sgx_ioc_enclave_provision(encl, (void __user *)arg);
710                 break;
711         default:
712                 ret = -ENOIOCTLCMD;
713                 break;
714         }
715
716         clear_bit(SGX_ENCL_IOCTL, &encl->flags);
717         return ret;
718 }