From nobody Fri Dec 19 19:16:32 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 AC0D62165E1; Thu, 9 Jan 2025 09:43:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736415833; cv=none; b=jh/PBY3rVCoKtz1Hvt5rdPNgPBurW+JDOPE7WRmrTTkCoFS3BUj/4CwnKkZ+HqwyW04m6UGqoCqU2yp99gED5E8JAu9dJYoieotN/p2i+81jtstY6YGXdEiT7M8l9jOLxlpZb0NP4KBkTQguyEROKP7oAcQ4CAKXmGC+2mUbul4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736415833; c=relaxed/simple; bh=qE3rhFKyKz/5BbG80HGlS3/B39RK0vYvYh20jSzHLXo=; h=Date:From:To:Subject:Cc:In-Reply-To:References:MIME-Version: Message-ID:Content-Type; b=LRB4WrGX0vno0UEyxsQ9gK8BSnZn2YLPZUCIfi/2peUV98UtT0Yy+CeeB/ReHP9d9FIHR5HQhBHan530dQ/8li6Oc/nsefk3C1/uTDyp2K6QLZCNcnA7flLR1t3zTWvhyM8ZbER6GkXx5IMGAeq0YIDWzgA7J92PeszuArztYW8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=089GYp6Z; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=2eoWctrX; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="089GYp6Z"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="2eoWctrX" Date: Thu, 09 Jan 2025 09:43:48 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1736415829; 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: in-reply-to:in-reply-to:references:references; bh=F/08VF4sxhlv0lAYdwKE5rODrY41nMSqazvCNOlfTwo=; b=089GYp6ZhxJjCdSzgV4Jxod6nCBxPDeUeHVT+LriyDqo+QGD38B8h5Xz6uimobXOYj87uo VwW8rF3jB6nQB4lLefDLqKqZVbwfLhirZhOa0+wemLzXB7d3zg6tDwvi3SvOpl13YlscYz 8P5lcqja9wAoGDFlQa998PxDZLiZQRKv+AZrXLNfKjeyacr75qawTQZ8Cmpzwq+TIY6CQj jVAegbpEsz3uL/Di0We/JF0uAv5nOSXNCaW6cgCw2KqS1ThGpwhiHw6aEkgKA0PdJwWPrK UK4S5JD9sEO09xNeftixqdo5GfOcbeJKDUDgaaU59Ct0VqyVlDQeScYR7u6pvQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1736415829; 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: in-reply-to:in-reply-to:references:references; bh=F/08VF4sxhlv0lAYdwKE5rODrY41nMSqazvCNOlfTwo=; b=2eoWctrXiXpQ4GrIrSB2X6T6ZzfA5BrZs7vhcvYrF2ef4WvVlMSSGxcyndRpA2aY2fXLxq pPvHWQ71wvc30eCA== From: "tip-bot2 for Nikunj A Dadhania" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/sev] x86/sev: Carve out and export SNP guest messaging init routines Cc: Nikunj A Dadhania , "Borislav Petkov (AMD)" , Tom Lendacky , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20250106124633.1418972-4-nikunj@amd.com> References: <20250106124633.1418972-4-nikunj@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <173641582864.399.17355271009773963917.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The following commit has been merged into the x86/sev branch of tip: Commit-ID: c5529418d05079384af4dbbb6f6156344c2ffce2 Gitweb: https://git.kernel.org/tip/c5529418d05079384af4dbbb6f6156344= c2ffce2 Author: Nikunj A Dadhania AuthorDate: Mon, 06 Jan 2025 18:16:23 +05:30 Committer: Borislav Petkov (AMD) CommitterDate: Tue, 07 Jan 2025 10:33:20 +01:00 x86/sev: Carve out and export SNP guest messaging init routines Currently, the sev-guest driver is the only user of SNP guest messaging. All routines for initializing SNP guest messaging are implemented within the sev-guest driver and are not available during early boot. In preparation for adding Secure TSC guest support, carve out APIs to alloc= ate and initialize the guest messaging descriptor context and make it part of coco/sev/core.c. As there is no user of sev_guest_platform_data anymore, remove the structure. Signed-off-by: Nikunj A Dadhania Signed-off-by: Borislav Petkov (AMD) Reviewed-by: Tom Lendacky Link: https://lore.kernel.org/r/20250106124633.1418972-4-nikunj@amd.com --- arch/x86/Kconfig | 1 +- arch/x86/coco/sev/core.c | 183 ++++++++++++++++++++++- arch/x86/include/asm/sev.h | 13 +- drivers/virt/coco/sev-guest/Kconfig | 1 +- drivers/virt/coco/sev-guest/sev-guest.c | 185 ++--------------------- 5 files changed, 208 insertions(+), 175 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 9d7bd0a..0f7e3ac 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1559,6 +1559,7 @@ config AMD_MEM_ENCRYPT select ARCH_HAS_CC_PLATFORM select X86_MEM_ENCRYPT select UNACCEPTED_MEMORY + select CRYPTO_LIB_AESGCM help Say yes to enable support for the encryption of system memory. This requires an AMD processor that supports Secure Memory diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c index c5b0148..30ce563 100644 --- a/arch/x86/coco/sev/core.c +++ b/arch/x86/coco/sev/core.c @@ -25,6 +25,7 @@ #include #include #include +#include =20 #include #include @@ -2580,15 +2581,9 @@ static struct platform_device sev_guest_device =3D { =20 static int __init snp_init_platform_device(void) { - struct sev_guest_platform_data data; - if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) return -ENODEV; =20 - data.secrets_gpa =3D secrets_pa; - if (platform_device_add_data(&sev_guest_device, &data, sizeof(data))) - return -ENODEV; - if (platform_device_register(&sev_guest_device)) return -ENODEV; =20 @@ -2667,3 +2662,179 @@ static int __init sev_sysfs_init(void) } arch_initcall(sev_sysfs_init); #endif // CONFIG_SYSFS + +static void free_shared_pages(void *buf, size_t sz) +{ + unsigned int npages =3D PAGE_ALIGN(sz) >> PAGE_SHIFT; + int ret; + + if (!buf) + return; + + ret =3D set_memory_encrypted((unsigned long)buf, npages); + if (ret) { + WARN_ONCE(ret, "failed to restore encryption mask (leak it)\n"); + return; + } + + __free_pages(virt_to_page(buf), get_order(sz)); +} + +static void *alloc_shared_pages(size_t sz) +{ + unsigned int npages =3D PAGE_ALIGN(sz) >> PAGE_SHIFT; + struct page *page; + int ret; + + page =3D alloc_pages(GFP_KERNEL_ACCOUNT, get_order(sz)); + if (!page) + return NULL; + + ret =3D set_memory_decrypted((unsigned long)page_address(page), npages); + if (ret) { + pr_err("failed to mark page shared, ret=3D%d\n", ret); + __free_pages(page, get_order(sz)); + return NULL; + } + + return page_address(page); +} + +static u8 *get_vmpck(int id, struct snp_secrets_page *secrets, u32 **seqno) +{ + u8 *key =3D NULL; + + switch (id) { + case 0: + *seqno =3D &secrets->os_area.msg_seqno_0; + key =3D secrets->vmpck0; + break; + case 1: + *seqno =3D &secrets->os_area.msg_seqno_1; + key =3D secrets->vmpck1; + break; + case 2: + *seqno =3D &secrets->os_area.msg_seqno_2; + key =3D secrets->vmpck2; + break; + case 3: + *seqno =3D &secrets->os_area.msg_seqno_3; + key =3D secrets->vmpck3; + break; + default: + break; + } + + return key; +} + +static struct aesgcm_ctx *snp_init_crypto(u8 *key, size_t keylen) +{ + struct aesgcm_ctx *ctx; + + ctx =3D kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return NULL; + + if (aesgcm_expandkey(ctx, key, keylen, AUTHTAG_LEN)) { + pr_err("Crypto context initialization failed\n"); + kfree(ctx); + return NULL; + } + + return ctx; +} + +int snp_msg_init(struct snp_msg_desc *mdesc, int vmpck_id) +{ + /* Adjust the default VMPCK key based on the executing VMPL level */ + if (vmpck_id =3D=3D -1) + vmpck_id =3D snp_vmpl; + + mdesc->vmpck =3D get_vmpck(vmpck_id, mdesc->secrets, &mdesc->os_area_msg_= seqno); + if (!mdesc->vmpck) { + pr_err("Invalid VMPCK%d communication key\n", vmpck_id); + return -EINVAL; + } + + /* Verify that VMPCK is not zero. */ + if (!memchr_inv(mdesc->vmpck, 0, VMPCK_KEY_LEN)) { + pr_err("Empty VMPCK%d communication key\n", vmpck_id); + return -EINVAL; + } + + mdesc->vmpck_id =3D vmpck_id; + + mdesc->ctx =3D snp_init_crypto(mdesc->vmpck, VMPCK_KEY_LEN); + if (!mdesc->ctx) + return -ENOMEM; + + return 0; +} +EXPORT_SYMBOL_GPL(snp_msg_init); + +struct snp_msg_desc *snp_msg_alloc(void) +{ + struct snp_msg_desc *mdesc; + void __iomem *mem; + + BUILD_BUG_ON(sizeof(struct snp_guest_msg) > PAGE_SIZE); + + mdesc =3D kzalloc(sizeof(struct snp_msg_desc), GFP_KERNEL); + if (!mdesc) + return ERR_PTR(-ENOMEM); + + mem =3D ioremap_encrypted(secrets_pa, PAGE_SIZE); + if (!mem) + goto e_free_mdesc; + + mdesc->secrets =3D (__force struct snp_secrets_page *)mem; + + /* Allocate the shared page used for the request and response message. */ + mdesc->request =3D alloc_shared_pages(sizeof(struct snp_guest_msg)); + if (!mdesc->request) + goto e_unmap; + + mdesc->response =3D alloc_shared_pages(sizeof(struct snp_guest_msg)); + if (!mdesc->response) + goto e_free_request; + + mdesc->certs_data =3D alloc_shared_pages(SEV_FW_BLOB_MAX_SIZE); + if (!mdesc->certs_data) + goto e_free_response; + + /* initial the input address for guest request */ + mdesc->input.req_gpa =3D __pa(mdesc->request); + mdesc->input.resp_gpa =3D __pa(mdesc->response); + mdesc->input.data_gpa =3D __pa(mdesc->certs_data); + + return mdesc; + +e_free_response: + free_shared_pages(mdesc->response, sizeof(struct snp_guest_msg)); +e_free_request: + free_shared_pages(mdesc->request, sizeof(struct snp_guest_msg)); +e_unmap: + iounmap(mem); +e_free_mdesc: + kfree(mdesc); + + return ERR_PTR(-ENOMEM); +} +EXPORT_SYMBOL_GPL(snp_msg_alloc); + +void snp_msg_free(struct snp_msg_desc *mdesc) +{ + if (!mdesc) + return; + + kfree(mdesc->ctx); + free_shared_pages(mdesc->response, sizeof(struct snp_guest_msg)); + free_shared_pages(mdesc->request, sizeof(struct snp_guest_msg)); + free_shared_pages(mdesc->certs_data, SEV_FW_BLOB_MAX_SIZE); + iounmap((__force void __iomem *)mdesc->secrets); + + memset(mdesc, 0, sizeof(*mdesc)); + kfree(mdesc); +} +EXPORT_SYMBOL_GPL(snp_msg_free); diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h index 91f08af..db08d0a 100644 --- a/arch/x86/include/asm/sev.h +++ b/arch/x86/include/asm/sev.h @@ -14,6 +14,7 @@ #include #include #include +#include =20 #define GHCB_PROTOCOL_MIN 1ULL #define GHCB_PROTOCOL_MAX 2ULL @@ -170,10 +171,6 @@ struct snp_guest_msg { u8 payload[PAGE_SIZE - sizeof(struct snp_guest_msg_hdr)]; } __packed; =20 -struct sev_guest_platform_data { - u64 secrets_gpa; -}; - struct snp_guest_req { void *req_buf; size_t req_sz; @@ -253,6 +250,7 @@ struct snp_msg_desc { =20 u32 *os_area_msg_seqno; u8 *vmpck; + int vmpck_id; }; =20 /* @@ -458,6 +456,10 @@ void set_pte_enc_mask(pte_t *kpte, unsigned long pfn, = pgprot_t new_prot); void snp_kexec_finish(void); void snp_kexec_begin(void); =20 +int snp_msg_init(struct snp_msg_desc *mdesc, int vmpck_id); +struct snp_msg_desc *snp_msg_alloc(void); +void snp_msg_free(struct snp_msg_desc *mdesc); + #else /* !CONFIG_AMD_MEM_ENCRYPT */ =20 #define snp_vmpl 0 @@ -498,6 +500,9 @@ static inline int prepare_pte_enc(struct pte_enc_desc *= d) { return 0; } static inline void set_pte_enc_mask(pte_t *kpte, unsigned long pfn, pgprot= _t new_prot) { } static inline void snp_kexec_finish(void) { } static inline void snp_kexec_begin(void) { } +static inline int snp_msg_init(struct snp_msg_desc *mdesc, int vmpck_id) {= return -1; } +static inline struct snp_msg_desc *snp_msg_alloc(void) { return NULL; } +static inline void snp_msg_free(struct snp_msg_desc *mdesc) { } =20 #endif /* CONFIG_AMD_MEM_ENCRYPT */ =20 diff --git a/drivers/virt/coco/sev-guest/Kconfig b/drivers/virt/coco/sev-gu= est/Kconfig index 0b772bd..a6405ab 100644 --- a/drivers/virt/coco/sev-guest/Kconfig +++ b/drivers/virt/coco/sev-guest/Kconfig @@ -2,7 +2,6 @@ config SEV_GUEST tristate "AMD SEV Guest driver" default m depends on AMD_MEM_ENCRYPT - select CRYPTO_LIB_AESGCM select TSM_REPORTS help SEV-SNP firmware provides the guest a mechanism to communicate with diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/se= v-guest/sev-guest.c index 250ce92..d0f7233 100644 --- a/drivers/virt/coco/sev-guest/sev-guest.c +++ b/drivers/virt/coco/sev-guest/sev-guest.c @@ -83,7 +83,7 @@ static DEFINE_MUTEX(snp_cmd_mutex); static void snp_disable_vmpck(struct snp_msg_desc *mdesc) { pr_alert("Disabling VMPCK%d communication key to prevent IV reuse.\n", - vmpck_id); + mdesc->vmpck_id); memzero_explicit(mdesc->vmpck, VMPCK_KEY_LEN); mdesc->vmpck =3D NULL; } @@ -137,23 +137,6 @@ static inline struct snp_guest_dev *to_snp_dev(struct = file *file) return container_of(dev, struct snp_guest_dev, misc); } =20 -static struct aesgcm_ctx *snp_init_crypto(u8 *key, size_t keylen) -{ - struct aesgcm_ctx *ctx; - - ctx =3D kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return NULL; - - if (aesgcm_expandkey(ctx, key, keylen, AUTHTAG_LEN)) { - pr_err("Crypto context initialization failed\n"); - kfree(ctx); - return NULL; - } - - return ctx; -} - static int verify_and_dec_payload(struct snp_msg_desc *mdesc, struct snp_g= uest_req *req) { struct snp_guest_msg *resp_msg =3D &mdesc->secret_response; @@ -404,7 +387,7 @@ static int get_report(struct snp_guest_dev *snp_dev, st= ruct snp_guest_request_io =20 req.msg_version =3D arg->msg_version; req.msg_type =3D SNP_MSG_REPORT_REQ; - req.vmpck_id =3D vmpck_id; + req.vmpck_id =3D mdesc->vmpck_id; req.req_buf =3D report_req; req.req_sz =3D sizeof(*report_req); req.resp_buf =3D report_resp->data; @@ -451,7 +434,7 @@ static int get_derived_key(struct snp_guest_dev *snp_de= v, struct snp_guest_reque =20 req.msg_version =3D arg->msg_version; req.msg_type =3D SNP_MSG_KEY_REQ; - req.vmpck_id =3D vmpck_id; + req.vmpck_id =3D mdesc->vmpck_id; req.req_buf =3D derived_key_req; req.req_sz =3D sizeof(*derived_key_req); req.resp_buf =3D buf; @@ -529,7 +512,7 @@ cmd: =20 req.msg_version =3D arg->msg_version; req.msg_type =3D SNP_MSG_REPORT_REQ; - req.vmpck_id =3D vmpck_id; + req.vmpck_id =3D mdesc->vmpck_id; req.req_buf =3D &report_req->data; req.req_sz =3D sizeof(report_req->data); req.resp_buf =3D report_resp->data; @@ -606,76 +589,11 @@ static long snp_guest_ioctl(struct file *file, unsign= ed int ioctl, unsigned long return ret; } =20 -static void free_shared_pages(void *buf, size_t sz) -{ - unsigned int npages =3D PAGE_ALIGN(sz) >> PAGE_SHIFT; - int ret; - - if (!buf) - return; - - ret =3D set_memory_encrypted((unsigned long)buf, npages); - if (ret) { - WARN_ONCE(ret, "failed to restore encryption mask (leak it)\n"); - return; - } - - __free_pages(virt_to_page(buf), get_order(sz)); -} - -static void *alloc_shared_pages(struct device *dev, size_t sz) -{ - unsigned int npages =3D PAGE_ALIGN(sz) >> PAGE_SHIFT; - struct page *page; - int ret; - - page =3D alloc_pages(GFP_KERNEL_ACCOUNT, get_order(sz)); - if (!page) - return NULL; - - ret =3D set_memory_decrypted((unsigned long)page_address(page), npages); - if (ret) { - dev_err(dev, "failed to mark page shared, ret=3D%d\n", ret); - __free_pages(page, get_order(sz)); - return NULL; - } - - return page_address(page); -} - static const struct file_operations snp_guest_fops =3D { .owner =3D THIS_MODULE, .unlocked_ioctl =3D snp_guest_ioctl, }; =20 -static u8 *get_vmpck(int id, struct snp_secrets_page *secrets, u32 **seqno) -{ - u8 *key =3D NULL; - - switch (id) { - case 0: - *seqno =3D &secrets->os_area.msg_seqno_0; - key =3D secrets->vmpck0; - break; - case 1: - *seqno =3D &secrets->os_area.msg_seqno_1; - key =3D secrets->vmpck1; - break; - case 2: - *seqno =3D &secrets->os_area.msg_seqno_2; - key =3D secrets->vmpck2; - break; - case 3: - *seqno =3D &secrets->os_area.msg_seqno_3; - key =3D secrets->vmpck3; - break; - default: - break; - } - - return key; -} - struct snp_msg_report_resp_hdr { u32 status; u32 report_size; @@ -969,13 +887,10 @@ static void unregister_sev_tsm(void *data) =20 static int __init sev_guest_probe(struct platform_device *pdev) { - struct sev_guest_platform_data *data; - struct snp_secrets_page *secrets; struct device *dev =3D &pdev->dev; struct snp_guest_dev *snp_dev; struct snp_msg_desc *mdesc; struct miscdevice *misc; - void __iomem *mapping; int ret; =20 BUILD_BUG_ON(sizeof(struct snp_guest_msg) > PAGE_SIZE); @@ -983,115 +898,57 @@ static int __init sev_guest_probe(struct platform_de= vice *pdev) if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) return -ENODEV; =20 - if (!dev->platform_data) - return -ENODEV; - - data =3D (struct sev_guest_platform_data *)dev->platform_data; - mapping =3D ioremap_encrypted(data->secrets_gpa, PAGE_SIZE); - if (!mapping) - return -ENODEV; - - secrets =3D (__force void *)mapping; - - ret =3D -ENOMEM; snp_dev =3D devm_kzalloc(&pdev->dev, sizeof(struct snp_guest_dev), GFP_KE= RNEL); if (!snp_dev) - goto e_unmap; - - mdesc =3D devm_kzalloc(&pdev->dev, sizeof(struct snp_msg_desc), GFP_KERNE= L); - if (!mdesc) - goto e_unmap; - - /* Adjust the default VMPCK key based on the executing VMPL level */ - if (vmpck_id =3D=3D -1) - vmpck_id =3D snp_vmpl; + return -ENOMEM; =20 - ret =3D -EINVAL; - mdesc->vmpck =3D get_vmpck(vmpck_id, secrets, &mdesc->os_area_msg_seqno); - if (!mdesc->vmpck) { - dev_err(dev, "Invalid VMPCK%d communication key\n", vmpck_id); - goto e_unmap; - } + mdesc =3D snp_msg_alloc(); + if (IS_ERR_OR_NULL(mdesc)) + return -ENOMEM; =20 - /* Verify that VMPCK is not zero. */ - if (!memchr_inv(mdesc->vmpck, 0, VMPCK_KEY_LEN)) { - dev_err(dev, "Empty VMPCK%d communication key\n", vmpck_id); - goto e_unmap; - } + ret =3D snp_msg_init(mdesc, vmpck_id); + if (ret) + goto e_msg_init; =20 platform_set_drvdata(pdev, snp_dev); snp_dev->dev =3D dev; - mdesc->secrets =3D secrets; - - /* Allocate the shared page used for the request and response message. */ - mdesc->request =3D alloc_shared_pages(dev, sizeof(struct snp_guest_msg)); - if (!mdesc->request) - goto e_unmap; - - mdesc->response =3D alloc_shared_pages(dev, sizeof(struct snp_guest_msg)); - if (!mdesc->response) - goto e_free_request; - - mdesc->certs_data =3D alloc_shared_pages(dev, SEV_FW_BLOB_MAX_SIZE); - if (!mdesc->certs_data) - goto e_free_response; - - ret =3D -EIO; - mdesc->ctx =3D snp_init_crypto(mdesc->vmpck, VMPCK_KEY_LEN); - if (!mdesc->ctx) - goto e_free_cert_data; =20 misc =3D &snp_dev->misc; misc->minor =3D MISC_DYNAMIC_MINOR; misc->name =3D DEVICE_NAME; misc->fops =3D &snp_guest_fops; =20 - /* Initialize the input addresses for guest request */ - mdesc->input.req_gpa =3D __pa(mdesc->request); - mdesc->input.resp_gpa =3D __pa(mdesc->response); - mdesc->input.data_gpa =3D __pa(mdesc->certs_data); - /* Set the privlevel_floor attribute based on the vmpck_id */ - sev_tsm_ops.privlevel_floor =3D vmpck_id; + sev_tsm_ops.privlevel_floor =3D mdesc->vmpck_id; =20 ret =3D tsm_register(&sev_tsm_ops, snp_dev); if (ret) - goto e_free_cert_data; + goto e_msg_init; =20 ret =3D devm_add_action_or_reset(&pdev->dev, unregister_sev_tsm, NULL); if (ret) - goto e_free_cert_data; + goto e_msg_init; =20 ret =3D misc_register(misc); if (ret) - goto e_free_ctx; + goto e_msg_init; =20 snp_dev->msg_desc =3D mdesc; - dev_info(dev, "Initialized SEV guest driver (using VMPCK%d communication = key)\n", vmpck_id); + dev_info(dev, "Initialized SEV guest driver (using VMPCK%d communication = key)\n", + mdesc->vmpck_id); return 0; =20 -e_free_ctx: - kfree(mdesc->ctx); -e_free_cert_data: - free_shared_pages(mdesc->certs_data, SEV_FW_BLOB_MAX_SIZE); -e_free_response: - free_shared_pages(mdesc->response, sizeof(struct snp_guest_msg)); -e_free_request: - free_shared_pages(mdesc->request, sizeof(struct snp_guest_msg)); -e_unmap: - iounmap(mapping); +e_msg_init: + snp_msg_free(mdesc); + return ret; } =20 static void __exit sev_guest_remove(struct platform_device *pdev) { struct snp_guest_dev *snp_dev =3D platform_get_drvdata(pdev); - struct snp_msg_desc *mdesc =3D snp_dev->msg_desc; =20 - free_shared_pages(mdesc->certs_data, SEV_FW_BLOB_MAX_SIZE); - free_shared_pages(mdesc->response, sizeof(struct snp_guest_msg)); - free_shared_pages(mdesc->request, sizeof(struct snp_guest_msg)); - kfree(mdesc->ctx); + snp_msg_free(snp_dev->msg_desc); misc_deregister(&snp_dev->misc); }