Received: by 2002:a6b:500f:0:0:0:0:0 with SMTP id e15csp960189iob; Fri, 13 May 2022 17:47:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzP1g6TxFUstSfZpHsdrMpum/+/vDSEn7duuFeKsBDXZ5fbXEJVmc8LxfRFYj/fF6OVs8Vq X-Received: by 2002:a05:6000:1e09:b0:20c:dbc7:e391 with SMTP id bj9-20020a0560001e0900b0020cdbc7e391mr5940328wrb.218.1652489227783; Fri, 13 May 2022 17:47:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1652489227; cv=none; d=google.com; s=arc-20160816; b=Jb1BHwTxuxS8T7bQs1AsrfF3Yyz5UJ2VAPKH1wOIg0L/wMcUSygkci/YOz5VD3rCgh AQYe4tSy5r6nL90vjjaMiS89ASNzeRTLLchvZt9fkQ5ozUQaUweXUuKyjG5MJXsS4ycp RTmU6X8o91m0vywpBHNo687W+ZqvebpZW2UH4fjD1pxZX8VsuvTAGdtuBL5NeoTExds6 LMFnDOpWtEH/bmizEvi/XP7U6rLl+fE1K6GAepoI2llfiNt3hzTxI5L38DX1g982Z1UO GfJuXZ5fjcc7A33xYaLZaBHwK5mJJIEGMBI8lB0lA5IObSQWcoRB2OPJr7ZuT7mFZHFs 4qWg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=dhXFGlguWWK/xpMeIBgI/aJBK8uyc5ZXULBfSzQ7dfM=; b=RdxrTsgxJwh9q7DdGfxvcPCgmucGsfJ62//Uj7PIdA8qQRPxr68b1waHG6Pwo5y1+n 0FGkfZQNQf6iDbNoyGKqovWLhzCgok7nX/iXQEWPGqyya4zc59//kHz26gLKILglg0/6 qdjLmFmyDVXRAQwUNp7BEv6ltZIdtVHWCA1DClwX/UiEkchBvvlgM281l3rH57H0SG10 uFDV7KLYrk2dZT8xmwiqwp6afwDF4yDzo3frKkAZ7F/4G2QtCZJ+cslVz7eTiybudc3J 2oWrQFD86Rmks4bT15vL/v3leyeNDvhodXrJ8RN/WNdVY62MikwlxPuKUf6JPHuR7H/F IHoA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=CdmswbfI; 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=NONE dis=NONE) header.from=intel.com Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id l14-20020a7bcf0e000000b00393ebc6eeefsi3670845wmg.210.2022.05.13.17.47.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 13 May 2022 17:47:07 -0700 (PDT) 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=@intel.com header.s=Intel header.b=CdmswbfI; 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=NONE dis=NONE) header.from=intel.com Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 4E5233327DA; Fri, 13 May 2022 16:26:04 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1358945AbiELVvz (ORCPT + 99 others); Thu, 12 May 2022 17:51:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39360 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1358947AbiELVvM (ORCPT ); Thu, 12 May 2022 17:51:12 -0400 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 149AA1AD92; Thu, 12 May 2022 14:51:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1652392270; x=1683928270; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=MKFAwZVRS9r1/eCEjiNekApOIfHXorRfBaCx1CM8ZLQ=; b=CdmswbfIRYEoZLkV2lv6tftjRGX1vyGmZ+P3bNI7s+gKkrp7QXxF1dwy s8hhaFpTUHVg95zyhAY+SQr5XZP1nCsT64V69aTdBycUr5Wk1kS7ztIXC OVSI55Q/jyBjgyuXtEiVZg3l8O07/kZ+dJnLzrXnhTgrgfRZ8DTvcBWU6 3dI3TLCOmqMa//9OYRvNRnqmQeXn/ky+2Fqma7tnJQRwckPokQqf3bHeb aqlZ0jHjM/E1+oi+zHwIHALxzcHvzruj93OfdmFiMhgWIIUSvrCVspclL V6cRu3YKqn9qlSZUFaoGxO9U9dRMCmLZRLPVJ3R77trdhFAyMFmHN3CFY A==; X-IronPort-AV: E=McAfee;i="6400,9594,10345"; a="267736144" X-IronPort-AV: E=Sophos;i="5.91,221,1647327600"; d="scan'208";a="267736144" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 May 2022 14:51:08 -0700 X-IronPort-AV: E=Sophos;i="5.91,221,1647327600"; d="scan'208";a="553955564" Received: from rchatre-ws.ostc.intel.com ([10.54.69.144]) by orsmga002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 May 2022 14:51:08 -0700 From: Reinette Chatre To: dave.hansen@linux.intel.com, jarkko@kernel.org, tglx@linutronix.de, bp@alien8.de, luto@kernel.org, mingo@redhat.com, linux-sgx@vger.kernel.org, x86@kernel.org Cc: haitao.huang@intel.com, hpa@zytor.com, linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH V3 1/5] x86/sgx: Disconnect backing page references from dirty status Date: Thu, 12 May 2022 14:50:57 -0700 Message-Id: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, 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=unavailable 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 SGX uses shmem backing storage to store encrypted enclave pages and their crypto metadata when enclave pages are moved out of enclave memory. Two shmem backing storage pages are associated with each enclave page - one backing page to contain the encrypted enclave page data and one backing page (shared by a few enclave pages) to contain the crypto metadata used by the processor to verify the enclave page when it is loaded back into the enclave. sgx_encl_put_backing() is used to release references to the backing storage and, optionally, mark both backing store pages as dirty. Managing references and dirty status together in this way results in both backing store pages marked as dirty, even if only one of the backing store pages are changed. Additionally, waiting until the page reference is dropped to set the page dirty risks a race with the page fault handler that may load outdated data into the enclave when a page is faulted right after it is reclaimed. Consider what happens if the reclaimer writes a page to the backing store and the page is immediately faulted back, before the reclaimer is able to set the dirty bit of the page: sgx_reclaim_pages() { sgx_vma_fault() { ... sgx_encl_get_backing(); ... ... sgx_reclaimer_write() { mutex_lock(&encl->lock); /* Write data to backing store */ mutex_unlock(&encl->lock); } mutex_lock(&encl->lock); __sgx_encl_eldu() { ... /* * Enclave backing store * page not released * nor marked dirty - * contents may not be * up to date. */ sgx_encl_get_backing(); ... /* * Enclave data restored * from backing store * and PCMD pages that * are not up to date. * ENCLS[ELDU] faults * because of MAC or PCMD * checking failure. */ sgx_encl_put_backing(); } ... /* set page dirty */ sgx_encl_put_backing(); ... mutex_unlock(&encl->lock); } } Remove the option to sgx_encl_put_backing() to set the backing pages as dirty and set the needed pages as dirty right after receiving important data while enclave mutex is held. This ensures that the page fault handler can get up to date data from a page and prepares the code for a following change where only one of the backing pages need to be marked as dirty. Cc: stable@vger.kernel.org Fixes: 1728ab54b4be ("x86/sgx: Add a page reclaimer") Suggested-by: Dave Hansen Tested-by: Haitao Huang Signed-off-by: Reinette Chatre Link: https://lore.kernel.org/linux-sgx/8922e48f-6646-c7cc-6393-7c78dcf23d23@intel.com/ --- Changes since V2: - Mark page as dirty after receiving important data, not before. (Dave) - Add cc to stable and include link to discussion. (Dave) - Update changelog and move changelog description of race between reclaimer and page fault handler from later in series to this patch. - Add Haitao's Tested-by tag. Changes since RFC v1: - New patch. arch/x86/kernel/cpu/sgx/encl.c | 10 ++-------- arch/x86/kernel/cpu/sgx/encl.h | 2 +- arch/x86/kernel/cpu/sgx/main.c | 6 ++++-- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c index 7c63a1911fae..398695a20605 100644 --- a/arch/x86/kernel/cpu/sgx/encl.c +++ b/arch/x86/kernel/cpu/sgx/encl.c @@ -94,7 +94,7 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page, kunmap_atomic(pcmd_page); kunmap_atomic((void *)(unsigned long)pginfo.contents); - sgx_encl_put_backing(&b, false); + sgx_encl_put_backing(&b); sgx_encl_truncate_backing_page(encl, page_index); @@ -645,15 +645,9 @@ int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index, /** * sgx_encl_put_backing() - Unpin the backing storage * @backing: data for accessing backing storage for the page - * @do_write: mark pages dirty */ -void sgx_encl_put_backing(struct sgx_backing *backing, bool do_write) +void sgx_encl_put_backing(struct sgx_backing *backing) { - if (do_write) { - set_page_dirty(backing->pcmd); - set_page_dirty(backing->contents); - } - put_page(backing->pcmd); put_page(backing->contents); } diff --git a/arch/x86/kernel/cpu/sgx/encl.h b/arch/x86/kernel/cpu/sgx/encl.h index fec43ca65065..d44e7372151f 100644 --- a/arch/x86/kernel/cpu/sgx/encl.h +++ b/arch/x86/kernel/cpu/sgx/encl.h @@ -107,7 +107,7 @@ void sgx_encl_release(struct kref *ref); int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm); int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index, struct sgx_backing *backing); -void sgx_encl_put_backing(struct sgx_backing *backing, bool do_write); +void sgx_encl_put_backing(struct sgx_backing *backing); int sgx_encl_test_and_clear_young(struct mm_struct *mm, struct sgx_encl_page *page); diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c index 8e4bc6453d26..e71df40a4f38 100644 --- a/arch/x86/kernel/cpu/sgx/main.c +++ b/arch/x86/kernel/cpu/sgx/main.c @@ -191,6 +191,8 @@ static int __sgx_encl_ewb(struct sgx_epc_page *epc_page, void *va_slot, backing->pcmd_offset; ret = __ewb(&pginfo, sgx_get_epc_virt_addr(epc_page), va_slot); + set_page_dirty(backing->pcmd); + set_page_dirty(backing->contents); kunmap_atomic((void *)(unsigned long)(pginfo.metadata - backing->pcmd_offset)); @@ -320,7 +322,7 @@ static void sgx_reclaimer_write(struct sgx_epc_page *epc_page, sgx_encl_free_epc_page(encl->secs.epc_page); encl->secs.epc_page = NULL; - sgx_encl_put_backing(&secs_backing, true); + sgx_encl_put_backing(&secs_backing); } out: @@ -411,7 +413,7 @@ static void sgx_reclaim_pages(void) encl_page = epc_page->owner; sgx_reclaimer_write(epc_page, &backing[i]); - sgx_encl_put_backing(&backing[i], true); + sgx_encl_put_backing(&backing[i]); kref_put(&encl_page->encl->refcount, sgx_encl_release); epc_page->flags &= ~SGX_EPC_PAGE_RECLAIMER_TRACKED; -- 2.25.1