[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <a5dfa1b5e73286c2d7a2d38422577aff9de48226.1753389962.git.ashish.kalra@amd.com>
Date: Thu, 24 Jul 2025 21:14:26 +0000
From: Ashish Kalra <Ashish.Kalra@....com>
To: <thomas.lendacky@....com>, <john.allen@....com>,
<herbert@...dor.apana.org.au>, <davem@...emloft.net>
CC: <seanjc@...gle.com>, <pbonzini@...hat.com>, <michael.roth@....com>,
<linux-crypto@...r.kernel.org>, <linux-kernel@...r.kernel.org>
Subject: [PATCH 1/2] crypto: ccp - Add new API for extending HV_Fixed Pages
From: Ashish Kalra <ashish.kalra@....com>
Implement new API to add support for extending the HV_Fixed pages list
passed to SNP_INIT_EX.
Adds a simple list based interface to extend the HV_Fixed pages list
for PSP sub-devices such as the SFS driver.
Suggested-by: Thomas.Lendacky@....com <Thomas.Lendacky@....com>
Signed-off-by: Ashish Kalra <ashish.kalra@....com>
---
drivers/crypto/ccp/sev-dev.c | 88 ++++++++++++++++++++++++++++++++++++
drivers/crypto/ccp/sev-dev.h | 3 ++
2 files changed, 91 insertions(+)
diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
index e058ba027792..c3ff40cd7a96 100644
--- a/drivers/crypto/ccp/sev-dev.c
+++ b/drivers/crypto/ccp/sev-dev.c
@@ -82,6 +82,14 @@ MODULE_FIRMWARE("amd/amd_sev_fam19h_model1xh.sbin"); /* 4th gen EPYC */
static bool psp_dead;
static int psp_timeout;
+struct snp_hv_fixed_pages_entry {
+ u64 base;
+ int npages;
+ struct list_head list;
+};
+static LIST_HEAD(snp_hv_fixed_pages);
+static DEFINE_SPINLOCK(snp_hv_fixed_pages_lock);
+
/* Trusted Memory Region (TMR):
* 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
@@ -1073,6 +1081,76 @@ static void snp_set_hsave_pa(void *arg)
wrmsrq(MSR_VM_HSAVE_PA, 0);
}
+int snp_insert_hypervisor_fixed_pages_list(u64 paddr, int npages)
+{
+ struct snp_hv_fixed_pages_entry *entry;
+
+ spin_lock(&snp_hv_fixed_pages_lock);
+
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry) {
+ spin_unlock(&snp_hv_fixed_pages_lock);
+ return -ENOMEM;
+ }
+ entry->base = paddr;
+ entry->npages = npages;
+ list_add_tail(&entry->list, &snp_hv_fixed_pages);
+
+ spin_unlock(&snp_hv_fixed_pages_lock);
+
+ return 0;
+}
+
+void snp_delete_hypervisor_fixed_pages_list(u64 paddr)
+{
+ struct snp_hv_fixed_pages_entry *entry, *nentry;
+
+ spin_lock(&snp_hv_fixed_pages_lock);
+ list_for_each_entry_safe(entry, nentry, &snp_hv_fixed_pages, list) {
+ if (entry->base == paddr) {
+ list_del(&entry->list);
+ kfree(entry);
+ break;
+ }
+ }
+ spin_unlock(&snp_hv_fixed_pages_lock);
+}
+
+static int snp_extend_hypervisor_fixed_pages(struct sev_data_range_list *range_list)
+{
+ struct sev_data_range *range = &range_list->ranges[range_list->num_elements];
+ struct snp_hv_fixed_pages_entry *entry;
+ int new_element_count, ret = 0;
+
+ spin_lock(&snp_hv_fixed_pages_lock);
+ if (list_empty(&snp_hv_fixed_pages))
+ goto out;
+
+ new_element_count = list_count_nodes(&snp_hv_fixed_pages) +
+ range_list->num_elements;
+
+ /*
+ * Ensure the list of HV_FIXED pages that will be passed to firmware
+ * do not exceed the page-sized argument buffer.
+ */
+ if (new_element_count * sizeof(struct sev_data_range) +
+ sizeof(struct sev_data_range_list) > PAGE_SIZE) {
+ ret = -E2BIG;
+ goto out;
+ }
+
+ list_for_each_entry(entry, &snp_hv_fixed_pages, list) {
+ range->base = entry->base;
+ range->page_count = entry->npages;
+ range++;
+ }
+ range_list->num_elements = new_element_count;
+out:
+ spin_unlock(&snp_hv_fixed_pages_lock);
+
+ return ret;
+}
+
static int snp_filter_reserved_mem_regions(struct resource *rs, void *arg)
{
struct sev_data_range_list *range_list = arg;
@@ -1163,6 +1241,16 @@ static int __sev_snp_init_locked(int *error)
return rc;
}
+ /*
+ * Extend the HV_Fixed pages list with HV_Fixed pages added from other
+ * PSP sub-devices such as SFS. Warn if the list can't be extended
+ * but continue with SNP_INIT_EX.
+ */
+ rc = snp_extend_hypervisor_fixed_pages(snp_range_list);
+ if (rc)
+ dev_warn(sev->dev,
+ "SEV: SNP_INIT_EX extend HV_Fixed pages failed rc = %d\n", rc);
+
memset(&data, 0, sizeof(data));
data.init_rmp = 1;
data.list_paddr_en = 1;
diff --git a/drivers/crypto/ccp/sev-dev.h b/drivers/crypto/ccp/sev-dev.h
index 3e4e5574e88a..444d7fffd801 100644
--- a/drivers/crypto/ccp/sev-dev.h
+++ b/drivers/crypto/ccp/sev-dev.h
@@ -65,4 +65,7 @@ void sev_dev_destroy(struct psp_device *psp);
void sev_pci_init(void);
void sev_pci_exit(void);
+int snp_insert_hypervisor_fixed_pages_list(u64 paddr, int npages);
+void snp_delete_hypervisor_fixed_pages_list(u64 paddr);
+
#endif /* __SEV_DEV_H */
--
2.34.1
Powered by blists - more mailing lists