lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240621123903.2411843-10-nikunj@amd.com>
Date: Fri, 21 Jun 2024 18:08:48 +0530
From: Nikunj A Dadhania <nikunj@....com>
To: <linux-kernel@...r.kernel.org>, <thomas.lendacky@....com>, <bp@...en8.de>,
	<x86@...nel.org>, <kvm@...r.kernel.org>
CC: <mingo@...hat.com>, <tglx@...utronix.de>, <dave.hansen@...ux.intel.com>,
	<pgonda@...gle.com>, <seanjc@...gle.com>, <pbonzini@...hat.com>,
	<nikunj@....com>
Subject: [PATCH v10 09/24] virt: sev-guest: Carve out SNP guest messaging init/exit

In preparation for the movement of common code required for both SEV guest
driver and Secure TSC, carve out initializaton and cleanup routines.

While at it, the device pointer in alloc_shared_pages() is used only in the
print routines, replace dev_err() with pr_err() and drop the device pointer
from the function prototype.

Signed-off-by: Nikunj A Dadhania <nikunj@....com>
---
 drivers/virt/coco/sev-guest/sev-guest.c | 152 ++++++++++++++----------
 1 file changed, 88 insertions(+), 64 deletions(-)

diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c
index ed00c21ca821..ec1ae5c3f4be 100644
--- a/drivers/virt/coco/sev-guest/sev-guest.c
+++ b/drivers/virt/coco/sev-guest/sev-guest.c
@@ -161,6 +161,11 @@ static struct aesgcm_ctx *snp_init_crypto(struct snp_guest_dev *snp_dev)
 	struct aesgcm_ctx *ctx;
 	u8 *key;
 
+	if (is_vmpck_empty(snp_dev)) {
+		pr_err("VM communication key VMPCK%u is invalid\n", snp_dev->vmpck_id);
+		return NULL;
+	}
+
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL_ACCOUNT);
 	if (!ctx)
 		return NULL;
@@ -640,7 +645,7 @@ static void free_shared_pages(void *buf, size_t sz)
 	__free_pages(virt_to_page(buf), get_order(sz));
 }
 
-static void *alloc_shared_pages(struct device *dev, size_t sz)
+static void *alloc_shared_pages(size_t sz)
 {
 	unsigned int npages = PAGE_ALIGN(sz) >> PAGE_SHIFT;
 	struct page *page;
@@ -652,7 +657,7 @@ static void *alloc_shared_pages(struct device *dev, size_t sz)
 
 	ret = set_memory_decrypted((unsigned long)page_address(page), npages);
 	if (ret) {
-		dev_err(dev, "failed to mark page shared, ret=%d\n", ret);
+		pr_err("failed to mark page shared, ret=%d\n", ret);
 		__free_pages(page, get_order(sz));
 		return NULL;
 	}
@@ -972,14 +977,80 @@ static void unregister_sev_tsm(void *data)
 	tsm_unregister(&sev_tsm_ops);
 }
 
+static int snp_guest_messaging_init(struct snp_guest_dev *snp_dev, u64 secrets_gpa)
+{
+	int ret = -ENOMEM;
+
+	snp_dev->secrets = (__force void *)ioremap_encrypted(secrets_gpa, PAGE_SIZE);
+	if (!snp_dev->secrets) {
+		pr_err("Failed to map SNP secrets page.\n");
+		return ret;
+	}
+
+	/* Allocate secret request and response message for double buffering */
+	snp_dev->secret_request = kzalloc(SNP_GUEST_MSG_SIZE, GFP_KERNEL);
+	if (!snp_dev->secret_request)
+		goto e_unmap;
+
+	snp_dev->secret_response = kzalloc(SNP_GUEST_MSG_SIZE, GFP_KERNEL);
+	if (!snp_dev->secret_response)
+		goto e_free_secret_req;
+
+	/* Allocate the shared page used for the request and response message. */
+	snp_dev->request = alloc_shared_pages(SNP_GUEST_MSG_SIZE);
+	if (!snp_dev->request)
+		goto e_free_secret_resp;
+
+	snp_dev->response = alloc_shared_pages(SNP_GUEST_MSG_SIZE);
+	if (!snp_dev->response)
+		goto e_free_request;
+
+	/* Initialize the input addresses for guest request */
+	snp_dev->input.req_gpa = __pa(snp_dev->request);
+	snp_dev->input.resp_gpa = __pa(snp_dev->response);
+
+	ret = -EIO;
+	snp_dev->ctx = snp_init_crypto(snp_dev);
+	if (!snp_dev->ctx) {
+		pr_err("SNP crypto context initialization failed\n");
+		goto e_free_response;
+	}
+
+	return 0;
+
+e_free_response:
+	free_shared_pages(snp_dev->response, sizeof(struct snp_guest_msg));
+e_free_request:
+	free_shared_pages(snp_dev->request, sizeof(struct snp_guest_msg));
+e_free_secret_resp:
+	kfree(snp_dev->secret_response);
+e_free_secret_req:
+	kfree(snp_dev->secret_request);
+e_unmap:
+	iounmap(snp_dev->secrets);
+
+	return ret;
+}
+
+static void snp_guest_messaging_exit(struct snp_guest_dev *snp_dev)
+{
+	if (!snp_dev)
+		return;
+
+	kfree(snp_dev->ctx);
+	free_shared_pages(snp_dev->response, sizeof(struct snp_guest_msg));
+	free_shared_pages(snp_dev->request, sizeof(struct snp_guest_msg));
+	kfree(snp_dev->secret_response);
+	kfree(snp_dev->secret_request);
+	iounmap(snp_dev->secrets);
+}
+
 static int __init sev_guest_probe(struct platform_device *pdev)
 {
 	struct sev_guest_platform_data *data;
-	struct snp_secrets_page *secrets;
 	struct device *dev = &pdev->dev;
 	struct snp_guest_dev *snp_dev;
 	struct miscdevice *misc;
-	void __iomem *mapping;
 	int ret;
 
 	if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
@@ -989,73 +1060,40 @@ static int __init sev_guest_probe(struct platform_device *pdev)
 		return -ENODEV;
 
 	data = (struct sev_guest_platform_data *)dev->platform_data;
-	mapping = ioremap_encrypted(data->secrets_gpa, PAGE_SIZE);
-	if (!mapping)
-		return -ENODEV;
-
-	secrets = (__force void *)mapping;
 
-	ret = -ENOMEM;
 	snp_dev = devm_kzalloc(&pdev->dev, sizeof(struct snp_guest_dev), GFP_KERNEL);
 	if (!snp_dev)
-		goto e_unmap;
+		return -ENOMEM;
 
 	/* Adjust the default VMPCK key based on the executing VMPL level */
 	if (vmpck_id == VMPCK_MAX_NUM)
 		vmpck_id = snp_vmpl;
 
 	ret = -EINVAL;
-	snp_dev->secrets = secrets;
 	if (!assign_vmpck(snp_dev, vmpck_id)) {
 		dev_err(dev, "Invalid VMPCK%d communication key\n", vmpck_id);
-		goto e_unmap;
+		return ret;
 	}
 
-	/* Verify that VMPCK is not zero. */
-	if (is_vmpck_empty(snp_dev)) {
-		dev_err(dev, "Empty VMPCK%d communication key\n", snp_dev->vmpck_id);
-		goto e_unmap;
+	if (snp_guest_messaging_init(snp_dev, data->secrets_gpa)) {
+		dev_err(dev, "Unable to setup SNP Guest messaging using VMPCK%u\n",
+			snp_dev->vmpck_id);
+		return ret;
 	}
 
 	platform_set_drvdata(pdev, snp_dev);
 	snp_dev->dev = dev;
 
-	/* Allocate secret request and response message for double buffering */
-	snp_dev->secret_request = kzalloc(SNP_GUEST_MSG_SIZE, GFP_KERNEL);
-	if (!snp_dev->secret_request)
-		goto e_unmap;
-
-	snp_dev->secret_response = kzalloc(SNP_GUEST_MSG_SIZE, GFP_KERNEL);
-	if (!snp_dev->secret_response)
-		goto e_free_secret_req;
-
-	/* Allocate the shared page used for the request and response message. */
-	snp_dev->request = alloc_shared_pages(dev, SNP_GUEST_MSG_SIZE);
-	if (!snp_dev->request)
-		goto e_free_secret_resp;
-
-	snp_dev->response = alloc_shared_pages(dev, SNP_GUEST_MSG_SIZE);
-	if (!snp_dev->response)
-		goto e_free_request;
-
-	snp_dev->certs_data = alloc_shared_pages(dev, SEV_FW_BLOB_MAX_SIZE);
+	ret = -ENOMEM;
+	snp_dev->certs_data = alloc_shared_pages(SEV_FW_BLOB_MAX_SIZE);
 	if (!snp_dev->certs_data)
-		goto e_free_response;
-
-	ret = -EIO;
-	snp_dev->ctx = snp_init_crypto(snp_dev);
-	if (!snp_dev->ctx)
-		goto e_free_cert_data;
+		goto e_cleanup_msg_init;
 
 	misc = &snp_dev->misc;
 	misc->minor = MISC_DYNAMIC_MINOR;
 	misc->name = DEVICE_NAME;
 	misc->fops = &snp_guest_fops;
 
-	/* Initialize the input addresses for guest request */
-	snp_dev->input.req_gpa = __pa(snp_dev->request);
-	snp_dev->input.resp_gpa = __pa(snp_dev->response);
-
 	/* Set the privlevel_floor attribute based on the vmpck_id */
 	sev_tsm_ops.privlevel_floor = vmpck_id;
 
@@ -1069,25 +1107,15 @@ static int __init sev_guest_probe(struct platform_device *pdev)
 
 	ret =  misc_register(misc);
 	if (ret)
-		goto e_free_ctx;
+		goto e_free_cert_data;
 
 	dev_info(dev, "Initialized SEV guest driver (using VMPCK%d communication key)\n", vmpck_id);
 	return 0;
 
-e_free_ctx:
-	kfree(snp_dev->ctx);
 e_free_cert_data:
 	free_shared_pages(snp_dev->certs_data, SEV_FW_BLOB_MAX_SIZE);
-e_free_response:
-	free_shared_pages(snp_dev->response, SNP_GUEST_MSG_SIZE);
-e_free_request:
-	free_shared_pages(snp_dev->request, SNP_GUEST_MSG_SIZE);
-e_free_secret_resp:
-	kfree(snp_dev->secret_response);
-e_free_secret_req:
-	kfree(snp_dev->secret_request);
-e_unmap:
-	iounmap(mapping);
+e_cleanup_msg_init:
+	snp_guest_messaging_exit(snp_dev);
 	return ret;
 }
 
@@ -1096,11 +1124,7 @@ static void __exit sev_guest_remove(struct platform_device *pdev)
 	struct snp_guest_dev *snp_dev = platform_get_drvdata(pdev);
 
 	free_shared_pages(snp_dev->certs_data, SEV_FW_BLOB_MAX_SIZE);
-	free_shared_pages(snp_dev->response, SNP_GUEST_MSG_SIZE);
-	free_shared_pages(snp_dev->request, SNP_GUEST_MSG_SIZE);
-	kfree(snp_dev->secret_response);
-	kfree(snp_dev->secret_request);
-	kfree(snp_dev->ctx);
+	snp_guest_messaging_exit(snp_dev);
 	misc_deregister(&snp_dev->misc);
 }
 
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ