Re: [PATCH v2 1/2] x86/sgx: Do not update sgx_nr_free_pages in sgx_setup_epc_section()

From: Jarkko Sakkinen
Date: Thu Apr 08 2021 - 04:48:53 EST


On Wed, Apr 07, 2021 at 06:18:11PM +0200, Borislav Petkov wrote:
> On Wed, Apr 07, 2021 at 07:03:47PM +0300, Jarkko Sakkinen wrote:
> > > Which leads to my question: what is sgx_nr_free_pages supposed to denote?
> > >
> > > Because I understand the callpath
> > >
> > > sgx_page_cache_init
> > > ...
> > > for (i = 0; i < ARRAY_SIZE(sgx_epc_sections); i++) {
> > > ...
> > > sgx_setup_epc_section
> > > ...
> > > sgx_nr_free_pages += nr_pages;
> > >
> > > as adding the number of pages of each new EPC section to the total
> > > number of the free pages. Unless that variable accounts something else.
> > >
> > > So what does this variable actually mean?
> >
> > It's used for only to trigger watermark for reclaiming. I.e. causes
> > ksgxd to trigger. And it gives the number of total free EPC pages in
> > all NUMA nodes.
>
> So the callpath I laid out above is adding the number of pages of each
> section to the total free EPC pages number.
>
> Why is that wrong and why is your patch needed?

As part of "x86/sgx: Replace section->init_laundry_list with sgx_dirty_page_list"
pages are processed from a global list by ksgxd.

This in turn introduces change to sanitization:

- if (!ret)
- list_move(&page->list, &section->page_list);
- else
+ if (!ret) {
+ /*
+ * page is now sanitized. Make it available via the SGX
+ * page allocator:
+ */
+ list_del(&page->list);
+ sgx_free_epc_page(page);
+ } else {
+ /* The page is not yet clean - move to the dirty list. */
list_move_tail(&page->list, &dirty);
-
- spin_unlock(&section->lock);
+ }

This is done for the reason that it is best to keep the logic to assign
available-for-use EPC pages to correct NUMA lists in a single location.

The regression is that the sgx_nr_free_pages is also incremented by
sgx_free_epc_pages(), and thus it ends up having double the number of
pages available.

/Jarkko