Re: [PATCH RFC] selftests/x86: Add a selftest for SGX

2018-11-15 Thread Jarkko Sakkinen
On Wed, Nov 14, 2018 at 08:09:42AM -0800, Sean Christopherson wrote:
> On Tue, Nov 13, 2018 at 11:40:09PM +0200, Jarkko Sakkinen wrote:
> > Add a selftest for SGX. It is a trivial test where a simple enclave
> > copies one 64-bit word of memory between two memory locations given to
> > the enclave as arguments.
> > 
> > Signed-off-by: Jarkko Sakkinen 
> > ---
> > +SUBDIRS_64 := sgx
> > +ASSERT(!DEFINED(.altinstructions), "ALTERNATIVES are not supported in the 
> > SGX LE")
> > +ASSERT(!DEFINED(.altinstr_replacement), "ALTERNATIVES are not supported in 
> > the SGX LE")
> > +ASSERT(!DEFINED(.discard.retpoline_safe), "RETPOLINE ALTERNATIVES are not 
> > supported in the SGX LE")
> > +ASSERT(!DEFINED(.discard.nospec), "RETPOLINE ALTERNATIVES are not 
> > supported in the SGX LE")
> 
> Maybe this?
> 
> s/LE/Test Enclave

Sure.

> > diff --git a/tools/testing/selftests/x86/sgx/encl_bootstrap.S 
> > b/tools/testing/selftests/x86/sgx/encl_bootstrap.S
> > new file mode 100644
> > index ..62251c7d9927
> > --- /dev/null
> > +++ b/tools/testing/selftests/x86/sgx/encl_bootstrap.S
> > @@ -0,0 +1,94 @@
> > +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
> > +/*
> > + * Copyright(c) 2016-18 Intel Corporation.
> > + */
> > +
> > +   .macro ENCLU
> > +   .byte 0x0f, 0x01, 0xd7
> > +   .endm
> > +
> > +   .section ".tcs", "a"
> > +   .balign 4096
> > +
> > +   .fill   1, 8, 0 # STATE (set by CPU)
> > +   .fill   1, 8, 0 # FLAGS
> > +   .long   encl_ssa# OSSA
> 
> Any reason not to do .quad for OSSA and OENTRY?

Probably not.

> > +   .fill   1, 4, 0
> > +   .fill   1, 4, 0 # CSSA (set by CPU)
> > +   .fill   1, 4, 1 # NSSA
> > +   .long   encl_entry  # OENTRY
> > +   .fill   1, 4, 0
> > +   .fill   1, 8, 0 # AEP (set by EENTER and ERESUME)
> > +   .fill   1, 8, 0 # OFSBASE
> > +   .fill   1, 8, 0 # OGSBASE
> > +   .fill   1, 4, 0x# FSLIMIT
> > +   .fill   1, 4, 0x# GSLIMIT
> > +   .fill   503, 8, 0   # Reserved
> 
> I'd prefer to do 1-byte fill with a size of 4024 to match the SDM.

Sure.

> > +
> > +   .text
> > +
> > +encl_entry:
> > +   # %rbx contains the base address for TCS, which is also the first
> > +   # address inside the enclave. By adding $le_stack_end to it, we get the
> > +   # absolute address for the stack.
> > +   lea (encl_stack)(%rbx), %rax
> > +   xchg%rsp, %rax
> > +   push%rax
> > +
> > +   push%rcx # push the address after EENTER
> > +   push%rbx # push the enclave base address
> > +
> > +   callencl_body
> > +
> > +   pop %rbx # pop the enclave base address
> > +
> > +   # Restore XSAVE registers to a synthetic state.
> > +   mov $0x, %rax
> > +   mov $0x, %rdx
> > +   lea (xsave_area)(%rbx), %rdi
> > +   fxrstor (%rdi)
> > +
> > +   # Clear GPRs
> > +   xor %rcx, %rcx
> > +   xor %rdx, %rdx
> > +   xor %rdi, %rdi
> > +   xor %rsi, %rsi
> > +   xor %r8, %r8
> > +   xor %r9, %r9
> > +   xor %r10, %r10
> > +   xor %r11, %r11
> > +   xor %r12, %r12
> > +   xor %r13, %r13
> > +   xor %r14, %r14
> > +   xor %r15, %r15
> > +
> > +   # Reset status flags
> > +   add %rdx, %rdx # OF = SF = AF = CF = 0; ZF = PF = 1
> > +
> > +   pop %rbx # pop the address after EENTER
> 
> Probably worth expanding the comment to explain that ENCLU[EEXIT] takes the
> target address via %rbx, i.e. we're "returning" from the EENTER "call".

Thank you for the feedback. I'll do all of these updates.

/Jarkko


Re: [PATCH RFC] selftests/x86: Add a selftest for SGX

2018-11-15 Thread Jarkko Sakkinen
On Wed, Nov 14, 2018 at 08:09:42AM -0800, Sean Christopherson wrote:
> On Tue, Nov 13, 2018 at 11:40:09PM +0200, Jarkko Sakkinen wrote:
> > Add a selftest for SGX. It is a trivial test where a simple enclave
> > copies one 64-bit word of memory between two memory locations given to
> > the enclave as arguments.
> > 
> > Signed-off-by: Jarkko Sakkinen 
> > ---
> > +SUBDIRS_64 := sgx
> > +ASSERT(!DEFINED(.altinstructions), "ALTERNATIVES are not supported in the 
> > SGX LE")
> > +ASSERT(!DEFINED(.altinstr_replacement), "ALTERNATIVES are not supported in 
> > the SGX LE")
> > +ASSERT(!DEFINED(.discard.retpoline_safe), "RETPOLINE ALTERNATIVES are not 
> > supported in the SGX LE")
> > +ASSERT(!DEFINED(.discard.nospec), "RETPOLINE ALTERNATIVES are not 
> > supported in the SGX LE")
> 
> Maybe this?
> 
> s/LE/Test Enclave

Sure.

> > diff --git a/tools/testing/selftests/x86/sgx/encl_bootstrap.S 
> > b/tools/testing/selftests/x86/sgx/encl_bootstrap.S
> > new file mode 100644
> > index ..62251c7d9927
> > --- /dev/null
> > +++ b/tools/testing/selftests/x86/sgx/encl_bootstrap.S
> > @@ -0,0 +1,94 @@
> > +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
> > +/*
> > + * Copyright(c) 2016-18 Intel Corporation.
> > + */
> > +
> > +   .macro ENCLU
> > +   .byte 0x0f, 0x01, 0xd7
> > +   .endm
> > +
> > +   .section ".tcs", "a"
> > +   .balign 4096
> > +
> > +   .fill   1, 8, 0 # STATE (set by CPU)
> > +   .fill   1, 8, 0 # FLAGS
> > +   .long   encl_ssa# OSSA
> 
> Any reason not to do .quad for OSSA and OENTRY?

Probably not.

> > +   .fill   1, 4, 0
> > +   .fill   1, 4, 0 # CSSA (set by CPU)
> > +   .fill   1, 4, 1 # NSSA
> > +   .long   encl_entry  # OENTRY
> > +   .fill   1, 4, 0
> > +   .fill   1, 8, 0 # AEP (set by EENTER and ERESUME)
> > +   .fill   1, 8, 0 # OFSBASE
> > +   .fill   1, 8, 0 # OGSBASE
> > +   .fill   1, 4, 0x# FSLIMIT
> > +   .fill   1, 4, 0x# GSLIMIT
> > +   .fill   503, 8, 0   # Reserved
> 
> I'd prefer to do 1-byte fill with a size of 4024 to match the SDM.

Sure.

> > +
> > +   .text
> > +
> > +encl_entry:
> > +   # %rbx contains the base address for TCS, which is also the first
> > +   # address inside the enclave. By adding $le_stack_end to it, we get the
> > +   # absolute address for the stack.
> > +   lea (encl_stack)(%rbx), %rax
> > +   xchg%rsp, %rax
> > +   push%rax
> > +
> > +   push%rcx # push the address after EENTER
> > +   push%rbx # push the enclave base address
> > +
> > +   callencl_body
> > +
> > +   pop %rbx # pop the enclave base address
> > +
> > +   # Restore XSAVE registers to a synthetic state.
> > +   mov $0x, %rax
> > +   mov $0x, %rdx
> > +   lea (xsave_area)(%rbx), %rdi
> > +   fxrstor (%rdi)
> > +
> > +   # Clear GPRs
> > +   xor %rcx, %rcx
> > +   xor %rdx, %rdx
> > +   xor %rdi, %rdi
> > +   xor %rsi, %rsi
> > +   xor %r8, %r8
> > +   xor %r9, %r9
> > +   xor %r10, %r10
> > +   xor %r11, %r11
> > +   xor %r12, %r12
> > +   xor %r13, %r13
> > +   xor %r14, %r14
> > +   xor %r15, %r15
> > +
> > +   # Reset status flags
> > +   add %rdx, %rdx # OF = SF = AF = CF = 0; ZF = PF = 1
> > +
> > +   pop %rbx # pop the address after EENTER
> 
> Probably worth expanding the comment to explain that ENCLU[EEXIT] takes the
> target address via %rbx, i.e. we're "returning" from the EENTER "call".

Thank you for the feedback. I'll do all of these updates.

/Jarkko


Re: [PATCH RFC] selftests/x86: Add a selftest for SGX

2018-11-15 Thread Jarkko Sakkinen
On Tue, Nov 13, 2018 at 01:51:06PM -0800, Dave Hansen wrote:
> On 11/13/18 1:40 PM, Jarkko Sakkinen wrote:
> > +int main(int argc, char **argv)
> > +{
> > +   unsigned long bin_size = (unsigned long)_bin_end -
> > +(unsigned long)_bin;
> > +   struct sgx_secs secs;
> > +   uint64_t result = 0;
> > +
> > +   if (!encl_load(, bin_size))
> > +   exit(1);
> > +
> > +   sgx_call((void *), , (void *)secs.base);
> > +   if (result != MAGIC) {
> > +   fprintf(stderr, "0x%lx != 0x%lx\n", result, MAGIC);
> > +   exit(1);
> > +   }
> > +
> > +   exit(0);
> > +}
> 
> Well, I guess 100 lines of code for something a wee bit shy of hello
> world isn't bad. :)
> 
> In general, this looks fine, but probably needs some better commenting
> and probably some messages that make it a bit more clear what is going on.
> 
> It would be _nice_, for instance to try to do some CPUID detection of
> SGX so that the error (or success?) message can tell you whether you're
> missing hardware support or kernel support.
> 
> Thanks for doing this, though.  It's sorely needed.

Great, thanks, I see what I can do.

/Jarkko


Re: [PATCH RFC] selftests/x86: Add a selftest for SGX

2018-11-15 Thread Jarkko Sakkinen
On Tue, Nov 13, 2018 at 01:51:06PM -0800, Dave Hansen wrote:
> On 11/13/18 1:40 PM, Jarkko Sakkinen wrote:
> > +int main(int argc, char **argv)
> > +{
> > +   unsigned long bin_size = (unsigned long)_bin_end -
> > +(unsigned long)_bin;
> > +   struct sgx_secs secs;
> > +   uint64_t result = 0;
> > +
> > +   if (!encl_load(, bin_size))
> > +   exit(1);
> > +
> > +   sgx_call((void *), , (void *)secs.base);
> > +   if (result != MAGIC) {
> > +   fprintf(stderr, "0x%lx != 0x%lx\n", result, MAGIC);
> > +   exit(1);
> > +   }
> > +
> > +   exit(0);
> > +}
> 
> Well, I guess 100 lines of code for something a wee bit shy of hello
> world isn't bad. :)
> 
> In general, this looks fine, but probably needs some better commenting
> and probably some messages that make it a bit more clear what is going on.
> 
> It would be _nice_, for instance to try to do some CPUID detection of
> SGX so that the error (or success?) message can tell you whether you're
> missing hardware support or kernel support.
> 
> Thanks for doing this, though.  It's sorely needed.

Great, thanks, I see what I can do.

/Jarkko


Re: [PATCH RFC] selftests/x86: Add a selftest for SGX

2018-11-14 Thread Sean Christopherson
On Tue, Nov 13, 2018 at 11:40:09PM +0200, Jarkko Sakkinen wrote:
> Add a selftest for SGX. It is a trivial test where a simple enclave
> copies one 64-bit word of memory between two memory locations given to
> the enclave as arguments.
> 
> Signed-off-by: Jarkko Sakkinen 
> ---
> +SUBDIRS_64 := sgx
> +ASSERT(!DEFINED(.altinstructions), "ALTERNATIVES are not supported in the 
> SGX LE")
> +ASSERT(!DEFINED(.altinstr_replacement), "ALTERNATIVES are not supported in 
> the SGX LE")
> +ASSERT(!DEFINED(.discard.retpoline_safe), "RETPOLINE ALTERNATIVES are not 
> supported in the SGX LE")
> +ASSERT(!DEFINED(.discard.nospec), "RETPOLINE ALTERNATIVES are not supported 
> in the SGX LE")

Maybe this?

s/LE/Test Enclave

> diff --git a/tools/testing/selftests/x86/sgx/encl_bootstrap.S 
> b/tools/testing/selftests/x86/sgx/encl_bootstrap.S
> new file mode 100644
> index ..62251c7d9927
> --- /dev/null
> +++ b/tools/testing/selftests/x86/sgx/encl_bootstrap.S
> @@ -0,0 +1,94 @@
> +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
> +/*
> + * Copyright(c) 2016-18 Intel Corporation.
> + */
> +
> + .macro ENCLU
> + .byte 0x0f, 0x01, 0xd7
> + .endm
> +
> + .section ".tcs", "a"
> + .balign 4096
> +
> + .fill   1, 8, 0 # STATE (set by CPU)
> + .fill   1, 8, 0 # FLAGS
> + .long   encl_ssa# OSSA

Any reason not to do .quad for OSSA and OENTRY?

> + .fill   1, 4, 0
> + .fill   1, 4, 0 # CSSA (set by CPU)
> + .fill   1, 4, 1 # NSSA
> + .long   encl_entry  # OENTRY
> + .fill   1, 4, 0
> + .fill   1, 8, 0 # AEP (set by EENTER and ERESUME)
> + .fill   1, 8, 0 # OFSBASE
> + .fill   1, 8, 0 # OGSBASE
> + .fill   1, 4, 0x# FSLIMIT
> + .fill   1, 4, 0x# GSLIMIT
> + .fill   503, 8, 0   # Reserved

I'd prefer to do 1-byte fill with a size of 4024 to match the SDM.

> +
> + .text
> +
> +encl_entry:
> + # %rbx contains the base address for TCS, which is also the first
> + # address inside the enclave. By adding $le_stack_end to it, we get the
> + # absolute address for the stack.
> + lea (encl_stack)(%rbx), %rax
> + xchg%rsp, %rax
> + push%rax
> +
> + push%rcx # push the address after EENTER
> + push%rbx # push the enclave base address
> +
> + callencl_body
> +
> + pop %rbx # pop the enclave base address
> +
> + # Restore XSAVE registers to a synthetic state.
> + mov $0x, %rax
> + mov $0x, %rdx
> + lea (xsave_area)(%rbx), %rdi
> + fxrstor (%rdi)
> +
> + # Clear GPRs
> + xor %rcx, %rcx
> + xor %rdx, %rdx
> + xor %rdi, %rdi
> + xor %rsi, %rsi
> + xor %r8, %r8
> + xor %r9, %r9
> + xor %r10, %r10
> + xor %r11, %r11
> + xor %r12, %r12
> + xor %r13, %r13
> + xor %r14, %r14
> + xor %r15, %r15
> +
> + # Reset status flags
> + add %rdx, %rdx # OF = SF = AF = CF = 0; ZF = PF = 1
> +
> + pop %rbx # pop the address after EENTER

Probably worth expanding the comment to explain that ENCLU[EEXIT] takes the
target address via %rbx, i.e. we're "returning" from the EENTER "call".

> +
> + # Restore the caller stack.
> + pop %rax
> + mov %rax, %rsp
> +
> + # EEXIT
> + mov $4, %rax
> + enclu
> +
> + .section ".data", "aw"
> +
> +encl_ssa:
> + .space 4096
> +
> +xsave_area:
> + .fill   1, 4, 0x037F# FCW
> + .fill   5, 4, 0
> + .fill   1, 4, 0x1F80# MXCSR
> + .fill   1, 4, 0x# MXCSR_MASK
> + .fill   123, 4, 0
> + .fill   1, 4, 0x8000# XCOMP_BV[63] = 1, compaction mode
> + .fill   12, 4, 0
> +
> + .balign 4096
> + .space 8192
> +encl_stack:


Re: [PATCH RFC] selftests/x86: Add a selftest for SGX

2018-11-14 Thread Sean Christopherson
On Tue, Nov 13, 2018 at 11:40:09PM +0200, Jarkko Sakkinen wrote:
> Add a selftest for SGX. It is a trivial test where a simple enclave
> copies one 64-bit word of memory between two memory locations given to
> the enclave as arguments.
> 
> Signed-off-by: Jarkko Sakkinen 
> ---
> +SUBDIRS_64 := sgx
> +ASSERT(!DEFINED(.altinstructions), "ALTERNATIVES are not supported in the 
> SGX LE")
> +ASSERT(!DEFINED(.altinstr_replacement), "ALTERNATIVES are not supported in 
> the SGX LE")
> +ASSERT(!DEFINED(.discard.retpoline_safe), "RETPOLINE ALTERNATIVES are not 
> supported in the SGX LE")
> +ASSERT(!DEFINED(.discard.nospec), "RETPOLINE ALTERNATIVES are not supported 
> in the SGX LE")

Maybe this?

s/LE/Test Enclave

> diff --git a/tools/testing/selftests/x86/sgx/encl_bootstrap.S 
> b/tools/testing/selftests/x86/sgx/encl_bootstrap.S
> new file mode 100644
> index ..62251c7d9927
> --- /dev/null
> +++ b/tools/testing/selftests/x86/sgx/encl_bootstrap.S
> @@ -0,0 +1,94 @@
> +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
> +/*
> + * Copyright(c) 2016-18 Intel Corporation.
> + */
> +
> + .macro ENCLU
> + .byte 0x0f, 0x01, 0xd7
> + .endm
> +
> + .section ".tcs", "a"
> + .balign 4096
> +
> + .fill   1, 8, 0 # STATE (set by CPU)
> + .fill   1, 8, 0 # FLAGS
> + .long   encl_ssa# OSSA

Any reason not to do .quad for OSSA and OENTRY?

> + .fill   1, 4, 0
> + .fill   1, 4, 0 # CSSA (set by CPU)
> + .fill   1, 4, 1 # NSSA
> + .long   encl_entry  # OENTRY
> + .fill   1, 4, 0
> + .fill   1, 8, 0 # AEP (set by EENTER and ERESUME)
> + .fill   1, 8, 0 # OFSBASE
> + .fill   1, 8, 0 # OGSBASE
> + .fill   1, 4, 0x# FSLIMIT
> + .fill   1, 4, 0x# GSLIMIT
> + .fill   503, 8, 0   # Reserved

I'd prefer to do 1-byte fill with a size of 4024 to match the SDM.

> +
> + .text
> +
> +encl_entry:
> + # %rbx contains the base address for TCS, which is also the first
> + # address inside the enclave. By adding $le_stack_end to it, we get the
> + # absolute address for the stack.
> + lea (encl_stack)(%rbx), %rax
> + xchg%rsp, %rax
> + push%rax
> +
> + push%rcx # push the address after EENTER
> + push%rbx # push the enclave base address
> +
> + callencl_body
> +
> + pop %rbx # pop the enclave base address
> +
> + # Restore XSAVE registers to a synthetic state.
> + mov $0x, %rax
> + mov $0x, %rdx
> + lea (xsave_area)(%rbx), %rdi
> + fxrstor (%rdi)
> +
> + # Clear GPRs
> + xor %rcx, %rcx
> + xor %rdx, %rdx
> + xor %rdi, %rdi
> + xor %rsi, %rsi
> + xor %r8, %r8
> + xor %r9, %r9
> + xor %r10, %r10
> + xor %r11, %r11
> + xor %r12, %r12
> + xor %r13, %r13
> + xor %r14, %r14
> + xor %r15, %r15
> +
> + # Reset status flags
> + add %rdx, %rdx # OF = SF = AF = CF = 0; ZF = PF = 1
> +
> + pop %rbx # pop the address after EENTER

Probably worth expanding the comment to explain that ENCLU[EEXIT] takes the
target address via %rbx, i.e. we're "returning" from the EENTER "call".

> +
> + # Restore the caller stack.
> + pop %rax
> + mov %rax, %rsp
> +
> + # EEXIT
> + mov $4, %rax
> + enclu
> +
> + .section ".data", "aw"
> +
> +encl_ssa:
> + .space 4096
> +
> +xsave_area:
> + .fill   1, 4, 0x037F# FCW
> + .fill   5, 4, 0
> + .fill   1, 4, 0x1F80# MXCSR
> + .fill   1, 4, 0x# MXCSR_MASK
> + .fill   123, 4, 0
> + .fill   1, 4, 0x8000# XCOMP_BV[63] = 1, compaction mode
> + .fill   12, 4, 0
> +
> + .balign 4096
> + .space 8192
> +encl_stack:


Re: [PATCH RFC] selftests/x86: Add a selftest for SGX

2018-11-13 Thread Dave Hansen
On 11/13/18 1:40 PM, Jarkko Sakkinen wrote:
> +int main(int argc, char **argv)
> +{
> + unsigned long bin_size = (unsigned long)_bin_end -
> +  (unsigned long)_bin;
> + struct sgx_secs secs;
> + uint64_t result = 0;
> +
> + if (!encl_load(, bin_size))
> + exit(1);
> +
> + sgx_call((void *), , (void *)secs.base);
> + if (result != MAGIC) {
> + fprintf(stderr, "0x%lx != 0x%lx\n", result, MAGIC);
> + exit(1);
> + }
> +
> + exit(0);
> +}

Well, I guess 100 lines of code for something a wee bit shy of hello
world isn't bad. :)

In general, this looks fine, but probably needs some better commenting
and probably some messages that make it a bit more clear what is going on.

It would be _nice_, for instance to try to do some CPUID detection of
SGX so that the error (or success?) message can tell you whether you're
missing hardware support or kernel support.

Thanks for doing this, though.  It's sorely needed.


Re: [PATCH RFC] selftests/x86: Add a selftest for SGX

2018-11-13 Thread Dave Hansen
On 11/13/18 1:40 PM, Jarkko Sakkinen wrote:
> +int main(int argc, char **argv)
> +{
> + unsigned long bin_size = (unsigned long)_bin_end -
> +  (unsigned long)_bin;
> + struct sgx_secs secs;
> + uint64_t result = 0;
> +
> + if (!encl_load(, bin_size))
> + exit(1);
> +
> + sgx_call((void *), , (void *)secs.base);
> + if (result != MAGIC) {
> + fprintf(stderr, "0x%lx != 0x%lx\n", result, MAGIC);
> + exit(1);
> + }
> +
> + exit(0);
> +}

Well, I guess 100 lines of code for something a wee bit shy of hello
world isn't bad. :)

In general, this looks fine, but probably needs some better commenting
and probably some messages that make it a bit more clear what is going on.

It would be _nice_, for instance to try to do some CPUID detection of
SGX so that the error (or success?) message can tell you whether you're
missing hardware support or kernel support.

Thanks for doing this, though.  It's sorely needed.


[PATCH RFC] selftests/x86: Add a selftest for SGX

2018-11-13 Thread Jarkko Sakkinen
Add a selftest for SGX. It is a trivial test where a simple enclave
copies one 64-bit word of memory between two memory locations given to
the enclave as arguments.

Signed-off-by: Jarkko Sakkinen 
---
Since this is my very first addition to selftests, I decided to roll out
an RFC patch before including this to the main SGX series.
 tools/testing/selftests/x86/Makefile  |  10 +
 tools/testing/selftests/x86/sgx/Makefile  |  47 ++
 tools/testing/selftests/x86/sgx/encl.c|  20 +
 tools/testing/selftests/x86/sgx/encl.lds  |  33 ++
 .../selftests/x86/sgx/encl_bootstrap.S|  94 
 tools/testing/selftests/x86/sgx/encl_piggy.S  |  16 +
 tools/testing/selftests/x86/sgx/encl_piggy.h  |  13 +
 .../testing/selftests/x86/sgx/sgx-selftest.c  | 146 +
 tools/testing/selftests/x86/sgx/sgx_arch.h| 109 
 tools/testing/selftests/x86/sgx/sgx_call.S|  20 +
 tools/testing/selftests/x86/sgx/sgx_uapi.h| 100 
 tools/testing/selftests/x86/sgx/sgxsign.c | 503 ++
 .../testing/selftests/x86/sgx/signing_key.pem |  39 ++
 13 files changed, 1150 insertions(+)
 create mode 100644 tools/testing/selftests/x86/sgx/Makefile
 create mode 100644 tools/testing/selftests/x86/sgx/encl.c
 create mode 100644 tools/testing/selftests/x86/sgx/encl.lds
 create mode 100644 tools/testing/selftests/x86/sgx/encl_bootstrap.S
 create mode 100644 tools/testing/selftests/x86/sgx/encl_piggy.S
 create mode 100644 tools/testing/selftests/x86/sgx/encl_piggy.h
 create mode 100644 tools/testing/selftests/x86/sgx/sgx-selftest.c
 create mode 100644 tools/testing/selftests/x86/sgx/sgx_arch.h
 create mode 100644 tools/testing/selftests/x86/sgx/sgx_call.S
 create mode 100644 tools/testing/selftests/x86/sgx/sgx_uapi.h
 create mode 100644 tools/testing/selftests/x86/sgx/sgxsign.c
 create mode 100644 tools/testing/selftests/x86/sgx/signing_key.pem

diff --git a/tools/testing/selftests/x86/Makefile 
b/tools/testing/selftests/x86/Makefile
index 186520198de7..4fc9a42f56ea 100644
--- a/tools/testing/selftests/x86/Makefile
+++ b/tools/testing/selftests/x86/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
+
+SUBDIRS_64 := sgx
+
 all:
 
 include ../lib.mk
@@ -67,6 +70,13 @@ all_32: $(BINARIES_32)
 
 all_64: $(BINARIES_64)
 
+all_64: $(SUBDIRS_64)
+   @for DIR in $(SUBDIRS_64); do   \
+   BUILD_TARGET=$(OUTPUT)/$$DIR;   \
+   mkdir $$BUILD_TARGET  -p;   \
+   make OUTPUT=$$BUILD_TARGET -C $$DIR $@; \
+   done
+
 EXTRA_CLEAN := $(BINARIES_32) $(BINARIES_64)
 
 $(BINARIES_32): $(OUTPUT)/%_32: %.c
diff --git a/tools/testing/selftests/x86/sgx/Makefile 
b/tools/testing/selftests/x86/sgx/Makefile
new file mode 100644
index ..04004d244de4
--- /dev/null
+++ b/tools/testing/selftests/x86/sgx/Makefile
@@ -0,0 +1,47 @@
+top_srcdir = ../../../../..
+
+include ../../lib.mk
+
+HOST_CFLAGS := -Wall -Werror -g
+ENCL_CFLAGS := -Wall -Werror -static -nostdlib -nostartfiles -fPIC \
+  -fno-stack-protector -mrdrnd
+
+TEST_CUSTOM_PROGS := $(OUTPUT)/sgx-selftest
+all_64: $(TEST_CUSTOM_PROGS)
+
+$(TEST_CUSTOM_PROGS): $(OUTPUT)/sgx-selftest.o $(OUTPUT)/sgx_call.o \
+ $(OUTPUT)/encl_piggy.o
+   $(CC) $(HOST_CFLAGS) -o $@ $^
+
+$(OUTPUT)/sgx-selftest.o: sgx-selftest.c
+   $(CC) $(HOST_CFLAGS) -c $< -o $@
+
+$(OUTPUT)/sgx_call.o: sgx_call.S
+   $(CC) $(HOST_CFLAGS) -c $< -o $@
+
+$(OUTPUT)/encl_piggy.o: $(OUTPUT)/encl.bin $(OUTPUT)/encl.ss
+
+$(OUTPUT)/encl.bin: $(OUTPUT)/encl.elf $(OUTPUT)/sgxsign
+   objcopy --remove-section=.got.plt -O binary $< $@
+
+$(OUTPUT)/encl.elf: $(OUTPUT)/encl.o $(OUTPUT)/encl_bootstrap.o
+   $(CC) $(ENCL_CFLAGS) -T encl.lds -o $@ $^
+
+$(OUTPUT)/encl.o: encl.c
+   $(CC) $(ENCL_CFLAGS) -c $< -o $@
+
+$(OUTPUT)/encl_bootstrap.o: encl_bootstrap.S
+   $(CC) $(ENCL_CFLAGS) -c $< -o $@
+
+$(OUTPUT)/encl.ss: $(OUTPUT)/encl.bin  $(OUTPUT)/sgxsign
+   $(OUTPUT)/sgxsign signing_key.pem $(OUTPUT)/encl.bin $(OUTPUT)/encl.ss
+
+$(OUTPUT)/sgxsign: sgxsign.c
+   $(CC) -o $@ $< -lcrypto
+
+EXTRA_CLEAN := $(OUTPUT)/sgx-selftest $(OUTPUT)/sgx-selftest.o \
+  $(OUTPUT)/sgx_call.o $(OUTPUT)/encl.bin $(OUTPUT)/encl.ss \
+  $(OUTPUT)/encl.elf $(OUTPUT)/encl.o $(OUTPUT)/encl_bootstrap.o \
+  $(OUTPUT)/sgxsign
+
+.PHONY: clean
diff --git a/tools/testing/selftests/x86/sgx/encl.c 
b/tools/testing/selftests/x86/sgx/encl.c
new file mode 100644
index ..eb6aa318d3f1
--- /dev/null
+++ b/tools/testing/selftests/x86/sgx/encl.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+// Copyright(c) 2016-18 Intel Corporation.
+
+#include 
+#include "sgx_arch.h"
+
+static void *memcpy(void *dest, const void *src, size_t n)
+{
+   size_t i;
+
+   for (i = 0; i < n; i++)
+   ((char *)dest)[i] = ((char *)src)[i];
+
+   return dest;
+}
+
+void encl_body(void *rdi, void *rsi)
+{
+   

[PATCH RFC] selftests/x86: Add a selftest for SGX

2018-11-13 Thread Jarkko Sakkinen
Add a selftest for SGX. It is a trivial test where a simple enclave
copies one 64-bit word of memory between two memory locations given to
the enclave as arguments.

Signed-off-by: Jarkko Sakkinen 
---
Since this is my very first addition to selftests, I decided to roll out
an RFC patch before including this to the main SGX series.
 tools/testing/selftests/x86/Makefile  |  10 +
 tools/testing/selftests/x86/sgx/Makefile  |  47 ++
 tools/testing/selftests/x86/sgx/encl.c|  20 +
 tools/testing/selftests/x86/sgx/encl.lds  |  33 ++
 .../selftests/x86/sgx/encl_bootstrap.S|  94 
 tools/testing/selftests/x86/sgx/encl_piggy.S  |  16 +
 tools/testing/selftests/x86/sgx/encl_piggy.h  |  13 +
 .../testing/selftests/x86/sgx/sgx-selftest.c  | 146 +
 tools/testing/selftests/x86/sgx/sgx_arch.h| 109 
 tools/testing/selftests/x86/sgx/sgx_call.S|  20 +
 tools/testing/selftests/x86/sgx/sgx_uapi.h| 100 
 tools/testing/selftests/x86/sgx/sgxsign.c | 503 ++
 .../testing/selftests/x86/sgx/signing_key.pem |  39 ++
 13 files changed, 1150 insertions(+)
 create mode 100644 tools/testing/selftests/x86/sgx/Makefile
 create mode 100644 tools/testing/selftests/x86/sgx/encl.c
 create mode 100644 tools/testing/selftests/x86/sgx/encl.lds
 create mode 100644 tools/testing/selftests/x86/sgx/encl_bootstrap.S
 create mode 100644 tools/testing/selftests/x86/sgx/encl_piggy.S
 create mode 100644 tools/testing/selftests/x86/sgx/encl_piggy.h
 create mode 100644 tools/testing/selftests/x86/sgx/sgx-selftest.c
 create mode 100644 tools/testing/selftests/x86/sgx/sgx_arch.h
 create mode 100644 tools/testing/selftests/x86/sgx/sgx_call.S
 create mode 100644 tools/testing/selftests/x86/sgx/sgx_uapi.h
 create mode 100644 tools/testing/selftests/x86/sgx/sgxsign.c
 create mode 100644 tools/testing/selftests/x86/sgx/signing_key.pem

diff --git a/tools/testing/selftests/x86/Makefile 
b/tools/testing/selftests/x86/Makefile
index 186520198de7..4fc9a42f56ea 100644
--- a/tools/testing/selftests/x86/Makefile
+++ b/tools/testing/selftests/x86/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
+
+SUBDIRS_64 := sgx
+
 all:
 
 include ../lib.mk
@@ -67,6 +70,13 @@ all_32: $(BINARIES_32)
 
 all_64: $(BINARIES_64)
 
+all_64: $(SUBDIRS_64)
+   @for DIR in $(SUBDIRS_64); do   \
+   BUILD_TARGET=$(OUTPUT)/$$DIR;   \
+   mkdir $$BUILD_TARGET  -p;   \
+   make OUTPUT=$$BUILD_TARGET -C $$DIR $@; \
+   done
+
 EXTRA_CLEAN := $(BINARIES_32) $(BINARIES_64)
 
 $(BINARIES_32): $(OUTPUT)/%_32: %.c
diff --git a/tools/testing/selftests/x86/sgx/Makefile 
b/tools/testing/selftests/x86/sgx/Makefile
new file mode 100644
index ..04004d244de4
--- /dev/null
+++ b/tools/testing/selftests/x86/sgx/Makefile
@@ -0,0 +1,47 @@
+top_srcdir = ../../../../..
+
+include ../../lib.mk
+
+HOST_CFLAGS := -Wall -Werror -g
+ENCL_CFLAGS := -Wall -Werror -static -nostdlib -nostartfiles -fPIC \
+  -fno-stack-protector -mrdrnd
+
+TEST_CUSTOM_PROGS := $(OUTPUT)/sgx-selftest
+all_64: $(TEST_CUSTOM_PROGS)
+
+$(TEST_CUSTOM_PROGS): $(OUTPUT)/sgx-selftest.o $(OUTPUT)/sgx_call.o \
+ $(OUTPUT)/encl_piggy.o
+   $(CC) $(HOST_CFLAGS) -o $@ $^
+
+$(OUTPUT)/sgx-selftest.o: sgx-selftest.c
+   $(CC) $(HOST_CFLAGS) -c $< -o $@
+
+$(OUTPUT)/sgx_call.o: sgx_call.S
+   $(CC) $(HOST_CFLAGS) -c $< -o $@
+
+$(OUTPUT)/encl_piggy.o: $(OUTPUT)/encl.bin $(OUTPUT)/encl.ss
+
+$(OUTPUT)/encl.bin: $(OUTPUT)/encl.elf $(OUTPUT)/sgxsign
+   objcopy --remove-section=.got.plt -O binary $< $@
+
+$(OUTPUT)/encl.elf: $(OUTPUT)/encl.o $(OUTPUT)/encl_bootstrap.o
+   $(CC) $(ENCL_CFLAGS) -T encl.lds -o $@ $^
+
+$(OUTPUT)/encl.o: encl.c
+   $(CC) $(ENCL_CFLAGS) -c $< -o $@
+
+$(OUTPUT)/encl_bootstrap.o: encl_bootstrap.S
+   $(CC) $(ENCL_CFLAGS) -c $< -o $@
+
+$(OUTPUT)/encl.ss: $(OUTPUT)/encl.bin  $(OUTPUT)/sgxsign
+   $(OUTPUT)/sgxsign signing_key.pem $(OUTPUT)/encl.bin $(OUTPUT)/encl.ss
+
+$(OUTPUT)/sgxsign: sgxsign.c
+   $(CC) -o $@ $< -lcrypto
+
+EXTRA_CLEAN := $(OUTPUT)/sgx-selftest $(OUTPUT)/sgx-selftest.o \
+  $(OUTPUT)/sgx_call.o $(OUTPUT)/encl.bin $(OUTPUT)/encl.ss \
+  $(OUTPUT)/encl.elf $(OUTPUT)/encl.o $(OUTPUT)/encl_bootstrap.o \
+  $(OUTPUT)/sgxsign
+
+.PHONY: clean
diff --git a/tools/testing/selftests/x86/sgx/encl.c 
b/tools/testing/selftests/x86/sgx/encl.c
new file mode 100644
index ..eb6aa318d3f1
--- /dev/null
+++ b/tools/testing/selftests/x86/sgx/encl.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+// Copyright(c) 2016-18 Intel Corporation.
+
+#include 
+#include "sgx_arch.h"
+
+static void *memcpy(void *dest, const void *src, size_t n)
+{
+   size_t i;
+
+   for (i = 0; i < n; i++)
+   ((char *)dest)[i] = ((char *)src)[i];
+
+   return dest;
+}
+
+void encl_body(void *rdi, void *rsi)
+{
+