From patchwork Mon Sep 11 23:23:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: tip-bot2 for Thomas Gleixner X-Patchwork-Id: 138468 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:9ecd:0:b0:3f2:4152:657d with SMTP id t13csp718651vqx; Tue, 12 Sep 2023 15:33:25 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHsezO7rvMjINKQ998/b2pfPBF/pMfCqwNBQI75PWJ/xHC6ktPr39QATNOJEcdvSxXdPGgj X-Received: by 2002:a05:6a20:12cc:b0:137:2f8c:fab0 with SMTP id v12-20020a056a2012cc00b001372f8cfab0mr986080pzg.49.1694558005013; Tue, 12 Sep 2023 15:33:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694558005; cv=none; d=google.com; s=arc-20160816; b=eXONthWpjt6qKN5+wYkHtuI7IjM25l/3F784FhDHnGmxEeXhVp3/KzWeEOEgY54GDi e5eC/VNECDUMBgUZxbgdLhBQao0kG0ndUH3le0AW4nChJUXwLukpeHL0DcKjkQsNPyqE HE4kl4Rw9LhnCrfvbkJc8wI5czOxuSySfxYA66RFvV5yhEUKjnyKT6AzgPC5/WjKfGyM niLgF2JfND3rgvHzkL+5XnNJ0DaaTaVm8jjg0ELW3i0DCMdwsC3kBeYod9dz75aOU+oF jHzTFiPdMs/TPCq3zBuA0x32ohgh0Ed5BbvT59UbMript00894Hf6MKey984GvIxRKBb 6L+w== 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:cc:subject:to:reply-to:sender:from :dkim-signature:dkim-signature:date; bh=RKNzrKDbxp6SlnBJWYyLW20AScpNUCzY5NycfewQzU8=; fh=QM2bHvJj/yAjc4r7lT+NxyEztCL3ISWFkz0FEnKR+5M=; b=z770hrDi+8FjYjdtTRcW88iYWOmdPQypsinOZcljRL0QzxuLNTGK0IzDZMQD57Ubwh Y9GpbSl5ajvHmL+cF1LSIkI+BxLtb06BQykVoSRjVmDTbVCVIGQ5yE/EnnAbjsEvFOaU w4dxtsOYITeojRhRrIw0uDKwgOyMPLj2NFOIx6ayErjKLZyULgPOx3pkSfuGHNvp0chK +IJDYefCVv+CZPVw3xLwPbmz/L1CBMnb7BN7dvJzemCrR17OgTDCwJZrfQritTJ574SM ojV3aI7Bh1dGiCjZlb+KGxakMcUTp369L4ZwvTKi5CQH+oZMH7b8jY4YZn919c4xqIIU xUUA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=T84vweB+; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=BMuE6VGZ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 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 howler.vger.email (howler.vger.email. [2620:137:e000::3:4]) by mx.google.com with ESMTPS id me5-20020a17090b17c500b0026b698fdda6si240832pjb.98.2023.09.12.15.33.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Sep 2023 15:33:24 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) client-ip=2620:137:e000::3:4; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=T84vweB+; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=BMuE6VGZ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 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 out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by howler.vger.email (Postfix) with ESMTP id 001A98489E56; Mon, 11 Sep 2023 21:42:28 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at howler.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235673AbjILDUG (ORCPT + 40 others); Mon, 11 Sep 2023 23:20:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36588 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241850AbjILDPJ (ORCPT ); Mon, 11 Sep 2023 23:15:09 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A694D7BE1C; Mon, 11 Sep 2023 18:49:51 -0700 (PDT) Date: Mon, 11 Sep 2023 23:23:59 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1694474641; 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; bh=RKNzrKDbxp6SlnBJWYyLW20AScpNUCzY5NycfewQzU8=; b=T84vweB+R9x28If2gtHm/pUig49hiZyfrUG48s04aidCB5GWg+fE6WHgKXfvC+sl5svqdJ /UCbijN39KxYkIa4D83T1/JULWErvvtDa+PwMq1p/iQ0RO4u79yvJzhP6ynhkjJ7L06lUK j+FjvrkL0fMbnUueccvw6/1wLwPh+sB9QEYqXu1CQCFB908CdBmlhCqBRXQxjLxJ2BzLHB 6CA5hH+mVROQMKyld+kie3zLRvmx7QKi70ivzUDK9r9pfWEr5ic6yCzsjcrAoMzVK6wXO0 PrDAsdZ6B2OKzS/BdR1gcEN/9zmQ0mdJEu4JT2lqZU+ImCTgER/+nI7SF3E4eA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1694474641; 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; bh=RKNzrKDbxp6SlnBJWYyLW20AScpNUCzY5NycfewQzU8=; b=BMuE6VGZZh8pEvc7QfpQ6uaw3NoPXQkW9C91xu4FyIVlNpGM4lzB2gKhrXgtmuqQXBzRq0 uITxsGU+lI6MUKCQ== From: "tip-bot2 for Dexuan Cui" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/tdx] x86/tdx: Retry partially-completed page conversion hypercalls Cc: Dexuan Cui , Dave Hansen , Michael Kelley , Kuppuswamy Sathyanarayanan , "Kirill A. Shutemov" , x86@kernel.org, linux-kernel@vger.kernel.org MIME-Version: 1.0 Message-ID: <169447463987.27769.8924490797849833894.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (howler.vger.email [0.0.0.0]); Mon, 11 Sep 2023 21:42:29 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1776872854595717113 X-GMAIL-MSGID: 1776872854595717113 The following commit has been merged into the x86/tdx branch of tip: Commit-ID: 019b383d1132e4051de0d2e43254454b86538cf4 Gitweb: https://git.kernel.org/tip/019b383d1132e4051de0d2e43254454b86538cf4 Author: Dexuan Cui AuthorDate: Thu, 10 Aug 2023 19:12:45 -07:00 Committer: Dave Hansen CommitterDate: Mon, 11 Sep 2023 16:19:33 -07:00 x86/tdx: Retry partially-completed page conversion hypercalls TDX guest memory is private by default and the VMM may not access it. However, in cases where the guest needs to share data with the VMM, the guest and the VMM can coordinate to make memory shared between them. The guest side of this protocol includes the "MapGPA" hypercall. This call takes a guest physical address range. The hypercall spec (aka. the GHCI) says that the MapGPA call is allowed to return partial progress in mapping this range and indicate that fact with a special error code. A guest that sees such partial progress is expected to retry the operation for the portion of the address range that was not completed. Hyper-V does this partial completion dance when set_memory_decrypted() is called to "decrypt" swiotlb bounce buffers that can be up to 1GB in size. It is evidently the only VMM that does this, which is why nobody noticed this until now. [ dhansen: rewrite changelog ] Signed-off-by: Dexuan Cui Signed-off-by: Dave Hansen Reviewed-by: Michael Kelley Reviewed-by: Kuppuswamy Sathyanarayanan Acked-by: Kirill A. Shutemov Link: https://lore.kernel.org/all/20230811021246.821-2-decui%40microsoft.com --- arch/x86/coco/tdx/tdx.c | 64 ++++++++++++++++++++++++------ arch/x86/include/asm/shared/tdx.h | 2 +- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c index 1d6b863..746075d 100644 --- a/arch/x86/coco/tdx/tdx.c +++ b/arch/x86/coco/tdx/tdx.c @@ -703,14 +703,15 @@ static bool tdx_cache_flush_required(void) } /* - * Inform the VMM of the guest's intent for this physical page: shared with - * the VMM or private to the guest. The VMM is expected to change its mapping - * of the page in response. + * Notify the VMM about page mapping conversion. More info about ABI + * can be found in TDX Guest-Host-Communication Interface (GHCI), + * section "TDG.VP.VMCALL". */ -static bool tdx_enc_status_changed(unsigned long vaddr, int numpages, bool enc) +static bool tdx_map_gpa(phys_addr_t start, phys_addr_t end, bool enc) { - phys_addr_t start = __pa(vaddr); - phys_addr_t end = __pa(vaddr + numpages * PAGE_SIZE); + /* Retrying the hypercall a second time should succeed; use 3 just in case */ + const int max_retries_per_page = 3; + int retry_count = 0; if (!enc) { /* Set the shared (decrypted) bits: */ @@ -718,12 +719,51 @@ static bool tdx_enc_status_changed(unsigned long vaddr, int numpages, bool enc) end |= cc_mkdec(0); } - /* - * Notify the VMM about page mapping conversion. More info about ABI - * can be found in TDX Guest-Host-Communication Interface (GHCI), - * section "TDG.VP.VMCALL" - */ - if (_tdx_hypercall(TDVMCALL_MAP_GPA, start, end - start, 0, 0)) + while (retry_count < max_retries_per_page) { + struct tdx_hypercall_args args = { + .r10 = TDX_HYPERCALL_STANDARD, + .r11 = TDVMCALL_MAP_GPA, + .r12 = start, + .r13 = end - start }; + + u64 map_fail_paddr; + u64 ret = __tdx_hypercall_ret(&args); + + if (ret != TDVMCALL_STATUS_RETRY) + return !ret; + /* + * The guest must retry the operation for the pages in the + * region starting at the GPA specified in R11. R11 comes + * from the untrusted VMM. Sanity check it. + */ + map_fail_paddr = args.r11; + if (map_fail_paddr < start || map_fail_paddr >= end) + return false; + + /* "Consume" a retry without forward progress */ + if (map_fail_paddr == start) { + retry_count++; + continue; + } + + start = map_fail_paddr; + retry_count = 0; + } + + return false; +} + +/* + * Inform the VMM of the guest's intent for this physical page: shared with + * the VMM or private to the guest. The VMM is expected to change its mapping + * of the page in response. + */ +static bool tdx_enc_status_changed(unsigned long vaddr, int numpages, bool enc) +{ + phys_addr_t start = __pa(vaddr); + phys_addr_t end = __pa(vaddr + numpages * PAGE_SIZE); + + if (!tdx_map_gpa(start, end, enc)) return false; /* shared->private conversion requires memory to be accepted before use */ diff --git a/arch/x86/include/asm/shared/tdx.h b/arch/x86/include/asm/shared/tdx.h index 7513b3b..22ee23a 100644 --- a/arch/x86/include/asm/shared/tdx.h +++ b/arch/x86/include/asm/shared/tdx.h @@ -24,6 +24,8 @@ #define TDVMCALL_MAP_GPA 0x10001 #define TDVMCALL_REPORT_FATAL_ERROR 0x10003 +#define TDVMCALL_STATUS_RETRY 1 + #ifndef __ASSEMBLY__ /*