From: Michael Roth <michael.roth@amd.com>
To: <x86@kernel.org>
Cc: <kvm@vger.kernel.org>, <linux-coco@lists.linux.dev>,
<linux-mm@kvack.org>, <linux-crypto@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, <tglx@linutronix.de>,
<mingo@redhat.com>, <jroedel@suse.de>, <thomas.lendacky@amd.com>,
<hpa@zytor.com>, <ardb@kernel.org>, <pbonzini@redhat.com>,
<seanjc@google.com>, <vkuznets@redhat.com>, <jmattson@google.com>,
<luto@kernel.org>, <dave.hansen@linux.intel.com>,
<slp@redhat.com>, <pgonda@google.com>, <peterz@infradead.org>,
<srinivas.pandruvada@linux.intel.com>, <rientjes@google.com>,
<tobin@ibm.com>, <bp@alien8.de>, <vbabka@suse.cz>,
<kirill@shutemov.name>, <ak@linux.intel.com>,
<tony.luck@intel.com>,
<sathyanarayanan.kuppuswamy@linux.intel.com>,
<alpergun@google.com>, <jarkko@kernel.org>,
<ashish.kalra@amd.com>, <nikunj.dadhania@amd.com>,
<pankaj.gupta@amd.com>, <liam.merwick@oracle.com>,
<zhi.a.wang@intel.com>
Subject: [PATCH v1 17/26] crypto: ccp: Handle non-volatile INIT_EX data when SNP is enabled
Date: Sat, 30 Dec 2023 10:19:45 -0600 [thread overview]
Message-ID: <20231230161954.569267-18-michael.roth@amd.com> (raw)
In-Reply-To: <20231230161954.569267-1-michael.roth@amd.com>
From: Tom Lendacky <thomas.lendacky@amd.com>
For SEV/SEV-ES, a buffer can be used to access non-volatile data so it
can be initialized from a specified by the init_ex_path CCP module
parameter instead of relying on the SPI bus for NV storage, and
afterward the buffer can be read from to sync new data back to the file.
When SNP is enabled, the pages comprising this buffer need to be set to
firmware-owned in the RMP table before they can be accessed by firmware
for subsequent updates to the initial contents.
Implement that handling here.
Setting these pages to firmware-owned will also result in them being
removed from the kernel direct map, since generally the hypervisor does
not access firmware-owned pages. However, in this exceptional case,
the hypervisor does need to read the buffer to transfer updated contents
back to the file at init_ex_path.
Support this by using vmap() to create temporary mappings to the
firmware-owned buffer whenever accesses are made, and rework the
existing code to track the struct page corresponding to the start of the
buffer rather than the virtual address that was previously provided via
the direct map.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Co-developed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
drivers/crypto/ccp/sev-dev.c | 104 ++++++++++++++++++++++++++---------
1 file changed, 79 insertions(+), 25 deletions(-)
diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
index 307eb3e7c354..dfe7f7afc411 100644
--- a/drivers/crypto/ccp/sev-dev.c
+++ b/drivers/crypto/ccp/sev-dev.c
@@ -88,8 +88,9 @@ static size_t sev_es_tmr_size = SEV_TMR_SIZE;
* allocator to allocate the memory, which will return aligned memory for the
* specified allocation order.
*/
-#define NV_LENGTH (32 * 1024)
-static void *sev_init_ex_buffer;
+#define NV_LENGTH (32 * 1024)
+#define NV_PAGES (NV_LENGTH >> PAGE_SHIFT)
+static struct page *sev_init_ex_page;
/*
* SEV_DATA_RANGE_LIST:
@@ -231,7 +232,7 @@ static int sev_read_init_ex_file(void)
lockdep_assert_held(&sev_cmd_mutex);
- if (!sev_init_ex_buffer)
+ if (!sev_init_ex_page)
return -EOPNOTSUPP;
fp = open_file_as_root(init_ex_path, O_RDONLY, 0);
@@ -251,7 +252,7 @@ static int sev_read_init_ex_file(void)
return ret;
}
- nread = kernel_read(fp, sev_init_ex_buffer, NV_LENGTH, NULL);
+ nread = kernel_read(fp, page_to_virt(sev_init_ex_page), NV_LENGTH, NULL);
if (nread != NV_LENGTH) {
dev_info(sev->dev,
"SEV: could not read %u bytes to non volatile memory area, ret %ld\n",
@@ -264,16 +265,44 @@ static int sev_read_init_ex_file(void)
return 0;
}
+/*
+ * When SNP is enabled, the pages comprising the buffer used to populate
+ * the file specified by the init_ex_path module parameter needs to be set
+ * to firmware-owned, which removes the mapping from the kernel direct
+ * mapping since generally the hypervisor does not access firmware-owned
+ * pages. However, in this case the hypervisor does need to read the
+ * buffer to transfer the contents to the file at init_ex_path, so this
+ * function is used to create a temporary virtual mapping to be used for
+ * this purpose.
+ */
+static void *vmap_sev_init_ex_buffer(void)
+{
+ struct page *pages[NV_PAGES];
+ unsigned long base_pfn;
+ int i;
+
+ if (WARN_ON_ONCE(!sev_init_ex_page))
+ return NULL;
+
+ base_pfn = page_to_pfn(sev_init_ex_page);
+
+ for (i = 0; i < NV_PAGES; i++)
+ pages[i] = pfn_to_page(base_pfn + i);
+
+ return vmap(pages, NV_PAGES, VM_MAP, PAGE_KERNEL_RO);
+}
+
static int sev_write_init_ex_file(void)
{
struct sev_device *sev = psp_master->sev_data;
+ void *sev_init_ex_buffer;
struct file *fp;
loff_t offset = 0;
ssize_t nwrite;
lockdep_assert_held(&sev_cmd_mutex);
- if (!sev_init_ex_buffer)
+ if (!sev_init_ex_page)
return 0;
fp = open_file_as_root(init_ex_path, O_CREAT | O_WRONLY, 0600);
@@ -286,6 +315,12 @@ static int sev_write_init_ex_file(void)
return ret;
}
+ sev_init_ex_buffer = vmap_sev_init_ex_buffer();
+ if (!sev_init_ex_buffer) {
+ dev_err(sev->dev, "SEV: failed to map non-volative memory area\n");
+ return -EIO;
+ }
+
nwrite = kernel_write(fp, sev_init_ex_buffer, NV_LENGTH, &offset);
vfs_fsync(fp, 0);
filp_close(fp, NULL);
@@ -294,10 +329,12 @@ static int sev_write_init_ex_file(void)
dev_err(sev->dev,
"SEV: failed to write %u bytes to non volatile memory area, ret %ld\n",
NV_LENGTH, nwrite);
+ vunmap(sev_init_ex_buffer);
return -EIO;
}
dev_dbg(sev->dev, "SEV: write successful to NV file\n");
+ vunmap(sev_init_ex_buffer);
return 0;
}
@@ -306,7 +343,7 @@ static int sev_write_init_ex_file_if_required(int cmd_id)
{
lockdep_assert_held(&sev_cmd_mutex);
- if (!sev_init_ex_buffer)
+ if (!sev_init_ex_page)
return 0;
/*
@@ -599,7 +636,7 @@ static int __sev_init_ex_locked(int *error)
memset(&data, 0, sizeof(data));
data.length = sizeof(data);
- data.nv_address = __psp_pa(sev_init_ex_buffer);
+ data.nv_address = sme_me_mask | PFN_PHYS(page_to_pfn(sev_init_ex_page));
data.nv_len = NV_LENGTH;
if (sev_es_tmr) {
@@ -618,7 +655,7 @@ static int __sev_init_ex_locked(int *error)
static inline int __sev_do_init_locked(int *psp_ret)
{
- if (sev_init_ex_buffer)
+ if (sev_init_ex_page)
return __sev_init_ex_locked(psp_ret);
else
return __sev_init_locked(psp_ret);
@@ -787,10 +824,38 @@ static int __sev_platform_init_locked(int *error)
}
}
- if (sev_init_ex_buffer) {
+ /*
+ * If an init_ex_path is provided allocate a buffer for the file and
+ * read in the contents. Additionally, if SNP is initialized, convert
+ * the buffer pages to firmware pages.
+ */
+ if (init_ex_path && !sev_init_ex_page) {
+ struct page *page;
+
+ page = alloc_pages(GFP_KERNEL, get_order(NV_LENGTH));
+ if (!page) {
+ dev_err(sev->dev, "SEV: INIT_EX NV memory allocation failed\n");
+ return -ENOMEM;
+ }
+
+ sev_init_ex_page = page;
+
rc = sev_read_init_ex_file();
if (rc)
return rc;
+
+ /* If SEV-SNP is initialized, transition to firmware page. */
+ if (sev->snp_initialized) {
+ unsigned long npages;
+
+ npages = 1UL << get_order(NV_LENGTH);
+ if (rmp_mark_pages_firmware(PFN_PHYS(page_to_pfn(sev_init_ex_page)),
+ npages, false)) {
+ dev_err(sev->dev,
+ "SEV: INIT_EX NV memory page state change failed.\n");
+ return -ENOMEM;
+ }
+ }
}
rc = __sev_do_init_locked(&psp_ret);
@@ -1689,10 +1754,11 @@ static void sev_firmware_shutdown(struct sev_device *sev)
sev_es_tmr = NULL;
}
- if (sev_init_ex_buffer) {
- free_pages((unsigned long)sev_init_ex_buffer,
- get_order(NV_LENGTH));
- sev_init_ex_buffer = NULL;
+ if (sev_init_ex_page) {
+ __snp_free_firmware_pages(sev_init_ex_page,
+ get_order(NV_LENGTH),
+ true);
+ sev_init_ex_page = NULL;
}
if (snp_range_list) {
@@ -1745,18 +1811,6 @@ void sev_pci_init(void)
if (sev_update_firmware(sev->dev) == 0)
sev_get_api_version();
- /* If an init_ex_path is provided rely on INIT_EX for PSP initialization
- * instead of INIT.
- */
- if (init_ex_path) {
- sev_init_ex_buffer = sev_fw_alloc(NV_LENGTH);
- if (!sev_init_ex_buffer) {
- dev_err(sev->dev,
- "SEV: INIT_EX NV memory allocation failed\n");
- goto err;
- }
- }
-
/* Initialize the platform */
args.probe = true;
rc = sev_platform_init(&args);
--
2.25.1
next prev parent reply other threads:[~2023-12-30 16:24 UTC|newest]
Thread overview: 102+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-30 16:19 [PATCH v1 00/26] Add AMD Secure Nested Paging (SEV-SNP) Initialization Support Michael Roth
2023-12-30 16:19 ` [PATCH v1 01/26] x86/cpufeatures: Add SEV-SNP CPU feature Michael Roth
2023-12-31 11:50 ` Borislav Petkov
2023-12-31 16:44 ` Michael Roth
2023-12-30 16:19 ` [PATCH v1 02/26] x86/speculation: Do not enable Automatic IBRS if SEV SNP is enabled Michael Roth
2023-12-30 16:19 ` [PATCH v1 03/26] iommu/amd: Don't rely on external callers to enable IOMMU SNP support Michael Roth
2024-01-04 10:30 ` Borislav Petkov
2024-01-04 10:58 ` Joerg Roedel
2023-12-30 16:19 ` [PATCH v1 04/26] x86/sev: Add the host SEV-SNP initialization support Michael Roth
2024-01-04 11:05 ` Jeremi Piotrowski
2024-01-05 16:09 ` Borislav Petkov
2024-01-05 16:21 ` Borislav Petkov
2024-01-08 16:49 ` Jeremi Piotrowski
2024-01-08 17:04 ` Borislav Petkov
2024-01-09 11:56 ` Jeremi Piotrowski
2024-01-09 12:29 ` Borislav Petkov
2024-01-09 12:44 ` Borislav Petkov
2024-02-14 16:56 ` Jeremi Piotrowski
2024-01-04 11:16 ` Borislav Petkov
2024-01-04 14:42 ` Borislav Petkov
2024-01-05 19:19 ` Borislav Petkov
2024-01-05 21:27 ` Borislav Petkov
2023-12-30 16:19 ` [PATCH v1 05/26] x86/mtrr: Don't print errors if MtrrFixDramModEn is set when SNP enabled Michael Roth
2023-12-30 16:19 ` [PATCH v1 06/26] x86/sev: Add RMP entry lookup helpers Michael Roth
2023-12-30 16:19 ` [PATCH v1 07/26] x86/fault: Add helper for dumping RMP entries Michael Roth
2024-01-10 9:59 ` Borislav Petkov
2024-01-10 20:18 ` Jarkko Sakkinen
2024-01-10 22:14 ` Borislav Petkov
2024-01-10 11:13 ` Borislav Petkov
2024-01-10 15:20 ` Tom Lendacky
2024-01-10 15:27 ` Borislav Petkov
2024-01-10 15:51 ` Tom Lendacky
2024-01-10 15:55 ` Borislav Petkov
2024-01-10 15:10 ` Tom Lendacky
2023-12-30 16:19 ` [PATCH v1 08/26] x86/traps: Define RMP violation #PF error code Michael Roth
2023-12-30 16:19 ` [PATCH v1 09/26] x86/fault: Dump RMP table information when RMP page faults occur Michael Roth
2023-12-30 16:19 ` [PATCH v1 10/26] x86/sev: Add helper functions for RMPUPDATE and PSMASH instruction Michael Roth
2024-01-12 14:49 ` Borislav Petkov
2023-12-30 16:19 ` [PATCH v1 11/26] x86/sev: Invalidate pages from the direct map when adding them to the RMP table Michael Roth
2024-01-12 19:48 ` Borislav Petkov
2024-01-12 20:00 ` Dave Hansen
2024-01-12 20:07 ` Borislav Petkov
2024-01-12 20:27 ` Vlastimil Babka
2024-01-15 9:06 ` Borislav Petkov
2024-01-15 9:14 ` Vlastimil Babka
2024-01-15 9:16 ` Mike Rapoport
2024-01-15 9:20 ` Borislav Petkov
2024-01-12 20:28 ` Tom Lendacky
2024-01-12 20:37 ` Dave Hansen
2024-01-15 9:23 ` Vlastimil Babka
2024-01-16 16:19 ` Michael Roth
2024-01-16 16:50 ` Michael Roth
2024-01-16 20:12 ` Mike Rapoport
2024-01-26 1:49 ` Michael Roth
2024-01-16 18:22 ` Borislav Petkov
2024-01-16 20:22 ` Dave Hansen
2024-01-26 1:35 ` Michael Roth
2024-01-15 9:09 ` Borislav Petkov
2024-01-16 16:21 ` Dave Hansen
2024-01-17 9:34 ` Borislav Petkov
2024-01-15 9:01 ` Borislav Petkov
2023-12-30 16:19 ` [PATCH v1 12/26] crypto: ccp: Define the SEV-SNP commands Michael Roth
2024-01-15 9:41 ` Borislav Petkov
2024-01-26 1:56 ` Michael Roth
2023-12-30 16:19 ` [PATCH v1 13/26] crypto: ccp: Add support to initialize the AMD-SP for SEV-SNP Michael Roth
2024-01-15 11:19 ` Borislav Petkov
2024-01-15 19:53 ` Borislav Petkov
2024-01-26 2:48 ` Michael Roth
2023-12-30 16:19 ` [PATCH v1 14/26] crypto: ccp: Provide API to issue SEV and SNP commands Michael Roth
2024-01-17 9:48 ` Borislav Petkov
2023-12-30 16:19 ` [PATCH v1 15/26] x86/sev: Introduce snp leaked pages list Michael Roth
2024-01-08 10:45 ` Vlastimil Babka
2024-01-09 22:19 ` Kalra, Ashish
2024-01-10 8:59 ` Vlastimil Babka
2023-12-30 16:19 ` [PATCH v1 16/26] crypto: ccp: Handle the legacy TMR allocation when SNP is enabled Michael Roth
2023-12-30 16:19 ` Michael Roth [this message]
2024-01-18 14:03 ` [PATCH v1 17/26] crypto: ccp: Handle non-volatile INIT_EX data " Borislav Petkov
2023-12-30 16:19 ` [PATCH v1 18/26] crypto: ccp: Handle legacy SEV commands " Michael Roth
2024-01-19 17:18 ` Borislav Petkov
2024-01-19 17:36 ` Tom Lendacky
2024-01-19 17:48 ` Borislav Petkov
2024-01-26 13:29 ` Michael Roth
2023-12-30 16:19 ` [PATCH v1 19/26] iommu/amd: Clean up RMP entries for IOMMU pages during SNP shutdown Michael Roth
2023-12-30 16:19 ` [PATCH v1 20/26] crypto: ccp: Add debug support for decrypting pages Michael Roth
2024-01-10 14:59 ` Sean Christopherson
2024-01-11 0:50 ` Michael Roth
2023-12-30 16:19 ` [PATCH v1 21/26] crypto: ccp: Add panic notifier for SEV/SNP firmware shutdown on kdump Michael Roth
2024-01-21 11:49 ` Borislav Petkov
2024-01-26 3:03 ` Kalra, Ashish
2024-01-26 13:38 ` Michael Roth
2023-12-30 16:19 ` [PATCH v1 22/26] KVM: SEV: Make AVIC backing, VMSA and VMCB memory allocation SNP safe Michael Roth
2024-01-21 11:51 ` Borislav Petkov
2024-01-26 3:44 ` Michael Roth
2023-12-30 16:19 ` [PATCH v1 23/26] x86/cpufeatures: Enable/unmask SEV-SNP CPU feature Michael Roth
2023-12-30 16:19 ` [PATCH v1 24/26] crypto: ccp: Add the SNP_PLATFORM_STATUS command Michael Roth
2024-01-21 12:29 ` Borislav Petkov
2024-01-26 3:32 ` Michael Roth
2023-12-30 16:19 ` [PATCH v1 25/26] crypto: ccp: Add the SNP_COMMIT command Michael Roth
2024-01-21 12:35 ` Borislav Petkov
2023-12-30 16:19 ` [PATCH v1 26/26] crypto: ccp: Add the SNP_SET_CONFIG command Michael Roth
2024-01-21 12:41 ` Borislav Petkov
2024-01-26 13:30 ` Michael Roth
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=20231230161954.569267-18-michael.roth@amd.com \
--to=michael.roth@amd.com \
--cc=ak@linux.intel.com \
--cc=alpergun@google.com \
--cc=ardb@kernel.org \
--cc=ashish.kalra@amd.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=jarkko@kernel.org \
--cc=jmattson@google.com \
--cc=jroedel@suse.de \
--cc=kirill@shutemov.name \
--cc=kvm@vger.kernel.org \
--cc=liam.merwick@oracle.com \
--cc=linux-coco@lists.linux.dev \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=luto@kernel.org \
--cc=mingo@redhat.com \
--cc=nikunj.dadhania@amd.com \
--cc=pankaj.gupta@amd.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=pgonda@google.com \
--cc=rientjes@google.com \
--cc=sathyanarayanan.kuppuswamy@linux.intel.com \
--cc=seanjc@google.com \
--cc=slp@redhat.com \
--cc=srinivas.pandruvada@linux.intel.com \
--cc=tglx@linutronix.de \
--cc=thomas.lendacky@amd.com \
--cc=tobin@ibm.com \
--cc=tony.luck@intel.com \
--cc=vbabka@suse.cz \
--cc=vkuznets@redhat.com \
--cc=x86@kernel.org \
--cc=zhi.a.wang@intel.com \
/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;
as well as URLs for NNTP newsgroup(s).