Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150086859
D11113.id29380.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
34 KB
Referenced Files
None
Subscribers
None
D11113.id29380.diff
View Options
Index: sys/amd64/sgx/sgx.h
===================================================================
--- /dev/null
+++ sys/amd64/sgx/sgx.h
@@ -0,0 +1,252 @@
+/*-
+ * Copyright (c) 2017 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * This software was developed by BAE Systems, the University of Cambridge
+ * Computer Laboratory, and Memorial University under DARPA/AFRL contract
+ * FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent Computing
+ * (TC) research program.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _AMD64_SGX_SGX_H_
+#define _AMD64_SGX_SGX_H_
+
+#define SGX_MAGIC 0xA4
+#define SGX_IOC_ENCLAVE_CREATE \
+ (_IOW(SGX_MAGIC, 0x00, struct sgx_enclave_create) & 0xffff)
+#define SGX_IOC_ENCLAVE_ADD_PAGE \
+ (_IOW(SGX_MAGIC, 0x01, struct sgx_enclave_add_page) & 0xffff)
+#define SGX_IOC_ENCLAVE_INIT \
+ (_IOW(SGX_MAGIC, 0x02, struct sgx_enclave_init) & 0xffff)
+
+#define SIGSTRUCT_SIZE 1808
+#define EINITTOKEN_SIZE 304
+
+/* Error codes */
+#define SGX_SUCCESS 0
+#define SGX_UNMASKED_EVENT 128
+
+struct sgx_enclave_create {
+ uint64_t src;
+};
+
+struct sgx_enclave_add_page {
+ uint64_t addr;
+ uint64_t src;
+ uint64_t secinfo;
+ uint16_t mrmask;
+};
+
+struct sgx_enclave_init {
+ uint64_t addr;
+ uint64_t sigstruct;
+ uint64_t einittoken;
+};
+
+enum {
+ ECREATE = 0x0,
+ EADD = 0x1,
+ EINIT = 0x2,
+ EREMOVE = 0x3,
+ EDGBRD = 0x4,
+ EDGBWR = 0x5,
+ EEXTEND = 0x6,
+ ELDU = 0x8,
+ EBLOCK = 0x9,
+ EPA = 0xA,
+ EWB = 0xB,
+ ETRACK = 0xC,
+};
+
+enum {
+ PT_SECS = 0x00,
+ PT_TCS = 0x01,
+ PT_REG = 0x02,
+ PT_VA = 0x03,
+ PT_TRIM = 0x04,
+};
+
+struct page_info {
+ uint64_t linaddr;
+ uint64_t srcpge;
+ union {
+ uint64_t secinfo;
+ uint64_t pcmd;
+ };
+ uint64_t secs;
+} __attribute__((aligned(32)));
+
+struct out_regs {
+ uint32_t oeax;
+ uint64_t orbx;
+ uint64_t orcx;
+ uint64_t ordx;
+};
+
+#define __encls(cmd, tmp, rbx, rcx, rdx) \
+ __asm __volatile( \
+ ".byte 0x0f, 0x01, 0xcf\n\t" \
+ :"=a"(tmp.oeax), \
+ "=b"(tmp.orbx), \
+ "=c"(tmp.orcx), \
+ "=d"(tmp.ordx) \
+ :"a"((uint32_t)cmd), \
+ "b"(rbx), \
+ "c"(rcx), \
+ "d"(rdx) \
+ :"memory");
+
+static inline u_long
+__ecreate(struct page_info *pginfo, void *secs)
+{
+ struct out_regs tmp;
+
+ __encls(ECREATE, tmp, pginfo, secs, 0);
+
+ return (tmp.oeax);
+}
+
+static inline u_long
+__eadd(struct page_info *pginfo, void *epc)
+{
+ struct out_regs tmp;
+
+ __encls(EADD, tmp, pginfo, epc, 0);
+
+ return (tmp.oeax);
+}
+
+static inline int
+__einit(void *sigstruct, void *secs, void *einittoken)
+{
+ struct out_regs tmp;
+
+ __encls(EINIT, tmp, sigstruct, secs, einittoken);
+
+ return (tmp.oeax);
+}
+
+static inline int
+__eextend(void *secs, void *epc)
+{
+ struct out_regs tmp;
+
+ __encls(EEXTEND, tmp, secs, epc, 0);
+
+ return (tmp.oeax);
+}
+
+static inline int
+__epa(void *epc)
+{
+ struct out_regs tmp;
+ uint64_t rbx;
+
+ rbx = PT_VA;
+
+ __encls(EPA, tmp, rbx, epc, 0);
+
+ return (tmp.oeax);
+}
+
+static inline int
+__eldu(uint64_t rbx, uint64_t rcx,
+ uint64_t rdx)
+{
+ struct out_regs tmp;
+
+ __encls(ELDU, tmp, rbx, rcx, rdx);
+
+ return (tmp.oeax);
+}
+
+static inline int
+__eremove(void *epc)
+{
+ struct out_regs tmp;
+
+ __encls(EREMOVE, tmp, 0, epc, 0);
+
+ return (tmp.oeax);
+}
+
+#define SECINFO_FLAGS_PT_S 8
+#define SECINFO_FLAGS_PT_M (0xff << SECINFO_FLAGS_PT_S)
+
+struct secinfo {
+ uint64_t flags;
+ uint64_t reserved[7];
+} __attribute__((aligned(128)));
+
+/*
+ * 2.7 SGX ENCLAVE CONTROL STRUCTURE (SECS)
+ * The SECS data structure requires 4K-Bytes alignment.
+ */
+
+struct secs_attr {
+ uint8_t reserved1: 1;
+ uint8_t debug: 1;
+ uint8_t mode64bit: 1;
+ uint8_t reserved2: 1;
+ uint8_t provisionkey: 1;
+ uint8_t einittokenkey: 1;
+ uint8_t reserved3: 2;
+ uint8_t reserved4[7];
+ uint64_t xfrm; /* X-Feature Request Mask */
+};
+
+struct secs {
+ uint64_t size;
+ uint64_t base;
+ uint32_t ssa_frame_size;
+ uint32_t misc_select;
+ uint8_t reserved1[24];
+ struct secs_attr attributes;
+ uint8_t mr_enclave[32];
+ uint8_t reserved2[32];
+ uint8_t mr_signer[32];
+ uint8_t reserved3[96];
+ uint16_t isv_prod_id;
+ uint16_t isv_svn;
+ uint8_t reserved4[3836];
+};
+
+struct tcs {
+ uint64_t state;
+ uint64_t flags;
+ uint64_t ossa;
+ uint32_t cssa;
+ uint32_t nssa;
+ uint64_t oentry;
+ uint64_t aep;
+ uint64_t ofsbasgx;
+ uint64_t ogsbasgx;
+ uint32_t fslimit;
+ uint32_t gslimit;
+ uint64_t reserved[503];
+};
+
+#endif /* !_AMD64_SGX_SGX_H_ */
Index: sys/amd64/sgx/sgx.c
===================================================================
--- /dev/null
+++ sys/amd64/sgx/sgx.c
@@ -0,0 +1,1090 @@
+/*-
+ * Copyright (c) 2017 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * This software was developed by BAE Systems, the University of Cambridge
+ * Computer Laboratory, and Memorial University under DARPA/AFRL contract
+ * FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent Computing
+ * (TC) research program.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/rwlock.h>
+#include <sys/conf.h>
+#include <sys/module.h>
+#include <sys/proc.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_pager.h>
+#include <vm/pmap.h>
+
+#include <machine/md_var.h>
+#include <machine/specialreg.h>
+#include <machine/bus.h>
+
+#include "sgx.h"
+
+#define SGX_CPUID 0x12
+#define SGX_PAGE_SIZE 4096
+#define SGX_VA_PAGE_SLOTS 512
+
+#define DEBUG
+#undef DEBUG
+
+#ifdef DEBUG
+#define debug_printf(dev, fmt, ...) \
+ device_printf(dev, fmt, ##__VA_ARGS__)
+#else
+#define debug_printf(dev, fmt, ...)
+#endif
+
+MALLOC_DEFINE(M_SGX, "sgx", "SGX driver");
+
+/* EPC (Enclave Page Cache) page */
+struct epc_page {
+ uint64_t base;
+ uint64_t phys;
+ uint8_t used;
+};
+
+/* Version Array page */
+struct va_page {
+ struct epc_page *epc_page;
+ TAILQ_ENTRY(va_page) va_next;
+ bool slots[SGX_VA_PAGE_SLOTS];
+};
+
+struct sgx_enclave_page {
+ struct epc_page *epc_page;
+ struct va_page *va_page;
+ int va_slot;
+ uint64_t addr;
+ TAILQ_ENTRY(sgx_enclave_page) next;
+};
+
+struct sgx_enclave {
+ uint64_t base;
+ uint64_t size;
+ struct sgx_enclave_page secs_page;
+ struct sgx_vm_handle *vmh;
+ struct mtx mtx;
+ TAILQ_ENTRY(sgx_enclave) next;
+ TAILQ_HEAD(, sgx_enclave_page) pages;
+ TAILQ_HEAD(, va_page) va_pages;
+};
+
+struct sgx_softc {
+ struct cdev *sgx_cdev;
+ device_t dev;
+ struct mtx mtx_epc;
+ struct mtx mtx;
+ struct epc_page *epc_pages;
+ uint32_t npages;
+ TAILQ_HEAD(, sgx_enclave) enclaves;
+};
+
+struct sgx_vm_handle {
+ struct sgx_softc *sc;
+ vm_object_t mem;
+ uint64_t base;
+ vm_size_t size;
+ struct sgx_enclave *enclave;
+};
+
+static struct epc_page *
+sgx_epc_page_get(struct sgx_softc *sc)
+{
+ struct epc_page *epc;
+ int i;
+
+ mtx_lock(&sc->mtx_epc);
+
+ for (i = 0; i < sc->npages; i++) {
+ epc = &sc->epc_pages[i];
+ if (epc->used == 0) {
+ epc->used = 1;
+ mtx_unlock(&sc->mtx_epc);
+ return (epc);
+ }
+ }
+
+ mtx_unlock(&sc->mtx_epc);
+
+ return (NULL);
+}
+
+static void
+sgx_epc_page_put(struct sgx_softc *sc, struct epc_page *epc)
+{
+
+ epc->used = 0;
+}
+
+static int
+sgx_epc_page_count(struct sgx_softc *sc)
+{
+ struct epc_page *epc;
+ int cnt;
+ int i;
+
+ cnt = 0;
+
+ for (i = 0; i < sc->npages; i++) {
+ epc = &sc->epc_pages[i];
+ if (epc->used == 0) {
+ cnt++;
+ }
+ }
+
+ return (cnt);
+}
+
+static int
+sgx_va_slot_alloc(struct va_page *va_page)
+{
+ int i;
+
+ for (i = 0; i < SGX_VA_PAGE_SLOTS; i++) {
+ if (va_page->slots[i] == 0) {
+ va_page->slots[i] = 1;
+ return (i);
+ }
+ }
+
+ return (-1);
+}
+
+static int
+sgx_va_slot_free(struct sgx_softc *sc,
+ struct sgx_enclave *enclave,
+ struct sgx_enclave_page *enclave_page)
+{
+ struct va_page *va_page;
+ struct epc_page *epc;
+ int va_slot;
+ int found;
+ int i;
+
+ found = 0;
+
+ va_page = enclave_page->va_page;
+ va_slot = enclave_page->va_slot;
+
+ KASSERT(va_page->slots[va_slot] == 1, ("freeing unused page"));
+
+ va_page->slots[va_slot] = 0;
+
+ /* Now check if we need to remove va_page. */
+ for (i = 0; i < SGX_VA_PAGE_SLOTS; i++) {
+ if (va_page->slots[i] == 1) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found == 0) {
+ mtx_lock(&enclave->mtx);
+ TAILQ_REMOVE(&enclave->va_pages, va_page, va_next);
+ mtx_unlock(&enclave->mtx);
+
+ epc = va_page->epc_page;
+ __eremove((void *)epc->base);
+ sgx_epc_page_put(sc, epc);
+ free(enclave_page->va_page, M_SGX);
+ }
+
+ return (0);
+}
+
+static int
+sgx_enclave_page_remove(struct sgx_softc *sc,
+ struct sgx_enclave *enclave,
+ struct sgx_enclave_page *enclave_page)
+{
+ struct epc_page *epc;
+
+ sgx_va_slot_free(sc, enclave, enclave_page);
+
+ epc = enclave_page->epc_page;
+ __eremove((void *)epc->base);
+ sgx_epc_page_put(sc, epc);
+
+ return (0);
+}
+
+static int
+sgx_enclave_page_construct(struct sgx_softc *sc,
+ struct sgx_enclave *enclave,
+ struct sgx_enclave_page *enclave_page)
+{
+ struct va_page *va_page;
+ struct va_page *va_page_tmp;
+ struct epc_page *epc;
+ int va_slot;
+
+ va_slot = -1;
+
+ mtx_lock(&enclave->mtx);
+ TAILQ_FOREACH_SAFE(va_page, &enclave->va_pages, va_next,
+ va_page_tmp) {
+ va_slot = sgx_va_slot_alloc(va_page);
+ if (va_slot >= 0) {
+ break;
+ }
+ }
+ mtx_unlock(&enclave->mtx);
+
+ if (va_slot < 0) {
+ epc = sgx_epc_page_get(sc);
+ if (epc == NULL) {
+ device_printf(sc->dev,
+ "%s: No free epc pages available\n", __func__);
+ return (-1);
+ }
+
+ va_page = malloc(sizeof(struct va_page), M_SGX, M_WAITOK | M_ZERO);
+ if (va_page == NULL) {
+ device_printf(sc->dev,
+ "%s: Can't alloc va_page\n", __func__);
+ sgx_epc_page_put(sc, epc);
+ return (-1);
+ }
+
+ va_slot = sgx_va_slot_alloc(va_page);
+ va_page->epc_page = epc;
+ __epa((void *)epc->base);
+
+ mtx_lock(&enclave->mtx);
+ TAILQ_INSERT_TAIL(&enclave->va_pages, va_page, va_next);
+ mtx_unlock(&enclave->mtx);
+ }
+
+ enclave_page->va_page = va_page;
+ enclave_page->va_slot = va_slot;
+
+ return (0);
+}
+
+static int
+sgx_mem_find(struct sgx_softc *sc, uint64_t addr,
+ vm_map_entry_t *entry0, vm_object_t *mem0)
+{
+ struct proc *proc;
+ vm_map_t map;
+ vm_map_entry_t entry;
+ vm_object_t mem;
+ vm_pindex_t pindex;
+ vm_prot_t prot;
+ boolean_t wired;
+ int error;
+
+ proc = curthread->td_proc;
+
+ map = &proc->p_vmspace->vm_map;
+ error = vm_map_lookup(&map, addr, VM_PROT_NONE, &entry,
+ &mem, &pindex, &prot, &wired);
+ vm_map_lookup_done(map, entry);
+ if (error != 0) {
+ device_printf(sc->dev,
+ "%s: can't find enclave\n", __func__);
+ return (-1);
+ }
+
+ *mem0 = mem;
+ *entry0 = entry;
+
+ return (0);
+}
+
+static int
+sgx_enclave_find(struct sgx_softc *sc, uint64_t addr,
+ struct sgx_enclave **encl)
+{
+ struct sgx_vm_handle *vmh;
+ vm_map_entry_t entry;
+ vm_object_t mem;
+ int ret;
+
+ ret = sgx_mem_find(sc, addr, &entry, &mem);
+ if (ret != 0) {
+ return (-1);
+ }
+
+ vmh = mem->handle;
+ *encl = vmh->enclave;
+
+ return (0);
+}
+
+static struct sgx_enclave *
+sgx_enclave_alloc(struct sgx_softc *sc, struct secs *secs)
+{
+ struct sgx_enclave *enclave;
+ struct sgx_vm_handle *vmh;
+ vm_map_entry_t entry;
+ vm_object_t mem;
+ int ret;
+
+ ret = sgx_mem_find(sc, secs->base, &entry, &mem);
+ if (ret != 0) {
+ device_printf(sc->dev, "Can't find vm_map\n");
+ return (NULL);
+ }
+
+ vmh = mem->handle;
+ vmh->base = (entry->start - entry->offset);
+
+ enclave = malloc(sizeof(struct sgx_enclave), M_SGX, M_WAITOK | M_ZERO);
+ if (enclave == NULL) {
+ device_printf(sc->dev, "Can't alloc memory for enclave\n");
+ return (NULL);
+ }
+
+ TAILQ_INIT(&enclave->pages);
+ TAILQ_INIT(&enclave->va_pages);
+
+ mtx_init(&enclave->mtx, "SGX enclave", NULL, MTX_DEF);
+
+ enclave->base = secs->base;
+ enclave->size = secs->size;
+
+ enclave->vmh = vmh;
+ vmh->enclave = enclave;
+
+ return (enclave);
+}
+
+static int
+sgx_enclave_free(struct sgx_softc *sc,
+ struct sgx_enclave *enclave)
+{
+ struct sgx_enclave_page *enclave_page_tmp;
+ struct sgx_enclave_page *enclave_page;
+
+ mtx_lock(&sc->mtx);
+ TAILQ_REMOVE(&sc->enclaves, enclave, next);
+ mtx_unlock(&sc->mtx);
+
+ /* Remove all the enclave pages */
+ TAILQ_FOREACH_SAFE(enclave_page, &enclave->pages, next,
+ enclave_page_tmp) {
+ TAILQ_REMOVE(&enclave->pages, enclave_page, next);
+ sgx_enclave_page_remove(sc, enclave, enclave_page);
+ free(enclave_page, M_SGX);
+ }
+
+ /* Remove SECS page */
+ enclave_page = &enclave->secs_page;
+ sgx_enclave_page_remove(sc, enclave, enclave_page);
+
+ free(enclave, M_SGX);
+
+ return (0);
+}
+
+static void
+sgx_measure_page(struct epc_page *secs, struct epc_page *epc,
+ uint16_t mrmask)
+{
+ int i, j;
+
+ for (i = 0, j = 1; i < PAGE_SIZE; i += 0x100, j <<= 1) {
+ if (!(j & mrmask)) {
+ continue;
+ }
+
+ __eextend((void *)secs->base,
+ (void *)((uint64_t)epc->base + i));
+ }
+}
+
+static int
+sgx_tcs_validate(struct tcs *tcs)
+{
+ int i;
+
+ if ((tcs->flags != 0) ||
+ (tcs->ossa & (PAGE_SIZE - 1)) ||
+ (tcs->ofsbasgx & (PAGE_SIZE - 1)) ||
+ (tcs->ogsbasgx & (PAGE_SIZE - 1)) ||
+ ((tcs->fslimit & 0xfff) != 0xfff) ||
+ ((tcs->gslimit & 0xfff) != 0xfff)) {
+ return (-1);
+ }
+
+ for (i = 0; i < sizeof(tcs->reserved)/sizeof(uint64_t); i++) {
+ if (tcs->reserved[i]) {
+ return (-1);
+ }
+ }
+
+ return (0);
+}
+
+static void
+sgx_tcs_dump(struct sgx_softc *sc, struct tcs *t)
+{
+
+ debug_printf(sc->dev, "t->state %lx\n", t->state);
+ debug_printf(sc->dev, "t->flags %lx\n", t->flags);
+ debug_printf(sc->dev, "t->ossa %lx\n", t->ossa);
+ debug_printf(sc->dev, "t->cssa %x\n", t->cssa);
+ debug_printf(sc->dev, "t->nssa %x\n", t->nssa);
+ debug_printf(sc->dev, "t->oentry %lx\n", t->oentry);
+ debug_printf(sc->dev, "t->aep %lx\n", t->aep);
+ debug_printf(sc->dev, "t->ofsbasgx %lx\n", t->ofsbasgx);
+ debug_printf(sc->dev, "t->ogsbasgx %lx\n", t->ogsbasgx);
+ debug_printf(sc->dev, "t->fslimit %x\n", t->fslimit);
+ debug_printf(sc->dev, "t->gslimit %x\n", t->gslimit);
+}
+
+static int
+sgx_pg_ctor(void *handle, vm_ooffset_t size, vm_prot_t prot,
+ vm_ooffset_t foff, struct ucred *cred, u_short *color)
+{
+ struct sgx_vm_handle *vmh;
+ struct sgx_softc *sc;
+
+ if (handle == NULL) {
+ printf("%s: vmh not found\n", __func__);
+ return (0);
+ }
+
+ vmh = handle;
+ sc = vmh->sc;
+
+ debug_printf(sc->dev,
+ "%s: vmh->base %lx foff 0x%lx size 0x%lx\n",
+ __func__, vmh->base, foff, size);
+
+ return (0);
+}
+
+static void
+sgx_pg_dtor(void *handle)
+{
+ struct sgx_vm_handle *vmh;
+ struct sgx_softc *sc;
+
+ if (handle == NULL) {
+ printf("%s: vmh not found\n", __func__);
+ return;
+ }
+
+ vmh = handle;
+ sc = vmh->sc;
+
+ if (vmh->enclave == NULL) {
+ device_printf(sc->dev,
+ "%s: enclave not found\n", __func__);
+ return;
+ }
+ sgx_enclave_free(sc, vmh->enclave);
+ free(vmh, M_SGX);
+
+ debug_printf(sc->dev, "count free epc pages: %d\n",
+ sgx_epc_page_count(sc));
+}
+
+static int
+sgx_pg_fault(vm_object_t object, vm_ooffset_t offset,
+ int prot, vm_page_t *mres)
+{
+ struct sgx_enclave *enclave;
+ struct sgx_vm_handle *vmh;
+ struct sgx_softc *sc;
+ vm_page_t page;
+ vm_memattr_t memattr;
+ vm_pindex_t pidx;
+ vm_paddr_t paddr;
+ struct sgx_enclave_page *enclave_page_tmp;
+ struct sgx_enclave_page *enclave_page;
+ struct epc_page *epc;
+ int found;
+
+ vmh = object->handle;
+ if (vmh == NULL) {
+ return (VM_PAGER_FAIL);
+ }
+
+ enclave = vmh->enclave;
+ if (enclave == NULL) {
+ return (VM_PAGER_FAIL);
+ }
+
+ sc = vmh->sc;
+
+ debug_printf(sc->dev, "%s: offset 0x%lx\n", __func__, offset);
+
+ memattr = object->memattr;
+ pidx = OFF_TO_IDX(offset);
+
+ found = 0;
+ mtx_lock(&enclave->mtx);
+ TAILQ_FOREACH_SAFE(enclave_page, &enclave->pages, next,
+ enclave_page_tmp) {
+ if ((vmh->base + offset) == enclave_page->addr) {
+ found = 1;
+ break;
+ }
+ }
+ mtx_unlock(&enclave->mtx);
+ if (found == 0) {
+ device_printf(sc->dev,
+ "%s: page not found\n", __func__);
+ return (VM_PAGER_FAIL);
+ }
+
+ epc = enclave_page->epc_page;
+ paddr = epc->phys;
+
+ if (((*mres)->flags & PG_FICTITIOUS) != 0) {
+ page = *mres;
+ vm_page_updatefake(page, paddr, memattr);
+ } else {
+ VM_OBJECT_WUNLOCK(object);
+ page = vm_page_getfake(paddr, memattr);
+ VM_OBJECT_WLOCK(object);
+ vm_page_lock(*mres);
+ vm_page_free(*mres);
+ vm_page_unlock(*mres);
+ *mres = page;
+ vm_page_insert(page, object, pidx);
+ }
+ page->valid = VM_PAGE_BITS_ALL;
+
+ return (VM_PAGER_OK);
+}
+
+static struct cdev_pager_ops sgx_pg_ops = {
+ .cdev_pg_ctor = sgx_pg_ctor,
+ .cdev_pg_dtor = sgx_pg_dtor,
+ .cdev_pg_fault = sgx_pg_fault,
+};
+
+static int
+sgx_create(struct sgx_softc *sc, struct sgx_enclave_create *param)
+{
+ struct sgx_enclave_page *secs_page;
+ struct page_info pginfo;
+ struct secinfo secinfo;
+ struct sgx_enclave *enclave;
+ struct epc_page *epc;
+ struct secs *m_secs;
+ int ret;
+
+ epc = NULL;
+ m_secs = NULL;
+ enclave = NULL;
+
+ /* SGX Enclave Control Structure (SECS) */
+ m_secs = (struct secs *)kmem_alloc_contig(kmem_arena, PAGE_SIZE,
+ 0/*flags*/, 0, BUS_SPACE_MAXADDR_32BIT,
+ PAGE_SIZE, 0, VM_MEMATTR_DEFAULT);
+ if (m_secs == NULL) {
+ device_printf(sc->dev, "Can't allocate memory.\n");
+ goto error;
+ }
+
+ ret = copyin((void *)param->src, m_secs, sizeof(struct secs));
+ if (ret != 0) {
+ device_printf(sc->dev, "Can't copy SECS\n");
+ goto error;
+ }
+
+ enclave = sgx_enclave_alloc(sc, m_secs);
+ if (enclave == NULL) {
+ device_printf(sc->dev, "Can't copy SECS\n");
+ goto error;
+ }
+
+ memset(&secinfo, 0, sizeof(struct secinfo));
+ memset(&pginfo, 0, sizeof(struct page_info));
+ pginfo.linaddr = 0;
+ pginfo.srcpge = (uint64_t)m_secs;
+ pginfo.secinfo = (uint64_t)&secinfo;
+ pginfo.secs = 0;
+
+ epc = sgx_epc_page_get(sc);
+ if (epc == NULL) {
+ device_printf(sc->dev,
+ "%s: failed to get epc page\n", __func__);
+ goto error;
+ }
+
+ ret = sgx_enclave_page_construct(sc, enclave, &enclave->secs_page);
+ if (ret != 0) {
+ device_printf(sc->dev, "can't construct page\n");
+ goto error;
+ }
+
+ secs_page = &enclave->secs_page;
+ secs_page->epc_page = epc;
+
+ __ecreate(&pginfo, (void *)epc->base);
+
+ mtx_lock(&sc->mtx);
+ TAILQ_INSERT_TAIL(&sc->enclaves, enclave, next);
+ mtx_unlock(&sc->mtx);
+
+ kmem_free(kmem_arena, (vm_offset_t)m_secs, PAGE_SIZE);
+
+ return (0);
+
+error:
+ if (m_secs != NULL) {
+ kmem_free(kmem_arena, (vm_offset_t)m_secs, PAGE_SIZE);
+ }
+ if (enclave != NULL) {
+ free(enclave, M_SGX);
+ }
+ if (epc != NULL) {
+ sgx_epc_page_put(sc, epc);
+ }
+
+ return (-1);
+}
+
+static int
+sgx_add_page(struct sgx_softc *sc, struct sgx_enclave_add_page *addp)
+{
+ struct sgx_enclave_page *enclave_page;
+ struct epc_page *secs_epc_page;
+ struct sgx_enclave *enclave;
+ struct epc_page *epc;
+ struct page_info pginfo;
+ struct secinfo secinfo;
+ void *tmp_vaddr;
+ uint64_t page_type;
+ struct proc *proc;
+ struct tcs *t;
+ pmap_t pmap;
+ int ret;
+
+ tmp_vaddr = NULL;
+ enclave_page = NULL;
+ epc = NULL;
+
+ ret = sgx_enclave_find(sc, addp->addr, &enclave);
+ if (ret != 0) {
+ device_printf(sc->dev, "Failed to find enclave\n");
+ return (-1);
+ }
+
+ proc = curthread->td_proc;
+ pmap = vm_map_pmap(&proc->p_vmspace->vm_map);
+
+ memset(&secinfo, 0, sizeof(struct secinfo));
+ ret = copyin((void *)addp->secinfo, &secinfo, sizeof(struct secinfo));
+ if (ret != 0) {
+ device_printf(sc->dev,
+ "%s: Failed to copy secinfo\n", __func__);
+ return (-1);
+ }
+
+ tmp_vaddr = (void *)kmem_alloc_contig(kmem_arena, PAGE_SIZE,
+ 0/*flags*/, 0, BUS_SPACE_MAXADDR_32BIT,
+ PAGE_SIZE, 0, VM_MEMATTR_DEFAULT);
+ if (tmp_vaddr == NULL) {
+ device_printf(sc->dev,
+ "%s: failed to alloc memory\n", __func__);
+ goto error;
+ }
+
+ ret = copyin((void *)addp->src, tmp_vaddr, PAGE_SIZE);
+ if (ret != 0) {
+ device_printf(sc->dev,
+ "%s: Failed to copy page\n", __func__);
+ goto error;
+ }
+
+ page_type = (secinfo.flags & SECINFO_FLAGS_PT_M) >> \
+ SECINFO_FLAGS_PT_S;
+ if (page_type == PT_TCS) {
+ t = (struct tcs *)tmp_vaddr;
+ if (sgx_tcs_validate(t) != 0) {
+ device_printf(sc->dev,
+ "%s: TCS page validation failed\n", __func__);
+ return (-1);
+ }
+ sgx_tcs_dump(sc, t);
+ }
+
+ enclave_page = malloc(sizeof(struct sgx_enclave_page),
+ M_SGX, M_WAITOK | M_ZERO);
+ if (enclave_page == NULL) {
+ device_printf(sc->dev,
+ "%s: Can't allocate enclave page.\n", __func__);
+ goto error;
+ }
+
+ epc = sgx_epc_page_get(sc);
+ if (epc == NULL) {
+ device_printf(sc->dev,
+ "%s: failed to get epc page\n", __func__);
+ goto error;
+ }
+
+ ret = sgx_enclave_page_construct(sc, enclave, enclave_page);
+ if (ret != 0) {
+ device_printf(sc->dev, "Can't construct page\n");
+ goto error;
+ }
+
+ enclave_page->epc_page = epc;
+ enclave_page->addr = addp->addr;
+ secs_epc_page = enclave->secs_page.epc_page;
+
+ memset(&pginfo, 0, sizeof(struct page_info));
+ pginfo.linaddr = (uint64_t)addp->addr;
+ pginfo.srcpge = (uint64_t)tmp_vaddr;
+ pginfo.secinfo = (uint64_t)&secinfo;
+ pginfo.secs = (uint64_t)secs_epc_page->base;
+ __eadd(&pginfo, (void *)epc->base);
+ kmem_free(kmem_arena, (vm_offset_t)tmp_vaddr, PAGE_SIZE);
+
+ sgx_measure_page(enclave->secs_page.epc_page, epc, addp->mrmask);
+
+ mtx_lock(&enclave->mtx);
+ TAILQ_INSERT_TAIL(&enclave->pages, enclave_page, next);
+ mtx_unlock(&enclave->mtx);
+
+ return (0);
+
+error:
+ if (tmp_vaddr != NULL) {
+ kmem_free(kmem_arena, (vm_offset_t)tmp_vaddr, PAGE_SIZE);
+ }
+ if (epc != NULL) {
+ sgx_epc_page_put(sc, epc);
+ }
+
+ return (-1);
+}
+
+static int
+sgx_init(struct sgx_softc *sc, struct sgx_enclave_init *initp)
+{
+ struct epc_page *secs_epc_page;
+ struct sgx_enclave *enclave;
+ void *tmp_vaddr;
+ void *einittoken;
+ void *sigstruct;
+ int retry;
+ int ret;
+
+ tmp_vaddr = NULL;
+
+ debug_printf(sc->dev, "%s: addr %lx, sigstruct %lx,"
+ "einittoken %lx\n", __func__, initp->addr,
+ initp->sigstruct, initp->einittoken);
+
+ ret = sgx_enclave_find(sc, initp->addr, &enclave);
+ if (ret != 0) {
+ device_printf(sc->dev, "Failed to get enclave\n");
+ goto error;
+ }
+
+ secs_epc_page = enclave->secs_page.epc_page;
+
+ tmp_vaddr = (void *)kmem_alloc_contig(kmem_arena, PAGE_SIZE,
+ 0/*flags*/, 0, BUS_SPACE_MAXADDR_32BIT,
+ PAGE_SIZE, 0, VM_MEMATTR_DEFAULT);
+ if (tmp_vaddr == NULL) {
+ device_printf(sc->dev,
+ "%s: failed to alloc memory\n", __func__);
+ goto error;
+ }
+ sigstruct = tmp_vaddr;
+ einittoken = (void *)((uint64_t)sigstruct + PAGE_SIZE / 2);
+
+ ret = copyin((void *)initp->sigstruct, sigstruct,
+ SIGSTRUCT_SIZE);
+ if (ret != 0) {
+ device_printf(sc->dev,
+ "%s: Failed to copy SIGSTRUCT page\n", __func__);
+ goto error;
+ }
+
+ ret = copyin((void *)initp->einittoken, einittoken,
+ EINITTOKEN_SIZE);
+ if (ret != 0) {
+ device_printf(sc->dev,
+ "%s: Failed to copy EINITTOKEN page\n", __func__);
+ goto error;
+ }
+
+ retry = 16;
+ do {
+ ret = __einit(sigstruct, (void *)secs_epc_page->base,
+ einittoken);
+ debug_printf(sc->dev,
+ "%s: __einit returned %d\n", __func__, ret);
+ } while (ret == SGX_UNMASKED_EVENT && retry--);
+
+ if (ret != 0) {
+ debug_printf(sc->dev,
+ "%s: Failed to init enclave: %d\n", __func__, ret);
+ goto error;
+ }
+
+error:
+ if (tmp_vaddr != NULL) {
+ kmem_free(kmem_arena, (vm_offset_t)tmp_vaddr, PAGE_SIZE);
+ }
+
+ return (ret);
+}
+
+static int
+sgx_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
+ struct thread *td)
+{
+ struct sgx_enclave_add_page *addp;
+ struct sgx_enclave_create *param;
+ struct sgx_enclave_init *initp;
+ struct sgx_softc *sc;
+ int ret;
+
+ sc = dev->si_drv1;
+ cmd &= 0xffff;
+
+ debug_printf(sc->dev, "%s: cmd %lx\n", __func__, cmd);
+
+ ret = 0;
+
+ switch (cmd) {
+ case SGX_IOC_ENCLAVE_CREATE:
+ param = (struct sgx_enclave_create *)addr;
+ ret = sgx_create(sc, param);
+ break;
+ case SGX_IOC_ENCLAVE_ADD_PAGE:
+ addp = (struct sgx_enclave_add_page *)addr;
+ ret = sgx_add_page(sc, addp);
+ break;
+ case SGX_IOC_ENCLAVE_INIT:
+ initp = (struct sgx_enclave_init *)addr;
+ ret = sgx_init(sc, initp);
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ if (ret < 0) {
+ return (EINVAL);
+ }
+
+ return (ret);
+}
+
+static int
+sgx_mmap_single(struct cdev *cdev, vm_ooffset_t *offset,
+ vm_size_t mapsize, struct vm_object **objp, int nprot)
+{
+ struct sgx_vm_handle *vmh;
+ struct sgx_softc *sc;
+
+ sc = cdev->si_drv1;
+
+ debug_printf(sc->dev, "%s: mapsize 0x%lx, offset %lx\n",
+ __func__, mapsize, *offset);
+
+ vmh = malloc(sizeof(struct sgx_vm_handle),
+ M_SGX, M_WAITOK | M_ZERO);
+ if (vmh == NULL) {
+ device_printf(sc->dev,
+ "%s: Can't alloc memory\n", __func__);
+ return (ENOMEM);
+ }
+
+ vmh->sc = sc;
+ vmh->size = mapsize;
+ vmh->mem = cdev_pager_allocate(vmh, OBJT_DEVICE, &sgx_pg_ops,
+ mapsize, nprot, *offset, NULL);
+ if (vmh->mem == NULL) {
+ free(vmh, M_SGX);
+ return (ENOMEM);
+ }
+
+ *objp = vmh->mem;
+
+ return (0);
+}
+
+static struct cdevsw sgx_cdevsw = {
+ .d_version = D_VERSION,
+ .d_ioctl = sgx_ioctl,
+ .d_mmap_single = sgx_mmap_single,
+ .d_name = "Intel SGX",
+};
+
+static int
+sgx_get_epc_area(struct sgx_softc *sc)
+{
+ vm_offset_t epc_base_vaddr;
+ uint64_t epc_base;
+ uint64_t epc_size;
+ u_int cp[4];
+ int i;
+
+ cpuid_count(SGX_CPUID, 0x2, cp);
+
+ epc_base = ((uint64_t)(cp[1] & 0xfffff) << 32) + \
+ (cp[0] & 0xfffff000);
+ epc_size = ((uint64_t)(cp[3] & 0xfffff) << 32) + \
+ (cp[2] & 0xfffff000);
+ sc->npages = epc_size / SGX_PAGE_SIZE;
+
+ device_printf(sc->dev, "%s: epc_base %lx size %lx (%d pages)\n",
+ __func__, epc_base, epc_size, sc->npages);
+
+ epc_base_vaddr = (vm_offset_t)pmap_mapdev(epc_base, epc_size);
+
+ sc->epc_pages = malloc(sizeof(struct epc_page) * sc->npages,
+ M_DEVBUF, M_WAITOK | M_ZERO);
+ if (sc->epc_pages == NULL) {
+ device_printf(sc->dev,
+ "%s: can't alloc memory\n", __func__);
+ return (ENOMEM);
+ }
+
+ for (i = 0; i < sc->npages; i++) {
+ sc->epc_pages[i].base = epc_base_vaddr + SGX_PAGE_SIZE * i;
+ sc->epc_pages[i].phys = epc_base + SGX_PAGE_SIZE * i;
+ sc->epc_pages[i].used = 0;
+ }
+
+ debug_printf(sc->dev, "npages %d\n", sc->npages);
+
+ return (0);
+}
+
+static void
+sgx_identify(driver_t *driver, device_t parent)
+{
+ u_int regs[4];
+
+ if ((cpu_stdext_feature & CPUID_STDEXT_SGX) == 0)
+ return;
+
+ do_cpuid(1, regs);
+
+ if ((regs[2] & CPUID2_OSXSAVE) == 0) {
+ device_printf(parent, "OSXSAVE not found\n");
+ return;
+ }
+
+ if ((rcr4() & CR4_XSAVE) == 0) {
+ device_printf(parent, "CR4_XSAVE not found\n");
+ return;
+ }
+
+ if ((rcr4() & CR4_FXSR) == 0) {
+ device_printf(parent, "CR4_FXSR not found\n");
+ return;
+ }
+
+ /* Make sure we're not being doubly invoked. */
+ if (device_find_child(parent, "sgx", -1) != NULL)
+ return;
+
+ /* We attach a sgx child for every CPU */
+ if (BUS_ADD_CHILD(parent, 10, "sgx", -1) == NULL)
+ device_printf(parent, "add sgx child failed\n");
+}
+
+static int
+sgx_probe(device_t dev)
+{
+
+ device_set_desc(dev, "Intel SGX");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+sgx_attach(device_t dev)
+{
+ struct sgx_softc *sc;
+ int ret;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ mtx_init(&sc->mtx, "SGX", NULL, MTX_DEF);
+ mtx_init(&sc->mtx_epc, "SGX EPC area", NULL, MTX_DEF);
+
+ ret = sgx_get_epc_area(sc);
+ if (ret != 0) {
+ device_printf(sc->dev,
+ "%s: Failed to get Processor Reserved Memory area\n",
+ __func__);
+ return (ENXIO);
+ }
+
+ sc->sgx_cdev = make_dev(&sgx_cdevsw, 0, UID_ROOT, GID_WHEEL,
+ 0600, "isgx");
+ if (sc->sgx_cdev == NULL) {
+ device_printf(dev,
+ "%s: Failed to create character device.\n", __func__);
+ return (ENXIO);
+ }
+ sc->sgx_cdev->si_drv1 = sc;
+
+ TAILQ_INIT(&sc->enclaves);
+
+ return (0);
+}
+
+static device_method_t sgx_methods[] = {
+ DEVMETHOD(device_identify, sgx_identify),
+ DEVMETHOD(device_probe, sgx_probe),
+ DEVMETHOD(device_attach, sgx_attach),
+ { 0, 0 }
+};
+
+static driver_t sgx_driver = {
+ "sgx",
+ sgx_methods,
+ sizeof(struct sgx_softc),
+};
+
+static devclass_t sgx_devclass;
+
+DRIVER_MODULE(sgx, nexus, sgx_driver, sgx_devclass, 0, 0);
Index: sys/amd64/sgx/sgx_linux.c
===================================================================
--- /dev/null
+++ sys/amd64/sgx/sgx_linux.c
@@ -0,0 +1,97 @@
+/*-
+ * Copyright (c) 2017 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * This software was developed by BAE Systems, the University of Cambridge
+ * Computer Laboratory, and Memorial University under DARPA/AFRL contract
+ * FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent Computing
+ * (TC) research program.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/capsicum.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/file.h>
+#include <sys/proc.h>
+#ifdef __amd64__
+#include <machine/../linux32/linux.h>
+#include <machine/../linux32/linux32_proto.h>
+#else
+#include <machine/../linux/linux.h>
+#include <machine/../linux/linux_proto.h>
+#endif
+#include <compat/linux/linux_ioctl.h>
+
+#include <amd64/sgx/sgx.h>
+#include <sys/ioccom.h>
+
+#define SGX_LINUX_IOCTL_MIN SGX_IOC_ENCLAVE_CREATE
+#define SGX_LINUX_IOCTL_MAX SGX_IOC_ENCLAVE_INIT
+
+static int
+sgx_linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
+{
+ cap_rights_t rights;
+ struct file *fp;
+ u_long cmd;
+ int error;
+
+ error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
+ if (error != 0) {
+ return (error);
+ }
+ cmd = args->cmd;
+
+ error = (fo_ioctl(fp, cmd, (caddr_t)args->arg, td->td_ucred, td));
+ fdrop(fp, td);
+
+ return (error);
+}
+
+static struct linux_ioctl_handler sgx_linux_handler = {
+ sgx_linux_ioctl,
+ SGX_LINUX_IOCTL_MIN,
+ SGX_LINUX_IOCTL_MAX,
+};
+
+SYSINIT(sgx_linux_register, SI_SUB_KLD, SI_ORDER_MIDDLE,
+ linux_ioctl_register_handler, &sgx_linux_handler);
+SYSUNINIT(sgx_linux_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
+ linux_ioctl_unregister_handler, &sgx_linux_handler);
+
+static int
+sgx_linux_modevent(module_t mod, int type, void *data)
+{
+
+ return (0);
+}
+
+DEV_MODULE(sgx_linux, sgx_linux_modevent, NULL);
+MODULE_DEPEND(sgx_linux, linux64, 1, 1, 1);
Index: sys/modules/sgx/Makefile
===================================================================
--- /dev/null
+++ sys/modules/sgx/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+.PATH: ${SRCTOP}/sys/amd64/sgx
+
+KMOD= sgx
+SRCS= sgx.c
+SRCS+= sgx.h
+SRCS+= bus_if.h device_if.h
+
+.include <bsd.kmod.mk>
Index: sys/modules/sgx_linux/Makefile
===================================================================
--- /dev/null
+++ sys/modules/sgx_linux/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+.PATH: ${SRCTOP}/sys/amd64/sgx
+
+KMOD= sgx_linux
+SRCS= sgx_linux.c
+
+.include <bsd.kmod.mk>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Mar 30, 7:01 AM (6 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30578163
Default Alt Text
D11113.id29380.diff (34 KB)
Attached To
Mode
D11113: Intel SGX driver
Attached
Detach File
Event Timeline
Log In to Comment