mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "tip-bot2 for Brijesh Singh" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: Brijesh Singh <brijesh.singh@amd.com>,
	Ashish Kalra <ashish.kalra@amd.com>,
	Michael Roth <michael.roth@amd.com>,
	"Borislav Petkov (AMD)" <bp@alien8.de>,
	x86@kernel.org, linux-kernel@vger.kernel.org
Subject: [tip: x86/sev] crypto: ccp: Handle the legacy TMR allocation when SNP is enabled
Date: Tue, 30 Jan 2024 16:26:03 -0000	[thread overview]
Message-ID: <170663196323.398.4233160033064909038.tip-bot2@tip-bot2> (raw)
In-Reply-To: <20240126041126.1927228-17-michael.roth@amd.com>

The following commit has been merged into the x86/sev branch of tip:

Commit-ID:     24512afa4336a1c14de750238abe32759cfba4b0
Gitweb:        https://git.kernel.org/tip/24512afa4336a1c14de750238abe32759cfba4b0
Author:        Brijesh Singh <brijesh.singh@amd.com>
AuthorDate:    Thu, 25 Jan 2024 22:11:16 -06:00
Committer:     Borislav Petkov (AMD) <bp@alien8.de>
CommitterDate: Mon, 29 Jan 2024 20:34:18 +01:00

crypto: ccp: Handle the legacy TMR allocation when SNP is enabled

The behavior and requirement for the SEV-legacy command is altered when
the SNP firmware is in the INIT state. See SEV-SNP firmware ABI
specification for more details.

Allocate the Trusted Memory Region (TMR) as a 2MB-sized/aligned region
when SNP is enabled to satisfy new requirements for SNP. Continue
allocating a 1MB-sized region for !SNP configuration.

  [ bp: Carve out TMR allocation into a helper. ]

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Co-developed-by: Ashish Kalra <ashish.kalra@amd.com>
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20240126041126.1927228-17-michael.roth@amd.com
---
 drivers/crypto/ccp/sev-dev.c | 193 +++++++++++++++++++++++++++++-----
 include/linux/psp-sev.h      |   9 ++-
 2 files changed, 176 insertions(+), 26 deletions(-)

diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
index abee1a6..70aabd1 100644
--- a/drivers/crypto/ccp/sev-dev.c
+++ b/drivers/crypto/ccp/sev-dev.c
@@ -30,6 +30,7 @@
 #include <asm/smp.h>
 #include <asm/cacheflush.h>
 #include <asm/e820/types.h>
+#include <asm/sev.h>
 
 #include "psp-dev.h"
 #include "sev-dev.h"
@@ -73,9 +74,14 @@ static int psp_timeout;
  *   The TMR is a 1MB area that must be 1MB aligned.  Use the page allocator
  *   to allocate the memory, which will return aligned memory for the specified
  *   allocation order.
+ *
+ * When SEV-SNP is enabled the TMR needs to be 2MB aligned and 2MB sized.
  */
-#define SEV_ES_TMR_SIZE		(1024 * 1024)
+#define SEV_TMR_SIZE		(1024 * 1024)
+#define SNP_TMR_SIZE		(2 * 1024 * 1024)
+
 static void *sev_es_tmr;
+static size_t sev_es_tmr_size = SEV_TMR_SIZE;
 
 /* INIT_EX NV Storage:
  *   The NV Storage is a 32Kb area and must be 4Kb page aligned.  Use the page
@@ -192,17 +198,6 @@ static int sev_cmd_buffer_len(int cmd)
 	return 0;
 }
 
-static void *sev_fw_alloc(unsigned long len)
-{
-	struct page *page;
-
-	page = alloc_pages(GFP_KERNEL, get_order(len));
-	if (!page)
-		return NULL;
-
-	return page_address(page);
-}
-
 static struct file *open_file_as_root(const char *filename, int flags, umode_t mode)
 {
 	struct file *fp;
@@ -333,6 +328,142 @@ static int sev_write_init_ex_file_if_required(int cmd_id)
 	return sev_write_init_ex_file();
 }
 
+/*
+ * snp_reclaim_pages() needs __sev_do_cmd_locked(), and __sev_do_cmd_locked()
+ * needs snp_reclaim_pages(), so a forward declaration is needed.
+ */
+static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret);
+
+static int snp_reclaim_pages(unsigned long paddr, unsigned int npages, bool locked)
+{
+	int ret, err, i;
+
+	paddr = __sme_clr(ALIGN_DOWN(paddr, PAGE_SIZE));
+
+	for (i = 0; i < npages; i++, paddr += PAGE_SIZE) {
+		struct sev_data_snp_page_reclaim data = {0};
+
+		data.paddr = paddr;
+
+		if (locked)
+			ret = __sev_do_cmd_locked(SEV_CMD_SNP_PAGE_RECLAIM, &data, &err);
+		else
+			ret = sev_do_cmd(SEV_CMD_SNP_PAGE_RECLAIM, &data, &err);
+
+		if (ret)
+			goto cleanup;
+
+		ret = rmp_make_shared(__phys_to_pfn(paddr), PG_LEVEL_4K);
+		if (ret)
+			goto cleanup;
+	}
+
+	return 0;
+
+cleanup:
+	/*
+	 * If there was a failure reclaiming the page then it is no longer safe
+	 * to release it back to the system; leak it instead.
+	 */
+	snp_leak_pages(__phys_to_pfn(paddr), npages - i);
+	return ret;
+}
+
+static int rmp_mark_pages_firmware(unsigned long paddr, unsigned int npages, bool locked)
+{
+	unsigned long pfn = __sme_clr(paddr) >> PAGE_SHIFT;
+	int rc, i;
+
+	for (i = 0; i < npages; i++, pfn++) {
+		rc = rmp_make_private(pfn, 0, PG_LEVEL_4K, 0, true);
+		if (rc)
+			goto cleanup;
+	}
+
+	return 0;
+
+cleanup:
+	/*
+	 * Try unrolling the firmware state changes by
+	 * reclaiming the pages which were already changed to the
+	 * firmware state.
+	 */
+	snp_reclaim_pages(paddr, i, locked);
+
+	return rc;
+}
+
+static struct page *__snp_alloc_firmware_pages(gfp_t gfp_mask, int order)
+{
+	unsigned long npages = 1ul << order, paddr;
+	struct sev_device *sev;
+	struct page *page;
+
+	if (!psp_master || !psp_master->sev_data)
+		return NULL;
+
+	page = alloc_pages(gfp_mask, order);
+	if (!page)
+		return NULL;
+
+	/* If SEV-SNP is initialized then add the page in RMP table. */
+	sev = psp_master->sev_data;
+	if (!sev->snp_initialized)
+		return page;
+
+	paddr = __pa((unsigned long)page_address(page));
+	if (rmp_mark_pages_firmware(paddr, npages, false))
+		return NULL;
+
+	return page;
+}
+
+void *snp_alloc_firmware_page(gfp_t gfp_mask)
+{
+	struct page *page;
+
+	page = __snp_alloc_firmware_pages(gfp_mask, 0);
+
+	return page ? page_address(page) : NULL;
+}
+EXPORT_SYMBOL_GPL(snp_alloc_firmware_page);
+
+static void __snp_free_firmware_pages(struct page *page, int order, bool locked)
+{
+	struct sev_device *sev = psp_master->sev_data;
+	unsigned long paddr, npages = 1ul << order;
+
+	if (!page)
+		return;
+
+	paddr = __pa((unsigned long)page_address(page));
+	if (sev->snp_initialized &&
+	    snp_reclaim_pages(paddr, npages, locked))
+		return;
+
+	__free_pages(page, order);
+}
+
+void snp_free_firmware_page(void *addr)
+{
+	if (!addr)
+		return;
+
+	__snp_free_firmware_pages(virt_to_page(addr), 0, false);
+}
+EXPORT_SYMBOL_GPL(snp_free_firmware_page);
+
+static void *sev_fw_alloc(unsigned long len)
+{
+	struct page *page;
+
+	page = __snp_alloc_firmware_pages(GFP_KERNEL, get_order(len));
+	if (!page)
+		return NULL;
+
+	return page_address(page);
+}
+
 static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
 {
 	struct psp_device *psp = psp_master;
@@ -456,7 +587,7 @@ static int __sev_init_locked(int *error)
 		data.tmr_address = __pa(sev_es_tmr);
 
 		data.flags |= SEV_INIT_FLAGS_SEV_ES;
-		data.tmr_len = SEV_ES_TMR_SIZE;
+		data.tmr_len = sev_es_tmr_size;
 	}
 
 	return __sev_do_cmd_locked(SEV_CMD_INIT, &data, error);
@@ -479,7 +610,7 @@ static int __sev_init_ex_locked(int *error)
 		data.tmr_address = __pa(sev_es_tmr);
 
 		data.flags |= SEV_INIT_FLAGS_SEV_ES;
-		data.tmr_len = SEV_ES_TMR_SIZE;
+		data.tmr_len = sev_es_tmr_size;
 	}
 
 	return __sev_do_cmd_locked(SEV_CMD_INIT_EX, &data, error);
@@ -623,9 +754,27 @@ static int __sev_snp_init_locked(int *error)
 	sev->snp_initialized = true;
 	dev_dbg(sev->dev, "SEV-SNP firmware initialized\n");
 
+	sev_es_tmr_size = SNP_TMR_SIZE;
+
 	return rc;
 }
 
+static void __sev_platform_init_handle_tmr(struct sev_device *sev)
+{
+	if (sev_es_tmr)
+		return;
+
+	/* Obtain the TMR memory area for SEV-ES use */
+	sev_es_tmr = sev_fw_alloc(sev_es_tmr_size);
+	if (sev_es_tmr) {
+		/* Must flush the cache before giving it to the firmware */
+		if (!sev->snp_initialized)
+			clflush_cache_range(sev_es_tmr, sev_es_tmr_size);
+	} else {
+			dev_warn(sev->dev, "SEV: TMR allocation failed, SEV-ES support unavailable\n");
+	}
+}
+
 static int __sev_platform_init_locked(int *error)
 {
 	int rc, psp_ret = SEV_RET_NO_FW_CALL;
@@ -639,16 +788,7 @@ static int __sev_platform_init_locked(int *error)
 	if (sev->state == SEV_STATE_INIT)
 		return 0;
 
-	if (!sev_es_tmr) {
-		/* Obtain the TMR memory area for SEV-ES use */
-		sev_es_tmr = sev_fw_alloc(SEV_ES_TMR_SIZE);
-		if (sev_es_tmr)
-			/* Must flush the cache before giving it to the firmware */
-			clflush_cache_range(sev_es_tmr, SEV_ES_TMR_SIZE);
-		else
-			dev_warn(sev->dev,
-				 "SEV: TMR allocation failed, SEV-ES support unavailable\n");
-		}
+	__sev_platform_init_handle_tmr(sev);
 
 	if (sev_init_ex_buffer) {
 		rc = sev_read_init_ex_file();
@@ -1546,8 +1686,9 @@ static void sev_firmware_shutdown(struct sev_device *sev)
 		/* The TMR area was encrypted, flush it from the cache */
 		wbinvd_on_all_cpus();
 
-		free_pages((unsigned long)sev_es_tmr,
-			   get_order(SEV_ES_TMR_SIZE));
+		__snp_free_firmware_pages(virt_to_page(sev_es_tmr),
+					  get_order(sev_es_tmr_size),
+					  false);
 		sev_es_tmr = NULL;
 	}
 
diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h
index bcf9ced..84eabbf 100644
--- a/include/linux/psp-sev.h
+++ b/include/linux/psp-sev.h
@@ -932,6 +932,8 @@ int sev_guest_decommission(struct sev_data_decommission *data, int *error);
 int sev_do_cmd(int cmd, void *data, int *psp_ret);
 
 void *psp_copy_user_blob(u64 uaddr, u32 len);
+void *snp_alloc_firmware_page(gfp_t mask);
+void snp_free_firmware_page(void *addr);
 
 #else	/* !CONFIG_CRYPTO_DEV_SP_PSP */
 
@@ -959,6 +961,13 @@ sev_issue_cmd_external_user(struct file *filep, unsigned int id, void *data, int
 
 static inline void *psp_copy_user_blob(u64 __user uaddr, u32 len) { return ERR_PTR(-EINVAL); }
 
+static inline void *snp_alloc_firmware_page(gfp_t mask)
+{
+	return NULL;
+}
+
+static inline void snp_free_firmware_page(void *addr) { }
+
 #endif	/* CONFIG_CRYPTO_DEV_SP_PSP */
 
 #endif	/* __PSP_SEV_H__ */

  parent reply	other threads:[~2024-01-30 16:26 UTC|newest]

Thread overview: 73+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-26  4:11 [PATCH v2 00/25] Add AMD Secure Nested Paging (SEV-SNP) Initialization Support Michael Roth
2024-01-26  4:11 ` [PATCH v2 01/25] x86/cpufeatures: Add SEV-SNP CPU feature Michael Roth
2024-01-30 16:26   ` [tip: x86/sev] " tip-bot2 for Brijesh Singh
2024-01-26  4:11 ` [PATCH v2 02/25] x86/speculation: Do not enable Automatic IBRS if SEV SNP is enabled Michael Roth
2024-01-30 16:26   ` [tip: x86/sev] x86/speculation: Do not enable Automatic IBRS if SEV-SNP " tip-bot2 for Kim Phillips
2024-01-26  4:11 ` [PATCH v2 03/25] iommu/amd: Don't rely on external callers to enable IOMMU SNP support Michael Roth
2024-01-30 16:26   ` [tip: x86/sev] " tip-bot2 for Ashish Kalra
2024-01-26  4:11 ` [PATCH v2 04/25] x86/sev: Add the host SEV-SNP initialization support Michael Roth
2024-01-30 16:26   ` [tip: x86/sev] x86/sev: Add SEV-SNP host " tip-bot2 for Brijesh Singh
2024-01-26  4:11 ` [PATCH v2 05/25] x86/mtrr: Don't print errors if MtrrFixDramModEn is set when SNP enabled Michael Roth
2024-01-30 16:26   ` [tip: x86/sev] " tip-bot2 for Ashish Kalra
2024-01-26  4:11 ` [PATCH v2 06/25] x86/sev: Add RMP entry lookup helpers Michael Roth
2024-01-30 16:26   ` [tip: x86/sev] " tip-bot2 for Brijesh Singh
2024-01-26  4:11 ` [PATCH v2 07/25] x86/fault: Add helper for dumping RMP entries Michael Roth
2024-01-30 16:26   ` [tip: x86/sev] " tip-bot2 for Brijesh Singh
2024-01-26  4:11 ` [PATCH v2 08/25] x86/traps: Define RMP violation #PF error code Michael Roth
2024-01-30 16:26   ` [tip: x86/sev] " tip-bot2 for Brijesh Singh
2024-01-26  4:11 ` [PATCH v2 09/25] x86/fault: Dump RMP table information when RMP page faults occur Michael Roth
2024-01-30 16:26   ` [tip: x86/sev] " tip-bot2 for Michael Roth
2024-01-26  4:11 ` [PATCH v2 10/25] x86/sev: Add helper functions for RMPUPDATE and PSMASH instruction Michael Roth
2024-01-29 18:00   ` Liam Merwick
2024-01-29 19:28     ` Borislav Petkov
2024-01-29 19:33       ` Borislav Petkov
2024-01-30 16:26   ` [tip: x86/sev] " tip-bot2 for Brijesh Singh
2024-01-26  4:11 ` [PATCH v2 11/25] x86/sev: Adjust directmap to avoid inadvertant RMP faults Michael Roth
2024-01-26 15:34   ` Borislav Petkov
2024-01-26 17:04     ` Michael Roth
2024-01-26 18:43       ` Borislav Petkov
2024-01-26 23:54         ` Michael Roth
2024-01-27 11:42           ` Borislav Petkov
2024-01-27 15:45             ` Michael Roth
2024-01-27 16:02               ` Borislav Petkov
2024-01-29 11:59                 ` Borislav Petkov
2024-01-29 15:26                   ` Vlastimil Babka
2024-01-30 16:26   ` [tip: x86/sev] x86/sev: Adjust the directmap to avoid inadvertent " tip-bot2 for Michael Roth
2024-01-26  4:11 ` [PATCH v2 12/25] crypto: ccp: Define the SEV-SNP commands Michael Roth
2024-01-30 16:26   ` [tip: x86/sev] " tip-bot2 for Brijesh Singh
2024-01-26  4:11 ` [PATCH v2 13/25] crypto: ccp: Add support to initialize the AMD-SP for SEV-SNP Michael Roth
2024-01-29 17:58   ` Borislav Petkov
2024-01-30 16:26   ` [tip: x86/sev] " tip-bot2 for Brijesh Singh
2024-01-26  4:11 ` [PATCH v2 14/25] crypto: ccp: Provide API to issue SEV and SNP commands Michael Roth
2024-01-30 16:26   ` [tip: x86/sev] crypto: ccp: Provide an " tip-bot2 for Brijesh Singh
2024-01-26  4:11 ` [PATCH v2 15/25] x86/sev: Introduce snp leaked pages list Michael Roth
2024-01-29 14:26   ` Vlastimil Babka
2024-01-29 14:29     ` Borislav Petkov
2024-01-30 16:26   ` [tip: x86/sev] x86/sev: Introduce an SNP " tip-bot2 for Ashish Kalra
2024-01-26  4:11 ` [PATCH v2 16/25] crypto: ccp: Handle the legacy TMR allocation when SNP is enabled Michael Roth
2024-01-29 15:04   ` Borislav Petkov
2024-01-30 16:26   ` tip-bot2 for Brijesh Singh [this message]
2024-01-26  4:11 ` [PATCH v2 17/25] crypto: ccp: Handle non-volatile INIT_EX data " Michael Roth
2024-01-29 15:12   ` Borislav Petkov
2024-01-30 16:26   ` [tip: x86/sev] " tip-bot2 for Tom Lendacky
2024-01-26  4:11 ` [PATCH v2 18/25] crypto: ccp: Handle legacy SEV commands " Michael Roth
2024-01-30 16:26   ` [tip: x86/sev] " tip-bot2 for Brijesh Singh
2024-01-26  4:11 ` [PATCH v2 19/25] iommu/amd: Clean up RMP entries for IOMMU pages during SNP shutdown Michael Roth
2024-01-30 16:26   ` [tip: x86/sev] " tip-bot2 for Ashish Kalra
2024-02-07 17:13   ` [tip: x86/sev] iommu/amd: Fix failure return from snp_lookup_rmpentry() tip-bot2 for Ashish Kalra
2024-01-26  4:11 ` [PATCH v2 20/25] crypto: ccp: Add panic notifier for SEV/SNP firmware shutdown on kdump Michael Roth
2024-01-30 16:25   ` [tip: x86/sev] " tip-bot2 for Ashish Kalra
2024-01-26  4:11 ` [PATCH v2 21/25] KVM: SEV: Make AVIC backing, VMSA and VMCB memory allocation SNP safe Michael Roth
2024-01-26 11:00   ` Paolo Bonzini
2024-01-30 16:25   ` [tip: x86/sev] " tip-bot2 for Brijesh Singh
2024-01-26  4:11 ` [PATCH v2 22/25] x86/cpufeatures: Enable/unmask SEV-SNP CPU feature Michael Roth
2024-01-30 16:25   ` [tip: x86/sev] " tip-bot2 for Michael Roth
2024-01-26  4:11 ` [PATCH v2 23/25] crypto: ccp: Add the SNP_PLATFORM_STATUS command Michael Roth
2024-01-30 16:25   ` [tip: x86/sev] " tip-bot2 for Brijesh Singh
2024-01-26  4:11 ` [PATCH v2 24/25] crypto: ccp: Add the SNP_COMMIT command Michael Roth
2024-01-30 16:25   ` [tip: x86/sev] " tip-bot2 for Tom Lendacky
2024-01-26  4:11 ` [PATCH v2 25/25] crypto: ccp: Add the SNP_SET_CONFIG command Michael Roth
2024-01-29 19:18   ` Liam Merwick
2024-01-29 20:10     ` Michael Roth
2024-01-30 16:25   ` [tip: x86/sev] " tip-bot2 for Brijesh Singh
2024-01-30 16:19 ` [PATCH v2 00/25] Add AMD Secure Nested Paging (SEV-SNP) Initialization Support Borislav Petkov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=170663196323.398.4233160033064909038.tip-bot2@tip-bot2 \
    --to=tip-bot2@linutronix.de \
    --cc=ashish.kalra@amd.com \
    --cc=bp@alien8.de \
    --cc=brijesh.singh@amd.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=michael.roth@amd.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®