From nobody Thu Dec 18 00:49:48 2025 Received: from NAM02-BN1-obe.outbound.protection.outlook.com (mail-bn1nam02on2073.outbound.protection.outlook.com [40.107.212.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E2CBF158A3B; Fri, 21 Jun 2024 12:39:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.212.73 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718973587; cv=fail; b=E00HVpFuEkUAbCeRy8n+Rni0yo72RIr4awS5evIsYNrSL/rUFRXb/64TJ2kT6gevlRxSYabARXJXSTJr9TBNMhPk95Td04goi82aSBLW1QGoPbPMvNgAMOGQOYXCDJz3/nZheyuHYA7d0opOB6dPYBIHqXoA8wOoZETZHS5Rr6o= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718973587; c=relaxed/simple; bh=nhopwv1xqw5OSYYxMfzNW4L3eNvdtMNLHjEi6LvRMlg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=XZYEDKTIr2iCGIN4fMuYWsWPh3YzXdwgwCfcO+Fma6Ldl/1qguUX013jfdpb+JtMpT+5xnbSzTtTtszFeK0kl1r0je/O4pZNYwL+iSM2kEoGRy8eJtzIRwjXiAR3Tz5KDkmQKaFckEyjLNURgw7Gm92HrqAjFlRhaoIB40UbDgg= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=f1xA5+u1; arc=fail smtp.client-ip=40.107.212.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="f1xA5+u1" ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=h1dC+vFstS8R2UWH9SXn1tEWwp0lEMg+y9O7ZRCtPgmS//I5V7eaEe/0tRVy1mg0PUygjixos3YoRtluPRRdgMhsOkBD18kTSPEgkK+Wn6NmODmpANsSzxr5FP0yeZw9I/KGElZIzqKOjadvSTNWx+JqLMsk9tEKAjbKvJs0Zow7hp9trcAYThLDazHWW1GWiRC1O9PcrnboZ0EvCimIG0aOl5Bt2lDbq9GHxgB1qHyah47hJ86bvx/Y9GQj/874eq1C860noUpmOtyFWPvnysKZkU3QqeI6e9DdjSe7WPJCzfQxhqaV1Le/4Ge151Ib2B6QEjN/SS4Aey30abMJ5w== 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=5nRkgU9Jj+AzG5AkempMdX+VSorFE48Wltl2G7KTzTo=; b=K+LkntPulV67E1+yvaHTxw6qwQjHgsZw6xz7UqX4M7CxUhE3ktMU2boOa2q2uNymKMUlPFGztqPjhsdf+83R65bIVP78QA7sBQ0OqAV2TgjeG96hSGBeobVIeWXRWq9i2tnEP/L89gnwtKcMBmNLRzeFcKDgIBZqBIE7lFMUWyJ5a85HRStgKKNLy3oSZT6kQF+JCnB959xqU7idyDycaCIPaSFT6NrK8d2wuOKbRUs5X8WPyiu6p90IslND6Xaeknc4VwgG0LIaGglgVhS5pk8J7IBQiRHhcX8psuKiw7UHOT/P+ylhcXUfy49ZABFb9p1H4j5Y79OHeYt1TP6B+Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5nRkgU9Jj+AzG5AkempMdX+VSorFE48Wltl2G7KTzTo=; b=f1xA5+u1PWPjbIzTis9ZD5hk+7TVFsYjkuYFCDUVYHCo9mCKKMHg8P7NdBJxnbXJMrNZKV8924o9BA6DoWgesC34BTLhXfmJuKeReEqCgyqCJD/3rQ+aM4XPQEgp+rzn9Om6+NbVps899aeKSi60+3XQI0nVtYhTzVf8zIN8Iro= Received: from PH7P220CA0056.NAMP220.PROD.OUTLOOK.COM (2603:10b6:510:32b::14) by CH2PR12MB4103.namprd12.prod.outlook.com (2603:10b6:610:7e::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7698.24; Fri, 21 Jun 2024 12:39:41 +0000 Received: from SN1PEPF00036F3C.namprd05.prod.outlook.com (2603:10b6:510:32b:cafe::47) by PH7P220CA0056.outlook.office365.com (2603:10b6:510:32b::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7677.36 via Frontend Transport; Fri, 21 Jun 2024 12:39:41 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SN1PEPF00036F3C.mail.protection.outlook.com (10.167.248.20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.7677.15 via Frontend Transport; Fri, 21 Jun 2024 12:39:40 +0000 Received: from gomati.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 21 Jun 2024 07:39:36 -0500 From: Nikunj A Dadhania To: , , , , CC: , , , , , , Subject: [PATCH v10 04/24] virt: sev-guest: Add SNP guest request structure Date: Fri, 21 Jun 2024 18:08:43 +0530 Message-ID: <20240621123903.2411843-5-nikunj@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240621123903.2411843-1-nikunj@amd.com> References: <20240621123903.2411843-1-nikunj@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: SATLEXMB04.amd.com (10.181.40.145) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SN1PEPF00036F3C:EE_|CH2PR12MB4103:EE_ X-MS-Office365-Filtering-Correlation-Id: b10a5f25-ea9c-45c6-b90e-08dc91ef387e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230037|1800799021|82310400023|36860700010|376011|7416011; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?PAwQnfuCzgJKvSzD4+1b9FfPF2PZ/Nql2dv2cYsDOMrMvELBZzH5t8qaY1js?= =?us-ascii?Q?uBZXLe2ea31sh5F1K7h9kkP9mw03meqKRztgfTKh6nJqekEhXxTRrekR85Qu?= =?us-ascii?Q?KCK13PS1b3zkL07Orfd/wrDOrtgmkyFyGWu2WV6wp8NX0ne81Iy/pqjvV4Of?= =?us-ascii?Q?IpZyCf2wMrriokMiqBWkOHHDYsqQomha42LOfH0ge3/H1ngMFkrnnSS6Jar0?= =?us-ascii?Q?A0mnP1cIFIO+ibwz5EPPsRuDN/AzqpBomn6J7cZfQTJXmTggdhUbXiSRarDM?= =?us-ascii?Q?vVIcuGHdXubP2hQLv0X3UHyswGvnqINCCwH/H5QBIoJ3VsWptWHrcz272ygK?= =?us-ascii?Q?kCz3UA1cEquHG8dbPS/jvHE4L3lPJn7S2oJ4MEFHXmrMUAtc11fQ299zh16u?= =?us-ascii?Q?NsWr6uFylt2d+eu7PmWFtPBIpIs/tEquE2fSqafUq4QdiwgYPALnpFVpNM9E?= =?us-ascii?Q?YKSEObHh7MKWGSVsQeIs/t7GNZQSC3QNMK3Z7DWtSUCYPUC0XaTQSEGTU3ui?= =?us-ascii?Q?YI5wKYwo7FbslMIVw9LLWo5oU1+8yEun12zlunDTdjylssXOa8KUFN/lcKaK?= =?us-ascii?Q?Skyb+qw96dFhT24VLVRLPOu/HIQorqRIUvsVufqU/Pp5N4IVQWUCyW0qeCGc?= =?us-ascii?Q?6h9/QdxNyOMCMDYlTQhyG/XJqMofQJoIXzFkjoLKtBP0YAjb+TcVXWuLWyOZ?= =?us-ascii?Q?t5qRZ8kdnKpUn56qI4KMFA6FQ6UVpxbb53UfBOEev+fonYojRc8cQXx8O9bv?= =?us-ascii?Q?tgBZCiVNODvldyXhRQEUclBatSSFrzKcSUG3I67NfTV6KkYYgEg+bYjuuf8x?= =?us-ascii?Q?eerwAldp/7NksiEQT76R1uPUzhWUenl3IPxHtOzHJv2DoLU9006CeRKuS+7V?= =?us-ascii?Q?ql0uKqFHj7gejWI1BkuCL8UrtM25mnUDQQneJTnn1tONHKr3zU7l+aT1c//l?= =?us-ascii?Q?nQ2kX0n2btDgWXrSiC45TQLduuB1BGv4fPB2+FLh2d3xykabN5p2C9ZcDMtx?= =?us-ascii?Q?mc96CmY2YSap6ZsZ/8W8KHrlL5jliezm/PfPhVE8Up5SoI6ga8Oxjp2KsPyE?= =?us-ascii?Q?pEXhNevTJCjlwW+N6o0/zfpKk54Pphp3223YwPiZ8HN06xvcOKxL0r8KJOZc?= =?us-ascii?Q?VRUDy2120noYWN7TRHdvtGYq52IEfaykSBJVpZwihGSjKjc4H/zvuDqGluNq?= =?us-ascii?Q?iE5BHBHDtUQ1IYqs5D5ejHcPOgjKCG3dVGko1ahVdrhGPKstgRrcxdgXzxgK?= =?us-ascii?Q?cwaaMNmOV2EdZoh6oUbb8zU7s3LVldlmHMWzEkhbpc8/XJXaG9A3ZQPxPxz8?= =?us-ascii?Q?rT+lu7Oj9fsz5EIpcUpmD4exuRLyKIdOCIXNByVB1JerKoKc3LXuNRILzmH+?= =?us-ascii?Q?gZszNIw=3D?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230037)(1800799021)(82310400023)(36860700010)(376011)(7416011);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Jun 2024 12:39:40.8620 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b10a5f25-ea9c-45c6-b90e-08dc91ef387e X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SN1PEPF00036F3C.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH2PR12MB4103 Content-Type: text/plain; charset="utf-8" Add a snp_guest_req structure to simplify the function arguments. This structure will be used to call the SNP Guest message request API instead of passing a long list of parameters. Update the snp_issue_guest_request() prototype to include the new guest request structure and move all the sev-guest.h header content to sev.h. Signed-off-by: Nikunj A Dadhania Reviewed-by: Tom Lendacky --- arch/x86/include/asm/sev.h | 77 ++++++++++- drivers/virt/coco/sev-guest/sev-guest.h | 69 ---------- arch/x86/coco/sev/core.c | 15 ++- drivers/virt/coco/sev-guest/sev-guest.c | 169 +++++++++++++----------- 4 files changed, 176 insertions(+), 154 deletions(-) delete mode 100644 drivers/virt/coco/sev-guest/sev-guest.h diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h index ac5886ce252e..2ac899adcbf6 100644 --- a/arch/x86/include/asm/sev.h +++ b/arch/x86/include/asm/sev.h @@ -112,8 +112,6 @@ struct rmp_state { struct snp_req_data { unsigned long req_gpa; unsigned long resp_gpa; - unsigned long data_gpa; - unsigned int data_npages; }; =20 struct sev_guest_platform_data { @@ -138,6 +136,75 @@ struct secrets_os_area { } __packed; =20 #define VMPCK_KEY_LEN 32 +#define MAX_AUTHTAG_LEN 32 +#define AUTHTAG_LEN 16 +#define AAD_LEN 48 +#define MSG_HDR_VER 1 + +/* See SNP spec SNP_GUEST_REQUEST section for the structure */ +enum msg_type { + SNP_MSG_TYPE_INVALID =3D 0, + SNP_MSG_CPUID_REQ, + SNP_MSG_CPUID_RSP, + SNP_MSG_KEY_REQ, + SNP_MSG_KEY_RSP, + SNP_MSG_REPORT_REQ, + SNP_MSG_REPORT_RSP, + SNP_MSG_EXPORT_REQ, + SNP_MSG_EXPORT_RSP, + SNP_MSG_IMPORT_REQ, + SNP_MSG_IMPORT_RSP, + SNP_MSG_ABSORB_REQ, + SNP_MSG_ABSORB_RSP, + SNP_MSG_VMRK_REQ, + SNP_MSG_VMRK_RSP, + + SNP_MSG_TYPE_MAX +}; + +enum aead_algo { + SNP_AEAD_INVALID, + SNP_AEAD_AES_256_GCM, +}; + +struct snp_guest_msg_hdr { + u8 authtag[MAX_AUTHTAG_LEN]; + u64 msg_seqno; + u8 rsvd1[8]; + u8 algo; + u8 hdr_version; + u16 hdr_sz; + u8 msg_type; + u8 msg_version; + u16 msg_sz; + u32 rsvd2; + u8 msg_vmpck; + u8 rsvd3[35]; +} __packed; + +struct snp_guest_msg { + struct snp_guest_msg_hdr hdr; + u8 payload[]; +} __packed; + +#define SNP_GUEST_MSG_SIZE 4096 +#define SNP_GUEST_MSG_PAYLOAD_SIZE (SNP_GUEST_MSG_SIZE - sizeof(struct snp= _guest_msg)) + +struct snp_guest_req { + void *req_buf; + size_t req_sz; + + void *resp_buf; + size_t resp_sz; + + void *data; + size_t data_npages; + + u64 exit_code; + unsigned int vmpck_id; + u8 msg_version; + u8 msg_type; +}; =20 /* See the SNP spec version 0.9 for secrets page format */ struct snp_secrets_page { @@ -341,7 +408,8 @@ void snp_set_wakeup_secondary_cpu(void); bool snp_init(struct boot_params *bp); void __noreturn snp_abort(void); void snp_dmi_setup(void); -int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, str= uct snp_guest_request_ioctl *rio); +int snp_issue_guest_request(struct snp_guest_req *req, struct snp_req_data= *input, + struct snp_guest_request_ioctl *rio); int snp_issue_svsm_attest_req(u64 call_id, struct svsm_call *call, struct = svsm_attest_call *input); void snp_accept_memory(phys_addr_t start, phys_addr_t end); u64 snp_get_unsupported_features(u64 status); @@ -371,7 +439,8 @@ static inline void snp_set_wakeup_secondary_cpu(void) {= } static inline bool snp_init(struct boot_params *bp) { return false; } static inline void snp_abort(void) { } static inline void snp_dmi_setup(void) { } -static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_da= ta *input, struct snp_guest_request_ioctl *rio) +static inline int snp_issue_guest_request(struct snp_guest_req *req, struc= t snp_req_data *input, + struct snp_guest_request_ioctl *rio) { return -ENOTTY; } diff --git a/drivers/virt/coco/sev-guest/sev-guest.h b/drivers/virt/coco/se= v-guest/sev-guest.h deleted file mode 100644 index 97796f658fd3..000000000000 --- a/drivers/virt/coco/sev-guest/sev-guest.h +++ /dev/null @@ -1,69 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2021 Advanced Micro Devices, Inc. - * - * Author: Brijesh Singh - * - * SEV-SNP API spec is available at https://developer.amd.com/sev - */ - -#ifndef __VIRT_SEVGUEST_H__ -#define __VIRT_SEVGUEST_H__ - -#include - -#define MAX_AUTHTAG_LEN 32 -#define AUTHTAG_LEN 16 -#define AAD_LEN 48 -#define MSG_HDR_VER 1 - -/* See SNP spec SNP_GUEST_REQUEST section for the structure */ -enum msg_type { - SNP_MSG_TYPE_INVALID =3D 0, - SNP_MSG_CPUID_REQ, - SNP_MSG_CPUID_RSP, - SNP_MSG_KEY_REQ, - SNP_MSG_KEY_RSP, - SNP_MSG_REPORT_REQ, - SNP_MSG_REPORT_RSP, - SNP_MSG_EXPORT_REQ, - SNP_MSG_EXPORT_RSP, - SNP_MSG_IMPORT_REQ, - SNP_MSG_IMPORT_RSP, - SNP_MSG_ABSORB_REQ, - SNP_MSG_ABSORB_RSP, - SNP_MSG_VMRK_REQ, - SNP_MSG_VMRK_RSP, - - SNP_MSG_TYPE_MAX -}; - -enum aead_algo { - SNP_AEAD_INVALID, - SNP_AEAD_AES_256_GCM, -}; - -struct snp_guest_msg_hdr { - u8 authtag[MAX_AUTHTAG_LEN]; - u64 msg_seqno; - u8 rsvd1[8]; - u8 algo; - u8 hdr_version; - u16 hdr_sz; - u8 msg_type; - u8 msg_version; - u16 msg_sz; - u32 rsvd2; - u8 msg_vmpck; - u8 rsvd3[35]; -} __packed; - -struct snp_guest_msg { - struct snp_guest_msg_hdr hdr; - u8 payload[]; -} __packed; - -#define SNP_GUEST_MSG_SIZE 4096 -#define SNP_GUEST_MSG_PAYLOAD_SIZE (SNP_GUEST_MSG_SIZE - sizeof(struct snp= _guest_msg)) - -#endif /* __VIRT_SEVGUEST_H__ */ diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c index 082d61d85dfc..d3c70604aba8 100644 --- a/arch/x86/coco/sev/core.c +++ b/arch/x86/coco/sev/core.c @@ -2441,7 +2441,8 @@ int snp_issue_svsm_attest_req(u64 call_id, struct svs= m_call *call, } EXPORT_SYMBOL_GPL(snp_issue_svsm_attest_req); =20 -int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, str= uct snp_guest_request_ioctl *rio) +int snp_issue_guest_request(struct snp_guest_req *req, struct snp_req_data= *input, + struct snp_guest_request_ioctl *rio) { struct ghcb_state state; struct es_em_ctxt ctxt; @@ -2465,12 +2466,12 @@ int snp_issue_guest_request(u64 exit_code, struct s= np_req_data *input, struct sn =20 vc_ghcb_invalidate(ghcb); =20 - if (exit_code =3D=3D SVM_VMGEXIT_EXT_GUEST_REQUEST) { - ghcb_set_rax(ghcb, input->data_gpa); - ghcb_set_rbx(ghcb, input->data_npages); + if (req->exit_code =3D=3D SVM_VMGEXIT_EXT_GUEST_REQUEST) { + ghcb_set_rax(ghcb, __pa(req->data)); + ghcb_set_rbx(ghcb, req->data_npages); } =20 - ret =3D sev_es_ghcb_hv_call(ghcb, &ctxt, exit_code, input->req_gpa, input= ->resp_gpa); + ret =3D sev_es_ghcb_hv_call(ghcb, &ctxt, req->exit_code, input->req_gpa, = input->resp_gpa); if (ret) goto e_put; =20 @@ -2485,8 +2486,8 @@ int snp_issue_guest_request(u64 exit_code, struct snp= _req_data *input, struct sn =20 case SNP_GUEST_VMM_ERR(SNP_GUEST_VMM_ERR_INVALID_LEN): /* Number of expected pages are returned in RBX */ - if (exit_code =3D=3D SVM_VMGEXIT_EXT_GUEST_REQUEST) { - input->data_npages =3D ghcb_get_rbx(ghcb); + if (req->exit_code =3D=3D SVM_VMGEXIT_EXT_GUEST_REQUEST) { + req->data_npages =3D ghcb_get_rbx(ghcb); ret =3D -ENOSPC; break; } diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/se= v-guest/sev-guest.c index e8cef42a211d..85e3d39bd5a9 100644 --- a/drivers/virt/coco/sev-guest/sev-guest.c +++ b/drivers/virt/coco/sev-guest/sev-guest.c @@ -29,8 +29,6 @@ #include #include =20 -#include "sev-guest.h" - #define DEVICE_NAME "sev-guest" =20 #define SNP_REQ_MAX_RETRY_DURATION (60*HZ) @@ -179,7 +177,7 @@ static struct aesgcm_ctx *snp_init_crypto(u8 *key, size= _t keylen) return ctx; } =20 -static int verify_and_dec_payload(struct snp_guest_dev *snp_dev, void *pay= load, u32 sz) +static int verify_and_dec_payload(struct snp_guest_dev *snp_dev, struct sn= p_guest_req *req) { struct snp_guest_msg *resp_msg =3D snp_dev->secret_response; struct snp_guest_msg *req_msg =3D snp_dev->secret_request; @@ -208,20 +206,19 @@ static int verify_and_dec_payload(struct snp_guest_de= v *snp_dev, void *payload, * If the message size is greater than our buffer length then return * an error. */ - if (unlikely((resp_msg_hdr->msg_sz + ctx->authsize) > sz)) + if (unlikely((resp_msg_hdr->msg_sz + ctx->authsize) > req->resp_sz)) return -EBADMSG; =20 /* Decrypt the payload */ memcpy(iv, &resp_msg_hdr->msg_seqno, min(sizeof(iv), sizeof(resp_msg_hdr-= >msg_seqno))); - if (!aesgcm_decrypt(ctx, payload, resp_msg->payload, resp_msg_hdr->msg_sz, + if (!aesgcm_decrypt(ctx, req->resp_buf, resp_msg->payload, resp_msg_hdr->= msg_sz, &resp_msg_hdr->algo, AAD_LEN, iv, resp_msg_hdr->authtag)) return -EBADMSG; =20 return 0; } =20 -static int enc_payload(struct snp_guest_dev *snp_dev, u64 seqno, int versi= on, u8 type, - void *payload, size_t sz) +static int enc_payload(struct snp_guest_dev *snp_dev, u64 seqno, struct sn= p_guest_req *req) { struct snp_guest_msg *msg =3D snp_dev->secret_request; struct snp_guest_msg_hdr *hdr =3D &msg->hdr; @@ -233,11 +230,11 @@ static int enc_payload(struct snp_guest_dev *snp_dev,= u64 seqno, int version, u8 hdr->algo =3D SNP_AEAD_AES_256_GCM; hdr->hdr_version =3D MSG_HDR_VER; hdr->hdr_sz =3D sizeof(*hdr); - hdr->msg_type =3D type; - hdr->msg_version =3D version; + hdr->msg_type =3D req->msg_type; + hdr->msg_version =3D req->msg_version; hdr->msg_seqno =3D seqno; - hdr->msg_vmpck =3D vmpck_id; - hdr->msg_sz =3D sz; + hdr->msg_vmpck =3D req->vmpck_id; + hdr->msg_sz =3D req->req_sz; =20 /* Verify the sequence number is non-zero */ if (!hdr->msg_seqno) @@ -246,17 +243,17 @@ static int enc_payload(struct snp_guest_dev *snp_dev,= u64 seqno, int version, u8 pr_debug("request [seqno %lld type %d version %d sz %d]\n", hdr->msg_seqno, hdr->msg_type, hdr->msg_version, hdr->msg_sz); =20 - if (WARN_ON((sz + ctx->authsize) > SNP_GUEST_MSG_PAYLOAD_SIZE)) + if (WARN_ON((req->req_sz + ctx->authsize) > SNP_GUEST_MSG_PAYLOAD_SIZE)) return -EBADMSG; =20 memcpy(iv, &hdr->msg_seqno, min(sizeof(iv), sizeof(hdr->msg_seqno))); - aesgcm_encrypt(ctx, msg->payload, payload, sz, &hdr->algo, AAD_LEN, - iv, hdr->authtag); + aesgcm_encrypt(ctx, msg->payload, req->req_buf, req->req_sz, &hdr->algo, + AAD_LEN, iv, hdr->authtag); =20 return 0; } =20 -static int __handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_= code, +static int __handle_guest_request(struct snp_guest_dev *snp_dev, struct sn= p_guest_req *req, struct snp_guest_request_ioctl *rio) { unsigned long req_start =3D jiffies; @@ -271,7 +268,7 @@ static int __handle_guest_request(struct snp_guest_dev = *snp_dev, u64 exit_code, * sequence number must be incremented or the VMPCK must be deleted to * prevent reuse of the IV. */ - rc =3D snp_issue_guest_request(exit_code, &snp_dev->input, rio); + rc =3D snp_issue_guest_request(req, &snp_dev->input, rio); switch (rc) { case -ENOSPC: /* @@ -281,8 +278,8 @@ static int __handle_guest_request(struct snp_guest_dev = *snp_dev, u64 exit_code, * order to increment the sequence number and thus avoid * IV reuse. */ - override_npages =3D snp_dev->input.data_npages; - exit_code =3D SVM_VMGEXIT_GUEST_REQUEST; + override_npages =3D req->data_npages; + req->exit_code =3D SVM_VMGEXIT_GUEST_REQUEST; =20 /* * Override the error to inform callers the given extended @@ -337,15 +334,13 @@ static int __handle_guest_request(struct snp_guest_de= v *snp_dev, u64 exit_code, } =20 if (override_npages) - snp_dev->input.data_npages =3D override_npages; + req->data_npages =3D override_npages; =20 return rc; } =20 -static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_co= de, - struct snp_guest_request_ioctl *rio, u8 type, - void *req_buf, size_t req_sz, void *resp_buf, - u32 resp_sz) +static int snp_send_guest_request(struct snp_guest_dev *snp_dev, struct sn= p_guest_req *req, + struct snp_guest_request_ioctl *rio) { u64 seqno; int rc; @@ -359,7 +354,7 @@ static int handle_guest_request(struct snp_guest_dev *s= np_dev, u64 exit_code, memset(snp_dev->response, 0, SNP_GUEST_MSG_SIZE); =20 /* Encrypt the userspace provided payload in snp_dev->secret_request. */ - rc =3D enc_payload(snp_dev, seqno, rio->msg_version, type, req_buf, req_s= z); + rc =3D enc_payload(snp_dev, seqno, req); if (rc) return rc; =20 @@ -367,9 +362,9 @@ static int handle_guest_request(struct snp_guest_dev *s= np_dev, u64 exit_code, * Write the fully encrypted request to the shared unencrypted * request page. */ - memcpy(snp_dev->request, &snp_dev->secret_request, SNP_GUEST_MSG_SIZE); + memcpy(snp_dev->request, snp_dev->secret_request, SNP_GUEST_MSG_SIZE); =20 - rc =3D __handle_guest_request(snp_dev, exit_code, rio); + rc =3D __handle_guest_request(snp_dev, req, rio); if (rc) { if (rc =3D=3D -EIO && rio->exitinfo2 =3D=3D SNP_GUEST_VMM_ERR(SNP_GUEST_VMM_ERR_INVALID_LE= N)) @@ -378,12 +373,11 @@ static int handle_guest_request(struct snp_guest_dev = *snp_dev, u64 exit_code, dev_alert(snp_dev->dev, "Detected error from ASP request. rc: %d, exitinfo2: 0x%llx\n", rc, rio->exitinfo2); - snp_disable_vmpck(snp_dev); return rc; } =20 - rc =3D verify_and_dec_payload(snp_dev, resp_buf, resp_sz); + rc =3D verify_and_dec_payload(snp_dev, req); if (rc) { dev_alert(snp_dev->dev, "Detected unexpected decode failure from ASP. rc= : %d\n", rc); snp_disable_vmpck(snp_dev); @@ -400,8 +394,9 @@ struct snp_req_resp { =20 static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_requ= est_ioctl *arg) { - struct snp_report_req *req =3D &snp_dev->req.report; - struct snp_report_resp *resp; + struct snp_report_req *report_req =3D &snp_dev->req.report; + struct snp_guest_req req =3D {0}; + struct snp_report_resp *report_resp; int rc, resp_len; =20 lockdep_assert_held(&snp_cmd_mutex); @@ -409,7 +404,7 @@ static int get_report(struct snp_guest_dev *snp_dev, st= ruct snp_guest_request_io if (!arg->req_data || !arg->resp_data) return -EINVAL; =20 - if (copy_from_user(req, (void __user *)arg->req_data, sizeof(*req))) + if (copy_from_user(report_req, (void __user *)arg->req_data, sizeof(*repo= rt_req))) return -EFAULT; =20 /* @@ -417,29 +412,37 @@ static int get_report(struct snp_guest_dev *snp_dev, = struct snp_guest_request_io * response payload. Make sure that it has enough space to cover the * authtag. */ - resp_len =3D sizeof(resp->data) + snp_dev->ctx->authsize; - resp =3D kzalloc(resp_len, GFP_KERNEL_ACCOUNT); - if (!resp) + resp_len =3D sizeof(report_resp->data) + snp_dev->ctx->authsize; + report_resp =3D kzalloc(resp_len, GFP_KERNEL_ACCOUNT); + if (!report_resp) return -ENOMEM; =20 - rc =3D handle_guest_request(snp_dev, SVM_VMGEXIT_GUEST_REQUEST, arg, - SNP_MSG_REPORT_REQ, req, sizeof(*req), resp->data, - resp_len); + req.msg_version =3D arg->msg_version; + req.msg_type =3D SNP_MSG_REPORT_REQ; + req.vmpck_id =3D vmpck_id; + req.req_buf =3D report_req; + req.req_sz =3D sizeof(*report_req); + req.resp_buf =3D report_resp->data; + req.resp_sz =3D resp_len; + req.exit_code =3D SVM_VMGEXIT_GUEST_REQUEST; + + rc =3D snp_send_guest_request(snp_dev, &req, arg); if (rc) goto e_free; =20 - if (copy_to_user((void __user *)arg->resp_data, resp, sizeof(*resp))) + if (copy_to_user((void __user *)arg->resp_data, report_resp, sizeof(*repo= rt_resp))) rc =3D -EFAULT; =20 e_free: - kfree(resp); + kfree(report_resp); return rc; } =20 static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest= _request_ioctl *arg) { - struct snp_derived_key_req *req =3D &snp_dev->req.derived_key; - struct snp_derived_key_resp resp =3D {0}; + struct snp_derived_key_req *derived_key_req =3D &snp_dev->req.derived_key; + struct snp_derived_key_resp derived_key_resp =3D {0}; + struct snp_guest_req req =3D {0}; int rc, resp_len; /* Response data is 64 bytes and max authsize for GCM is 16 bytes. */ u8 buf[64 + 16]; @@ -454,25 +457,35 @@ static int get_derived_key(struct snp_guest_dev *snp_= dev, struct snp_guest_reque * response payload. Make sure that it has enough space to cover the * authtag. */ - resp_len =3D sizeof(resp.data) + snp_dev->ctx->authsize; + resp_len =3D sizeof(derived_key_resp.data) + snp_dev->ctx->authsize; if (sizeof(buf) < resp_len) return -ENOMEM; =20 - if (copy_from_user(req, (void __user *)arg->req_data, sizeof(*req))) + if (copy_from_user(derived_key_req, (void __user *)arg->req_data, + sizeof(*derived_key_req))) return -EFAULT; =20 - rc =3D handle_guest_request(snp_dev, SVM_VMGEXIT_GUEST_REQUEST, arg, - SNP_MSG_KEY_REQ, req, sizeof(*req), buf, resp_len); + req.msg_version =3D arg->msg_version; + req.msg_type =3D SNP_MSG_KEY_REQ; + req.vmpck_id =3D vmpck_id; + req.req_buf =3D derived_key_req; + req.req_sz =3D sizeof(*derived_key_req); + req.resp_buf =3D buf; + req.resp_sz =3D resp_len; + req.exit_code =3D SVM_VMGEXIT_GUEST_REQUEST; + + rc =3D snp_send_guest_request(snp_dev, &req, arg); if (rc) return rc; =20 - memcpy(resp.data, buf, sizeof(resp.data)); - if (copy_to_user((void __user *)arg->resp_data, &resp, sizeof(resp))) + memcpy(derived_key_resp.data, buf, sizeof(derived_key_resp.data)); + if (copy_to_user((void __user *)arg->resp_data, &derived_key_resp, + sizeof(derived_key_resp))) rc =3D -EFAULT; =20 /* The response buffer contains the sensitive data, explicitly clear it. = */ memzero_explicit(buf, sizeof(buf)); - memzero_explicit(&resp, sizeof(resp)); + memzero_explicit(&derived_key_resp, sizeof(derived_key_resp)); return rc; } =20 @@ -480,32 +493,33 @@ static int get_ext_report(struct snp_guest_dev *snp_d= ev, struct snp_guest_reques struct snp_req_resp *io) =20 { - struct snp_ext_report_req *req =3D &snp_dev->req.ext_report; - struct snp_report_resp *resp; - int ret, npages =3D 0, resp_len; + struct snp_ext_report_req *report_req =3D &snp_dev->req.ext_report; + struct snp_guest_req req =3D {0}; + struct snp_report_resp *report_resp; sockptr_t certs_address; + int ret, resp_len; =20 lockdep_assert_held(&snp_cmd_mutex); =20 if (sockptr_is_null(io->req_data) || sockptr_is_null(io->resp_data)) return -EINVAL; =20 - if (copy_from_sockptr(req, io->req_data, sizeof(*req))) + if (copy_from_sockptr(report_req, io->req_data, sizeof(*report_req))) return -EFAULT; =20 /* caller does not want certificate data */ - if (!req->certs_len || !req->certs_address) + if (!report_req->certs_len || !report_req->certs_address) goto cmd; =20 - if (req->certs_len > SEV_FW_BLOB_MAX_SIZE || - !IS_ALIGNED(req->certs_len, PAGE_SIZE)) + if (report_req->certs_len > SEV_FW_BLOB_MAX_SIZE || + !IS_ALIGNED(report_req->certs_len, PAGE_SIZE)) return -EINVAL; =20 if (sockptr_is_kernel(io->resp_data)) { - certs_address =3D KERNEL_SOCKPTR((void *)req->certs_address); + certs_address =3D KERNEL_SOCKPTR((void *)report_req->certs_address); } else { - certs_address =3D USER_SOCKPTR((void __user *)req->certs_address); - if (!access_ok(certs_address.user, req->certs_len)) + certs_address =3D USER_SOCKPTR((void __user *)report_req->certs_address); + if (!access_ok(certs_address.user, report_req->certs_len)) return -EFAULT; } =20 @@ -515,45 +529,53 @@ static int get_ext_report(struct snp_guest_dev *snp_d= ev, struct snp_guest_reques * the host. If host does not supply any certs in it, then copy * zeros to indicate that certificate data was not provided. */ - memset(snp_dev->certs_data, 0, req->certs_len); - npages =3D req->certs_len >> PAGE_SHIFT; + memset(snp_dev->certs_data, 0, report_req->certs_len); + req.data_npages =3D report_req->certs_len >> PAGE_SHIFT; cmd: /* * The intermediate response buffer is used while decrypting the * response payload. Make sure that it has enough space to cover the * authtag. */ - resp_len =3D sizeof(resp->data) + snp_dev->ctx->authsize; - resp =3D kzalloc(resp_len, GFP_KERNEL_ACCOUNT); - if (!resp) + resp_len =3D sizeof(report_resp->data) + snp_dev->ctx->authsize; + report_resp =3D kzalloc(resp_len, GFP_KERNEL_ACCOUNT); + if (!report_resp) return -ENOMEM; =20 - snp_dev->input.data_npages =3D npages; - ret =3D handle_guest_request(snp_dev, SVM_VMGEXIT_EXT_GUEST_REQUEST, arg, - SNP_MSG_REPORT_REQ, &req->data, - sizeof(req->data), resp->data, resp_len); + req.msg_version =3D arg->msg_version; + req.msg_type =3D SNP_MSG_REPORT_REQ; + req.vmpck_id =3D vmpck_id; + req.req_buf =3D &report_req->data; + req.req_sz =3D sizeof(report_req->data); + req.resp_buf =3D report_resp->data; + req.resp_sz =3D resp_len; + req.exit_code =3D SVM_VMGEXIT_EXT_GUEST_REQUEST; + req.data =3D snp_dev->certs_data; + + ret =3D snp_send_guest_request(snp_dev, &req, arg); =20 /* If certs length is invalid then copy the returned length */ if (arg->vmm_error =3D=3D SNP_GUEST_VMM_ERR_INVALID_LEN) { - req->certs_len =3D snp_dev->input.data_npages << PAGE_SHIFT; + report_req->certs_len =3D req.data_npages << PAGE_SHIFT; =20 - if (copy_to_sockptr(io->req_data, req, sizeof(*req))) + if (copy_to_sockptr(io->req_data, report_req, sizeof(*report_req))) ret =3D -EFAULT; } =20 if (ret) goto e_free; =20 - if (npages && copy_to_sockptr(certs_address, snp_dev->certs_data, req->ce= rts_len)) { + if (req.data_npages && report_req->certs_len && + copy_to_sockptr(certs_address, snp_dev->certs_data, report_req->certs= _len)) { ret =3D -EFAULT; goto e_free; } =20 - if (copy_to_sockptr(io->resp_data, resp, sizeof(*resp))) + if (copy_to_sockptr(io->resp_data, report_resp, sizeof(*report_resp))) ret =3D -EFAULT; =20 e_free: - kfree(resp); + kfree(report_resp); return ret; } =20 @@ -1064,10 +1086,9 @@ static int __init sev_guest_probe(struct platform_de= vice *pdev) misc->name =3D DEVICE_NAME; misc->fops =3D &snp_guest_fops; =20 - /* initial the input address for guest request */ + /* Initialize the input addresses for guest request */ snp_dev->input.req_gpa =3D __pa(snp_dev->request); snp_dev->input.resp_gpa =3D __pa(snp_dev->response); - snp_dev->input.data_gpa =3D __pa(snp_dev->certs_data); =20 /* Set the privlevel_floor attribute based on the vmpck_id */ sev_tsm_ops.privlevel_floor =3D vmpck_id; --=20 2.34.1