Re: [PATCH v38 14/24] x86/sgx: Add SGX_IOC_ENCLAVE_INIT

From: Sean Christopherson
Date: Tue Sep 22 2020 - 12:29:48 EST


On Tue, Sep 22, 2020 at 02:56:19PM +0200, Jethro Beekman wrote:
> On 2020-09-22 10:29, Borislav Petkov wrote:
> > On Mon, Sep 21, 2020 at 12:17:00PM -0700, Sean Christopherson wrote:
> >> That was effectively my original suggestion as well, check for a stale cache
> >> and retry indefinitely. I capitulated because it did feel like I was being
> >> overly paranoid. I'm obviously ok going the retry indefinitely route :-).
> >>
> >> https://lkml.kernel.org/r/20180904163546.GA5421@xxxxxxxxxxxxxxx
> >
> > Right, so if EINIT is so expensive, why does it matter how many cyccles
> > WRMSR has? I.e., you don't really need to cache - you simply write the 4
> > MSRs and you're done. Simple.

Hmm, true. The 1200+ cycles to write the hash MSRs (they're 3x slower than
other MSRs) seems scary, but compared to the 60k cycles it really doesn't
matter.

> > As to "indefinitely" - caller can increment a counter which counts
> > how many times it returned SGX_INVALID_EINITTOKEN. I guess when it
> > reaches some too high number which should not be reached during normal
> > usage patterns, you can give up and issue a message to say that counter
> > reached max retries or so but other than that, you should be ok. That
> > thing is running interruptible in a loop anyway...
>
> I don't see why you'd need to retry indefinitely. Yes the MSRs may not match
> the cached value for “reasons”, but if after you've written them once it
> still doesn't work, clearly either 1) an “unhelpful” VMM is actively messing
> with the MSRs which I'd say is at best a VMM bug or 2) there was an EPC reset
> and your enclave is now invalid anyway, so no need to EINIT.

Ah, also true, I overlooked that an MSR reset would also kill the enclave.

So yeah, this can be simplified to:

if (SGX_LC) {
for (i = 0; i < 4; i++)
wrmsrl(...);
}
return __einit(...);