From patchwork Thu Aug 25 06:17:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 12954213 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A7984C04AA5 for ; Thu, 25 Aug 2022 06:17:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233849AbiHYGR2 (ORCPT ); Thu, 25 Aug 2022 02:17:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56928 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231953AbiHYGR1 (ORCPT ); Thu, 25 Aug 2022 02:17:27 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 605DE9F8CA; Wed, 24 Aug 2022 23:17:26 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id CD3886190F; Thu, 25 Aug 2022 06:17:25 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B14E1C433C1; Thu, 25 Aug 2022 06:17:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1661408245; bh=H/5r/QpdAo5BW4BPKN593MzBeyF0N/Ah4GhagLkmtEk=; h=From:To:Cc:Subject:Date:From; b=NoSoHZ+bb8AOwEHsI8XSEsceCwr+1d0xvZoNF+y8hFZwng+RmjkixeNkhbxhjgeQL +P8Yc/3aiA1MPXe+2QKQtqeOZpJW8YCbFUX3+GiWqoWnMlz0eDKAq1Mrb3Dkf5EcN9 y8OD7wUFH6FgdyS4VIFgPWJLLhLGkbR2IzbTDxriszWZGoCRX55YgxOrirgwpWTmLK T/bjyPlrGd7ot5HCe78wt8CtQxQMYQsBWszyh+A1mgX1RVYqXIsdNup1ec6SvqZHzq DMNaJGUlaqKY/JEv+WQLDSYdw7SaRg5eOD9mXZe84A9IsvEU8VyPszw6a3epwEcrIp uL3uSIjlMvF7w== From: Jarkko Sakkinen To: linux-sgx@vger.kernel.org Cc: Jarkko Sakkinen , Paul Menzel , Haitao Huang , Dave Hansen , Reinette Chatre , Thomas Gleixner , Ingo Molnar , Borislav Petkov , x86@kernel.org (maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT)), "H. Peter Anvin" , linux-kernel@vger.kernel.org (open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)) Subject: [PATCH v2] x86/sgx: Do not consider unsanitized pages an error Date: Thu, 25 Aug 2022 09:17:10 +0300 Message-Id: <20220825061710.256125-1-jarkko@kernel.org> X-Mailer: git-send-email 2.37.1 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-sgx@vger.kernel.org If sgx_dirty_page_list ends up being non-empty, currently this triggers WARN_ON(), which produces a lot of noise, and can potentially crash the kernel, depending on the kernel command line. However, if the SGX subsystem initialization is retracted, the sanitization process could end up in the middle, and sgx_dirty_page_list be left non-empty for legit reasons. Replace this faulty behavior with more verbose version __sgx_sanitize_pages(), which can optionally print EREMOVE error code and the number of unsanitized pages. Link: https://lore.kernel.org/linux-sgx/20220825051827.246698-1-jarkko@kernel.org/T/#u Reported-by: Paul Menzel Fixes: 51ab30eb2ad4 ("x86/sgx: Replace section->init_laundry_list with sgx_dirty_page_list") Signed-off-by: Jarkko Sakkinen Cc: Haitao Huang Cc: Dave Hansen Cc: Reinette Chatre --- v2: - Replaced WARN_ON() with optional pr_info() inside __sgx_sanitize_pages(). - Rewrote the commit message. - Added the fixes tag. --- arch/x86/kernel/cpu/sgx/main.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c index 515e2a5f25bb..b57118f8641d 100644 --- a/arch/x86/kernel/cpu/sgx/main.c +++ b/arch/x86/kernel/cpu/sgx/main.c @@ -50,16 +50,17 @@ static LIST_HEAD(sgx_dirty_page_list); * from the input list, and made available for the page allocator. SECS pages * prepending their children in the input list are left intact. */ -static void __sgx_sanitize_pages(struct list_head *dirty_page_list) +static void __sgx_sanitize_pages(struct list_head *dirty_page_list, bool verbose) { struct sgx_epc_page *page; + int dirty_count = 0; LIST_HEAD(dirty); int ret; /* dirty_page_list is thread-local, no need for a lock: */ while (!list_empty(dirty_page_list)) { if (kthread_should_stop()) - return; + break; page = list_first_entry(dirty_page_list, struct sgx_epc_page, list); @@ -90,14 +91,27 @@ static void __sgx_sanitize_pages(struct list_head *dirty_page_list) list_del(&page->list); sgx_free_epc_page(page); } else { + if (verbose) + pr_err_ratelimited(EREMOVE_ERROR_MESSAGE, ret, ret); + /* The page is not yet clean - move to the dirty list. */ list_move_tail(&page->list, &dirty); + dirty_count++; } cond_resched(); } list_splice(&dirty, dirty_page_list); + + /* + * In addition to the kexec usual scenario, if the driver and/or KVM + * does not initialize, ksgx will be stopped, which can leave pages + * unsanitized. It's legit behaviour but it does not hurt to make it + * visible. + */ + if (verbose && dirty_count > 0) + pr_info("%d unsanitized pages\n", dirty_count); } static bool sgx_reclaimer_age(struct sgx_epc_page *epc_page) @@ -394,8 +408,8 @@ static int ksgxd(void *p) * Sanitize pages in order to recover from kexec(). The 2nd pass is * required for SECS pages, whose child pages blocked EREMOVE. */ - __sgx_sanitize_pages(&sgx_dirty_page_list); - __sgx_sanitize_pages(&sgx_dirty_page_list); + __sgx_sanitize_pages(&sgx_dirty_page_list, false); + __sgx_sanitize_pages(&sgx_dirty_page_list, true); /* sanity check: */ WARN_ON(!list_empty(&sgx_dirty_page_list));