diff mbox series

selftests/sgx: Fix an enclave built with extended instructions

Message ID 20250409165510.23066-1-vdronov@redhat.com (mailing list archive)
State New
Headers show
Series selftests/sgx: Fix an enclave built with extended instructions | expand

Commit Message

Vladis Dronov April 9, 2025, 4:55 p.m. UTC
Creating an enclave with xfrm == 3 disables extended CPU states and instruction
sets, like AVX2 and AVX512 inside the enclave. Thus the enclave code has to be
built with a compiler which does not produce instructions from the extended
instruction sets. Nevertheless certain Linux distributions confgure a compiler
so it produces extended instructions by default ("--with-arch_64=x86-64-v3" for
gcc). Thus an enclave code from test_encl.c is built with extended instructions
and an enclave execution hits the #UD exception (note exception_vector == 6):

    # ./test_sgx
    ...
    #  RUN           enclave.unclobbered_vdso_oversubscribed_remove ...
    # main.c:481:unclobbered_vdso_oversubscribed_remove:Expected self->run.exception_vector (6) == 0 (0)
    # main.c:485:unclobbered_vdso_oversubscribed_remove:Expected self->run.function (3) == EEXIT (4)
    # unclobbered_vdso_oversubscribed_remove: Test terminated by assertion
    #          FAIL  enclave.unclobbered_vdso_oversubscribed_remove
    not ok 3 enclave.unclobbered_vdso_oversubscribed_remove

Fix this by adding "-mno-avx" to ENCL_CFLAGS in Makefile. Add some comments
about this to code locations where enclave's xfrm field is set.

Suggested-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Vladis Dronov <vdronov@redhat.com>
---
an out-of-commit-message note:

I would greatly appreciate if someone reviews and possibly fixes my wording
of the commit message and the code comments.

 tools/testing/selftests/sgx/Makefile    | 2 +-
 tools/testing/selftests/sgx/load.c      | 8 +++++++-
 tools/testing/selftests/sgx/sigstruct.c | 6 ++++++
 3 files changed, 14 insertions(+), 2 deletions(-)

Comments

Dave Hansen April 9, 2025, 5:05 p.m. UTC | #1
On 4/9/25 09:55, Vladis Dronov wrote:
...
> Fix this by adding "-mno-avx" to ENCL_CFLAGS in Makefile. Add some comments
> about this to code locations where enclave's xfrm field is set.
> 
> Suggested-by: Dave Hansen <dave.hansen@linux.intel.com>
> Signed-off-by: Vladis Dronov <vdronov@redhat.com>
First of all, this looks fine to me:

Acked-by: Dave Hansen <dave.hansen@linux.intel.com>

The code comments are fine. I'm much less picky about selftests.

I'm also open to other solutions here. We could, for instance, set
xfrm=7 to allow AVX2 instructions (which are generated by
"--with-arch_64=x86-64-v3") or use some compiler flags other than
"-mno-avx".

But "-mno-avx" does seem good to me.
Vladis Dronov April 9, 2025, 5:17 p.m. UTC | #2
On Wed, Apr 9, 2025 at 7:07 PM Dave Hansen <dave.hansen@intel.com> wrote:
>
> On 4/9/25 09:55, Vladis Dronov wrote:
> ...
> > Fix this by adding "-mno-avx" to ENCL_CFLAGS in Makefile. Add some comments
> > about this to code locations where enclave's xfrm field is set.
> >
> > Suggested-by: Dave Hansen <dave.hansen@linux.intel.com>
> > Signed-off-by: Vladis Dronov <vdronov@redhat.com>
>
> First of all, this looks fine to me:
>
> Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
>
> The code comments are fine. I'm much less picky about selftests.
>
> I'm also open to other solutions here. We could, for instance, set
> xfrm=7 to allow AVX2 instructions (which are generated by
> "--with-arch_64=x86-64-v3") or use some compiler flags other than
> "-mno-avx".
>
> But "-mno-avx" does seem good to me.
>

Thank you for the ACK, Dave.

I've tested an enclave with xfrm=7 and it errors out at the AVX512
instruction (namely, vmovdqa64) in the same way. So if there is a
compiler built with "--with-arch_64=x86-64-v4" in some future, we
would get into the exact same situation.

So I believe a solution when we disable extended instruction sets
in an enclave as one covering all future cases.
diff mbox series

Patch

diff --git a/tools/testing/selftests/sgx/Makefile b/tools/testing/selftests/sgx/Makefile
index 03b5e13b872b..ab2561b4456d 100644
--- a/tools/testing/selftests/sgx/Makefile
+++ b/tools/testing/selftests/sgx/Makefile
@@ -15,7 +15,7 @@  INCLUDES := -I$(top_srcdir)/tools/include
 HOST_CFLAGS := -Wall -Werror -g $(INCLUDES) -fPIC $(CFLAGS)
 HOST_LDFLAGS := -z noexecstack -lcrypto
 ENCL_CFLAGS += -Wall -Werror -static-pie -nostdlib -ffreestanding -fPIE \
-	       -fno-stack-protector -mrdrnd $(INCLUDES)
+	       -fno-stack-protector -mrdrnd -mno-avx $(INCLUDES)
 ENCL_LDFLAGS := -Wl,-T,test_encl.lds,--build-id=none
 
 ifeq ($(CAN_BUILD_X86_64), 1)
diff --git a/tools/testing/selftests/sgx/load.c b/tools/testing/selftests/sgx/load.c
index c9f658e44de6..79946ca8f1a5 100644
--- a/tools/testing/selftests/sgx/load.c
+++ b/tools/testing/selftests/sgx/load.c
@@ -88,10 +88,16 @@  static bool encl_ioc_create(struct encl *encl)
 	memset(secs, 0, sizeof(*secs));
 	secs->ssa_frame_size = 1;
 	secs->attributes = SGX_ATTR_MODE64BIT;
-	secs->xfrm = 3;
 	secs->base = encl->encl_base;
 	secs->size = encl->encl_size;
 
+	/*
+	 * Setting xfrm to 3 disables extended CPU states and instruction sets
+	 * like AVX2 inside the enclave. Thus the enclave code has to be built
+	 * without instructions from extended instruction sets (-mno-avx).
+	 */
+	secs->xfrm = 3;
+
 	ioc.src = (unsigned long)secs;
 	rc = ioctl(encl->fd, SGX_IOC_ENCLAVE_CREATE, &ioc);
 	if (rc) {
diff --git a/tools/testing/selftests/sgx/sigstruct.c b/tools/testing/selftests/sgx/sigstruct.c
index d73b29becf5b..f548392a2fee 100644
--- a/tools/testing/selftests/sgx/sigstruct.c
+++ b/tools/testing/selftests/sgx/sigstruct.c
@@ -331,6 +331,12 @@  bool encl_measure(struct encl *encl)
 	sigstruct->header.header2[1] = header2[1];
 	sigstruct->exponent = 3;
 	sigstruct->body.attributes = SGX_ATTR_MODE64BIT;
+
+	/*
+	 * Setting xfrm to 3 disables extended CPU states and instruction sets
+	 * like AVX2 inside the enclave. Thus the enclave code has to be built
+	 * without instructions from extended instruction sets (-mno-avx).
+	 */
 	sigstruct->body.xfrm = 3;
 
 	/* sanity check */