Message ID | 20221121195151.21812-2-decui@microsoft.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp1798385wrr; Mon, 21 Nov 2022 11:53:53 -0800 (PST) X-Google-Smtp-Source: AA0mqf6JhYPGuH96Iwp5tTokt7vLTR7OF1SjHwOY0M4sDvGY8jtcuc8iRsJlB4SANQHbosm936Gu X-Received: by 2002:a17:90a:9bcb:b0:206:f02a:cb4b with SMTP id b11-20020a17090a9bcb00b00206f02acb4bmr22031208pjw.159.1669060433361; Mon, 21 Nov 2022 11:53:53 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1669060433; cv=pass; d=google.com; s=arc-20160816; b=JTdv8VyHqqVYd//12zxdQtj0ioOFmFHmlhkrXLS2pw3BIXRnYAAtNKCMtD9IWEdLiD 2VTWjLygfOsUlESE30cFILpHPC3VYxmW+1nBcg89y+xmZwv5Zkje4Kh0ZOYxIwMRTXlo FGgu/QAaAtBhro6fBY8uvN4WcokUYT+zVDkshWOGwBX8kTspTGXlPBBJhes5G6Yp8f6l jFX32BP4l0QCjWYMORnKUbEEPoG8A1N/vKg8bRr0Fnav2PSYouczLt2KXPoMtTVPFxkd GICBv7rhCctSKiAlYGJZ+q5ddKN1Ntn1xmDnM8hlvklmpPFhutyL2tSoa3euohCdrFQQ Xrvw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=uQ5cCBCdmXSDGpxujQ4rE647Xt26Pt7EGMqw+j0HTOk=; b=pAuG9157wJfloSUwSaUU1jI8v9uMvpQG4C5fVtcmCK6HDd2HcJk3UaqVHHHYcjiMds 3/iSQXFSkSPCQ+Y53lMH765MyUDG5w4y+Vt9pGuxTg1nxT6DZjAVs2xcdZG17WH2tF6a afvHoQvD7FLOqy81zcmxHZ/OwV0izV/sGn3iYvIC+klX+wE0AijW9t8PElYaK8/mtrA0 q34Ku8xBrXVEwKGQdFZmY9J+32zZXLkYgTPPsURU85/qoR9QoceVy496VJYLFHH8jTih PEexFTTsAZC8PomlgaOCWb7IjIztVUlf1U1zhRbni/r5AS4cFVxEnG09hQ4vJBZz1Lc8 VMOQ== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@microsoft.com header.s=selector2 header.b=X02ybRpd; arc=pass (i=1 spf=pass spfdomain=microsoft.com dkim=pass dkdomain=microsoft.com dmarc=pass fromdomain=microsoft.com); spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=microsoft.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id s2-20020a17090302c200b00176d22a068csi10609012plk.515.2022.11.21.11.53.40; Mon, 21 Nov 2022 11:53:53 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@microsoft.com header.s=selector2 header.b=X02ybRpd; arc=pass (i=1 spf=pass spfdomain=microsoft.com dkim=pass dkdomain=microsoft.com dmarc=pass fromdomain=microsoft.com); spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=microsoft.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231771AbiKUTxN (ORCPT <rfc822;cjcooper78@gmail.com> + 99 others); Mon, 21 Nov 2022 14:53:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43262 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231705AbiKUTxA (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Mon, 21 Nov 2022 14:53:00 -0500 Received: from na01-obe.outbound.protection.outlook.com (mail-eastusazon11022019.outbound.protection.outlook.com [52.101.53.19]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 273A323EAC; Mon, 21 Nov 2022 11:52:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=CE3Ao5ZNjyaGCiLV0uMIDZZSGVLf42nu4LDOtGJZyOdp9F5h6e2NtZ1aKMSi3/3ll11DVHA3lPFpAiX9zyGMUU/ZFhZzkRcRVv5/mEp35yrzq3udKtP4j+paZEBRkjtkkTtH5FH37KSWxZ2MB9cvMQy1/ENqaSQkucasvIAd9Py2lyaezXCmMeCRfPaHIcb0vY8ShWaVdBte/K7pCZwH+dN6R8NUA/QDRSDPnGs3DOzlBUB7DXtIrcR5vwMvqEcDGkz+5iejSgwdG7jFYwwGV7Tck9PZT2Dj+38Fr2bPkyij6R1XZg14MQuWHXN8r25C4AUqDfTcsJbVL3nSABY5tQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=uQ5cCBCdmXSDGpxujQ4rE647Xt26Pt7EGMqw+j0HTOk=; b=Ma7hj/S6oBktG+5vINq+rMDaES4069aQpkzOHliA7NXVp9dMGNvr4aPJDoo0R8mAYFl3F5psdtB9J8AWKrFFUExtz+ClVZ7Nni84Km4EiBTLxHrvvmL74IrQpdUXTaSneEEjP12rvKY6erHZzVCDDRS56A0fn0MuvVYfNOAApIVyibSVSd9UmFTVg1Ts6DRnRKX7QOWS9LXNqmf57xzMgDlsFc616BLtmxNMFpEfedb6iL01eKgrCdUFDQK15L8L5Mvzc/3yX0No4066pl4O50jenJ6A7mQrefonHYAA3SVRSxFhs11wLmNA7jC0YAk4VlgR7PgJpspYTIl1tk+VqA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=microsoft.com; dmarc=pass action=none header.from=microsoft.com; dkim=pass header.d=microsoft.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=uQ5cCBCdmXSDGpxujQ4rE647Xt26Pt7EGMqw+j0HTOk=; b=X02ybRpdPPYInfPGf2fzTYP121P1LsSSDuAjFD1LSLQbcc48f/gStlQcBIKyGRflbrzKfKmtMgCLU53cNPm7xQreRbYRPnhZiagu/uT3BkQoc/BwbqYfsXJc3d5/mBZCIzdJOpFS7U+ctayICjh6l8V4lXY8KSrkGxq3eWZlHro= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=microsoft.com; Received: from BL0PR2101MB1092.namprd21.prod.outlook.com (2603:10b6:207:30::23) by BL1PR21MB3280.namprd21.prod.outlook.com (2603:10b6:208:398::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5880.2; Mon, 21 Nov 2022 19:52:50 +0000 Received: from BL0PR2101MB1092.namprd21.prod.outlook.com ([fe80::ae03:5b1e:755c:a020]) by BL0PR2101MB1092.namprd21.prod.outlook.com ([fe80::ae03:5b1e:755c:a020%7]) with mapi id 15.20.5880.001; Mon, 21 Nov 2022 19:52:50 +0000 From: Dexuan Cui <decui@microsoft.com> To: ak@linux.intel.com, arnd@arndb.de, bp@alien8.de, brijesh.singh@amd.com, dan.j.williams@intel.com, dave.hansen@linux.intel.com, haiyangz@microsoft.com, hpa@zytor.com, jane.chu@oracle.com, kirill.shutemov@linux.intel.com, kys@microsoft.com, linux-arch@vger.kernel.org, linux-hyperv@vger.kernel.org, luto@kernel.org, mingo@redhat.com, peterz@infradead.org, rostedt@goodmis.org, sathyanarayanan.kuppuswamy@linux.intel.com, seanjc@google.com, tglx@linutronix.de, tony.luck@intel.com, wei.liu@kernel.org, x86@kernel.org Cc: linux-kernel@vger.kernel.org, Dexuan Cui <decui@microsoft.com> Subject: [PATCH 1/6] x86/tdx: Support hypercalls for TDX guests on Hyper-V Date: Mon, 21 Nov 2022 11:51:46 -0800 Message-Id: <20221121195151.21812-2-decui@microsoft.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221121195151.21812-1-decui@microsoft.com> References: <20221121195151.21812-1-decui@microsoft.com> Content-Type: text/plain X-ClientProxiedBy: BY3PR03CA0027.namprd03.prod.outlook.com (2603:10b6:a03:39a::32) To BL0PR2101MB1092.namprd21.prod.outlook.com (2603:10b6:207:30::23) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL0PR2101MB1092:EE_|BL1PR21MB3280:EE_ X-MS-Office365-Filtering-Correlation-Id: f5ec224f-0622-4ad8-4be5-08dacbf9f88b X-LD-Processed: 72f988bf-86f1-41af-91ab-2d7cd011db47,ExtAddr X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: UE4lUQCW+7X/AnYNMvIgeQLHLzJs3fEMg1avC14vyGDfE1ioGF01VaF6y5e/LDdNcsx8xBZbLD0ALyUJAMwL8P0jdFw3VueCgEgGKStK4ss90WAyShZ6MChy3VsNw1X9wVKSy8dIx+jwNVqgeKezWm2QhBiHLBpVbdSxV7Yy7ZdD9N0kG4VUVKxy8zU49AXY1Kubi6d9TMQQN4zIWNXNBps4/Bv4wYIiVP5pvvIXdfok4H7Ie4IDYbJSKGGTIgIChbZkVqhNymp79/otuHa9msYe7CZomPc4uy5vGgTwyxQQyR16K3sSD7mNEfkSLQM71WDqnOQlfsHIzpOjSfIiM1ciqybA0CiwfTozNSTc1AFNoCUjuKpsglq9LbjOHxfGyp2wDhNBHycOEa67CTJb5G9myKNNMzejCR6vZ5S4qaOpuUQHnsVVFEuGbbPrhBf8fjb1QTAwi5l9q/WAraejhP/1naabz2XzsJxSWi71DoJXWYDAphp+EigJKuxy7o6+1goC3pc5ajjrYvxOczUt8XdSYplbShGIAXMabk1z0GKv7jx4T1V1O9nfxIEmmxKE3LSNAe8OLAPDlOiQQKST7TRCpPX2U2yRkUo6iyawuuZQtfBClzJNK0KCJ9gF81ZRIrV1rp46Zh9RSX9G74dliQLBAWThQzqNgZGfkWmL3pL9LitRfr9ZX+V7KfYdgwZRl9x9AKJhtwECpMdtSH3dERcOc8uilsrQcxYPrsNL4dU= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BL0PR2101MB1092.namprd21.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230022)(4636009)(346002)(366004)(396003)(136003)(376002)(39860400002)(451199015)(83380400001)(2906002)(7416002)(5660300002)(8936002)(2616005)(186003)(1076003)(36756003)(86362001)(41300700001)(82950400001)(38100700002)(921005)(82960400001)(6666004)(10290500003)(107886003)(6506007)(52116002)(6512007)(316002)(478600001)(66556008)(8676002)(66946007)(66476007)(6486002)(4326008);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: GXS3KDBBxm5RrpxH2mBzI09aEVDEUVEW0AYLlLxkwpUI2SEijYGQDvEVORUPbTxf4fFOsyqZI1IYDSTM7PjkWl7NQgGBhfoSp8DLTnW4RtIiqSZvtA5emrVtXvnrilwDWc6x3LoBr/p4A1PPb7rm4OhhBpOYpxHBWVycwQNIVFNy7amNN/TmzMm2ss8fmmVYyh+2XIKSd7yULJ3w8AfELmqG335CEPCqBE81vsGlieRwpxzhZv/PET5tMZ6fa2M0d3cPld0sdbAwq0weNyoJrMMGeuq0nbe+x5QU5beTBQqvAkdUKcI64Krk42pvL1BqgmfWuXK14yi53bOnx6wLPjEo0zO7MRxOdVt1RQKzzMnd9Vw0Qyum1gqn8bqAPkYmukR1LWsRPiNVI/zE60SOkNdwf5ZDhWL+f/4N6Lr9J9FVd06EoUbrWTEb2dUMlcJm1aBfhSIgYwMOIjQFxYd0f05544IOjAxo327D++ySCtcX9+Za0td1/DYc8FHr+DpQovUiqSHxdxewAKINPcX9bvmxwut63kBrIPCnNESeoJe+GEhyiE8+tOkk4kB8b/s5mAVy1oA1OTBqDsrilvv1DAp6UGO0b4lGzSFZOLtmzCGbsFlYhIH1xzn7TbVE3jR6JpoPXndIxIotVWZpr/qbDG2o8zfOsBzsdAKu45HrXLls10r5m7uUfd8Am87lC2sfUSW9MHCgaLjQ9p4YKDaU0/d4+5oZWqaejocJgS9mh321ylTb7zgiOTC+6MF/U8oPlTjxmdLyPoW7cFEvFM133YFndFN76BuXi5yD8ONC3Jqf5HQ7uwG4URrK9CzGe8v6TpH3YEULt9EGfCRcYiyUaovkm+8gXJIGQdd9BVjorerxhnf0Oh7w+192zWYYhbO8Fyn7bqvHbzaGP6qauacxLV1l3g80g14VNyhaV8EsTXr8usxL83EFHiDA2LxnMfg3z/xzQRzRJMsVcZqV/ohNoAjO/vldagrZoMNIS6JkKpkE3dTEGyHYMiRu4lFcoU2DDr5F/DPnMVI7z0z5Yzp/yLceFvJUjH3avbYRRmZz/60ieAwX8eSgSIN1hgLRuQgEyezp8vucOZHb2xQw5olsZpJVwuUcj2s1aQzBKiTeMMsCYhvErrrfBzC9bb4P1Z3z9fKMbDhjpu4iqok7BuV7kjhrkkXqqhR0fwomHYfYLQbDjeKmagt87N5VzSF183Tdq57/Cxcj0UMhjRcbJVUKU1axpF1tV5Rh0r5mnUjb6rYWNPVDA+tE2vkfrzaCyTKJeLimNADiS/USWn2oqajsDhamFz7hkAxFtEpxzbI6BfTVzhtfe4v324sLhkVFK7oA1nxEGqJStSuV27I1d+LIFYx9NgyZDv/aMFN8gqnZHIEAtlHagcJlJOmwiYbzE61TM4lhMngXSg1io+IGUxVEgEeQh9zyrXutwV2txvdylTl9gZX/zS61Zo0tttKBQb6N/26bo0O6tWG0BvXKntfa2BXvALyUwWSp/NkWf9aXtexjJiI3PVN7jFmGccUXwXngQYzukBuglJDlrW5KvHGJ4kRrYXQ9isRjB3prTxcZDIkvqbDugTwpCYhQOhkuRg8Xylk3KcMj7ORHFHaaUa3wX8Q1B+YmuOwyYtaZDgEhnDVI5yJ7LAy9grcJMz5DRHl9 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-Network-Message-Id: f5ec224f-0622-4ad8-4be5-08dacbf9f88b X-MS-Exchange-CrossTenant-AuthSource: BL0PR2101MB1092.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Nov 2022 19:52:50.4926 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: QSBjbq8M1+6wqoVG1zFvUIz6hTXhNnH6dKwoPd72A+7S32dqhdGSsIv7sR6+jD+vzvrYi09pTXkJd5tPNsU58g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL1PR21MB3280 X-Spam-Status: No, score=-1.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FORGED_SPF_HELO, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_NONE 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: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1750136712978543143?= X-GMAIL-MSGID: =?utf-8?q?1750136712978543143?= |
Series |
Support TDX guests on Hyper-V
|
|
Commit Message
Dexuan Cui
Nov. 21, 2022, 7:51 p.m. UTC
__tdx_hypercall() doesn't work for a TDX guest running on Hyper-V,
because Hyper-V uses a different calling convention, so add the
new function __tdx_ms_hv_hypercall().
Signed-off-by: Dexuan Cui <decui@microsoft.com>
---
arch/x86/coco/tdx/tdcall.S | 87 +++++++++++++++++++++++++++++++++
arch/x86/include/asm/mshyperv.h | 2 +
2 files changed, 89 insertions(+)
Comments
On 11/21/22 11:51, Dexuan Cui wrote: > __tdx_hypercall() doesn't work for a TDX guest running on Hyper-V, > because Hyper-V uses a different calling convention, so add the > new function __tdx_ms_hv_hypercall(). Other than R10 being variable here and fixed for __tdx_hypercall(), this looks *EXACTLY* the same as __tdx_hypercall(), or at least a strict subset of what __tdx_hypercall() can do. Did I miss something? Another way of saying this: It seems like you could do this with a new version of _tdx_hypercall() (and all in C) instead of a new __tdx_hypercall().
On Mon, Nov 21, 2022 at 12:38:36PM -0800, Dave Hansen wrote: > On 11/21/22 11:51, Dexuan Cui wrote: > > __tdx_hypercall() doesn't work for a TDX guest running on Hyper-V, > > because Hyper-V uses a different calling convention, so add the > > new function __tdx_ms_hv_hypercall(). > > Other than R10 being variable here and fixed for __tdx_hypercall(), this > looks *EXACTLY* the same as __tdx_hypercall(), or at least a strict > subset of what __tdx_hypercall() can do. > > Did I miss something? > > Another way of saying this: It seems like you could do this with a new > version of _tdx_hypercall() (and all in C) instead of a new > __tdx_hypercall(). +1. There should be a strong reason to add another asm helper.
> From: Dave Hansen <dave.hansen@intel.com> > Sent: Monday, November 21, 2022 12:39 PM > [...] > On 11/21/22 11:51, Dexuan Cui wrote: > > __tdx_hypercall() doesn't work for a TDX guest running on Hyper-V, > > because Hyper-V uses a different calling convention, so add the > > new function __tdx_ms_hv_hypercall(). > > Other than R10 being variable here and fixed for __tdx_hypercall(), this > looks *EXACTLY* the same as __tdx_hypercall(), or at least a strict > subset of what __tdx_hypercall() can do. > > Did I miss something? The existing asm code for __tdx_hypercall() passes through R10~R15 (see TDVMCALL_EXPOSE_REGS_MASK) to the (KVM) hypervisor. Unluckily, for Hyper-V, we need to pass through RDX, R8, R10 and R11 to Hyper-V, so I don't think I can use the existing __tdx_hypercall() ? > Another way of saying this: It seems like you could do this with a new > version of _tdx_hypercall() (and all in C) instead of a new > __tdx_hypercall(). I don't think the current TDVMCALL_EXPOSE_REGS_MASK allows me to pass through RDX and R8 to Hyper-V. PS, the comment before __tdx_hypercall() contains this line: "* RBX, RBP, RDI, RSI - Used to pass VMCALL sub function specific arguments." But it looks like currently RBX an RBP are not used at all in arch/x86/coco/tdx/tdcall.S ?
> From: Dexuan Cui > [...] > The existing asm code for __tdx_hypercall() passes through R10~R15 > (see TDVMCALL_EXPOSE_REGS_MASK) to the (KVM) hypervisor. > > Unluckily, for Hyper-V, we need to pass through RDX, R8, R10 and R11 > to Hyper-V, so I don't think I can use the existing __tdx_hypercall() ? I'm checking with the Hyper-V team to see if it's possible for them to not use RDX and R8, and use R12 and R13 instead. Will keep the thread updated.
On 11/22/22 5:37 PM, Dexuan Cui wrote: >> From: Dave Hansen <dave.hansen@intel.com> >> Sent: Monday, November 21, 2022 12:39 PM >> [...] >> On 11/21/22 11:51, Dexuan Cui wrote: >>> __tdx_hypercall() doesn't work for a TDX guest running on Hyper-V, >>> because Hyper-V uses a different calling convention, so add the >>> new function __tdx_ms_hv_hypercall(). >> >> Other than R10 being variable here and fixed for __tdx_hypercall(), this >> looks *EXACTLY* the same as __tdx_hypercall(), or at least a strict >> subset of what __tdx_hypercall() can do. >> >> Did I miss something? > > The existing asm code for __tdx_hypercall() passes through R10~R15 > (see TDVMCALL_EXPOSE_REGS_MASK) to the (KVM) hypervisor. > > Unluckily, for Hyper-V, we need to pass through RDX, R8, R10 and R11 > to Hyper-V, so I don't think I can use the existing __tdx_hypercall() ? > >> Another way of saying this: It seems like you could do this with a new >> version of _tdx_hypercall() (and all in C) instead of a new >> __tdx_hypercall(). > > I don't think the current TDVMCALL_EXPOSE_REGS_MASK allows me > to pass through RDX and R8 to Hyper-V. Because TDVMCALLs defined in the GHCI specification only use registers R10-R15, only those registers are currently exposed. However, the TDVMCALL ABI allows the use of input registers such as RBX, RBP, RDI, RSI, R8 or R9. Instead of creating a new variant of __tdx_hypercall() to handle your use case, perhaps you can add the registers you require to the TDVMCALL EXPOSE REGS MASK. You just need to make sure they are zeroed out for other users of __tdx_hypercall(). > > PS, the comment before __tdx_hypercall() contains this line: > > "* RBX, RBP, RDI, RSI - Used to pass VMCALL sub function specific > arguments." > > But it looks like currently RBX an RBP are not used at all in > arch/x86/coco/tdx/tdcall.S ? >
On Wed, Nov 23, 2022 at 01:37:26AM +0000, Dexuan Cui wrote: > > From: Dave Hansen <dave.hansen@intel.com> > > Sent: Monday, November 21, 2022 12:39 PM > > [...] > > On 11/21/22 11:51, Dexuan Cui wrote: > > > __tdx_hypercall() doesn't work for a TDX guest running on Hyper-V, > > > because Hyper-V uses a different calling convention, so add the > > > new function __tdx_ms_hv_hypercall(). > > > > Other than R10 being variable here and fixed for __tdx_hypercall(), this > > looks *EXACTLY* the same as __tdx_hypercall(), or at least a strict > > subset of what __tdx_hypercall() can do. > > > > Did I miss something? > > The existing asm code for __tdx_hypercall() passes through R10~R15 > (see TDVMCALL_EXPOSE_REGS_MASK) to the (KVM) hypervisor. > > Unluckily, for Hyper-V, we need to pass through RDX, R8, R10 and R11 > to Hyper-V, so I don't think I can use the existing __tdx_hypercall() ? > > > Another way of saying this: It seems like you could do this with a new > > version of _tdx_hypercall() (and all in C) instead of a new > > __tdx_hypercall(). > > I don't think the current TDVMCALL_EXPOSE_REGS_MASK allows me > to pass through RDX and R8 to Hyper-V. > > PS, the comment before __tdx_hypercall() contains this line: > > "* RBX, RBP, RDI, RSI - Used to pass VMCALL sub function specific > arguments." > > But it looks like currently RBX an RBP are not used at all in > arch/x86/coco/tdx/tdcall.S ? I have plan to expand __tdx_hypercall() to cover more registers. See the patch below. Is it enough for you? --- arch/x86/coco/tdx/tdcall.S | 82 ++++++++++++++++++++++--------- arch/x86/include/asm/shared/tdx.h | 6 +++ arch/x86/kernel/asm-offsets.c | 6 +++ 3 files changed, 70 insertions(+), 24 deletions(-) diff --git a/arch/x86/coco/tdx/tdcall.S b/arch/x86/coco/tdx/tdcall.S index f9eb1134f22d..64e57739dc9d 100644 --- a/arch/x86/coco/tdx/tdcall.S +++ b/arch/x86/coco/tdx/tdcall.S @@ -13,6 +13,12 @@ /* * Bitmasks of exposed registers (with VMM). */ +#define TDX_RDX BIT(2) +#define TDX_RBX BIT(3) +#define TDX_RSI BIT(6) +#define TDX_RDI BIT(7) +#define TDX_R8 BIT(8) +#define TDX_R9 BIT(9) #define TDX_R10 BIT(10) #define TDX_R11 BIT(11) #define TDX_R12 BIT(12) @@ -27,9 +33,9 @@ * details can be found in TDX GHCI specification, section * titled "TDCALL [TDG.VP.VMCALL] leaf". */ -#define TDVMCALL_EXPOSE_REGS_MASK ( TDX_R10 | TDX_R11 | \ - TDX_R12 | TDX_R13 | \ - TDX_R14 | TDX_R15 ) +#define TDVMCALL_EXPOSE_REGS_MASK \ + ( TDX_RDX | TDX_RBX | TDX_RSI | TDX_RDI | TDX_R8 | TDX_R9 | \ + TDX_R10 | TDX_R11 | TDX_R12 | TDX_R13 | TDX_R14 | TDX_R15 ) /* * __tdx_module_call() - Used by TDX guests to request services from @@ -124,19 +130,32 @@ SYM_FUNC_START(__tdx_hypercall) push %r14 push %r13 push %r12 + push %rbx + push %rbp + + movq %rdi, %rax + movq %rsi, %rbp + + /* Copy hypercall registers from arg struct: */ + movq TDX_HYPERCALL_r8(%rax), %r8 + movq TDX_HYPERCALL_r9(%rax), %r9 + movq TDX_HYPERCALL_r10(%rax), %r10 + movq TDX_HYPERCALL_r11(%rax), %r11 + movq TDX_HYPERCALL_r12(%rax), %r12 + movq TDX_HYPERCALL_r13(%rax), %r13 + movq TDX_HYPERCALL_r14(%rax), %r14 + movq TDX_HYPERCALL_r15(%rax), %r15 + movq TDX_HYPERCALL_rdi(%rax), %rdi + movq TDX_HYPERCALL_rsi(%rax), %rsi + movq TDX_HYPERCALL_rbx(%rax), %rbx + movq TDX_HYPERCALL_rdx(%rax), %rdx + + push %rax /* Mangle function call ABI into TDCALL ABI: */ /* Set TDCALL leaf ID (TDVMCALL (0)) in RAX */ xor %eax, %eax - /* Copy hypercall registers from arg struct: */ - movq TDX_HYPERCALL_r10(%rdi), %r10 - movq TDX_HYPERCALL_r11(%rdi), %r11 - movq TDX_HYPERCALL_r12(%rdi), %r12 - movq TDX_HYPERCALL_r13(%rdi), %r13 - movq TDX_HYPERCALL_r14(%rdi), %r14 - movq TDX_HYPERCALL_r15(%rdi), %r15 - movl $TDVMCALL_EXPOSE_REGS_MASK, %ecx /* @@ -148,14 +167,14 @@ SYM_FUNC_START(__tdx_hypercall) * HLT operation indefinitely. Since this is the not the desired * result, conditionally call STI before TDCALL. */ - testq $TDX_HCALL_ISSUE_STI, %rsi + testq $TDX_HCALL_ISSUE_STI, %rbp jz .Lskip_sti sti .Lskip_sti: tdcall /* - * RAX==0 indicates a failure of the TDVMCALL mechanism itself and that + * RAX!=0 indicates a failure of the TDVMCALL mechanism itself and that * something has gone horribly wrong with the TDX module. * * The return status of the hypercall operation is in a separate @@ -165,30 +184,45 @@ SYM_FUNC_START(__tdx_hypercall) testq %rax, %rax jne .Lpanic - /* TDVMCALL leaf return code is in R10 */ - movq %r10, %rax + pop %rax /* Copy hypercall result registers to arg struct if needed */ - testq $TDX_HCALL_HAS_OUTPUT, %rsi + testq $TDX_HCALL_HAS_OUTPUT, %rbp jz .Lout - movq %r10, TDX_HYPERCALL_r10(%rdi) - movq %r11, TDX_HYPERCALL_r11(%rdi) - movq %r12, TDX_HYPERCALL_r12(%rdi) - movq %r13, TDX_HYPERCALL_r13(%rdi) - movq %r14, TDX_HYPERCALL_r14(%rdi) - movq %r15, TDX_HYPERCALL_r15(%rdi) + movq %r8, TDX_HYPERCALL_r8(%rax) + movq %r9, TDX_HYPERCALL_r9(%rax) + movq %r10, TDX_HYPERCALL_r10(%rax) + movq %r11, TDX_HYPERCALL_r11(%rax) + movq %r12, TDX_HYPERCALL_r12(%rax) + movq %r13, TDX_HYPERCALL_r13(%rax) + movq %r14, TDX_HYPERCALL_r14(%rax) + movq %r15, TDX_HYPERCALL_r15(%rax) + movq %rdi, TDX_HYPERCALL_rdi(%rax) + movq %rsi, TDX_HYPERCALL_rsi(%rax) + movq %rbx, TDX_HYPERCALL_rbx(%rax) + movq %rdx, TDX_HYPERCALL_rdx(%rax) .Lout: + /* TDVMCALL leaf return code is in R10 */ + movq %r10, %rax + /* * Zero out registers exposed to the VMM to avoid speculative execution * with VMM-controlled values. This needs to include all registers - * present in TDVMCALL_EXPOSE_REGS_MASK (except R12-R15). R12-R15 - * context will be restored. + * present in TDVMCALL_EXPOSE_REGS_MASK, except RBX, and R12-R15 which + * will be restored. */ + xor %r8d, %r8d + xor %r9d, %r9d xor %r10d, %r10d xor %r11d, %r11d + xor %rdi, %rdi + xor %rsi, %rsi + xor %rdx, %rdx /* Restore callee-saved GPRs as mandated by the x86_64 ABI */ + pop %rbp + pop %rbx pop %r12 pop %r13 pop %r14 diff --git a/arch/x86/include/asm/shared/tdx.h b/arch/x86/include/asm/shared/tdx.h index e53f26228fbb..8068faa52de1 100644 --- a/arch/x86/include/asm/shared/tdx.h +++ b/arch/x86/include/asm/shared/tdx.h @@ -22,12 +22,18 @@ * This is a software only structure and not part of the TDX module/VMM ABI. */ struct tdx_hypercall_args { + u64 r8; + u64 r9; u64 r10; u64 r11; u64 r12; u64 r13; u64 r14; u64 r15; + u64 rdi; + u64 rsi; + u64 rbx; + u64 rdx; }; /* Used to request services from the VMM */ diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c index 437308004ef2..cf819c5ed2de 100644 --- a/arch/x86/kernel/asm-offsets.c +++ b/arch/x86/kernel/asm-offsets.c @@ -81,6 +81,12 @@ static void __used common(void) OFFSET(TDX_HYPERCALL_r13, tdx_hypercall_args, r13); OFFSET(TDX_HYPERCALL_r14, tdx_hypercall_args, r14); OFFSET(TDX_HYPERCALL_r15, tdx_hypercall_args, r15); + OFFSET(TDX_HYPERCALL_rbx, tdx_hypercall_args, rbx); + OFFSET(TDX_HYPERCALL_rdi, tdx_hypercall_args, rdi); + OFFSET(TDX_HYPERCALL_rsi, tdx_hypercall_args, rsi); + OFFSET(TDX_HYPERCALL_r8, tdx_hypercall_args, r8); + OFFSET(TDX_HYPERCALL_r9, tdx_hypercall_args, r9); + OFFSET(TDX_HYPERCALL_rdx, tdx_hypercall_args, rdx); BLANK(); OFFSET(BP_scratch, boot_params, scratch);
On 11/22/22 17:37, Dexuan Cui wrote: >> From: Dave Hansen <dave.hansen@intel.com> >> Sent: Monday, November 21, 2022 12:39 PM >> [...] >> On 11/21/22 11:51, Dexuan Cui wrote: >>> __tdx_hypercall() doesn't work for a TDX guest running on Hyper-V, >>> because Hyper-V uses a different calling convention, so add the >>> new function __tdx_ms_hv_hypercall(). >> >> Other than R10 being variable here and fixed for __tdx_hypercall(), this >> looks *EXACTLY* the same as __tdx_hypercall(), or at least a strict >> subset of what __tdx_hypercall() can do. >> >> Did I miss something? > > The existing asm code for __tdx_hypercall() passes through R10~R15 > (see TDVMCALL_EXPOSE_REGS_MASK) to the (KVM) hypervisor. > > Unluckily, for Hyper-V, we need to pass through RDX, R8, R10 and R11 > to Hyper-V, so I don't think I can use the existing __tdx_hypercall() ? What's to prevent you from adding RDX and R8? You could make TDVMCALL_EXPOSE_REGS_MASK a macro argument. Look at 'has_erro_code', for instance in "idtentry_body" arch/x86/entry/entry_64.S. >> Another way of saying this: It seems like you could do this with a new >> version of _tdx_hypercall() (and all in C) instead of a new >> __tdx_hypercall(). > > I don't think the current TDVMCALL_EXPOSE_REGS_MASK allows me > to pass through RDX and R8 to Hyper-V. Right. So pass it in. > PS, the comment before __tdx_hypercall() contains this line: > > "* RBX, RBP, RDI, RSI - Used to pass VMCALL sub function specific > arguments." > > But it looks like currently RBX an RBP are not used at all in > arch/x86/coco/tdx/tdcall.S ? Yeah, it looks like they are a part of the hypercall ABI but no existing hypercall is using them. Patches to fix it accepted. :)
On 11/22/22 17:56, Dexuan Cui wrote: >> From: Dexuan Cui >> [...] >> The existing asm code for __tdx_hypercall() passes through R10~R15 >> (see TDVMCALL_EXPOSE_REGS_MASK) to the (KVM) hypervisor. >> >> Unluckily, for Hyper-V, we need to pass through RDX, R8, R10 and R11 >> to Hyper-V, so I don't think I can use the existing __tdx_hypercall() ? > I'm checking with the Hyper-V team to see if it's possible for them > to not use RDX and R8, and use R12 and R13 instead. Will keep the > thread updated. That would be nice. But, to be honest, I don't expect them to change the ABI for one OS. It's not a big deal to just make the function a bit more flexible.
> From: Kirill A. Shutemov <kirill@shutemov.name> > Sent: Wednesday, November 23, 2022 6:41 AM > [...] > I have plan to expand __tdx_hypercall() to cover more registers. > See the patch below. Great! Thank you! > Is it enough for you? Yes.
> From: Dave Hansen <dave.hansen@intel.com> > Sent: Wednesday, November 23, 2022 8:05 AM > On 11/22/22 17:56, Dexuan Cui wrote: > >> From: Dexuan Cui > >> [...] > >> The existing asm code for __tdx_hypercall() passes through R10~R15 > >> (see TDVMCALL_EXPOSE_REGS_MASK) to the (KVM) hypervisor. > >> > >> Unluckily, for Hyper-V, we need to pass through RDX, R8, R10 and R11 > >> to Hyper-V, so I don't think I can use the existing __tdx_hypercall() ? > > I'm checking with the Hyper-V team to see if it's possible for them > > to not use RDX and R8, and use R12 and R13 instead. Will keep the > > thread updated. > > That would be nice. But, to be honest, I don't expect them to change > the ABI for one OS. It's not a big deal to just make the function a bit > more flexible. Then I'll implement a C function using __tdx_hypercall() that will be expaneed by Kirill. Thank you all for the suggestions!
> From: Dexuan Cui > Sent: Wednesday, November 23, 2022 10:55 AM > To: Kirill A. Shutemov <kirill@shutemov.name> > > > From: Kirill A. Shutemov <kirill@shutemov.name> > > Sent: Wednesday, November 23, 2022 6:41 AM > > [...] > > I have plan to expand __tdx_hypercall() to cover more registers. > > See the patch below. > > Great! Thank you! > > > Is it enough for you? > Yes. Hi Kirill, it would be great if you could post a formal patch so that I can rebase my patchset accordingly.
On Wed, Nov 30, 2022 at 07:14:49PM +0000, Dexuan Cui wrote: > > From: Dexuan Cui > > Sent: Wednesday, November 23, 2022 10:55 AM > > To: Kirill A. Shutemov <kirill@shutemov.name> > > > > > From: Kirill A. Shutemov <kirill@shutemov.name> > > > Sent: Wednesday, November 23, 2022 6:41 AM > > > [...] > > > I have plan to expand __tdx_hypercall() to cover more registers. > > > See the patch below. > > > > Great! Thank you! > > > > > Is it enough for you? > > Yes. > > Hi Kirill, it would be great if you could post a formal patch so that > I can rebase my patchset accordingly. The patch doesn't make sense without a user. The use-case I wanted to use it for awaits update of GHCI. It make take time. Below is proper patch. Feel free to include it into your patchset. From fdf892e8f84c98e4cb7f3f7a613f32c8da396bd7 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> Date: Wed, 23 Nov 2022 07:31:05 +0300 Subject: [PATCH] x86/tdx: Expand __tdx_hypercall() to handle more arguments So far __tdx_hypercall() only handles six arguments for VMCALL. Expanding it to six more register would allow to cover more use-cases. Using RDI and RSI as VMCALL arguments requires more register shuffling. RAX is used to hold tdx_hypercall_args pointer and RBP stores flags. While there, fix typo in the comment on panic branch. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> --- arch/x86/coco/tdx/tdcall.S | 82 ++++++++++++++++++++++--------- arch/x86/include/asm/shared/tdx.h | 6 +++ arch/x86/kernel/asm-offsets.c | 6 +++ 3 files changed, 70 insertions(+), 24 deletions(-) diff --git a/arch/x86/coco/tdx/tdcall.S b/arch/x86/coco/tdx/tdcall.S index f9eb1134f22d..64e57739dc9d 100644 --- a/arch/x86/coco/tdx/tdcall.S +++ b/arch/x86/coco/tdx/tdcall.S @@ -13,6 +13,12 @@ /* * Bitmasks of exposed registers (with VMM). */ +#define TDX_RDX BIT(2) +#define TDX_RBX BIT(3) +#define TDX_RSI BIT(6) +#define TDX_RDI BIT(7) +#define TDX_R8 BIT(8) +#define TDX_R9 BIT(9) #define TDX_R10 BIT(10) #define TDX_R11 BIT(11) #define TDX_R12 BIT(12) @@ -27,9 +33,9 @@ * details can be found in TDX GHCI specification, section * titled "TDCALL [TDG.VP.VMCALL] leaf". */ -#define TDVMCALL_EXPOSE_REGS_MASK ( TDX_R10 | TDX_R11 | \ - TDX_R12 | TDX_R13 | \ - TDX_R14 | TDX_R15 ) +#define TDVMCALL_EXPOSE_REGS_MASK \ + ( TDX_RDX | TDX_RBX | TDX_RSI | TDX_RDI | TDX_R8 | TDX_R9 | \ + TDX_R10 | TDX_R11 | TDX_R12 | TDX_R13 | TDX_R14 | TDX_R15 ) /* * __tdx_module_call() - Used by TDX guests to request services from @@ -124,19 +130,32 @@ SYM_FUNC_START(__tdx_hypercall) push %r14 push %r13 push %r12 + push %rbx + push %rbp + + movq %rdi, %rax + movq %rsi, %rbp + + /* Copy hypercall registers from arg struct: */ + movq TDX_HYPERCALL_r8(%rax), %r8 + movq TDX_HYPERCALL_r9(%rax), %r9 + movq TDX_HYPERCALL_r10(%rax), %r10 + movq TDX_HYPERCALL_r11(%rax), %r11 + movq TDX_HYPERCALL_r12(%rax), %r12 + movq TDX_HYPERCALL_r13(%rax), %r13 + movq TDX_HYPERCALL_r14(%rax), %r14 + movq TDX_HYPERCALL_r15(%rax), %r15 + movq TDX_HYPERCALL_rdi(%rax), %rdi + movq TDX_HYPERCALL_rsi(%rax), %rsi + movq TDX_HYPERCALL_rbx(%rax), %rbx + movq TDX_HYPERCALL_rdx(%rax), %rdx + + push %rax /* Mangle function call ABI into TDCALL ABI: */ /* Set TDCALL leaf ID (TDVMCALL (0)) in RAX */ xor %eax, %eax - /* Copy hypercall registers from arg struct: */ - movq TDX_HYPERCALL_r10(%rdi), %r10 - movq TDX_HYPERCALL_r11(%rdi), %r11 - movq TDX_HYPERCALL_r12(%rdi), %r12 - movq TDX_HYPERCALL_r13(%rdi), %r13 - movq TDX_HYPERCALL_r14(%rdi), %r14 - movq TDX_HYPERCALL_r15(%rdi), %r15 - movl $TDVMCALL_EXPOSE_REGS_MASK, %ecx /* @@ -148,14 +167,14 @@ SYM_FUNC_START(__tdx_hypercall) * HLT operation indefinitely. Since this is the not the desired * result, conditionally call STI before TDCALL. */ - testq $TDX_HCALL_ISSUE_STI, %rsi + testq $TDX_HCALL_ISSUE_STI, %rbp jz .Lskip_sti sti .Lskip_sti: tdcall /* - * RAX==0 indicates a failure of the TDVMCALL mechanism itself and that + * RAX!=0 indicates a failure of the TDVMCALL mechanism itself and that * something has gone horribly wrong with the TDX module. * * The return status of the hypercall operation is in a separate @@ -165,30 +184,45 @@ SYM_FUNC_START(__tdx_hypercall) testq %rax, %rax jne .Lpanic - /* TDVMCALL leaf return code is in R10 */ - movq %r10, %rax + pop %rax /* Copy hypercall result registers to arg struct if needed */ - testq $TDX_HCALL_HAS_OUTPUT, %rsi + testq $TDX_HCALL_HAS_OUTPUT, %rbp jz .Lout - movq %r10, TDX_HYPERCALL_r10(%rdi) - movq %r11, TDX_HYPERCALL_r11(%rdi) - movq %r12, TDX_HYPERCALL_r12(%rdi) - movq %r13, TDX_HYPERCALL_r13(%rdi) - movq %r14, TDX_HYPERCALL_r14(%rdi) - movq %r15, TDX_HYPERCALL_r15(%rdi) + movq %r8, TDX_HYPERCALL_r8(%rax) + movq %r9, TDX_HYPERCALL_r9(%rax) + movq %r10, TDX_HYPERCALL_r10(%rax) + movq %r11, TDX_HYPERCALL_r11(%rax) + movq %r12, TDX_HYPERCALL_r12(%rax) + movq %r13, TDX_HYPERCALL_r13(%rax) + movq %r14, TDX_HYPERCALL_r14(%rax) + movq %r15, TDX_HYPERCALL_r15(%rax) + movq %rdi, TDX_HYPERCALL_rdi(%rax) + movq %rsi, TDX_HYPERCALL_rsi(%rax) + movq %rbx, TDX_HYPERCALL_rbx(%rax) + movq %rdx, TDX_HYPERCALL_rdx(%rax) .Lout: + /* TDVMCALL leaf return code is in R10 */ + movq %r10, %rax + /* * Zero out registers exposed to the VMM to avoid speculative execution * with VMM-controlled values. This needs to include all registers - * present in TDVMCALL_EXPOSE_REGS_MASK (except R12-R15). R12-R15 - * context will be restored. + * present in TDVMCALL_EXPOSE_REGS_MASK, except RBX, and R12-R15 which + * will be restored. */ + xor %r8d, %r8d + xor %r9d, %r9d xor %r10d, %r10d xor %r11d, %r11d + xor %rdi, %rdi + xor %rsi, %rsi + xor %rdx, %rdx /* Restore callee-saved GPRs as mandated by the x86_64 ABI */ + pop %rbp + pop %rbx pop %r12 pop %r13 pop %r14 diff --git a/arch/x86/include/asm/shared/tdx.h b/arch/x86/include/asm/shared/tdx.h index e53f26228fbb..8068faa52de1 100644 --- a/arch/x86/include/asm/shared/tdx.h +++ b/arch/x86/include/asm/shared/tdx.h @@ -22,12 +22,18 @@ * This is a software only structure and not part of the TDX module/VMM ABI. */ struct tdx_hypercall_args { + u64 r8; + u64 r9; u64 r10; u64 r11; u64 r12; u64 r13; u64 r14; u64 r15; + u64 rdi; + u64 rsi; + u64 rbx; + u64 rdx; }; /* Used to request services from the VMM */ diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c index 437308004ef2..9f09947495e2 100644 --- a/arch/x86/kernel/asm-offsets.c +++ b/arch/x86/kernel/asm-offsets.c @@ -75,12 +75,18 @@ static void __used common(void) OFFSET(TDX_MODULE_r11, tdx_module_output, r11); BLANK(); + OFFSET(TDX_HYPERCALL_r8, tdx_hypercall_args, r8); + OFFSET(TDX_HYPERCALL_r9, tdx_hypercall_args, r9); OFFSET(TDX_HYPERCALL_r10, tdx_hypercall_args, r10); OFFSET(TDX_HYPERCALL_r11, tdx_hypercall_args, r11); OFFSET(TDX_HYPERCALL_r12, tdx_hypercall_args, r12); OFFSET(TDX_HYPERCALL_r13, tdx_hypercall_args, r13); OFFSET(TDX_HYPERCALL_r14, tdx_hypercall_args, r14); OFFSET(TDX_HYPERCALL_r15, tdx_hypercall_args, r15); + OFFSET(TDX_HYPERCALL_rdi, tdx_hypercall_args, rdi); + OFFSET(TDX_HYPERCALL_rsi, tdx_hypercall_args, rsi); + OFFSET(TDX_HYPERCALL_rbx, tdx_hypercall_args, rbx); + OFFSET(TDX_HYPERCALL_rdx, tdx_hypercall_args, rdx); BLANK(); OFFSET(BP_scratch, boot_params, scratch);
diff --git a/arch/x86/coco/tdx/tdcall.S b/arch/x86/coco/tdx/tdcall.S index f9eb1134f22d..468b71738485 100644 --- a/arch/x86/coco/tdx/tdcall.S +++ b/arch/x86/coco/tdx/tdcall.S @@ -13,6 +13,8 @@ /* * Bitmasks of exposed registers (with VMM). */ +#define TDX_RDX BIT(2) +#define TDX_R8 BIT(8) #define TDX_R10 BIT(10) #define TDX_R11 BIT(11) #define TDX_R12 BIT(12) @@ -203,3 +205,88 @@ SYM_FUNC_START(__tdx_hypercall) REACHABLE jmp .Lpanic SYM_FUNC_END(__tdx_hypercall) + +/* + * __tdx_ms_hv_hypercall() - Make hypercalls to Hype-V using TDVMCALL leaf + * of TDCALL instruction + * + * Transforms values in function call arguments "input control, output_addr, + * and input_addr" into the TDCALL register ABI. After TDCALL operation, + * Hyper-V has changed the memory pointed by output_addr, and R11 is the + * output control code. Note: before the TDCALL operation, the guest must + * share the memory pointed by input_addr and output_addr with Hyper-V. + *------------------------------------------------------------------------- + * TD VMCALL ABI on Hyper-V: + *------------------------------------------------------------------------- + * + * Input Registers: + * + * RAX - TDCALL instruction leaf number (0 - TDG.VP.VMCALL) + * RCX - BITMAP which controls which part of TD Guest GPR + * is passed as-is to the VMM and back. + * R10 - Set to Hyper-V hypercall input control code. + * Note: legal Hyper-V hypercall input control codes + * are always non-zero, i.e. they don't conflict with + * TDX_HYPERCALL_STANDARD. + * R8 - Output physical addr. + * RDX - Input physical addr. + * + * Output Registers: + * + * RAX - TDCALL instruction status (Not related to hypercall + * output). + * R11 - Output control code. + * + *------------------------------------------------------------------------- + * + * __tdx_ms_hv_hypercall() function ABI: + * + * @arg (RDI) - Input control code, moved to R10 + * @arg (RSI) - Output address, moved to R8 + * @arg (RDX) - Input address. RDX is passed to Hyper-V as-is. + * + * On successful completion, return the hypercall output control code. + */ +SYM_FUNC_START(__tdx_ms_hv_hypercall) + FRAME_BEGIN + + /* Set TDCALL leaf ID (TDVMCALL (0)) in RAX */ + xor %eax, %eax + + /* Do not leak the value of the output-only register to Hyper-V */ + xor %r11, %r11 + + /* Load input control code */ + mov %rdi, %r10 + + /* Load output addr. NB: input addr is already in RDX. */ + mov %rsi, %r8 + + /* Expose these registers to Hyper-V as-is */ + mov $(TDX_RDX | TDX_R8 | TDX_R10 |TDX_R11), %ecx + + tdcall + + /* + * RAX==0 indicates a failure of the TDVMCALL mechanism itself and that + * something has gone horribly wrong with the TDX module. + * + * The return status of the hypercall operation is in a separate + * register (in R11). Hypercall errors are a part of normal operation + * and are handled by callers. + */ + testq %rax, %rax + jne .Lpanic_ms_hv + + /* Copy output control code as the function's return value */ + movq %r11, %rax + + FRAME_END + + RET +.Lpanic_ms_hv: + call __tdx_hypercall_failed + /* __tdx_hypercall_failed never returns */ + REACHABLE + jmp .Lpanic_ms_hv +SYM_FUNC_END(__tdx_ms_hv_hypercall) diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index 61f0c206bff0..fc09b6739922 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -36,6 +36,8 @@ int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages); int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id); int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags); +u64 __tdx_ms_hv_hypercall(u64 control, u64 output_addr, u64 input_addr); + static inline u64 hv_do_hypercall(u64 control, void *input, void *output) { u64 input_address = input ? virt_to_phys(input) : 0;