linux-sgx.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Reinette Chatre <reinette.chatre@intel.com>
To: Dave Hansen <dave.hansen@intel.com>,
	<dave.hansen@linux.intel.com>, <jarkko@kernel.org>,
	<linux-sgx@vger.kernel.org>
Cc: <haitao.huang@intel.com>
Subject: Re: [RFC PATCH 0/4] SGX shmem backing store issue
Date: Mon, 2 May 2022 10:11:19 -0700	[thread overview]
Message-ID: <f6e64c4f-8539-b7e7-7890-a4b1acc073fe@intel.com> (raw)
In-Reply-To: <d7a3929d-3b49-dc77-8f6c-0308fbcf3948@intel.com>

Hi Dave,

On 5/2/2022 7:36 AM, Dave Hansen wrote:
> On 4/29/22 20:22, Reinette Chatre wrote:
>> -	if (pcmd_page_empty) {
>> +	if (pcmd_page_empty && && put_page_testzero(b.pcmd)) {
>>  		ida_free(&encl->pcmd_in_backing, PFN_DOWN(page_pcmd_off));
>>  		sgx_encl_truncate_backing_page(encl, PFN_DOWN(page_pcmd_off));
>>  	}
> 
> Reinette, nice work on tracking this down!
> 
> One comment on the fix though:  Will this put_page_testzero() ever
> actually trigger?  The page cache itself holds a reference, which is
> released in this case via:
> 
> 	shmem_truncate_range() ->
> 	truncate_inode_pages_range() ->
> 	truncate_inode_folio() ->
> 	filemap_remove_folio() ->
> 	filemap_free_folio() ->
> 	folio_put_refs()
> 
> So I think the lowest the page refcount can actually be at the point of
> put_page_testzero() is 1.

oh, I see, thank you for pointing that out. We then need something like
"put_page_testone()".

> 
> I suspect the end result of that patch would actually just be that PCMD
> pages are never freed at runtime, which would also work around the bug
> you discovered.
> 
> No matter what we do here, we need to ensure that there is no race between:
> 
>         pcmd_page_empty = !memchr_inv(pcmd_page, 0, PAGE_SIZE);
> and
> 	sgx_encl_truncate_backing_page(encl, PFN_DOWN(page_pcmd_off));
> 
> Holding the encl->lock over that section of code would work.  It also
> would not be awful to add a special "truncation lock" which is taken
> before putting data in a pcmd page and is taken over the
> memchr()->truncate window as well.

&encl->lock is already held over that section of the code so there
never is a race between the empty check and the truncate call.

The problem as I see it is that at the time __sgx_encl_eldu() is called
by the page fault handler (with enclave mutex held), the reclaimer already
has a reference to the PCMD page (but of course does _not_ have the enclave
mutex). The reclaimer expects to write to the PCMD page later when it obtains
the enclave mutex again and expects it to be safe since it has a reference
to the PCMD page.

The page fault handler will find the PCMD page empty when it removes
the last entry and thus truncate the page.

When reclaimer runs again it writes to the just-truncated PCMD page and
when it releases its reference the page is removed and the just written
data is lost.

My goal was to prevent the page fault handler from doing a "is the PCMD
page empty" if the reclaimer has a reference to it. Even if the PCMD page
is empty when the page fault handler checks it the page is expected to
get data right when reclaimer can get the mutex back since the reclaimer
already has a reference to the page.

Regarding your other suggestion, to use a "truncation lock". SGX just
gets the page pointer from shmem every time it is needed so there is
no room as I see it to add metadata to a PCMD page. One possibility
that we could do is for the page fault handler to check if any enclave
page sharing the PCMD page is being reclaimed (has the SGX_ENCL_PAGE_BEING_RECLAIMED
flag set). The reclaimer sets SGX_ENCL_PAGE_BEING_RECLAIMED for an enclave
page when it obtains the reference to its PCMD page and clears the flag
when it releases the reference.

Reinette

  reply	other threads:[~2022-05-02 17:11 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-28 20:11 [RFC PATCH 0/4] SGX shmem backing store issue Reinette Chatre
2022-04-28 20:11 ` [RFC PATCH 1/4] x86/sgx: Do not free backing memory on ENCLS[ELDU] failure Reinette Chatre
2022-04-28 21:30   ` Dave Hansen
2022-04-28 22:20     ` Reinette Chatre
2022-04-28 22:53       ` Dave Hansen
2022-04-28 23:49         ` Reinette Chatre
2022-05-03  2:01           ` Kai Huang
2022-05-07 17:25           ` Jarkko Sakkinen
2022-05-09 17:17             ` Reinette Chatre
2022-05-10  0:36               ` Kai Huang
2022-05-11 10:26                 ` Jarkko Sakkinen
2022-05-11 18:29                   ` Haitao Huang
2022-05-11 22:00                     ` Kai Huang
2022-05-12 21:14                     ` Jarkko Sakkinen
2022-05-06 22:09     ` Jarkko Sakkinen
2022-04-28 20:11 ` [RFC PATCH 2/4] x86/sgx: Set dirty bit after modifying page contents Reinette Chatre
2022-04-28 21:40   ` Dave Hansen
2022-04-28 22:41     ` Reinette Chatre
2022-05-06 22:27   ` Jarkko Sakkinen
2022-05-06 22:40     ` Reinette Chatre
2022-05-07 18:01       ` Jarkko Sakkinen
2022-04-28 20:11 ` [RFC PATCH 3/4] x86/sgx: Obtain backing storage page with enclave mutex held Reinette Chatre
2022-04-28 21:58   ` Dave Hansen
2022-04-28 22:44     ` Reinette Chatre
2022-05-06 22:43   ` Jarkko Sakkinen
2022-04-28 20:11 ` [RFC PATCH 4/4] x86/sgx: Do not allocate backing pages when loading from backing store Reinette Chatre
2022-04-28 21:12 ` [RFC PATCH 0/4] SGX shmem backing store issue Dave Hansen
2022-04-29 18:50   ` Reinette Chatre
2022-04-29 19:45     ` Dave Hansen
2022-04-30  3:22       ` Reinette Chatre
2022-04-30 15:52         ` Reinette Chatre
2022-05-02 14:36         ` Dave Hansen
2022-05-02 17:11           ` Reinette Chatre [this message]
2022-05-02 21:33             ` Dave Hansen
2022-05-04 22:13               ` Reinette Chatre
2022-05-04 22:58                 ` Dave Hansen
2022-05-04 23:36                   ` Reinette Chatre
2022-05-04 23:50                     ` Dave Hansen
2022-05-05  0:08                       ` Reinette Chatre
2022-05-04 23:05                 ` Dave Hansen
2022-05-07 17:46               ` Jarkko Sakkinen
2022-05-07 17:48                 ` Jarkko Sakkinen
2022-05-09 17:09                   ` Reinette Chatre
2022-05-10 22:28                     ` Jarkko Sakkinen
2022-05-11 17:23                       ` Reinette Chatre
2022-05-12 14:10                         ` Jarkko Sakkinen
2022-04-28 21:29 ` Dave Hansen
2022-04-28 22:20   ` Reinette Chatre
2022-05-04  6:40 ` Jarkko Sakkinen
2022-05-05  6:09 ` Jarkko Sakkinen

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=f6e64c4f-8539-b7e7-7890-a4b1acc073fe@intel.com \
    --to=reinette.chatre@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=haitao.huang@intel.com \
    --cc=jarkko@kernel.org \
    --cc=linux-sgx@vger.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;
as well as URLs for NNTP newsgroup(s).