Skip to content

Commit 97f9ac3

Browse files
tlendackyherbertx
authored andcommitted
crypto: ccp - Add support for SEV-ES to the PSP driver
To provide support for SEV-ES, the hypervisor must provide an area of memory to the PSP. Once this Trusted Memory Region (TMR) is provided to the PSP, the contents of this area of memory are no longer available to the x86. Update the PSP driver to allocate a 1MB region for the TMR that is 1MB aligned and then provide it to the PSP through the SEV INIT command. Signed-off-by: Tom Lendacky <[email protected]> Reviewed-by: Brijesh Singh <[email protected]> Reviewed-by: Joerg Roedel <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent 3c2214b commit 97f9ac3

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

drivers/crypto/ccp/sev-dev.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/hw_random.h>
2121
#include <linux/ccp.h>
2222
#include <linux/firmware.h>
23+
#include <linux/gfp.h>
2324

2425
#include <asm/smp.h>
2526

@@ -44,6 +45,14 @@ MODULE_PARM_DESC(psp_probe_timeout, " default timeout value, in seconds, during
4445
static bool psp_dead;
4546
static int psp_timeout;
4647

48+
/* Trusted Memory Region (TMR):
49+
* The TMR is a 1MB area that must be 1MB aligned. Use the page allocator
50+
* to allocate the memory, which will return aligned memory for the specified
51+
* allocation order.
52+
*/
53+
#define SEV_ES_TMR_SIZE (1024 * 1024)
54+
static void *sev_es_tmr;
55+
4756
static inline bool sev_version_greater_or_equal(u8 maj, u8 min)
4857
{
4958
struct sev_device *sev = psp_master->sev_data;
@@ -214,6 +223,20 @@ static int __sev_platform_init_locked(int *error)
214223
if (sev->state == SEV_STATE_INIT)
215224
return 0;
216225

226+
if (sev_es_tmr) {
227+
u64 tmr_pa;
228+
229+
/*
230+
* Do not include the encryption mask on the physical
231+
* address of the TMR (firmware should clear it anyway).
232+
*/
233+
tmr_pa = __pa(sev_es_tmr);
234+
235+
sev->init_cmd_buf.flags |= SEV_INIT_FLAGS_SEV_ES;
236+
sev->init_cmd_buf.tmr_address = tmr_pa;
237+
sev->init_cmd_buf.tmr_len = SEV_ES_TMR_SIZE;
238+
}
239+
217240
rc = __sev_do_cmd_locked(SEV_CMD_INIT, &sev->init_cmd_buf, error);
218241
if (rc)
219242
return rc;
@@ -1012,6 +1035,7 @@ EXPORT_SYMBOL_GPL(sev_issue_cmd_external_user);
10121035
void sev_pci_init(void)
10131036
{
10141037
struct sev_device *sev = psp_master->sev_data;
1038+
struct page *tmr_page;
10151039
int error, rc;
10161040

10171041
if (!sev)
@@ -1041,6 +1065,16 @@ void sev_pci_init(void)
10411065
sev_update_firmware(sev->dev) == 0)
10421066
sev_get_api_version();
10431067

1068+
/* Obtain the TMR memory area for SEV-ES use */
1069+
tmr_page = alloc_pages(GFP_KERNEL, get_order(SEV_ES_TMR_SIZE));
1070+
if (tmr_page) {
1071+
sev_es_tmr = page_address(tmr_page);
1072+
} else {
1073+
sev_es_tmr = NULL;
1074+
dev_warn(sev->dev,
1075+
"SEV: TMR allocation failed, SEV-ES support unavailable\n");
1076+
}
1077+
10441078
/* Initialize the platform */
10451079
rc = sev_platform_init(&error);
10461080
if (rc && (error == SEV_RET_SECURE_DATA_INVALID)) {
@@ -1075,4 +1109,13 @@ void sev_pci_exit(void)
10751109
return;
10761110

10771111
sev_platform_shutdown(NULL);
1112+
1113+
if (sev_es_tmr) {
1114+
/* The TMR area was encrypted, flush it from the cache */
1115+
wbinvd_on_all_cpus();
1116+
1117+
free_pages((unsigned long)sev_es_tmr,
1118+
get_order(SEV_ES_TMR_SIZE));
1119+
sev_es_tmr = NULL;
1120+
}
10781121
}

include/linux/psp-sev.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ struct sev_data_init {
100100
u32 tmr_len; /* In */
101101
} __packed;
102102

103+
#define SEV_INIT_FLAGS_SEV_ES 0x01
104+
103105
/**
104106
* struct sev_data_pek_csr - PEK_CSR command parameters
105107
*

include/uapi/linux/psp-sev.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ struct sev_user_data_status {
8383
__u32 guest_count; /* Out */
8484
} __packed;
8585

86+
#define SEV_STATUS_FLAGS_CONFIG_ES 0x0100
87+
8688
/**
8789
* struct sev_user_data_pek_csr - PEK_CSR command parameters
8890
*

0 commit comments

Comments
 (0)