Received: by 2002:a05:6a10:413:0:0:0:0 with SMTP id 19csp777310pxp; Fri, 11 Mar 2022 14:53:00 -0800 (PST) X-Google-Smtp-Source: ABdhPJyPZEQKwBlYHyHgInfhPmfNyOQSC4iLLXvdh6qj85TuQjZBkue+eqwYDv2iSYyW3vBR2myt X-Received: by 2002:a17:902:8f94:b0:14f:d9b3:52c2 with SMTP id z20-20020a1709028f9400b0014fd9b352c2mr12504497plo.103.1647039180633; Fri, 11 Mar 2022 14:53:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1647039180; cv=none; d=google.com; s=arc-20160816; b=Ch/X5sTaKOk2AM3JCY4QN/FkWytQWJU09DWwtjrF1fS6T97ZpF/uQlErLo15UrAYDN YdaZ65HgV/eDrt3ORJr30C8nj7oIdZtfsm8du3DmEDmMUw62yJyWPHKJUdwtUq1pKQTQ iu/cESJawOveJnyS/uRmr6pRPVcRz3dbjJMEXp0nqGjVFTlyHcMZT+61G9QxSebbqzAZ Eo+1BsqFL0LXhKzH629r5VIsxTJts1xs+KqlWr5dd1JJueMlFq8WYtOKXChBZP5u62Od BE7U0LOEOPO119Y8GRVCuiaTCdK/LbamXnQ7o6ggVho8LixR6elZgCKMPNmrFJq23wad 2xQQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:robot-unsubscribe :robot-id:message-id:mime-version:references:in-reply-to:cc:subject :to:reply-to:sender:from:dkim-signature:dkim-signature:date; bh=GqhfUnvgx3zutM5wq9PzoICDyE5PuKyGmo3SlOl+R+A=; b=lsVEoJTOkdSM4ZechaqiVitsdwuPaU2uJUTmI0LswID2N2k+1MNztdXlihgnape5rQ vaW8y0hSKoo3jMS0Hdo9uUX8UH1E9Eh6iQx4AYJ5byGTLIvZsamCDtuXXGPUluIci6el WmjMBkofFoShjZWq/GN0L7jTVIznUgad4dZb+ovZRvZ1FtU29A/kyGyVNcO7oVCuax/j jxfce4YDXEptd9/3AnF5xS0h7AjoXmCKYOxC0rsy4mkKsY4RPzLuPZv3nS1xPX68cbRI Ku1SsXeJ8gD/yywdcFk+cG61ZJ3eCknQWEltZmslCTFNB14rvsiiNLrMZzbwAmXnDpnT BDQQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=TfK5fXyS; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id z69-20020a633348000000b0036fe3b212cfsi9340214pgz.602.2022.03.11.14.53.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Mar 2022 14:53:00 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=TfK5fXyS; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 724EE2687A6; Fri, 11 Mar 2022 13:51:12 -0800 (PST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245507AbiCKTKq (ORCPT + 99 others); Fri, 11 Mar 2022 14:10:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57894 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234133AbiCKTKp (ORCPT ); Fri, 11 Mar 2022 14:10:45 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 768A21B8FF2; Fri, 11 Mar 2022 11:09:41 -0800 (PST) Date: Fri, 11 Mar 2022 19:09:37 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1647025779; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GqhfUnvgx3zutM5wq9PzoICDyE5PuKyGmo3SlOl+R+A=; b=TfK5fXySwYR+amND7V+O3HNYsezzElFTg59kCq6IOjhYQy5WciVU2AW7pG2EX+9kAHNYSf SyEbzy9C+jFBfyMiMKi1qVSmt4BMkk0QtRB3EFUgb/l75XO6f1/UG6HO8jmpkSiOz5fvmB wb73uEYR674JBbjvtFBa945mPHMeUZa1Ix7JqDRi8+MReMq0GmRThe9+bVn5/pczeenYMk sYG89moUuiJkDgLlIEmAQtcn/5xijsJpof/9cCIoeT0t3njsgKZpbfl1sigThFRfAovEeS FlxUcZ0QlJ1qWqMXupFPRMJjQIzyr6NflkS76wNa9mziu0lFNmGRcU7mPR/0kA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1647025779; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GqhfUnvgx3zutM5wq9PzoICDyE5PuKyGmo3SlOl+R+A=; b=v5VweIFZGgYROgAHH6hqT+OkAjXYm/nZpmryaPti1qwYCyZmIYM9WuKRmpss7cAYxYOlHE EfFY+zFDLy1M4sAQ== From: "tip-bot2 for Jarkko Sakkinen" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/urgent] x86/sgx: Free backing memory after faulting the enclave page Cc: stable@vger.kernel.org, Dave Hansen , Jarkko Sakkinen , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20220303223859.273187-1-jarkko@kernel.org> References: <20220303223859.273187-1-jarkko@kernel.org> MIME-Version: 1.0 Message-ID: <164702577786.16921.17768116446491945567.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The following commit has been merged into the x86/urgent branch of tip: Commit-ID: 08999b2489b4c9b939d7483dbd03702ee4576d96 Gitweb: https://git.kernel.org/tip/08999b2489b4c9b939d7483dbd03702ee4576d96 Author: Jarkko Sakkinen AuthorDate: Fri, 04 Mar 2022 00:38:58 +02:00 Committer: Dave Hansen CommitterDate: Fri, 11 Mar 2022 10:31:06 -08:00 x86/sgx: Free backing memory after faulting the enclave page There is a limited amount of SGX memory (EPC) on each system. When that memory is used up, SGX has its own swapping mechanism which is similar in concept but totally separate from the core mm/* code. Instead of swapping to disk, SGX swaps from EPC to normal RAM. That normal RAM comes from a shared memory pseudo-file and can itself be swapped by the core mm code. There is a hierarchy like this: EPC <-> shmem <-> disk After data is swapped back in from shmem to EPC, the shmem backing storage needs to be freed. Currently, the backing shmem is not freed. This effectively wastes the shmem while the enclave is running. The memory is recovered when the enclave is destroyed and the backing storage freed. Sort this out by freeing memory with shmem_truncate_range(), as soon as a page is faulted back to the EPC. In addition, free the memory for PCMD pages as soon as all PCMD's in a page have been marked as unused by zeroing its contents. Cc: stable@vger.kernel.org Fixes: 1728ab54b4be ("x86/sgx: Add a page reclaimer") Reported-by: Dave Hansen Signed-off-by: Jarkko Sakkinen Signed-off-by: Dave Hansen Link: https://lkml.kernel.org/r/20220303223859.273187-1-jarkko@kernel.org --- arch/x86/kernel/cpu/sgx/encl.c | 57 +++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c index 48afe96..7c63a19 100644 --- a/arch/x86/kernel/cpu/sgx/encl.c +++ b/arch/x86/kernel/cpu/sgx/encl.c @@ -13,6 +13,30 @@ #include "sgx.h" /* + * Calculate byte offset of a PCMD struct associated with an enclave page. PCMD's + * follow right after the EPC data in the backing storage. In addition to the + * visible enclave pages, there's one extra page slot for SECS, before PCMD + * structs. + */ +static inline pgoff_t sgx_encl_get_backing_page_pcmd_offset(struct sgx_encl *encl, + unsigned long page_index) +{ + pgoff_t epc_end_off = encl->size + sizeof(struct sgx_secs); + + return epc_end_off + page_index * sizeof(struct sgx_pcmd); +} + +/* + * Free a page from the backing storage in the given page index. + */ +static inline void sgx_encl_truncate_backing_page(struct sgx_encl *encl, unsigned long page_index) +{ + struct inode *inode = file_inode(encl->backing); + + shmem_truncate_range(inode, PFN_PHYS(page_index), PFN_PHYS(page_index) + PAGE_SIZE - 1); +} + +/* * ELDU: Load an EPC page as unblocked. For more info, see "OS Management of EPC * Pages" in the SDM. */ @@ -22,9 +46,11 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page, { unsigned long va_offset = encl_page->desc & SGX_ENCL_PAGE_VA_OFFSET_MASK; struct sgx_encl *encl = encl_page->encl; + pgoff_t page_index, page_pcmd_off; struct sgx_pageinfo pginfo; struct sgx_backing b; - pgoff_t page_index; + bool pcmd_page_empty; + u8 *pcmd_page; int ret; if (secs_page) @@ -32,14 +58,16 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page, else page_index = PFN_DOWN(encl->size); + page_pcmd_off = sgx_encl_get_backing_page_pcmd_offset(encl, page_index); + ret = sgx_encl_get_backing(encl, page_index, &b); if (ret) return ret; pginfo.addr = encl_page->desc & PAGE_MASK; pginfo.contents = (unsigned long)kmap_atomic(b.contents); - pginfo.metadata = (unsigned long)kmap_atomic(b.pcmd) + - b.pcmd_offset; + pcmd_page = kmap_atomic(b.pcmd); + pginfo.metadata = (unsigned long)pcmd_page + b.pcmd_offset; if (secs_page) pginfo.secs = (u64)sgx_get_epc_virt_addr(secs_page); @@ -55,11 +83,24 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page, ret = -EFAULT; } - kunmap_atomic((void *)(unsigned long)(pginfo.metadata - b.pcmd_offset)); + memset(pcmd_page + b.pcmd_offset, 0, sizeof(struct sgx_pcmd)); + + /* + * The area for the PCMD in the page was zeroed above. Check if the + * whole page is now empty meaning that all PCMD's have been zeroed: + */ + pcmd_page_empty = !memchr_inv(pcmd_page, 0, PAGE_SIZE); + + kunmap_atomic(pcmd_page); kunmap_atomic((void *)(unsigned long)pginfo.contents); sgx_encl_put_backing(&b, false); + sgx_encl_truncate_backing_page(encl, page_index); + + if (pcmd_page_empty) + sgx_encl_truncate_backing_page(encl, PFN_DOWN(page_pcmd_off)); + return ret; } @@ -579,7 +620,7 @@ static struct page *sgx_encl_get_backing_page(struct sgx_encl *encl, int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index, struct sgx_backing *backing) { - pgoff_t pcmd_index = PFN_DOWN(encl->size) + 1 + (page_index >> 5); + pgoff_t page_pcmd_off = sgx_encl_get_backing_page_pcmd_offset(encl, page_index); struct page *contents; struct page *pcmd; @@ -587,7 +628,7 @@ int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index, if (IS_ERR(contents)) return PTR_ERR(contents); - pcmd = sgx_encl_get_backing_page(encl, pcmd_index); + pcmd = sgx_encl_get_backing_page(encl, PFN_DOWN(page_pcmd_off)); if (IS_ERR(pcmd)) { put_page(contents); return PTR_ERR(pcmd); @@ -596,9 +637,7 @@ int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index, backing->page_index = page_index; backing->contents = contents; backing->pcmd = pcmd; - backing->pcmd_offset = - (page_index & (PAGE_SIZE / sizeof(struct sgx_pcmd) - 1)) * - sizeof(struct sgx_pcmd); + backing->pcmd_offset = page_pcmd_off & (PAGE_SIZE - 1); return 0; }