Re: [PATCH 2/2] x86: sgx_vepc: implement SGX_IOC_VEPC_REMOVE ioctl

From: Dave Hansen
Date: Mon Sep 13 2021 - 15:33:31 EST


On 9/13/21 6:11 AM, Paolo Bonzini wrote:
> +static long sgx_vepc_remove_all(struct sgx_vepc *vepc)
> +{
> + struct sgx_epc_page *entry;
> + unsigned long index;
> + long failures = 0;
> +
> + xa_for_each(&vepc->page_array, index, entry)
> + if (sgx_vepc_remove_page(entry))
> + failures++;
> +
> + /*
> + * Return the number of pages that failed to be removed, so
> + * userspace knows that there are still SECS pages lying
> + * around.
> + */
> + return failures;
> +}

I'm not sure the retry logic should be in userspace. Also, is this
strictly limited to SECS pages? It could also happen if there were
enclaves running that used the page. Granted, userspace can probably
stop all the vcpus, but the *interface* doesn't prevent it being called
like that.

What else can userspace do but:

ret = ioctl(fd, SGX_IOC_VEPC_REMOVE);
if (ret)
ret = ioctl(fd, SGX_IOC_VEPC_REMOVE);
if (ret)
printf("uh oh\n");

We already have existing code to gather up the pages that couldn't be
EREMOVE'd and selectively EREMOVE them again. Why not reuse that code
here? If there is 100GB of EPC, it's gotta be painful to run through
the ->page_array twice when once plus a small list iteration will do.

Which reminds me... Do we need a cond_resched() in there or anything?
That loop could theoretically get really, really long.