Index: head/sys/amd64/include/cpufunc.h =================================================================== --- head/sys/amd64/include/cpufunc.h (revision 322573) +++ head/sys/amd64/include/cpufunc.h (revision 322574) @@ -1,911 +1,990 @@ /*- * Copyright (c) 2003 Peter Wemm. * Copyright (c) 1993 The Regents of the University of California. * All rights reserved. * * 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. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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$ */ /* * Functions to provide access to special i386 instructions. * This in included in sys/systm.h, and that file should be * used in preference to this. */ #ifndef _MACHINE_CPUFUNC_H_ #define _MACHINE_CPUFUNC_H_ #ifndef _SYS_CDEFS_H_ #error this file needs sys/cdefs.h as a prerequisite #endif struct region_descriptor; #define readb(va) (*(volatile uint8_t *) (va)) #define readw(va) (*(volatile uint16_t *) (va)) #define readl(va) (*(volatile uint32_t *) (va)) #define readq(va) (*(volatile uint64_t *) (va)) #define writeb(va, d) (*(volatile uint8_t *) (va) = (d)) #define writew(va, d) (*(volatile uint16_t *) (va) = (d)) #define writel(va, d) (*(volatile uint32_t *) (va) = (d)) #define writeq(va, d) (*(volatile uint64_t *) (va) = (d)) #if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE) static __inline void breakpoint(void) { __asm __volatile("int $3"); } static __inline __pure2 u_int bsfl(u_int mask) { u_int result; __asm __volatile("bsfl %1,%0" : "=r" (result) : "rm" (mask)); return (result); } static __inline __pure2 u_long bsfq(u_long mask) { u_long result; __asm __volatile("bsfq %1,%0" : "=r" (result) : "rm" (mask)); return (result); } static __inline __pure2 u_int bsrl(u_int mask) { u_int result; __asm __volatile("bsrl %1,%0" : "=r" (result) : "rm" (mask)); return (result); } static __inline __pure2 u_long bsrq(u_long mask) { u_long result; __asm __volatile("bsrq %1,%0" : "=r" (result) : "rm" (mask)); return (result); } static __inline void clflush(u_long addr) { __asm __volatile("clflush %0" : : "m" (*(char *)addr)); } static __inline void clflushopt(u_long addr) { __asm __volatile(".byte 0x66;clflush %0" : : "m" (*(char *)addr)); } static __inline void clts(void) { __asm __volatile("clts"); } static __inline void disable_intr(void) { __asm __volatile("cli" : : : "memory"); } static __inline void do_cpuid(u_int ax, u_int *p) { __asm __volatile("cpuid" : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) : "0" (ax)); } static __inline void cpuid_count(u_int ax, u_int cx, u_int *p) { __asm __volatile("cpuid" : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) : "0" (ax), "c" (cx)); } static __inline void enable_intr(void) { __asm __volatile("sti"); } #ifdef _KERNEL #define HAVE_INLINE_FFS #define ffs(x) __builtin_ffs(x) #define HAVE_INLINE_FFSL static __inline __pure2 int ffsl(long mask) { return (mask == 0 ? mask : (int)bsfq((u_long)mask) + 1); } #define HAVE_INLINE_FFSLL static __inline __pure2 int ffsll(long long mask) { return (ffsl((long)mask)); } #define HAVE_INLINE_FLS static __inline __pure2 int fls(int mask) { return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1); } #define HAVE_INLINE_FLSL static __inline __pure2 int flsl(long mask) { return (mask == 0 ? mask : (int)bsrq((u_long)mask) + 1); } #define HAVE_INLINE_FLSLL static __inline __pure2 int flsll(long long mask) { return (flsl((long)mask)); } #endif /* _KERNEL */ static __inline void halt(void) { __asm __volatile("hlt"); } static __inline u_char inb(u_int port) { u_char data; __asm __volatile("inb %w1, %0" : "=a" (data) : "Nd" (port)); return (data); } static __inline u_int inl(u_int port) { u_int data; __asm __volatile("inl %w1, %0" : "=a" (data) : "Nd" (port)); return (data); } static __inline void insb(u_int port, void *addr, size_t count) { __asm __volatile("cld; rep; insb" : "+D" (addr), "+c" (count) : "d" (port) : "memory"); } static __inline void insw(u_int port, void *addr, size_t count) { __asm __volatile("cld; rep; insw" : "+D" (addr), "+c" (count) : "d" (port) : "memory"); } static __inline void insl(u_int port, void *addr, size_t count) { __asm __volatile("cld; rep; insl" : "+D" (addr), "+c" (count) : "d" (port) : "memory"); } static __inline void invd(void) { __asm __volatile("invd"); } static __inline u_short inw(u_int port) { u_short data; __asm __volatile("inw %w1, %0" : "=a" (data) : "Nd" (port)); return (data); } static __inline void outb(u_int port, u_char data) { __asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port)); } static __inline void outl(u_int port, u_int data) { __asm __volatile("outl %0, %w1" : : "a" (data), "Nd" (port)); } static __inline void outsb(u_int port, const void *addr, size_t count) { __asm __volatile("cld; rep; outsb" : "+S" (addr), "+c" (count) : "d" (port)); } static __inline void outsw(u_int port, const void *addr, size_t count) { __asm __volatile("cld; rep; outsw" : "+S" (addr), "+c" (count) : "d" (port)); } static __inline void outsl(u_int port, const void *addr, size_t count) { __asm __volatile("cld; rep; outsl" : "+S" (addr), "+c" (count) : "d" (port)); } static __inline void outw(u_int port, u_short data) { __asm __volatile("outw %0, %w1" : : "a" (data), "Nd" (port)); } static __inline u_long popcntq(u_long mask) { u_long result; __asm __volatile("popcntq %1,%0" : "=r" (result) : "rm" (mask)); return (result); } static __inline void lfence(void) { __asm __volatile("lfence" : : : "memory"); } static __inline void mfence(void) { __asm __volatile("mfence" : : : "memory"); } static __inline void sfence(void) { __asm __volatile("sfence" : : : "memory"); } static __inline void ia32_pause(void) { __asm __volatile("pause"); } static __inline u_long read_rflags(void) { u_long rf; __asm __volatile("pushfq; popq %0" : "=r" (rf)); return (rf); } static __inline uint64_t rdmsr(u_int msr) { uint32_t low, high; __asm __volatile("rdmsr" : "=a" (low), "=d" (high) : "c" (msr)); return (low | ((uint64_t)high << 32)); } static __inline uint32_t rdmsr32(u_int msr) { uint32_t low; __asm __volatile("rdmsr" : "=a" (low) : "c" (msr) : "rdx"); return (low); } static __inline uint64_t rdpmc(u_int pmc) { uint32_t low, high; __asm __volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (pmc)); return (low | ((uint64_t)high << 32)); } static __inline uint64_t rdtsc(void) { uint32_t low, high; __asm __volatile("rdtsc" : "=a" (low), "=d" (high)); return (low | ((uint64_t)high << 32)); } static __inline uint32_t rdtsc32(void) { uint32_t rv; __asm __volatile("rdtsc" : "=a" (rv) : : "edx"); return (rv); } static __inline void wbinvd(void) { __asm __volatile("wbinvd"); } static __inline void write_rflags(u_long rf) { __asm __volatile("pushq %0; popfq" : : "r" (rf)); } static __inline void wrmsr(u_int msr, uint64_t newval) { uint32_t low, high; low = newval; high = newval >> 32; __asm __volatile("wrmsr" : : "a" (low), "d" (high), "c" (msr)); } static __inline void load_cr0(u_long data) { __asm __volatile("movq %0,%%cr0" : : "r" (data)); } static __inline u_long rcr0(void) { u_long data; __asm __volatile("movq %%cr0,%0" : "=r" (data)); return (data); } static __inline u_long rcr2(void) { u_long data; __asm __volatile("movq %%cr2,%0" : "=r" (data)); return (data); } static __inline void load_cr3(u_long data) { __asm __volatile("movq %0,%%cr3" : : "r" (data) : "memory"); } static __inline u_long rcr3(void) { u_long data; __asm __volatile("movq %%cr3,%0" : "=r" (data)); return (data); } static __inline void load_cr4(u_long data) { __asm __volatile("movq %0,%%cr4" : : "r" (data)); } static __inline u_long rcr4(void) { u_long data; __asm __volatile("movq %%cr4,%0" : "=r" (data)); return (data); } static __inline u_long rxcr(u_int reg) { u_int low, high; __asm __volatile("xgetbv" : "=a" (low), "=d" (high) : "c" (reg)); return (low | ((uint64_t)high << 32)); } static __inline void load_xcr(u_int reg, u_long val) { u_int low, high; low = val; high = val >> 32; __asm __volatile("xsetbv" : : "c" (reg), "a" (low), "d" (high)); } /* * Global TLB flush (except for thise for pages marked PG_G) */ static __inline void invltlb(void) { load_cr3(rcr3()); } #ifndef CR4_PGE #define CR4_PGE 0x00000080 /* Page global enable */ #endif /* * Perform the guaranteed invalidation of all TLB entries. This * includes the global entries, and entries in all PCIDs, not only the * current context. The function works both on non-PCID CPUs and CPUs * with the PCID turned off or on. See IA-32 SDM Vol. 3a 4.10.4.1 * Operations that Invalidate TLBs and Paging-Structure Caches. */ static __inline void invltlb_glob(void) { uint64_t cr4; cr4 = rcr4(); load_cr4(cr4 & ~CR4_PGE); /* * Although preemption at this point could be detrimental to * performance, it would not lead to an error. PG_G is simply * ignored if CR4.PGE is clear. Moreover, in case this block * is re-entered, the load_cr4() either above or below will * modify CR4.PGE flushing the TLB. */ load_cr4(cr4 | CR4_PGE); } /* * TLB flush for an individual page (even if it has PG_G). * Only works on 486+ CPUs (i386 does not have PG_G). */ static __inline void invlpg(u_long addr) { __asm __volatile("invlpg %0" : : "m" (*(char *)addr) : "memory"); } #define INVPCID_ADDR 0 #define INVPCID_CTX 1 #define INVPCID_CTXGLOB 2 #define INVPCID_ALLCTX 3 struct invpcid_descr { uint64_t pcid:12 __packed; uint64_t pad:52 __packed; uint64_t addr; } __packed; static __inline void invpcid(struct invpcid_descr *d, int type) { __asm __volatile("invpcid (%0),%1" : : "r" (d), "r" ((u_long)type) : "memory"); } static __inline u_short rfs(void) { u_short sel; __asm __volatile("movw %%fs,%0" : "=rm" (sel)); return (sel); } static __inline u_short rgs(void) { u_short sel; __asm __volatile("movw %%gs,%0" : "=rm" (sel)); return (sel); } static __inline u_short rss(void) { u_short sel; __asm __volatile("movw %%ss,%0" : "=rm" (sel)); return (sel); } static __inline void load_ds(u_short sel) { __asm __volatile("movw %0,%%ds" : : "rm" (sel)); } static __inline void load_es(u_short sel) { __asm __volatile("movw %0,%%es" : : "rm" (sel)); } static __inline void cpu_monitor(const void *addr, u_long extensions, u_int hints) { __asm __volatile("monitor" : : "a" (addr), "c" (extensions), "d" (hints)); } static __inline void cpu_mwait(u_long extensions, u_int hints) { __asm __volatile("mwait" : : "a" (hints), "c" (extensions)); } #ifdef _KERNEL /* This is defined in but is too painful to get to */ #ifndef MSR_FSBASE #define MSR_FSBASE 0xc0000100 #endif static __inline void load_fs(u_short sel) { /* Preserve the fsbase value across the selector load */ __asm __volatile("rdmsr; movw %0,%%fs; wrmsr" : : "rm" (sel), "c" (MSR_FSBASE) : "eax", "edx"); } #ifndef MSR_GSBASE #define MSR_GSBASE 0xc0000101 #endif static __inline void load_gs(u_short sel) { /* * Preserve the gsbase value across the selector load. * Note that we have to disable interrupts because the gsbase * being trashed happens to be the kernel gsbase at the time. */ __asm __volatile("pushfq; cli; rdmsr; movw %0,%%gs; wrmsr; popfq" : : "rm" (sel), "c" (MSR_GSBASE) : "eax", "edx"); } #else /* Usable by userland */ static __inline void load_fs(u_short sel) { __asm __volatile("movw %0,%%fs" : : "rm" (sel)); } static __inline void load_gs(u_short sel) { __asm __volatile("movw %0,%%gs" : : "rm" (sel)); } #endif static __inline uint64_t rdfsbase(void) { uint64_t x; __asm __volatile("rdfsbase %0" : "=r" (x)); return (x); } static __inline void wrfsbase(uint64_t x) { __asm __volatile("wrfsbase %0" : : "r" (x)); } static __inline uint64_t rdgsbase(void) { uint64_t x; __asm __volatile("rdgsbase %0" : "=r" (x)); return (x); } static __inline void wrgsbase(uint64_t x) { __asm __volatile("wrgsbase %0" : : "r" (x)); } static __inline void bare_lgdt(struct region_descriptor *addr) { __asm __volatile("lgdt (%0)" : : "r" (addr)); } static __inline void sgdt(struct region_descriptor *addr) { char *loc; loc = (char *)addr; __asm __volatile("sgdt %0" : "=m" (*loc) : : "memory"); } static __inline void lidt(struct region_descriptor *addr) { __asm __volatile("lidt (%0)" : : "r" (addr)); } static __inline void sidt(struct region_descriptor *addr) { char *loc; loc = (char *)addr; __asm __volatile("sidt %0" : "=m" (*loc) : : "memory"); } static __inline void lldt(u_short sel) { __asm __volatile("lldt %0" : : "r" (sel)); } static __inline void ltr(u_short sel) { __asm __volatile("ltr %0" : : "r" (sel)); } static __inline uint32_t read_tr(void) { u_short sel; __asm __volatile("str %0" : "=r" (sel)); return (sel); } static __inline uint64_t rdr0(void) { uint64_t data; __asm __volatile("movq %%dr0,%0" : "=r" (data)); return (data); } static __inline void load_dr0(uint64_t dr0) { __asm __volatile("movq %0,%%dr0" : : "r" (dr0)); } static __inline uint64_t rdr1(void) { uint64_t data; __asm __volatile("movq %%dr1,%0" : "=r" (data)); return (data); } static __inline void load_dr1(uint64_t dr1) { __asm __volatile("movq %0,%%dr1" : : "r" (dr1)); } static __inline uint64_t rdr2(void) { uint64_t data; __asm __volatile("movq %%dr2,%0" : "=r" (data)); return (data); } static __inline void load_dr2(uint64_t dr2) { __asm __volatile("movq %0,%%dr2" : : "r" (dr2)); } static __inline uint64_t rdr3(void) { uint64_t data; __asm __volatile("movq %%dr3,%0" : "=r" (data)); return (data); } static __inline void load_dr3(uint64_t dr3) { __asm __volatile("movq %0,%%dr3" : : "r" (dr3)); } static __inline uint64_t rdr6(void) { uint64_t data; __asm __volatile("movq %%dr6,%0" : "=r" (data)); return (data); } static __inline void load_dr6(uint64_t dr6) { __asm __volatile("movq %0,%%dr6" : : "r" (dr6)); } static __inline uint64_t rdr7(void) { uint64_t data; __asm __volatile("movq %%dr7,%0" : "=r" (data)); return (data); } static __inline void load_dr7(uint64_t dr7) { __asm __volatile("movq %0,%%dr7" : : "r" (dr7)); } static __inline register_t intr_disable(void) { register_t rflags; rflags = read_rflags(); disable_intr(); return (rflags); } static __inline void intr_restore(register_t rflags) { write_rflags(rflags); } +enum { + SGX_ECREATE = 0x0, + SGX_EADD = 0x1, + SGX_EINIT = 0x2, + SGX_EREMOVE = 0x3, + SGX_EDGBRD = 0x4, + SGX_EDGBWR = 0x5, + SGX_EEXTEND = 0x6, + SGX_ELDU = 0x8, + SGX_EBLOCK = 0x9, + SGX_EPA = 0xA, + SGX_EWB = 0xB, + SGX_ETRACK = 0xC, +}; + +enum { + SGX_PT_SECS = 0x00, + SGX_PT_TCS = 0x01, + SGX_PT_REG = 0x02, + SGX_PT_VA = 0x03, + SGX_PT_TRIM = 0x04, +}; + +int sgx_encls(uint32_t eax, uint64_t rbx, uint64_t rcx, uint64_t rdx); + +static __inline int +sgx_ecreate(void *pginfo, void *secs) +{ + + return (sgx_encls(SGX_ECREATE, (uint64_t)pginfo, + (uint64_t)secs, 0)); +} + +static __inline int +sgx_eadd(void *pginfo, void *epc) +{ + + return (sgx_encls(SGX_EADD, (uint64_t)pginfo, + (uint64_t)epc, 0)); +} + +static __inline int +sgx_einit(void *sigstruct, void *secs, void *einittoken) +{ + + return (sgx_encls(SGX_EINIT, (uint64_t)sigstruct, + (uint64_t)secs, (uint64_t)einittoken)); +} + +static __inline int +sgx_eextend(void *secs, void *epc) +{ + + return (sgx_encls(SGX_EEXTEND, (uint64_t)secs, + (uint64_t)epc, 0)); +} + +static __inline int +sgx_epa(void *epc) +{ + + return (sgx_encls(SGX_EPA, SGX_PT_VA, (uint64_t)epc, 0)); +} + +static __inline int +sgx_eldu(uint64_t rbx, uint64_t rcx, + uint64_t rdx) +{ + + return (sgx_encls(SGX_ELDU, rbx, rcx, rdx)); +} + +static __inline int +sgx_eremove(void *epc) +{ + + return (sgx_encls(SGX_EREMOVE, 0, (uint64_t)epc, 0)); +} + #else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */ int breakpoint(void); u_int bsfl(u_int mask); u_int bsrl(u_int mask); void clflush(u_long addr); void clts(void); void cpuid_count(u_int ax, u_int cx, u_int *p); void disable_intr(void); void do_cpuid(u_int ax, u_int *p); void enable_intr(void); void halt(void); void ia32_pause(void); u_char inb(u_int port); u_int inl(u_int port); void insb(u_int port, void *addr, size_t count); void insl(u_int port, void *addr, size_t count); void insw(u_int port, void *addr, size_t count); register_t intr_disable(void); void intr_restore(register_t rf); void invd(void); void invlpg(u_int addr); void invltlb(void); u_short inw(u_int port); void lidt(struct region_descriptor *addr); void lldt(u_short sel); void load_cr0(u_long cr0); void load_cr3(u_long cr3); void load_cr4(u_long cr4); void load_dr0(uint64_t dr0); void load_dr1(uint64_t dr1); void load_dr2(uint64_t dr2); void load_dr3(uint64_t dr3); void load_dr6(uint64_t dr6); void load_dr7(uint64_t dr7); void load_fs(u_short sel); void load_gs(u_short sel); void ltr(u_short sel); void outb(u_int port, u_char data); void outl(u_int port, u_int data); void outsb(u_int port, const void *addr, size_t count); void outsl(u_int port, const void *addr, size_t count); void outsw(u_int port, const void *addr, size_t count); void outw(u_int port, u_short data); u_long rcr0(void); u_long rcr2(void); u_long rcr3(void); u_long rcr4(void); uint64_t rdmsr(u_int msr); uint32_t rdmsr32(u_int msr); uint64_t rdpmc(u_int pmc); uint64_t rdr0(void); uint64_t rdr1(void); uint64_t rdr2(void); uint64_t rdr3(void); uint64_t rdr6(void); uint64_t rdr7(void); uint64_t rdtsc(void); u_long read_rflags(void); u_int rfs(void); u_int rgs(void); void wbinvd(void); void write_rflags(u_int rf); void wrmsr(u_int msr, uint64_t newval); #endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */ void reset_dbregs(void); #ifdef _KERNEL int rdmsr_safe(u_int msr, uint64_t *val); int wrmsr_safe(u_int msr, uint64_t newval); #endif #endif /* !_MACHINE_CPUFUNC_H_ */ Index: head/sys/amd64/include/sgx.h =================================================================== --- head/sys/amd64/include/sgx.h (nonexistent) +++ head/sys/amd64/include/sgx.h (revision 322574) @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 2017 Ruslan Bukin + * 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$ + */ + +/* User-visible header. */ + +#ifndef _MACHINE_SGX_H_ +#define _MACHINE_SGX_H_ + +#define SGX_MAGIC 0xA4 +#define SGX_IOC_ENCLAVE_CREATE \ + _IOW(SGX_MAGIC, 0x00, struct sgx_enclave_create) +#define SGX_IOC_ENCLAVE_ADD_PAGE \ + _IOW(SGX_MAGIC, 0x01, struct sgx_enclave_add_page) +#define SGX_IOC_ENCLAVE_INIT \ + _IOW(SGX_MAGIC, 0x02, struct sgx_enclave_init) + +struct sgx_enclave_create { + uint64_t src; +} __packed; + +struct sgx_enclave_add_page { + uint64_t addr; + uint64_t src; + uint64_t secinfo; + uint16_t mrmask; +} __packed; + +struct sgx_enclave_init { + uint64_t addr; + uint64_t sigstruct; + uint64_t einittoken; +} __packed; + +#endif /* !_MACHINE_SGX_H_ */ Property changes on: head/sys/amd64/include/sgx.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/amd64/include/sgxreg.h =================================================================== --- head/sys/amd64/include/sgxreg.h (nonexistent) +++ head/sys/amd64/include/sgxreg.h (revision 322574) @@ -0,0 +1,155 @@ +/*- + * Copyright (c) 2017 Ruslan Bukin + * 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$ + */ + +/* Machine-defined variables. */ + +#ifndef _MACHINE_SGXREG_H_ +#define _MACHINE_SGXREG_H_ + +/* Error codes. */ +#define SGX_SUCCESS 0 +#define SGX_INVALID_SIG_STRUCT 1 /* EINIT */ +#define SGX_INVALID_ATTRIBUTE 2 /* EINIT, EGETKEY */ +#define SGX_BLSTATE 3 /* EBLOCK */ +#define SGX_INVALID_MEASUREMENT 4 /* EINIT */ +#define SGX_NOTBLOCKABLE 5 /* EBLOCK */ +#define SGX_PG_INVLD 6 /* EBLOCK */ +#define SGX_LOCKFAIL 7 /* EBLOCK, EMODPR, EMODT */ +#define SGX_INVALID_SIGNATURE 8 /* EINIT */ +#define SGX_MAC_COMPARE_FAIL 9 /* ELDB, ELDU */ +#define SGX_PAGE_NOT_BLOCKED 10 /* EWB */ +#define SGX_NOT_TRACKED 11 /* EWB, EACCEPT */ +#define SGX_VA_SLOT_OCCUPIED 12 /* EWB */ +#define SGX_CHILD_PRESENT 13 /* EWB, EREMOVE */ +#define SGX_ENCLAVE_ACT 14 /* EREMOVE */ +#define SGX_ENTRYEPOCH_LOCKED 15 /* EBLOCK */ +#define SGX_INVALID_EINIT_TOKEN 16 /* EINIT */ +#define SGX_PREV_TRK_INCMPL 17 /* ETRACK */ +#define SGX_PG_IS_SECS 18 /* EBLOCK */ +#define SGX_PAGE_ATTRIBUTES_MISMATCH 19 /* EACCEPT, EACCEPTCOPY */ +#define SGX_PAGE_NOT_MODIFIABLE 20 /* EMODPR, EMODT */ +#define SGX_INVALID_CPUSVN 32 /* EINIT, EGETKEY */ +#define SGX_INVALID_ISVSVN 64 /* EGETKEY */ +#define SGX_UNMASKED_EVENT 128 /* EINIT */ +#define SGX_INVALID_KEYNAME 256 /* EGETKEY */ + +/* + * 2.10 Page Information (PAGEINFO) + * PAGEINFO is an architectural data structure that is used as a parameter + * to the EPC-management instructions. It requires 32-Byte alignment. + */ +struct page_info { + uint64_t linaddr; + uint64_t srcpge; + union { + struct secinfo *secinfo; + uint64_t pcmd; + }; + uint64_t secs; +} __aligned(32); + +/* + * 2.11 Security Information (SECINFO) + * The SECINFO data structure holds meta-data about an enclave page. + */ +struct secinfo { + uint64_t flags; +#define SECINFO_FLAGS_PT_S 8 /* Page type shift */ +#define SECINFO_FLAGS_PT_M (0xff << SECINFO_FLAGS_PT_S) + uint64_t reserved[7]; +} __aligned(64); + +/* + * 2.7.1 ATTRIBUTES + * The ATTRIBUTES data structure is comprised of bit-granular fields that + * are used in the SECS, CPUID enumeration, the REPORT and the KEYREQUEST + * structures. + */ +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; +#define SECS_ATTR_RSV4_SIZE 7 + uint8_t reserved4[SECS_ATTR_RSV4_SIZE]; + uint64_t xfrm; /* X-Feature Request Mask */ +}; + +/* + * 2.7 SGX Enclave Control Structure (SECS) + * The SECS data structure requires 4K-Bytes alignment. + */ +struct secs { + uint64_t size; + uint64_t base; + uint32_t ssa_frame_size; + uint32_t misc_select; +#define SECS_RSV1_SIZE 24 + uint8_t reserved1[SECS_RSV1_SIZE]; + struct secs_attr attributes; + uint8_t mr_enclave[32]; +#define SECS_RSV2_SIZE 32 + uint8_t reserved2[SECS_RSV2_SIZE]; + uint8_t mr_signer[32]; +#define SECS_RSV3_SIZE 96 + uint8_t reserved3[SECS_RSV3_SIZE]; + uint16_t isv_prod_id; + uint16_t isv_svn; +#define SECS_RSV4_SIZE 3836 + uint8_t reserved4[SECS_RSV4_SIZE]; +}; + +/* + * 2.8 Thread Control Structure (TCS) + * Each executing thread in the enclave is associated with a + * Thread Control Structure. It requires 4K-Bytes alignment. + */ +struct tcs { + uint64_t reserved1; + uint64_t flags; + uint64_t ossa; + uint32_t cssa; + uint32_t nssa; + uint64_t oentry; + uint64_t reserved2; + uint64_t ofsbasgx; + uint64_t ogsbasgx; + uint32_t fslimit; + uint32_t gslimit; + uint64_t reserved3[503]; +}; + +#endif /* !_MACHINE_SGXREG_H_ */ Property changes on: head/sys/amd64/include/sgxreg.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/amd64/sgx/sgx.c =================================================================== --- head/sys/amd64/sgx/sgx.c (nonexistent) +++ head/sys/amd64/sgx/sgx.c (revision 322574) @@ -0,0 +1,1211 @@ +/*- + * Copyright (c) 2017 Ruslan Bukin + * 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. + */ + +/* + * Design overview. + * + * The driver provides character device for mmap(2) and ioctl(2) system calls + * allowing user to manage isolated compartments ("enclaves") in user VA space. + * + * The driver duties is EPC pages management, enclave management, user data + * validation. + * + * This driver requires Intel SGX support from hardware. + * + * /dev/sgx: + * .mmap: + * sgx_mmap_single() allocates VM object with following pager + * operations: + * a) sgx_pg_ctor(): + * VM object constructor does nothing + * b) sgx_pg_dtor(): + * VM object destructor destroys the SGX enclave associated + * with the object: it frees all the EPC pages allocated for + * enclave and removes the enclave. + * c) sgx_pg_fault(): + * VM object fault handler does nothing + * + * .ioctl: + * sgx_ioctl(): + * a) SGX_IOC_ENCLAVE_CREATE + * Adds Enclave SECS page: initial step of enclave creation. + * b) SGX_IOC_ENCLAVE_ADD_PAGE + * Adds TCS, REG pages to the enclave. + * c) SGX_IOC_ENCLAVE_INIT + * Finalizes enclave creation. + * + * Enclave lifecycle: + * .-- ECREATE -- Add SECS page + * Kernel | EADD -- Add TCS, REG pages + * space | EEXTEND -- Measure the page (take unique hash) + * ENCLS | EPA -- Allocate version array page + * '-- EINIT -- Finalize enclave creation + * User .-- EENTER -- Go to entry point of enclave + * space | EEXIT -- Exit back to main application + * ENCLU '-- ERESUME -- Resume enclave execution (e.g. after exception) + * + * Enclave lifecycle from driver point of view: + * 1) User calls mmap() on /dev/sgx: we allocate a VM object + * 2) User calls ioctl SGX_IOC_ENCLAVE_CREATE: we look for the VM object + * associated with user process created on step 1, create SECS physical + * page and store it in enclave's VM object queue by special index + * SGX_SECS_VM_OBJECT_INDEX. + * 3) User calls ioctl SGX_IOC_ENCLAVE_ADD_PAGE: we look for enclave created + * on step 2, create TCS or REG physical page and map it to specified by + * user address of enclave VM object. + * 4) User finalizes enclave creation with ioctl SGX_IOC_ENCLAVE_INIT call. + * 5) User can freely enter to and exit from enclave using ENCLU instructions + * from userspace: the driver does nothing here. + * 6) User proceed munmap(2) system call (or the process with enclave dies): + * we destroy the enclave associated with the object. + * + * EPC page types and their indexes in VM object queue: + * - PT_SECS index is special and equals SGX_SECS_VM_OBJECT_INDEX (-1); + * - PT_TCS and PT_REG indexes are specified by user in addr field of ioctl + * request data and determined as follows: + * pidx = OFF_TO_IDX(addp->addr - vmh->base); + * - PT_VA index is special, created for PT_REG, PT_TCS and PT_SECS pages + * and determined by formula: + * va_page_idx = - SGX_VA_PAGES_OFFS - (page_idx / SGX_VA_PAGE_SLOTS); + * PT_VA page can hold versions of up to 512 pages, and slot for each + * page in PT_VA page is determined as follows: + * va_slot_idx = page_idx % SGX_VA_PAGE_SLOTS; + * - PT_TRIM is unused. + * + * Locking: + * SGX ENCLS set of instructions have limitations on concurrency: + * some instructions can't be executed same time on different CPUs. + * We use sc->mtx_encls lock around them to prevent concurrent execution. + * sc->mtx lock is used to manage list of created enclaves and the state of + * SGX driver. + * + * Eviction of EPC pages: + * Eviction support is not implemented in this driver, however the driver + * manages VA (version array) pages: it allocates a VA slot for each EPC + * page. This will be required for eviction support in future. + * VA pages and slots are currently unused. + * + * IntelĀ® 64 and IA-32 Architectures Software Developer's Manual + * https://software.intel.com/en-us/articles/intel-sdm + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#define DEBUG +#undef DEBUG + +#ifdef DEBUG +#define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__) +#else +#define dprintf(fmt, ...) +#endif + +static struct cdev_pager_ops sgx_pg_ops; +struct sgx_softc sgx_sc; + +static int +sgx_get_epc_page(struct sgx_softc *sc, struct epc_page **epc) +{ + vmem_addr_t addr; + int i; + + if (vmem_alloc(sc->vmem_epc, PAGE_SIZE, M_FIRSTFIT | M_NOWAIT, + &addr) == 0) { + i = (addr - sc->epc_base) / PAGE_SIZE; + *epc = &sc->epc_pages[i]; + return (0); + } + + return (ENOMEM); +} + +static void +sgx_put_epc_page(struct sgx_softc *sc, struct epc_page *epc) +{ + vmem_addr_t addr; + + if (epc == NULL) + return; + + addr = (epc->index * PAGE_SIZE) + sc->epc_base; + vmem_free(sc->vmem_epc, addr, PAGE_SIZE); +} + +static int +sgx_va_slot_init_by_index(struct sgx_softc *sc, vm_object_t object, + uint64_t idx) +{ + struct epc_page *epc; + vm_page_t page; + vm_page_t p; + int ret; + + VM_OBJECT_ASSERT_WLOCKED(object); + + p = vm_page_lookup(object, idx); + if (p == NULL) { + ret = sgx_get_epc_page(sc, &epc); + if (ret) { + dprintf("%s: No free EPC pages available.\n", + __func__); + return (ret); + } + + mtx_lock(&sc->mtx_encls); + sgx_epa((void *)epc->base); + mtx_unlock(&sc->mtx_encls); + + page = PHYS_TO_VM_PAGE(epc->phys); + + vm_page_insert(page, object, idx); + page->valid = VM_PAGE_BITS_ALL; + } + + return (0); +} + +static int +sgx_va_slot_init(struct sgx_softc *sc, + struct sgx_enclave *enclave, + uint64_t addr) +{ + vm_pindex_t pidx; + uint64_t va_page_idx; + uint64_t idx; + vm_object_t object; + int va_slot; + int ret; + + object = enclave->object; + + VM_OBJECT_ASSERT_WLOCKED(object); + + pidx = OFF_TO_IDX(addr); + + va_slot = pidx % SGX_VA_PAGE_SLOTS; + va_page_idx = pidx / SGX_VA_PAGE_SLOTS; + idx = - SGX_VA_PAGES_OFFS - va_page_idx; + + ret = sgx_va_slot_init_by_index(sc, object, idx); + + return (ret); +} + +static int +sgx_mem_find(struct sgx_softc *sc, uint64_t addr, + vm_map_entry_t *entry0, vm_object_t *object0) +{ + vm_map_t map; + vm_map_entry_t entry; + vm_object_t object; + + map = &curproc->p_vmspace->vm_map; + + vm_map_lock_read(map); + if (!vm_map_lookup_entry(map, addr, &entry)) { + vm_map_unlock_read(map); + dprintf("%s: Can't find enclave.\n", __func__); + return (EINVAL); + } + + object = entry->object.vm_object; + if (object == NULL || object->handle == NULL) { + vm_map_unlock_read(map); + return (EINVAL); + } + + if (object->type != OBJT_MGTDEVICE || + object->un_pager.devp.ops != &sgx_pg_ops) { + vm_map_unlock_read(map); + return (EINVAL); + } + + vm_object_reference(object); + + *object0 = object; + *entry0 = entry; + vm_map_unlock_read(map); + + return (0); +} + +static int +sgx_enclave_find(struct sgx_softc *sc, uint64_t addr, + struct sgx_enclave **encl) +{ + struct sgx_vm_handle *vmh; + struct sgx_enclave *enclave; + vm_map_entry_t entry; + vm_object_t object; + int ret; + + ret = sgx_mem_find(sc, addr, &entry, &object); + if (ret) + return (ret); + + vmh = object->handle; + if (vmh == NULL) { + vm_object_deallocate(object); + return (EINVAL); + } + + enclave = vmh->enclave; + if (enclave == NULL || enclave->object == NULL) { + vm_object_deallocate(object); + return (EINVAL); + } + + *encl = enclave; + + return (0); +} + +static int +sgx_enclave_alloc(struct sgx_softc *sc, struct secs *secs, + struct sgx_enclave **enclave0) +{ + struct sgx_enclave *enclave; + + enclave = malloc(sizeof(struct sgx_enclave), + M_SGX, M_WAITOK | M_ZERO); + + enclave->base = secs->base; + enclave->size = secs->size; + + *enclave0 = enclave; + + return (0); +} + +static void +sgx_epc_page_remove(struct sgx_softc *sc, + struct epc_page *epc) +{ + + mtx_lock(&sc->mtx_encls); + sgx_eremove((void *)epc->base); + mtx_unlock(&sc->mtx_encls); +} + +static void +sgx_page_remove(struct sgx_softc *sc, vm_page_t p) +{ + struct epc_page *epc; + vm_paddr_t pa; + uint64_t offs; + + vm_page_lock(p); + vm_page_remove(p); + vm_page_unlock(p); + + dprintf("%s: p->pidx %ld\n", __func__, p->pindex); + + pa = VM_PAGE_TO_PHYS(p); + epc = &sc->epc_pages[0]; + offs = (pa - epc->phys) / PAGE_SIZE; + epc = &sc->epc_pages[offs]; + + sgx_epc_page_remove(sc, epc); + sgx_put_epc_page(sc, epc); +} + +static void +sgx_enclave_remove(struct sgx_softc *sc, + struct sgx_enclave *enclave) +{ + vm_object_t object; + vm_page_t p, p_secs, p_next; + + mtx_lock(&sc->mtx); + TAILQ_REMOVE(&sc->enclaves, enclave, next); + mtx_unlock(&sc->mtx); + + object = enclave->object; + + VM_OBJECT_WLOCK(object); + + /* + * First remove all the pages except SECS, + * then remove SECS page. + */ + p_secs = NULL; + TAILQ_FOREACH_SAFE(p, &object->memq, listq, p_next) { + if (p->pindex == SGX_SECS_VM_OBJECT_INDEX) { + p_secs = p; + continue; + } + sgx_page_remove(sc, p); + } + /* Now remove SECS page */ + if (p_secs != NULL) + sgx_page_remove(sc, p_secs); + + KASSERT(TAILQ_EMPTY(&object->memq) == 1, ("not empty")); + KASSERT(object->resident_page_count == 0, ("count")); + + VM_OBJECT_WUNLOCK(object); +} + +static int +sgx_measure_page(struct sgx_softc *sc, struct epc_page *secs, + struct epc_page *epc, uint16_t mrmask) +{ + int i, j; + int ret; + + mtx_lock(&sc->mtx_encls); + + for (i = 0, j = 1; i < PAGE_SIZE; i += 0x100, j <<= 1) { + if (!(j & mrmask)) + continue; + + ret = sgx_eextend((void *)secs->base, + (void *)(epc->base + i)); + if (ret == SGX_EFAULT) { + mtx_unlock(&sc->mtx_encls); + return (ret); + } + } + + mtx_unlock(&sc->mtx_encls); + + return (0); +} + +static int +sgx_secs_validate(struct sgx_softc *sc, struct secs *secs) +{ + struct secs_attr *attr; + int i; + + if (secs->size == 0) + return (EINVAL); + + /* BASEADDR must be naturally aligned on an SECS.SIZE boundary. */ + if (secs->base & (secs->size - 1)) + return (EINVAL); + + /* SECS.SIZE must be at least 2 pages. */ + if (secs->size < 2 * PAGE_SIZE) + return (EINVAL); + + if ((secs->size & (secs->size - 1)) != 0) + return (EINVAL); + + attr = &secs->attributes; + + if (attr->reserved1 != 0 || + attr->reserved2 != 0 || + attr->reserved3 != 0) + return (EINVAL); + + for (i = 0; i < SECS_ATTR_RSV4_SIZE; i++) + if (attr->reserved4[i]) + return (EINVAL); + + /* + * IntelĀ® Software Guard Extensions Programming Reference + * 6.7.2 Relevant Fields in Various Data Structures + * 6.7.2.1 SECS.ATTRIBUTES.XFRM + * XFRM[1:0] must be set to 0x3. + */ + if ((attr->xfrm & 0x3) != 0x3) + return (EINVAL); + + if (!attr->mode64bit) + return (EINVAL); + + if (secs->size > sc->enclave_size_max) + return (EINVAL); + + for (i = 0; i < SECS_RSV1_SIZE; i++) + if (secs->reserved1[i]) + return (EINVAL); + + for (i = 0; i < SECS_RSV2_SIZE; i++) + if (secs->reserved2[i]) + return (EINVAL); + + for (i = 0; i < SECS_RSV3_SIZE; i++) + if (secs->reserved3[i]) + return (EINVAL); + + for (i = 0; i < SECS_RSV4_SIZE; i++) + if (secs->reserved4[i]) + return (EINVAL); + + return (0); +} + +static int +sgx_tcs_validate(struct tcs *tcs) +{ + int i; + + if ((tcs->flags) || + (tcs->ossa & (PAGE_SIZE - 1)) || + (tcs->ofsbasgx & (PAGE_SIZE - 1)) || + (tcs->ogsbasgx & (PAGE_SIZE - 1)) || + ((tcs->fslimit & 0xfff) != 0xfff) || + ((tcs->gslimit & 0xfff) != 0xfff)) + return (EINVAL); + + for (i = 0; i < nitems(tcs->reserved3); i++) + if (tcs->reserved3[i]) + return (EINVAL); + + return (0); +} + +static void +sgx_tcs_dump(struct sgx_softc *sc, struct tcs *t) +{ + + dprintf("t->flags %lx\n", t->flags); + dprintf("t->ossa %lx\n", t->ossa); + dprintf("t->cssa %x\n", t->cssa); + dprintf("t->nssa %x\n", t->nssa); + dprintf("t->oentry %lx\n", t->oentry); + dprintf("t->ofsbasgx %lx\n", t->ofsbasgx); + dprintf("t->ogsbasgx %lx\n", t->ogsbasgx); + dprintf("t->fslimit %x\n", t->fslimit); + dprintf("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; + + vmh = handle; + if (vmh == NULL) { + dprintf("%s: vmh not found.\n", __func__); + return (0); + } + + dprintf("%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; + + vmh = handle; + if (vmh == NULL) { + dprintf("%s: vmh not found.\n", __func__); + return; + } + + sc = vmh->sc; + if (sc == NULL) { + dprintf("%s: sc is NULL\n", __func__); + return; + } + + if (vmh->enclave == NULL) { + dprintf("%s: Enclave not found.\n", __func__); + return; + } + + sgx_enclave_remove(sc, vmh->enclave); + + free(vmh->enclave, M_SGX); + free(vmh, M_SGX); +} + +static int +sgx_pg_fault(vm_object_t object, vm_ooffset_t offset, + int prot, vm_page_t *mres) +{ + + /* + * The purpose of this trivial handler is to handle the race + * when user tries to access mmaped region before or during + * enclave creation ioctl calls. + */ + + dprintf("%s: offset 0x%lx\n", __func__, offset); + + return (VM_PAGER_FAIL); +} + +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 void +sgx_insert_epc_page_by_index(vm_page_t page, vm_object_t object, + vm_pindex_t pidx) +{ + + VM_OBJECT_ASSERT_WLOCKED(object); + + vm_page_insert(page, object, pidx); + page->valid = VM_PAGE_BITS_ALL; +} + +static void +sgx_insert_epc_page(struct sgx_enclave *enclave, + struct epc_page *epc, uint64_t addr) +{ + vm_pindex_t pidx; + vm_page_t page; + + VM_OBJECT_ASSERT_WLOCKED(enclave->object); + + pidx = OFF_TO_IDX(addr); + page = PHYS_TO_VM_PAGE(epc->phys); + + sgx_insert_epc_page_by_index(page, enclave->object, pidx); +} + +static int +sgx_ioctl_create(struct sgx_softc *sc, struct sgx_enclave_create *param) +{ + struct sgx_vm_handle *vmh; + vm_map_entry_t entry; + vm_page_t p; + struct page_info pginfo; + struct secinfo secinfo; + struct sgx_enclave *enclave; + struct epc_page *epc; + struct secs *secs; + vm_object_t object; + vm_page_t page; + int ret; + + epc = NULL; + secs = NULL; + enclave = NULL; + object = NULL; + + /* SGX Enclave Control Structure (SECS) */ + secs = malloc(PAGE_SIZE, M_SGX, M_WAITOK | M_ZERO); + ret = copyin((void *)param->src, secs, sizeof(struct secs)); + if (ret) { + dprintf("%s: Can't copy SECS.\n", __func__); + goto error; + } + + ret = sgx_secs_validate(sc, secs); + if (ret) { + dprintf("%s: SECS validation failed.\n", __func__); + goto error; + } + + ret = sgx_mem_find(sc, secs->base, &entry, &object); + if (ret) { + dprintf("%s: Can't find vm_map.\n", __func__); + goto error; + } + + vmh = object->handle; + if (!vmh) { + dprintf("%s: Can't find vmh.\n", __func__); + ret = ENXIO; + goto error; + } + + dprintf("%s: entry start %lx offset %lx\n", + __func__, entry->start, entry->offset); + vmh->base = (entry->start - entry->offset); + + ret = sgx_enclave_alloc(sc, secs, &enclave); + if (ret) { + dprintf("%s: Can't alloc enclave.\n", __func__); + goto error; + } + enclave->object = object; + enclave->vmh = vmh; + + memset(&secinfo, 0, sizeof(struct secinfo)); + memset(&pginfo, 0, sizeof(struct page_info)); + pginfo.linaddr = 0; + pginfo.srcpge = (uint64_t)secs; + pginfo.secinfo = &secinfo; + pginfo.secs = 0; + + ret = sgx_get_epc_page(sc, &epc); + if (ret) { + dprintf("%s: Failed to get free epc page.\n", __func__); + goto error; + } + enclave->secs_epc_page = epc; + + VM_OBJECT_WLOCK(object); + p = vm_page_lookup(object, SGX_SECS_VM_OBJECT_INDEX); + if (p) { + VM_OBJECT_WUNLOCK(object); + /* SECS page already added. */ + ret = ENXIO; + goto error; + } + + ret = sgx_va_slot_init_by_index(sc, object, + - SGX_VA_PAGES_OFFS - SGX_SECS_VM_OBJECT_INDEX); + if (ret) { + VM_OBJECT_WUNLOCK(object); + dprintf("%s: Can't init va slot.\n", __func__); + goto error; + } + + mtx_lock(&sc->mtx); + if ((sc->state & SGX_STATE_RUNNING) == 0) { + mtx_unlock(&sc->mtx); + /* Remove VA page that was just created for SECS page. */ + p = vm_page_lookup(enclave->object, + - SGX_VA_PAGES_OFFS - SGX_SECS_VM_OBJECT_INDEX); + sgx_page_remove(sc, p); + VM_OBJECT_WUNLOCK(object); + goto error; + } + mtx_lock(&sc->mtx_encls); + ret = sgx_ecreate(&pginfo, (void *)epc->base); + mtx_unlock(&sc->mtx_encls); + if (ret == SGX_EFAULT) { + dprintf("%s: gp fault\n", __func__); + mtx_unlock(&sc->mtx); + /* Remove VA page that was just created for SECS page. */ + p = vm_page_lookup(enclave->object, + - SGX_VA_PAGES_OFFS - SGX_SECS_VM_OBJECT_INDEX); + sgx_page_remove(sc, p); + VM_OBJECT_WUNLOCK(object); + goto error; + } + + TAILQ_INSERT_TAIL(&sc->enclaves, enclave, next); + mtx_unlock(&sc->mtx); + + vmh->enclave = enclave; + + page = PHYS_TO_VM_PAGE(epc->phys); + sgx_insert_epc_page_by_index(page, enclave->object, + SGX_SECS_VM_OBJECT_INDEX); + + VM_OBJECT_WUNLOCK(object); + + /* Release the reference. */ + vm_object_deallocate(object); + + free(secs, M_SGX); + + return (0); + +error: + free(secs, M_SGX); + sgx_put_epc_page(sc, epc); + free(enclave, M_SGX); + vm_object_deallocate(object); + + return (ret); +} + +static int +sgx_ioctl_add_page(struct sgx_softc *sc, + struct sgx_enclave_add_page *addp) +{ + struct epc_page *secs_epc_page; + struct sgx_enclave *enclave; + struct sgx_vm_handle *vmh; + struct epc_page *epc; + struct page_info pginfo; + struct secinfo secinfo; + vm_object_t object; + void *tmp_vaddr; + uint64_t page_type; + struct tcs *t; + uint64_t addr; + uint64_t pidx; + vm_page_t p; + int ret; + + tmp_vaddr = NULL; + epc = NULL; + object = NULL; + + /* Find and get reference to VM object. */ + ret = sgx_enclave_find(sc, addp->addr, &enclave); + if (ret) { + dprintf("%s: Failed to find enclave.\n", __func__); + goto error; + } + + object = enclave->object; + KASSERT(object != NULL, ("vm object is NULL\n")); + vmh = object->handle; + + ret = sgx_get_epc_page(sc, &epc); + if (ret) { + dprintf("%s: Failed to get free epc page.\n", __func__); + goto error; + } + + memset(&secinfo, 0, sizeof(struct secinfo)); + ret = copyin((void *)addp->secinfo, &secinfo, + sizeof(struct secinfo)); + if (ret) { + dprintf("%s: Failed to copy secinfo.\n", __func__); + goto error; + } + + tmp_vaddr = malloc(PAGE_SIZE, M_SGX, M_WAITOK | M_ZERO); + ret = copyin((void *)addp->src, tmp_vaddr, PAGE_SIZE); + if (ret) { + dprintf("%s: Failed to copy page.\n", __func__); + goto error; + } + + page_type = (secinfo.flags & SECINFO_FLAGS_PT_M) >> + SECINFO_FLAGS_PT_S; + if (page_type != SGX_PT_TCS && page_type != SGX_PT_REG) { + dprintf("%s: page can't be added.\n", __func__); + goto error; + } + if (page_type == SGX_PT_TCS) { + t = (struct tcs *)tmp_vaddr; + ret = sgx_tcs_validate(t); + if (ret) { + dprintf("%s: TCS page validation failed.\n", + __func__); + goto error; + } + sgx_tcs_dump(sc, t); + } + + addr = (addp->addr - vmh->base); + pidx = OFF_TO_IDX(addr); + + VM_OBJECT_WLOCK(object); + p = vm_page_lookup(object, pidx); + if (p) { + VM_OBJECT_WUNLOCK(object); + /* Page already added. */ + ret = ENXIO; + goto error; + } + + ret = sgx_va_slot_init(sc, enclave, addr); + if (ret) { + VM_OBJECT_WUNLOCK(object); + dprintf("%s: Can't init va slot.\n", __func__); + goto error; + } + + secs_epc_page = enclave->secs_epc_page; + memset(&pginfo, 0, sizeof(struct page_info)); + pginfo.linaddr = (uint64_t)addp->addr; + pginfo.srcpge = (uint64_t)tmp_vaddr; + pginfo.secinfo = &secinfo; + pginfo.secs = (uint64_t)secs_epc_page->base; + + mtx_lock(&sc->mtx_encls); + ret = sgx_eadd(&pginfo, (void *)epc->base); + if (ret == SGX_EFAULT) { + dprintf("%s: gp fault on eadd\n", __func__); + mtx_unlock(&sc->mtx_encls); + VM_OBJECT_WUNLOCK(object); + goto error; + } + mtx_unlock(&sc->mtx_encls); + + ret = sgx_measure_page(sc, enclave->secs_epc_page, epc, addp->mrmask); + if (ret == SGX_EFAULT) { + dprintf("%s: gp fault on eextend\n", __func__); + sgx_epc_page_remove(sc, epc); + VM_OBJECT_WUNLOCK(object); + goto error; + } + + sgx_insert_epc_page(enclave, epc, addr); + + VM_OBJECT_WUNLOCK(object); + + /* Release the reference. */ + vm_object_deallocate(object); + + free(tmp_vaddr, M_SGX); + + return (0); + +error: + free(tmp_vaddr, M_SGX); + sgx_put_epc_page(sc, epc); + vm_object_deallocate(object); + + return (ret); +} + +static int +sgx_ioctl_init(struct sgx_softc *sc, struct sgx_enclave_init *initp) +{ + struct epc_page *secs_epc_page; + struct sgx_enclave *enclave; + struct thread *td; + void *tmp_vaddr; + void *einittoken; + void *sigstruct; + vm_object_t object; + int retry; + int ret; + + td = curthread; + tmp_vaddr = NULL; + object = NULL; + + dprintf("%s: addr %lx, sigstruct %lx, einittoken %lx\n", + __func__, initp->addr, initp->sigstruct, initp->einittoken); + + /* Find and get reference to VM object. */ + ret = sgx_enclave_find(sc, initp->addr, &enclave); + if (ret) { + dprintf("%s: Failed to find enclave.\n", __func__); + goto error; + } + + object = enclave->object; + + tmp_vaddr = malloc(PAGE_SIZE, M_SGX, M_WAITOK | M_ZERO); + sigstruct = tmp_vaddr; + einittoken = (void *)((uint64_t)sigstruct + PAGE_SIZE / 2); + + ret = copyin((void *)initp->sigstruct, sigstruct, + SGX_SIGSTRUCT_SIZE); + if (ret) { + dprintf("%s: Failed to copy SIGSTRUCT page.\n", __func__); + goto error; + } + + ret = copyin((void *)initp->einittoken, einittoken, + SGX_EINITTOKEN_SIZE); + if (ret) { + dprintf("%s: Failed to copy EINITTOKEN page.\n", __func__); + goto error; + } + + secs_epc_page = enclave->secs_epc_page; + retry = 16; + do { + mtx_lock(&sc->mtx_encls); + ret = sgx_einit(sigstruct, (void *)secs_epc_page->base, + einittoken); + mtx_unlock(&sc->mtx_encls); + dprintf("%s: sgx_einit returned %d\n", __func__, ret); + } while (ret == SGX_UNMASKED_EVENT && retry--); + + if (ret) { + dprintf("%s: Failed init enclave: %d\n", __func__, ret); + td->td_retval[0] = ret; + ret = 0; + } + +error: + free(tmp_vaddr, M_SGX); + + /* Release the reference. */ + vm_object_deallocate(object); + + 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; + int len; + + sc = &sgx_sc; + + len = IOCPARM_LEN(cmd); + + dprintf("%s: cmd %lx, addr %lx, len %d\n", + __func__, cmd, (uint64_t)addr, len); + + if (len > SGX_IOCTL_MAX_DATA_LEN) + return (EINVAL); + + switch (cmd) { + case SGX_IOC_ENCLAVE_CREATE: + param = (struct sgx_enclave_create *)addr; + ret = sgx_ioctl_create(sc, param); + break; + case SGX_IOC_ENCLAVE_ADD_PAGE: + addp = (struct sgx_enclave_add_page *)addr; + ret = sgx_ioctl_add_page(sc, addp); + break; + case SGX_IOC_ENCLAVE_INIT: + initp = (struct sgx_enclave_init *)addr; + ret = sgx_ioctl_init(sc, initp); + break; + default: + 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 = &sgx_sc; + + dprintf("%s: mapsize 0x%lx, offset %lx\n", + __func__, mapsize, *offset); + + vmh = malloc(sizeof(struct sgx_vm_handle), + M_SGX, M_WAITOK | M_ZERO); + vmh->sc = sc; + vmh->size = mapsize; + vmh->mem = cdev_pager_allocate(vmh, OBJT_MGTDEVICE, &sgx_pg_ops, + mapsize, nprot, *offset, NULL); + if (vmh->mem == NULL) { + free(vmh, M_SGX); + return (ENOMEM); + } + + VM_OBJECT_WLOCK(vmh->mem); + vm_object_set_flag(vmh->mem, OBJ_PG_DTOR); + VM_OBJECT_WUNLOCK(vmh->mem); + + *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; + u_int cp[4]; + int error; + int i; + + cpuid_count(SGX_CPUID, 0x2, cp); + + sc->epc_base = ((uint64_t)(cp[1] & 0xfffff) << 32) + + (cp[0] & 0xfffff000); + sc->epc_size = ((uint64_t)(cp[3] & 0xfffff) << 32) + + (cp[2] & 0xfffff000); + sc->npages = sc->epc_size / SGX_PAGE_SIZE; + + if (cp[3] & 0xffff) + sc->enclave_size_max = (1 << ((cp[3] >> 8) & 0xff)); + else + sc->enclave_size_max = SGX_ENCL_SIZE_MAX_DEF; + + epc_base_vaddr = (vm_offset_t)pmap_mapdev_attr(sc->epc_base, + sc->epc_size, VM_MEMATTR_DEFAULT); + + sc->epc_pages = malloc(sizeof(struct epc_page) * sc->npages, + M_DEVBUF, M_WAITOK | M_ZERO); + + for (i = 0; i < sc->npages; i++) { + sc->epc_pages[i].base = epc_base_vaddr + SGX_PAGE_SIZE * i; + sc->epc_pages[i].phys = sc->epc_base + SGX_PAGE_SIZE * i; + sc->epc_pages[i].index = i; + } + + sc->vmem_epc = vmem_create("SGX EPC", sc->epc_base, sc->epc_size, + PAGE_SIZE, PAGE_SIZE, M_FIRSTFIT | M_WAITOK); + if (sc->vmem_epc == NULL) { + printf("%s: Can't create vmem arena.\n", __func__); + free(sc->epc_pages, M_SGX); + return (EINVAL); + } + + error = vm_phys_fictitious_reg_range(sc->epc_base, + sc->epc_base + sc->epc_size, VM_MEMATTR_DEFAULT); + if (error) { + printf("%s: Can't register fictitious space.\n", __func__); + free(sc->epc_pages, M_SGX); + return (EINVAL); + } + + return (0); +} + +static void +sgx_put_epc_area(struct sgx_softc *sc) +{ + + vm_phys_fictitious_unreg_range(sc->epc_base, + sc->epc_base + sc->epc_size); + + free(sc->epc_pages, M_SGX); +} + +static int +sgx_load(void) +{ + struct sgx_softc *sc; + int error; + + sc = &sgx_sc; + + if ((cpu_stdext_feature & CPUID_STDEXT_SGX) == 0) + return (ENXIO); + + mtx_init(&sc->mtx_encls, "SGX ENCLS", NULL, MTX_DEF); + mtx_init(&sc->mtx, "SGX driver", NULL, MTX_DEF); + + error = sgx_get_epc_area(sc); + if (error) { + printf("%s: Failed to get Processor Reserved Memory area.\n", + __func__); + return (ENXIO); + } + + TAILQ_INIT(&sc->enclaves); + + sc->sgx_cdev = make_dev(&sgx_cdevsw, 0, UID_ROOT, GID_WHEEL, + 0600, "isgx"); + + sc->state |= SGX_STATE_RUNNING; + + printf("SGX initialized: EPC base 0x%lx size %ld (%d pages)\n", + sc->epc_base, sc->epc_size, sc->npages); + + return (0); +} + +static int +sgx_unload(void) +{ + struct sgx_softc *sc; + + sc = &sgx_sc; + + mtx_lock(&sc->mtx); + if (!TAILQ_EMPTY(&sc->enclaves)) { + mtx_unlock(&sc->mtx); + return (EBUSY); + } + sc->state &= ~SGX_STATE_RUNNING; + mtx_unlock(&sc->mtx); + + destroy_dev(sc->sgx_cdev); + + vmem_destroy(sc->vmem_epc); + sgx_put_epc_area(sc); + + mtx_destroy(&sc->mtx_encls); + mtx_destroy(&sc->mtx); + + return (0); +} + +static int +sgx_handler(module_t mod, int what, void *arg) +{ + int error; + + switch (what) { + case MOD_LOAD: + error = sgx_load(); + break; + case MOD_UNLOAD: + error = sgx_unload(); + break; + default: + error = 0; + break; + } + + return (error); +} + +static moduledata_t sgx_kmod = { + "sgx", + sgx_handler, + NULL +}; + +DECLARE_MODULE(sgx, sgx_kmod, SI_SUB_LAST, SI_ORDER_ANY); +MODULE_VERSION(sgx, 1); Property changes on: head/sys/amd64/sgx/sgx.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/amd64/sgx/sgx_linux.c =================================================================== --- head/sys/amd64/sgx/sgx_linux.c (nonexistent) +++ head/sys/amd64/sgx/sgx_linux.c (revision 322574) @@ -0,0 +1,119 @@ +/*- + * Copyright (c) 2017 Ruslan Bukin + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +#define SGX_LINUX_IOCTL_MIN (SGX_IOC_ENCLAVE_CREATE & 0xffff) +#define SGX_LINUX_IOCTL_MAX (SGX_IOC_ENCLAVE_INIT & 0xffff) + +static int +sgx_linux_ioctl(struct thread *td, struct linux_ioctl_args *args) +{ + uint8_t data[SGX_IOCTL_MAX_DATA_LEN]; + cap_rights_t rights; + struct file *fp; + u_long cmd; + int error; + int len; + + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) + return (error); + + cmd = args->cmd; + + args->cmd &= ~(LINUX_IOC_IN | LINUX_IOC_OUT); + if (cmd & LINUX_IOC_IN) + args->cmd |= IOC_IN; + if (cmd & LINUX_IOC_OUT) + args->cmd |= IOC_OUT; + + len = IOCPARM_LEN(cmd); + if (len > SGX_IOCTL_MAX_DATA_LEN) { + printf("%s: Can't copy data: cmd len is too big %d\n", + __func__, len); + return (EINVAL); + } + + if (cmd & LINUX_IOC_IN) { + error = copyin((void *)args->arg, data, len); + if (error) { + printf("%s: Can't copy data, error %d\n", + __func__, error); + return (EINVAL); + } + } + + error = (fo_ioctl(fp, args->cmd, (caddr_t)data, 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); Property changes on: head/sys/amd64/sgx/sgx_linux.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/amd64/sgx/sgx_support.S =================================================================== --- head/sys/amd64/sgx/sgx_support.S (nonexistent) +++ head/sys/amd64/sgx/sgx_support.S (revision 322574) @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2017 Ruslan Bukin + * 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$ + */ + +#include +#include + +#include "assym.s" + + .text + +/* + * int + * sgx_encls(uint32_t eax, uint64_t rbx, uint64_t rcx, uint64_t rdx); + * %edi, %rsi, %rdx, %rcx + */ +ENTRY(sgx_encls) + PUSH_FRAME_POINTER + pushq %rbx + movq PCPU(CURPCB),%r8 + movl %edi,%eax + movq %rsi,%rbx + xchgq %rdx,%rcx + movq $sgx_onfault,PCB_ONFAULT(%r8) + .byte 0x0f, 0x01, 0xcf + movq $0,PCB_ONFAULT(%r8) + popq %rbx + POP_FRAME_POINTER + ret +END(sgx_encls) + +/* + * SGX operations fault handler + */ + ALIGN_TEXT +sgx_onfault: + movq $0,PCB_ONFAULT(%r8) + movl $SGX_EFAULT,%eax + popq %rbx + POP_FRAME_POINTER + ret Property changes on: head/sys/amd64/sgx/sgx_support.S ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/amd64/sgx/sgxvar.h =================================================================== --- head/sys/amd64/sgx/sgxvar.h (nonexistent) +++ head/sys/amd64/sgx/sgxvar.h (revision 322574) @@ -0,0 +1,91 @@ +/*- + * Copyright (c) 2017 Ruslan Bukin + * 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_SGXVAR_H_ +#define _AMD64_SGX_SGXVAR_H_ + +#define SGX_CPUID 0x12 +#define SGX_PAGE_SIZE 4096 +#define SGX_VA_PAGE_SLOTS 512 +#define SGX_VA_PAGES_OFFS 512 +#define SGX_SECS_VM_OBJECT_INDEX -1 +#define SGX_SIGSTRUCT_SIZE 1808 +#define SGX_EINITTOKEN_SIZE 304 +#define SGX_IOCTL_MAX_DATA_LEN 26 +#define SGX_ENCL_SIZE_MAX_DEF 0x1000000000ULL +#define SGX_EFAULT 99 + +#ifndef LOCORE +static MALLOC_DEFINE(M_SGX, "sgx", "SGX driver"); + +struct sgx_vm_handle { + struct sgx_softc *sc; + vm_object_t mem; + uint64_t base; + vm_size_t size; + struct sgx_enclave *enclave; +}; + +/* EPC (Enclave Page Cache) page. */ +struct epc_page { + uint64_t base; + uint64_t phys; + int index; +}; + +struct sgx_enclave { + uint64_t base; + uint64_t size; + struct sgx_vm_handle *vmh; + TAILQ_ENTRY(sgx_enclave) next; + vm_object_t object; + struct epc_page *secs_epc_page; +}; + +struct sgx_softc { + struct cdev *sgx_cdev; + struct mtx mtx_encls; + struct mtx mtx; + uint64_t epc_base; + uint64_t epc_size; + struct epc_page *epc_pages; + struct vmem *vmem_epc; + uint32_t npages; + TAILQ_HEAD(, sgx_enclave) enclaves; + uint64_t enclave_size_max; + uint8_t state; +#define SGX_STATE_RUNNING (1 << 0) +}; +#endif /* !LOCORE */ + +#endif /* !_AMD64_SGX_SGXVAR_H_ */ Property changes on: head/sys/amd64/sgx/sgxvar.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/modules/Makefile =================================================================== --- head/sys/modules/Makefile (revision 322573) +++ head/sys/modules/Makefile (revision 322574) @@ -1,821 +1,825 @@ # $FreeBSD$ SYSDIR?=${SRCTOP}/sys .include "${SYSDIR}/conf/kern.opts.mk" SUBDIR_PARALLEL= # Modules that include binary-only blobs of microcode should be selectable by # MK_SOURCELESS_UCODE option (see below). .if defined(MODULES_OVERRIDE) && !defined(ALL_MODULES) SUBDIR=${MODULES_OVERRIDE} .else SUBDIR= \ ${_3dfx} \ ${_3dfx_linux} \ ${_aac} \ ${_aacraid} \ accf_data \ accf_dns \ accf_http \ acl_nfs4 \ acl_posix1e \ ${_acpi} \ ae \ ${_aesni} \ age \ ${_agp} \ aha \ ahci \ ${_aic} \ aic7xxx \ alc \ ale \ alq \ ${_amd_ecc_inject} \ ${_amdsbwd} \ ${_amdtemp} \ amr \ ${_an} \ ${_aout} \ ${_apm} \ ${_arcmsr} \ ${_arcnet} \ ${_armv8crypto} \ ${_asmc} \ ata \ ath \ ath_dfs \ ath_hal \ ath_hal_ar5210 \ ath_hal_ar5211 \ ath_hal_ar5212 \ ath_hal_ar5416 \ ath_hal_ar9300 \ ath_main \ ath_rate \ ath_pci \ ${_autofs} \ ${_auxio} \ ${_bce} \ bfe \ bge \ bhnd \ ${_bxe} \ ${_bios} \ ${_bktr} \ ${_bm} \ bnxt \ bridgestp \ bwi \ bwn \ bwn_pci \ ${_bytgpio} \ cam \ ${_cardbus} \ ${_carp} \ cas \ ${_cbb} \ cc \ cd9660 \ cd9660_iconv \ ${_ce} \ ${_cfi} \ chacha20 \ ${_chromebook_platform} \ ${_ciss} \ cloudabi \ ${_cloudabi32} \ ${_cloudabi64} \ ${_cm} \ ${_cmx} \ ${_coff} \ ${_coretemp} \ ${_cp} \ ${_cpsw} \ ${_cpuctl} \ ${_cpufreq} \ ${_crypto} \ ${_cryptodev} \ ${_cs} \ ${_ctau} \ ctl \ ${_cxgb} \ ${_cxgbe} \ dc \ dcons \ dcons_crom \ de \ ${_dpms} \ ${_dpt} \ ${_drm} \ ${_drm2} \ dummynet \ ${_ed} \ ${_efirt} \ ${_elink} \ ${_em} \ ${_ena} \ ${_ep} \ ${_epic} \ esp \ ${_et} \ evdev \ ${_ex} \ ${_exca} \ ext2fs \ fdc \ fdescfs \ ${_fe} \ ${_ffec} \ filemon \ firewire \ firmware \ fuse \ ${_fxp} \ gem \ geom \ ${_glxiic} \ ${_glxsb} \ gpio \ hifn \ hme \ ${_hpt27xx} \ ${_hptiop} \ ${_hptmv} \ ${_hptnr} \ ${_hptrr} \ hwpmc \ ${_hwpmc_mips24k} \ ${_hwpmc_mips74k} \ ${_hyperv} \ i2c \ ${_ibcore} \ ${_ibcs2} \ ${_ichwd} \ ${_ida} \ if_bridge \ if_disc \ if_edsc \ ${_if_enc} \ if_epair \ ${_if_gif} \ ${_if_gre} \ ${_if_me} \ if_lagg \ ${_if_ndis} \ ${_if_stf} \ if_tap \ if_tun \ if_vlan \ if_vxlan \ ${_iir} \ imgact_binmisc \ ${_intelspi} \ ${_io} \ ${_ioat} \ ${_ipoib} \ ${_ipdivert} \ ${_ipfilter} \ ${_ipfw} \ ipfw_nat \ ${_ipfw_nat64} \ ${_ipfw_nptv6} \ ${_ipfw_pmod} \ ${_ipmi} \ ip6_mroute_mod \ ip_mroute_mod \ ${_ips} \ ${_ipsec} \ ${_ipw} \ ${_ipwfw} \ ${_isci} \ ${_iser} \ isp \ ${_ispfw} \ ${_iwi} \ ${_iwifw} \ ${_iwm} \ ${_iwmfw} \ ${_iwn} \ ${_iwnfw} \ ${_ix} \ ${_ixv} \ ${_ixgb} \ ${_ixl} \ ${_ixlv} \ jme \ joy \ kbdmux \ kgssapi \ kgssapi_krb5 \ khelp \ krpc \ ksyms \ le \ lge \ libalias \ libiconv \ libmbpool \ libmchain \ ${_linprocfs} \ ${_linsysfs} \ ${_linux} \ ${_linux_common} \ ${_linux64} \ linuxkpi \ lmc \ lpt \ mac_biba \ mac_bsdextended \ mac_ifoff \ mac_lomac \ mac_mls \ mac_none \ mac_partition \ mac_portacl \ mac_seeotheruids \ mac_stub \ mac_test \ malo \ md \ mdio \ mem \ mfi \ mii \ mlx \ ${_mlx4} \ ${_mlx4ib} \ ${_mlx4en} \ ${_mlx5} \ ${_mlx5en} \ ${_mly} \ mmc \ mmcsd \ mpr \ mps \ mpt \ mqueue \ mrsas \ msdosfs \ msdosfs_iconv \ ${_mse} \ msk \ ${_mthca} \ mvs \ mwl \ ${_mwlfw} \ mxge \ my \ ${_nandfs} \ ${_nandsim} \ ${_ncr} \ ${_nctgpio} \ ${_ncv} \ ${_ndis} \ ${_netgraph} \ ${_nfe} \ nfscl \ nfscommon \ nfsd \ nfslock \ nfslockd \ nfssvc \ nge \ nmdm \ ${_nsp} \ nullfs \ ${_ntb} \ ${_nvd} \ ${_nvme} \ ${_nvram} \ ${_nxge} \ oce \ otus \ ${_otusfw} \ ow \ ${_padlock} \ ${_padlock_rng} \ ${_pccard} \ ${_pcfclock} \ pcn \ ${_pf} \ ${_pflog} \ ${_pfsync} \ plip \ ${_pms} \ ppbus \ ppc \ ppi \ pps \ procfs \ proto \ pseudofs \ ${_pst} \ pty \ puc \ ${_qlxge} \ ${_qlxgb} \ ${_qlxgbe} \ ${_qlnx} \ ral \ ${_ralfw} \ ${_random_fortuna} \ ${_random_yarrow} \ ${_random_other} \ rc4 \ ${_rdma} \ ${_rdrand_rng} \ re \ rl \ rtwn \ rtwn_pci \ rtwn_usb \ ${_rtwnfw} \ ${_s3} \ ${_safe} \ ${_sbni} \ scc \ ${_scsi_low} \ sdhci \ ${_sdhci_acpi} \ sdhci_pci \ sem \ send \ ${_sf} \ ${_sfxge} \ sge \ + ${_sgx} \ + ${_sgx_linux} \ siba_bwn \ siftr \ siis \ sis \ sk \ smbfs \ sn \ snp \ sound \ ${_speaker} \ spigen \ ${_splash} \ ${_sppp} \ ste \ ${_stg} \ stge \ ${_sym} \ ${_syscons} \ sysvipc \ tcp \ ${_ti} \ tl \ tmpfs \ ${_toecore} \ ${_tpm} \ trm \ ${_twa} \ twe \ tws \ tx \ ${_txp} \ uart \ ubsec \ udf \ udf_iconv \ ufs \ uinput \ unionfs \ usb \ ${_vesa} \ ${_virtio} \ vge \ ${_viawd} \ videomode \ vkbd \ ${_vmm} \ ${_vmware} \ ${_vpo} \ vr \ vte \ vx \ ${_vxge} \ wb \ ${_wbwd} \ ${_wi} \ wlan \ wlan_acl \ wlan_amrr \ wlan_ccmp \ wlan_rssadapt \ wlan_tkip \ wlan_wep \ wlan_xauth \ ${_wpi} \ ${_wpifw} \ ${_x86bios} \ ${_xe} \ xl \ zlib .if ${MK_AUTOFS} != "no" || defined(ALL_MODULES) _autofs= autofs .endif .if ${MK_CDDL} != "no" || defined(ALL_MODULES) .if (${MACHINE_CPUARCH} != "arm" || ${MACHINE_ARCH:Marmv6*} != "") && \ ${MACHINE_CPUARCH} != "mips" && \ ${MACHINE_CPUARCH} != "sparc64" SUBDIR+= dtrace .endif SUBDIR+= opensolaris .endif .if ${MK_CRYPT} != "no" || defined(ALL_MODULES) .if exists(${SRCTOP}/sys/opencrypto) _crypto= crypto _cryptodev= cryptodev _random_fortuna=random_fortuna _random_yarrow= random_yarrow _random_other= random_other .endif .endif .if ${MK_CUSE} != "no" || defined(ALL_MODULES) SUBDIR+= cuse .endif .if (${MK_INET_SUPPORT} != "no" || ${MK_INET6_SUPPORT} != "no") || \ defined(ALL_MODULES) _carp= carp _toecore= toecore _if_enc= if_enc _if_gif= if_gif _if_gre= if_gre _ipfw_pmod= ipfw_pmod .if ${MK_IPSEC_SUPPORT} != "no" _ipsec= ipsec .endif .endif .if (${MK_INET_SUPPORT} != "no" && ${MK_INET6_SUPPORT} != "no") || \ defined(ALL_MODULES) _if_stf= if_stf .endif .if ${MK_INET_SUPPORT} != "no" || defined(ALL_MODULES) _if_me= if_me _ipdivert= ipdivert _ipfw= ipfw .if ${MK_INET6_SUPPORT} != "no" || defined(ALL_MODULES) _ipfw_nat64= ipfw_nat64 .endif .endif .if ${MK_INET6_SUPPORT} != "no" || defined(ALL_MODULES) _ipfw_nptv6= ipfw_nptv6 .endif .if ${MK_IPFILTER} != "no" || defined(ALL_MODULES) _ipfilter= ipfilter .endif .if ${MK_ISCSI} != "no" || defined(ALL_MODULES) SUBDIR+= cfiscsi SUBDIR+= iscsi SUBDIR+= iscsi_initiator .endif .if ${MK_NAND} != "no" || defined(ALL_MODULES) _nandfs= nandfs _nandsim= nandsim .endif .if ${MK_NETGRAPH} != "no" || defined(ALL_MODULES) _netgraph= netgraph .endif .if (${MK_PF} != "no" && (${MK_INET_SUPPORT} != "no" || \ ${MK_INET6_SUPPORT} != "no")) || defined(ALL_MODULES) _pf= pf _pflog= pflog .if ${MK_INET_SUPPORT} != "no" _pfsync= pfsync .endif .endif .if ${MK_SOURCELESS_UCODE} != "no" _bce= bce _fxp= fxp _ispfw= ispfw _sf= sf _ti= ti _txp= txp .if ${MACHINE_CPUARCH} != "mips" _mwlfw= mwlfw _otusfw= otusfw _ralfw= ralfw _rtwnfw= rtwnfw .endif .endif .if ${MK_SOURCELESS_UCODE} != "no" && ${MACHINE_CPUARCH} != "arm" && \ ${MACHINE_CPUARCH} != "mips" && \ ${MACHINE_ARCH} != "powerpc" && ${MACHINE_ARCH} != "powerpcspe" && \ ${MACHINE_CPUARCH} != "riscv" _cxgbe= cxgbe .endif .if ${MK_TESTS} != "no" || defined(ALL_MODULES) SUBDIR+= tests .endif .if ${MK_ZFS} != "no" || defined(ALL_MODULES) SUBDIR+= zfs .endif .if (${MACHINE_CPUARCH} == "mips" && ${MACHINE_ARCH:Mmips64} == "") _hwpmc_mips24k= hwpmc_mips24k _hwpmc_mips74k= hwpmc_mips74k .endif .if ${MACHINE_CPUARCH} != "aarch64" && ${MACHINE_CPUARCH} != "arm" && \ ${MACHINE_CPUARCH} != "mips" && ${MACHINE_CPUARCH} != "powerpc" && \ ${MACHINE_CPUARCH} != "riscv" _syscons= syscons _vpo= vpo .endif .if ${MACHINE_CPUARCH} != "mips" # no BUS_SPACE_UNSPECIFIED # No barrier instruction support (specific to this driver) _sym= sym # intr_disable() is a macro, causes problems .if ${MK_SOURCELESS_UCODE} != "no" _cxgb= cxgb .endif .endif .if ${MACHINE_CPUARCH} == "aarch64" _armv8crypto= armv8crypto _em= em .endif .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" _agp= agp _an= an _aout= aout _bios= bios _bktr= bktr _bxe= bxe _cardbus= cardbus _cbb= cbb _cpuctl= cpuctl _cpufreq= cpufreq _cs= cs _dpms= dpms _drm= drm _drm2= drm2 _ed= ed _em= em _ena= ena _ep= ep _et= et _exca= exca _fe= fe .if ${MK_OFED} != "no" || defined(ALL_MODULES) _ibcore= ibcore .endif _if_ndis= if_ndis _io= io .if ${MK_OFED} != "no" || defined(ALL_MODULES) _ipoib= ipoib _iser= iser .endif _ix= ix _ixv= ixv _linprocfs= linprocfs _linsysfs= linsysfs _linux= linux _nctgpio= nctgpio _ndis= ndis _pccard= pccard .if ${MK_OFED} != "no" || defined(ALL_MODULES) _rdma= rdma .endif _safe= safe _scsi_low= scsi_low _speaker= speaker _splash= splash _sppp= sppp _vmware= vmware _vxge= vxge _wbwd= wbwd _wi= wi _xe= xe _aac= aac _aacraid= aacraid _acpi= acpi .if ${MK_CRYPT} != "no" || defined(ALL_MODULES) _aesni= aesni .endif _amd_ecc_inject=amd_ecc_inject _amdsbwd= amdsbwd _amdtemp= amdtemp _arcmsr= arcmsr _asmc= asmc _bytgpio= bytgpio _ciss= ciss _chromebook_platform= chromebook_platform _cmx= cmx _coretemp= coretemp .if ${MK_SOURCELESS_HOST} != "no" _hpt27xx= hpt27xx .endif _hptiop= hptiop .if ${MK_SOURCELESS_HOST} != "no" _hptmv= hptmv _hptnr= hptnr _hptrr= hptrr .endif _hyperv= hyperv _ichwd= ichwd _ida= ida _iir= iir _intelspi= intelspi _ipmi= ipmi _ips= ips _isci= isci _ipw= ipw _iwi= iwi _iwm= iwm _iwn= iwn _ixgb= ixgb .if ${MK_SOURCELESS_UCODE} != "no" _ipwfw= ipwfw _iwifw= iwifw _iwmfw= iwmfw _iwnfw= iwnfw .endif _mlx4= mlx4 _mlx5= mlx5 .if (${MK_INET_SUPPORT} != "no" && ${MK_INET6_SUPPORT} != "no") || \ defined(ALL_MODULES) _mlx4en= mlx4en _mlx5en= mlx5en .endif .if ${MK_OFED} != "no" || defined(ALL_MODULES) _mlx4ib= mlx4ib .endif _mly= mly .if ${MK_OFED} != "no" || defined(ALL_MODULES) _mthca= mthca .endif _nfe= nfe _nvd= nvd _nvme= nvme _nvram= nvram _nxge= nxge .if ${MK_CRYPT} != "no" || defined(ALL_MODULES) _padlock= padlock _padlock_rng= padlock_rng _rdrand_rng= rdrand_rng .endif _s3= s3 _sdhci_acpi= sdhci_acpi _tpm= tpm _twa= twa _vesa= vesa _viawd= viawd _virtio= virtio _wpi= wpi .if ${MK_SOURCELESS_UCODE} != "no" _wpifw= wpifw .endif _x86bios= x86bios .endif .if ${MACHINE_CPUARCH} == "amd64" _efirt= efirt _ioat= ioat _ixl= ixl _ixlv= ixlv _linux64= linux64 _linux_common= linux_common _ntb= ntb _pms= pms _qlxge= qlxge _qlxgb= qlxgb _qlxgbe= qlxgbe _qlnx= qlnx _sfxge= sfxge +_sgx= sgx +_sgx_linux= sgx_linux .if ${MK_BHYVE} != "no" || defined(ALL_MODULES) _vmm= vmm .endif .endif .if ${MACHINE_CPUARCH} == "i386" # XXX some of these can move to the general case when de-i386'ed # XXX some of these can move now, but are untested on other architectures. _3dfx= 3dfx _3dfx_linux= 3dfx_linux _aic= aic _apm= apm _arcnet= arcnet .if ${MK_SOURCELESS_UCODE} != "no" _ce= ce .endif _coff= coff .if ${MK_SOURCELESS_UCODE} != "no" _cp= cp .endif _elink= elink _glxiic= glxiic _glxsb= glxsb #_ibcs2= ibcs2 _mse= mse _ncr= ncr _ncv= ncv _nsp= nsp _pcfclock= pcfclock _pst= pst _sbni= sbni _stg= stg _cm= cm .if ${MK_SOURCELESS_UCODE} != "no" _ctau= ctau .endif _dpt= dpt _ex= ex .endif .if ${MACHINE_CPUARCH} == "arm" _cfi= cfi _cpsw= cpsw .endif .if ${MACHINE_CPUARCH} == "powerpc" _agp= agp _an= an _bm= bm _cardbus= cardbus _cbb= cbb _cfi= cfi _cpufreq= cpufreq _drm= drm _exca= exca _ffec= ffec _pccard= pccard _wi= wi .endif .if ${MACHINE_ARCH} == "powerpc64" _drm2= drm2 .endif .if ${MACHINE_ARCH} == "powerpc64" || ${MACHINE_ARCH} == "powerpc" # Don't build powermac_nvram for powerpcspe, it's never supported. _nvram= powermac_nvram .endif .if ${MACHINE_CPUARCH} == "sparc64" _auxio= auxio _em= em _epic= epic .endif .if (${MACHINE_CPUARCH} == "amd64" || ${MACHINE_ARCH} == "armv6" || \ ${MACHINE_CPUARCH} == "i386") _cloudabi32= cloudabi32 .endif .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" _cloudabi64= cloudabi64 .endif .endif .if ${MACHINE_ARCH} == "armv6" _ffec= ffec .endif SUBDIR+=${MODULES_EXTRA} .for reject in ${WITHOUT_MODULES} SUBDIR:= ${SUBDIR:N${reject}} .endfor # Calling kldxref(8) for each module is expensive. .if !defined(NO_XREF) .MAKEFLAGS+= -DNO_XREF afterinstall: .PHONY @if type kldxref >/dev/null 2>&1; then \ ${ECHO} kldxref ${DESTDIR}${KMODDIR}; \ kldxref ${DESTDIR}${KMODDIR}; \ fi .endif .include "${SYSDIR}/conf/config.mk" SUBDIR:= ${SUBDIR:u:O} .include Index: head/sys/modules/sgx/Makefile =================================================================== --- head/sys/modules/sgx/Makefile (nonexistent) +++ head/sys/modules/sgx/Makefile (revision 322574) @@ -0,0 +1,12 @@ +# $FreeBSD$ + +.PATH: ${SRCTOP}/sys/amd64/sgx + +KMOD= sgx +SRCS= sgx.c sgxvar.h assym.s sgx_support.S + +sgx_support.o: assym.s + ${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \ + ${.IMPSRC} -o ${.TARGET} + +.include Property changes on: head/sys/modules/sgx/Makefile ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/modules/sgx_linux/Makefile =================================================================== --- head/sys/modules/sgx_linux/Makefile (nonexistent) +++ head/sys/modules/sgx_linux/Makefile (revision 322574) @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${SRCTOP}/sys/amd64/sgx + +KMOD= sgx_linux +SRCS= sgx_linux.c + +.include Property changes on: head/sys/modules/sgx_linux/Makefile ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property