From 9c514d13a756bfce387e5ece3bb91d3f377becfa Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 17 May 2023 16:02:11 +0200 Subject: [PATCH] 5.10-stable patches added patches: crypto-ccp-play-nice-with-vmalloc-d-memory-for-sev-command-structs.patch series --- ...loc-d-memory-for-sev-command-structs.patch | 123 ++++++++++++++++++ queue-5.10/series | 1 + 2 files changed, 124 insertions(+) create mode 100644 queue-5.10/crypto-ccp-play-nice-with-vmalloc-d-memory-for-sev-command-structs.patch create mode 100644 queue-5.10/series diff --git a/queue-5.10/crypto-ccp-play-nice-with-vmalloc-d-memory-for-sev-command-structs.patch b/queue-5.10/crypto-ccp-play-nice-with-vmalloc-d-memory-for-sev-command-structs.patch new file mode 100644 index 00000000000..1e77ebfaae7 --- /dev/null +++ b/queue-5.10/crypto-ccp-play-nice-with-vmalloc-d-memory-for-sev-command-structs.patch @@ -0,0 +1,123 @@ +From 8347b99473a313be6549a5b940bc3c56a71be81c Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Tue, 6 Apr 2021 15:49:48 -0700 +Subject: crypto: ccp: Play nice with vmalloc'd memory for SEV command structs + +From: Sean Christopherson + +commit 8347b99473a313be6549a5b940bc3c56a71be81c upstream. + +Copy the incoming @data comman to an internal buffer so that callers can +put SEV command buffers on the stack without running afoul of +CONFIG_VMAP_STACK=y, i.e. without bombing on vmalloc'd pointers. As of +today, the largest supported command takes a 68 byte buffer, i.e. pretty +much every command can be put on the stack. Because sev_cmd_mutex is +held for the entirety of a transaction, only a single bounce buffer is +required. + +Use the internal buffer unconditionally, as the majority of in-kernel +users will soon switch to using the stack. At that point, checking +virt_addr_valid() becomes (negligible) overhead in most cases, and +supporting both paths slightly increases complexity. Since the commands +are all quite small, the cost of the copies is insignificant compared to +the latency of communicating with the PSP. + +Allocate a full page for the buffer as opportunistic preparation for +SEV-SNP, which requires the command buffer to be in firmware state for +commands that trigger memory writes from the PSP firmware. Using a full +page now will allow SEV-SNP support to simply transition the page as +needed. + +Cc: Brijesh Singh +Cc: Borislav Petkov +Cc: Tom Lendacky +Cc: Christophe Leroy +Signed-off-by: Sean Christopherson +Message-Id: <20210406224952.4177376-5-seanjc@google.com> +Reviewed-by: Brijesh Singh +Acked-by: Tom Lendacky +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + drivers/crypto/ccp/sev-dev.c | 28 +++++++++++++++++++++++----- + drivers/crypto/ccp/sev-dev.h | 2 ++ + 2 files changed, 25 insertions(+), 5 deletions(-) + +--- a/drivers/crypto/ccp/sev-dev.c ++++ b/drivers/crypto/ccp/sev-dev.c +@@ -165,12 +165,17 @@ static int __sev_do_cmd_locked(int cmd, + + sev = psp->sev_data; + +- if (data && WARN_ON_ONCE(!virt_addr_valid(data))) +- return -EINVAL; ++ /* ++ * Copy the incoming data to driver's scratch buffer as __pa() will not ++ * work for some memory, e.g. vmalloc'd addresses, and @data may not be ++ * physically contiguous. ++ */ ++ if (data) ++ memcpy(sev->cmd_buf, data, buf_len); + + /* Get the physical address of the command buffer */ +- phys_lsb = data ? lower_32_bits(__psp_pa(data)) : 0; +- phys_msb = data ? upper_32_bits(__psp_pa(data)) : 0; ++ phys_lsb = data ? lower_32_bits(__psp_pa(sev->cmd_buf)) : 0; ++ phys_msb = data ? upper_32_bits(__psp_pa(sev->cmd_buf)) : 0; + + dev_dbg(sev->dev, "sev command id %#x buffer 0x%08x%08x timeout %us\n", + cmd, phys_msb, phys_lsb, psp_timeout); +@@ -214,6 +219,13 @@ static int __sev_do_cmd_locked(int cmd, + print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data, + sev_cmd_buffer_len(cmd), false); + ++ /* ++ * Copy potential output from the PSP back to data. Do this even on ++ * failure in case the caller wants to glean something from the error. ++ */ ++ if (data) ++ memcpy(data, sev->cmd_buf, buf_len); ++ + return ret; + } + +@@ -974,6 +986,10 @@ int sev_dev_init(struct psp_device *psp) + if (!sev) + goto e_err; + ++ sev->cmd_buf = (void *)devm_get_free_pages(dev, GFP_KERNEL, 0); ++ if (!sev->cmd_buf) ++ goto e_sev; ++ + psp->sev_data = sev; + + sev->dev = dev; +@@ -985,7 +1001,7 @@ int sev_dev_init(struct psp_device *psp) + if (!sev->vdata) { + ret = -ENODEV; + dev_err(dev, "sev: missing driver data\n"); +- goto e_sev; ++ goto e_buf; + } + + psp_set_sev_irq_handler(psp, sev_irq_handler, sev); +@@ -1000,6 +1016,8 @@ int sev_dev_init(struct psp_device *psp) + + e_irq: + psp_clear_sev_irq_handler(psp); ++e_buf: ++ devm_free_pages(dev, (unsigned long)sev->cmd_buf); + e_sev: + devm_kfree(dev, sev); + e_err: +--- a/drivers/crypto/ccp/sev-dev.h ++++ b/drivers/crypto/ccp/sev-dev.h +@@ -51,6 +51,8 @@ struct sev_device { + u8 api_major; + u8 api_minor; + u8 build; ++ ++ void *cmd_buf; + }; + + int sev_dev_init(struct psp_device *psp); diff --git a/queue-5.10/series b/queue-5.10/series new file mode 100644 index 00000000000..c37a87ea0da --- /dev/null +++ b/queue-5.10/series @@ -0,0 +1 @@ +crypto-ccp-play-nice-with-vmalloc-d-memory-for-sev-command-structs.patch -- 2.47.3