linux-crypto.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] crypto: ccp: Add support for SEV-ES to the PSP driver
@ 2020-04-20 19:54 Tom Lendacky
  2020-04-21 12:33 ` Joerg Roedel
  0 siblings, 1 reply; 3+ messages in thread
From: Tom Lendacky @ 2020-04-20 19:54 UTC (permalink / raw)
  To: linux-kernel, linux-crypto
  Cc: Herbert Xu, David Miller, Joerg Roedel, Borislav Petkov, Brijesh Singh

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 <thomas.lendacky@amd.com>
---
 drivers/crypto/ccp/sev-dev.c | 47 ++++++++++++++++++++++++++++++++++++
 include/linux/psp-sev.h      |  2 ++
 include/uapi/linux/psp-sev.h |  2 ++
 3 files changed, 51 insertions(+)

diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
index 896f190b9a50..0d978bad60d9 100644
--- a/drivers/crypto/ccp/sev-dev.c
+++ b/drivers/crypto/ccp/sev-dev.c
@@ -20,6 +20,7 @@
 #include <linux/hw_random.h>
 #include <linux/ccp.h>
 #include <linux/firmware.h>
+#include <linux/gfp.h>
 
 #include <asm/smp.h>
 
@@ -44,6 +45,17 @@ MODULE_PARM_DESC(psp_probe_timeout, " default timeout value, in seconds, during
 static bool psp_dead;
 static int psp_timeout;
 
+/* Trusted Memory Region (TMR):
+ *   The TMR is a 1MB area that must be 1MB aligned.  To achieve this, allocate
+ *   an amount that is the size of area plus an amount equal to the required
+ *   alignment. The aligned address will be calculated from the returned
+ *   address.
+ */
+#define SEV_ES_TMR_ALIGN	(1024 * 1024)
+#define SEV_ES_TMR_SIZE		(1024 * 1024)
+#define SEV_ES_TMR_LEN		(SEV_ES_TMR_ALIGN + SEV_ES_TMR_SIZE)
+static void *sev_es_tmr;
+
 static inline bool sev_version_greater_or_equal(u8 maj, u8 min)
 {
 	struct sev_device *sev = psp_master->sev_data;
@@ -214,6 +226,21 @@ static int __sev_platform_init_locked(int *error)
 	if (sev->state == SEV_STATE_INIT)
 		return 0;
 
+	if (sev_es_tmr) {
+		u64 tmr_pa;
+
+		/*
+		 * Do not include the encryption mask on the physical
+		 * address of the TMR (firmware should clear it anyway).
+		 */
+		tmr_pa = __pa(sev_es_tmr);
+		tmr_pa = ALIGN(tmr_pa, SEV_ES_TMR_ALIGN);
+
+		sev->init_cmd_buf.flags |= SEV_INIT_FLAGS_SEV_ES;
+		sev->init_cmd_buf.tmr_address = tmr_pa;
+		sev->init_cmd_buf.tmr_len = SEV_ES_TMR_SIZE;
+	}
+
 	rc = __sev_do_cmd_locked(SEV_CMD_INIT, &sev->init_cmd_buf, error);
 	if (rc)
 		return rc;
@@ -1012,6 +1039,7 @@ EXPORT_SYMBOL_GPL(sev_issue_cmd_external_user);
 void sev_pci_init(void)
 {
 	struct sev_device *sev = psp_master->sev_data;
+	struct page *tmr_page;
 	int error, rc;
 
 	if (!sev)
@@ -1041,6 +1069,16 @@ void sev_pci_init(void)
 	    sev_update_firmware(sev->dev) == 0)
 		sev_get_api_version();
 
+	/* Obtain the TMR memory area for SEV-ES use */
+	tmr_page = alloc_pages(GFP_KERNEL, get_order(SEV_ES_TMR_LEN));
+	if (tmr_page) {
+		sev_es_tmr = page_address(tmr_page);
+	} else {
+		sev_es_tmr = NULL;
+		dev_warn(sev->dev,
+			 "SEV: TMR allocation failed, SEV-ES support unavailable\n");
+	}
+
 	/* Initialize the platform */
 	rc = sev_platform_init(&error);
 	if (rc && (error == SEV_RET_SECURE_DATA_INVALID)) {
@@ -1075,4 +1113,13 @@ void sev_pci_exit(void)
 		return;
 
 	sev_platform_shutdown(NULL);
+
+	if (sev_es_tmr) {
+		/* 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_LEN));
+		sev_es_tmr = NULL;
+	}
 }
diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h
index 5167bf2bfc75..7fbc8679145c 100644
--- a/include/linux/psp-sev.h
+++ b/include/linux/psp-sev.h
@@ -100,6 +100,8 @@ struct sev_data_init {
 	u32 tmr_len;			/* In */
 } __packed;
 
+#define SEV_INIT_FLAGS_SEV_ES	0x01
+
 /**
  * struct sev_data_pek_csr - PEK_CSR command parameters
  *
diff --git a/include/uapi/linux/psp-sev.h b/include/uapi/linux/psp-sev.h
index 0549a5c622bf..91b4c63d5cbf 100644
--- a/include/uapi/linux/psp-sev.h
+++ b/include/uapi/linux/psp-sev.h
@@ -83,6 +83,8 @@ struct sev_user_data_status {
 	__u32 guest_count;			/* Out */
 } __packed;
 
+#define SEV_STATUS_FLAGS_CONFIG_ES	0x0100
+
 /**
  * struct sev_user_data_pek_csr - PEK_CSR command parameters
  *
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] crypto: ccp: Add support for SEV-ES to the PSP driver
  2020-04-20 19:54 [PATCH] crypto: ccp: Add support for SEV-ES to the PSP driver Tom Lendacky
@ 2020-04-21 12:33 ` Joerg Roedel
  2020-04-21 13:15   ` Tom Lendacky
  0 siblings, 1 reply; 3+ messages in thread
From: Joerg Roedel @ 2020-04-21 12:33 UTC (permalink / raw)
  To: Tom Lendacky
  Cc: linux-kernel, linux-crypto, Herbert Xu, David Miller,
	Borislav Petkov, Brijesh Singh

Hi Tom,

On Mon, Apr 20, 2020 at 02:54:58PM -0500, Tom Lendacky wrote:
>  static inline bool sev_version_greater_or_equal(u8 maj, u8 min)
>  {
>  	struct sev_device *sev = psp_master->sev_data;
> @@ -214,6 +226,21 @@ static int __sev_platform_init_locked(int *error)
>  	if (sev->state == SEV_STATE_INIT)
>  		return 0;
>  
> +	if (sev_es_tmr) {
> +		u64 tmr_pa;
> +
> +		/*
> +		 * Do not include the encryption mask on the physical
> +		 * address of the TMR (firmware should clear it anyway).
> +		 */
> +		tmr_pa = __pa(sev_es_tmr);
> +		tmr_pa = ALIGN(tmr_pa, SEV_ES_TMR_ALIGN);

No need to manually align the region, see below.

> +	/* Obtain the TMR memory area for SEV-ES use */
> +	tmr_page = alloc_pages(GFP_KERNEL, get_order(SEV_ES_TMR_LEN));
> +	if (tmr_page) {
> +		sev_es_tmr = page_address(tmr_page);
> +	} else {
> +		sev_es_tmr = NULL;
> +		dev_warn(sev->dev,
> +			 "SEV: TMR allocation failed, SEV-ES support unavailable\n");
> +	}

This allocates a 2M region where 1M is needed. The page allocator gives
you naturally aligned region for any allocation order, so when you
allocate 1M, it will automatically be 1M aligned.

Other than that this patch looks good to me.

Regards,

	Joerg

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] crypto: ccp: Add support for SEV-ES to the PSP driver
  2020-04-21 12:33 ` Joerg Roedel
@ 2020-04-21 13:15   ` Tom Lendacky
  0 siblings, 0 replies; 3+ messages in thread
From: Tom Lendacky @ 2020-04-21 13:15 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: linux-kernel, linux-crypto, Herbert Xu, David Miller,
	Borislav Petkov, Brijesh Singh

On 4/21/20 7:33 AM, Joerg Roedel wrote:
> Hi Tom,
> 
> On Mon, Apr 20, 2020 at 02:54:58PM -0500, Tom Lendacky wrote:
>>   static inline bool sev_version_greater_or_equal(u8 maj, u8 min)
>>   {
>>   	struct sev_device *sev = psp_master->sev_data;
>> @@ -214,6 +226,21 @@ static int __sev_platform_init_locked(int *error)
>>   	if (sev->state == SEV_STATE_INIT)
>>   		return 0;
>>   
>> +	if (sev_es_tmr) {
>> +		u64 tmr_pa;
>> +
>> +		/*
>> +		 * Do not include the encryption mask on the physical
>> +		 * address of the TMR (firmware should clear it anyway).
>> +		 */
>> +		tmr_pa = __pa(sev_es_tmr);
>> +		tmr_pa = ALIGN(tmr_pa, SEV_ES_TMR_ALIGN);
> 
> No need to manually align the region, see below.
> 
>> +	/* Obtain the TMR memory area for SEV-ES use */
>> +	tmr_page = alloc_pages(GFP_KERNEL, get_order(SEV_ES_TMR_LEN));
>> +	if (tmr_page) {
>> +		sev_es_tmr = page_address(tmr_page);
>> +	} else {
>> +		sev_es_tmr = NULL;
>> +		dev_warn(sev->dev,
>> +			 "SEV: TMR allocation failed, SEV-ES support unavailable\n");
>> +	}
> 
> This allocates a 2M region where 1M is needed. The page allocator gives
> you naturally aligned region for any allocation order, so when you
> allocate 1M, it will automatically be 1M aligned.

Ah, I did not realize that. I'll update the patch to allocate just 1M then.

Thanks,
Tom

> 
> Other than that this patch looks good to me.
> 
> Regards,
> 
> 	Joerg
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-04-21 13:15 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-20 19:54 [PATCH] crypto: ccp: Add support for SEV-ES to the PSP driver Tom Lendacky
2020-04-21 12:33 ` Joerg Roedel
2020-04-21 13:15   ` Tom Lendacky

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).