]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 May 2023 14:02:11 +0000 (16:02 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 May 2023 14:02:11 +0000 (16:02 +0200)
added patches:
crypto-ccp-play-nice-with-vmalloc-d-memory-for-sev-command-structs.patch
series

queue-5.10/crypto-ccp-play-nice-with-vmalloc-d-memory-for-sev-command-structs.patch [new file with mode: 0644]
queue-5.10/series [new file with mode: 0644]

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 (file)
index 0000000..1e77ebf
--- /dev/null
@@ -0,0 +1,123 @@
+From 8347b99473a313be6549a5b940bc3c56a71be81c Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+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 <seanjc@google.com>
+
+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 <brijesh.singh@amd.com>
+Cc: Borislav Petkov <bp@suse.de>
+Cc: Tom Lendacky <thomas.lendacky@amd.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20210406224952.4177376-5-seanjc@google.com>
+Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
+Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..c37a87e
--- /dev/null
@@ -0,0 +1 @@
+crypto-ccp-play-nice-with-vmalloc-d-memory-for-sev-command-structs.patch