From: "Huang, Kai" <kai.huang@intel.com>
To: "Reshetova, Elena" <elena.reshetova@intel.com>,
"seanjc@google.com" <seanjc@google.com>
Cc: "Hansen, Dave" <dave.hansen@intel.com>,
"linux-sgx@vger.kernel.org" <linux-sgx@vger.kernel.org>,
"Scarlata, Vincent R" <vincent.r.scarlata@intel.com>,
"x86@kernel.org" <x86@kernel.org>,
"jarkko@kernel.org" <jarkko@kernel.org>,
"Annapurve, Vishal" <vannapurve@google.com>,
"Cai, Chong" <chongc@google.com>,
"Mallick, Asit K" <asit.k.mallick@intel.com>,
"Aktas, Erdem" <erdemaktas@google.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"bondarn@google.com" <bondarn@google.com>,
"dionnaglaze@google.com" <dionnaglaze@google.com>,
"Raynor, Scott" <scott.raynor@intel.com>
Subject: Re: [PATCH v3 2/2] x86/sgx: Implement EUPDATESVN and opportunistically call it during first EPC page alloc
Date: Tue, 22 Apr 2025 07:23:17 +0000 [thread overview]
Message-ID: <f5cb3c37589791b2004a100ca3ea3deb9e1ae708.camel@intel.com> (raw)
In-Reply-To: <aAJn8tgubjT5t7DB@google.com>
On Fri, 2025-04-18 at 07:55 -0700, Sean Christopherson wrote:
> On Tue, Apr 15, 2025, Elena Reshetova wrote:
> > +/* This lock is held to prevent new EPC pages from being created
> > + * during the execution of ENCLS[EUPDATESVN].
> > + */
> > +static DEFINE_SPINLOCK(sgx_epc_eupdatesvn_lock);
> > +
> > static atomic_long_t sgx_nr_used_pages = ATOMIC_LONG_INIT(0);
> > static unsigned long sgx_nr_total_pages;
> >
> > @@ -444,6 +449,7 @@ static struct sgx_epc_page *__sgx_alloc_epc_page_from_node(int nid)
> > {
> > struct sgx_numa_node *node = &sgx_numa_nodes[nid];
> > struct sgx_epc_page *page = NULL;
> > + bool ret;
> >
> > spin_lock(&node->lock);
> >
> > @@ -452,12 +458,33 @@ static struct sgx_epc_page *__sgx_alloc_epc_page_from_node(int nid)
> > return NULL;
> > }
> >
> > + if (!atomic_long_inc_not_zero(&sgx_nr_used_pages)) {
>
> FWIW, the entire automatic scheme has terrible behavior when KVM is running SGX
> capable guests. KVM will allocate EPC when the virtual EPC is first touched by
> the guest, and won't free the EPC pages until the VM is terminated. And IIRC,
> userspace (QEMU) typically preallocates the virtual EPC to ensure the VM doesn't
> need to be killed later on due to lack of EPC.
>
> I.e. running an SGX capable VM, even if there are no active enclaves in said VM,
> will prevent SVN updates.
>
> Unfortunately, I can't think of a sane way around that, because while it would
> be easy enough to force interception of ECREATE, there's no definitive ENCLS leaf
> that KVM can intercept to detect when an enclave is destroyed (interception
> EREMOVE would have terrible performance implications).
>
> That said, handling this deep in the bowels of EPC page allocation seems
> unnecessary. The only way for there to be no active EPC pages is if there are
> no enclaves. As above, virtual EPC usage is already all but guaranteed to hit
> false positives, so I don't think there's anything gained by trying to update
> the SVN based on EPC allocations.
>
> So rather than react to EPC allocations, why not hook sgx_open() and sgx_vepc_open()?
The only thing I don't like about this is we need to hook both of them.
> Then you're hooking a relative slow path (I assume EUPDATESVN is not fast),
>
I was expecting the SGX_NO_UPDATE case should be fast, i.e., some sort of simple
compare and return, but looking at the pseudo code it still re-generates the
CR_BASE_KEY etc.
> error
> codes can be returned to userspace (if you really want the kernel to freak out if
> EUPDATESVN unexpected fails), and you don't _have_ to use a spinlock, e.g. if
> EUPDATESVN takes a long time, using a mutex might be desirable.
Seems reasonable to me.
>
> > +bool sgx_updatesvn(void)
> > +{
> > + int retry = 10;
> > + int ret;
> > +
> > + lockdep_assert_held(&sgx_epc_eupdatesvn_lock);
> > +
> > + if (!(cpuid_eax(SGX_CPUID) & SGX_CPUID_EUPDATESVN))
> > + return true;
>
> Checking CPUID features inside the spinlock is asinine. They can't change, barring
> a misbehaving hypervisor. This should be a "cache once during boot" sorta thing.
Agreed.
>
> > +
> > + /*
> > + * Do not execute ENCLS[EUPDATESVN] if running in a VM since
> > + * microcode updates are only meaningful to be applied on the host.
>
> I don't think the kernel should check HYPERVISOR. The SDM doesn't actually
> say anything about EUPDATESVN, but unless it's explicitly special cased, I doubt
> XuCode cares whether ENCLS was executed in Root vs. Non-Root.
The spec is here:
[1] https://cdrdv2.intel.com/v1/dl/getContent/648682?explicitVersion=true
And from the pseudo code it doesn't distinguish root vs non-root.
>
> It's the hypervisor's responsibility to enumerate SGX_CPUID_EUPDATESVN or not.
> E.g. if the kernel is running in a "passthrough" type setup, it would be perfectly
> fine to do EUPDATESVN from a guest kernel. EUPDATESVN could even be proxied,
> e.g. by intercepting ECREATE to track EPC usage
I am open to this HYPERVISOR check, because I don't think we currently support
any kind of "passthrough" setup? And depending on what kinda of "passthrough"
types, the things that the hypervisor traps can vary.
Anyway, I agree it's not necessary to have this check, because currently it is
not possible for a guest to see the EUPDATESVN in CPUID.
next prev parent reply other threads:[~2025-04-22 7:23 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-15 11:51 [PATCH v3 0/2] Enable automatic SVN updates for SGX enclaves Elena Reshetova
2025-04-15 11:51 ` [PATCH v3 1/2] x86/sgx: Use sgx_nr_used_pages for EPC page count instead of sgx_nr_free_pages Elena Reshetova
2025-04-16 10:33 ` Huang, Kai
2025-04-16 11:50 ` Reshetova, Elena
2025-04-16 18:50 ` Jarkko Sakkinen
2025-04-16 19:12 ` Jarkko Sakkinen
2025-04-15 11:51 ` [PATCH v3 2/2] x86/sgx: Implement EUPDATESVN and opportunistically call it during first EPC page alloc Elena Reshetova
2025-04-16 7:36 ` Huang, Kai
2025-04-16 12:06 ` Reshetova, Elena
2025-04-17 11:12 ` Huang, Kai
2025-04-18 14:18 ` Sean Christopherson
2025-04-22 6:58 ` Huang, Kai
2025-04-16 19:01 ` Jarkko Sakkinen
2025-04-18 14:55 ` Sean Christopherson
2025-04-22 7:23 ` Huang, Kai [this message]
2025-04-22 13:54 ` Sean Christopherson
2025-04-22 21:57 ` Huang, Kai
2025-04-24 8:34 ` Reshetova, Elena
2025-04-24 13:42 ` Sean Christopherson
2025-04-24 14:16 ` Reshetova, Elena
2025-04-24 17:19 ` Sean Christopherson
2025-04-25 6:52 ` Reshetova, Elena
2025-04-25 17:40 ` Sean Christopherson
2025-04-25 18:04 ` Dave Hansen
2025-04-25 19:29 ` Sean Christopherson
2025-04-25 20:11 ` Dave Hansen
2025-04-25 21:04 ` Sean Christopherson
2025-04-25 21:23 ` Dave Hansen
2025-04-25 21:58 ` Sean Christopherson
2025-04-25 22:07 ` Dave Hansen
2025-04-29 11:44 ` Reshetova, Elena
2025-04-29 14:46 ` Dave Hansen
2025-04-30 6:53 ` Reshetova, Elena
2025-04-30 15:16 ` Jarkko Sakkinen
2025-05-02 7:22 ` Reshetova, Elena
2025-05-02 8:56 ` Jarkko Sakkinen
2025-05-06 20:32 ` Nataliia Bondarevska
2025-04-28 6:25 ` Reshetova, Elena
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f5cb3c37589791b2004a100ca3ea3deb9e1ae708.camel@intel.com \
--to=kai.huang@intel.com \
--cc=asit.k.mallick@intel.com \
--cc=bondarn@google.com \
--cc=chongc@google.com \
--cc=dave.hansen@intel.com \
--cc=dionnaglaze@google.com \
--cc=elena.reshetova@intel.com \
--cc=erdemaktas@google.com \
--cc=jarkko@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sgx@vger.kernel.org \
--cc=scott.raynor@intel.com \
--cc=seanjc@google.com \
--cc=vannapurve@google.com \
--cc=vincent.r.scarlata@intel.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox