Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2018-10-11 18:42:22 +0200
committerBorislav Petkov <bp@suse.de>2018-10-11 18:42:22 +0200
commit912dad4fe5c609e3053b5f5d34ddb8a81995c182 (patch)
treebbaefad0cb9ec5098909579f091e7eea1db5c56e
parentddc67eb7a19e57bc4565f132e7ad3665a03eb88c (diff)
crypto: ccp - add timeout support in the SEV command
(bsc#1106838).
-rw-r--r--patches.drivers/crypto-ccp-add-timeout-support-in-the-sev-command.patch118
-rw-r--r--series.conf1
2 files changed, 119 insertions, 0 deletions
diff --git a/patches.drivers/crypto-ccp-add-timeout-support-in-the-sev-command.patch b/patches.drivers/crypto-ccp-add-timeout-support-in-the-sev-command.patch
new file mode 100644
index 0000000000..95ec118d85
--- /dev/null
+++ b/patches.drivers/crypto-ccp-add-timeout-support-in-the-sev-command.patch
@@ -0,0 +1,118 @@
+From: Brijesh Singh <brijesh.singh@amd.com>
+Date: Wed, 15 Aug 2018 16:11:25 -0500
+Subject: crypto: ccp - add timeout support in the SEV command
+Git-commit: 3702a0585e64d70d5bf73bf3e943b8d6005b72c1
+Patch-mainline: v4.19-rc5
+References: bsc#1106838
+
+Currently, the CCP driver assumes that the SEV command issued to the PSP
+will always return (i.e. it will never hang). But recently, firmware bugs
+have shown that a command can hang. Since of the SEV commands are used
+in probe routines, this can cause boot hangs and/or loss of virtualization
+capabilities.
+
+To protect against firmware bugs, add a timeout in the SEV command
+execution flow. If a command does not complete within the specified
+timeout then return -ETIMEOUT and stop the driver from executing any
+further commands since the state of the SEV firmware is unknown.
+
+Cc: Tom Lendacky <thomas.lendacky@amd.com>
+Cc: Gary Hook <Gary.Hook@amd.com>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: linux-kernel@vger.kernel.org
+Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Acked-by: Borislav Petkov <bp@suse.de>
+---
+ drivers/crypto/ccp/psp-dev.c | 46 ++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 41 insertions(+), 5 deletions(-)
+
+--- a/drivers/crypto/ccp/psp-dev.c
++++ b/drivers/crypto/ccp/psp-dev.c
+@@ -32,6 +32,17 @@ static DEFINE_MUTEX(sev_cmd_mutex);
+ static struct sev_misc_dev *misc_dev;
+ static struct psp_device *psp_master;
+
++static int psp_cmd_timeout = 100;
++module_param(psp_cmd_timeout, int, 0644);
++MODULE_PARM_DESC(psp_cmd_timeout, " default timeout value, in seconds, for PSP commands");
++
++static int psp_probe_timeout = 5;
++module_param(psp_probe_timeout, int, 0644);
++MODULE_PARM_DESC(psp_probe_timeout, " default timeout value, in seconds, during PSP device probe");
++
++static bool psp_dead;
++static int psp_timeout;
++
+ static struct psp_device *psp_alloc_struct(struct sp_device *sp)
+ {
+ struct device *dev = sp->dev;
+@@ -76,10 +87,19 @@ done:
+ return IRQ_HANDLED;
+ }
+
+-static void sev_wait_cmd_ioc(struct psp_device *psp, unsigned int *reg)
++static int sev_wait_cmd_ioc(struct psp_device *psp,
++ unsigned int *reg, unsigned int timeout)
+ {
+- wait_event(psp->sev_int_queue, psp->sev_int_rcvd);
++ int ret;
++
++ ret = wait_event_timeout(psp->sev_int_queue,
++ psp->sev_int_rcvd, timeout * HZ);
++ if (!ret)
++ return -ETIMEDOUT;
++
+ *reg = ioread32(psp->io_regs + PSP_CMDRESP);
++
++ return 0;
+ }
+
+ static int sev_cmd_buffer_len(int cmd)
+@@ -125,12 +145,15 @@ static int __sev_do_cmd_locked(int cmd,
+ if (!psp)
+ return -ENODEV;
+
++ if (psp_dead)
++ return -EBUSY;
++
+ /* 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;
+
+- dev_dbg(psp->dev, "sev command id %#x buffer 0x%08x%08x\n",
+- cmd, phys_msb, phys_lsb);
++ dev_dbg(psp->dev, "sev command id %#x buffer 0x%08x%08x timeout %us\n",
++ cmd, phys_msb, phys_lsb, psp_timeout);
+
+ print_hex_dump_debug("(in): ", DUMP_PREFIX_OFFSET, 16, 2, data,
+ sev_cmd_buffer_len(cmd), false);
+@@ -146,7 +169,18 @@ static int __sev_do_cmd_locked(int cmd,
+ iowrite32(reg, psp->io_regs + PSP_CMDRESP);
+
+ /* wait for command completion */
+- sev_wait_cmd_ioc(psp, &reg);
++ ret = sev_wait_cmd_ioc(psp, &reg, psp_timeout);
++ if (ret) {
++ if (psp_ret)
++ *psp_ret = 0;
++
++ dev_err(psp->dev, "sev command %#x timed out, disabling PSP \n", cmd);
++ psp_dead = true;
++
++ return ret;
++ }
++
++ psp_timeout = psp_cmd_timeout;
+
+ if (psp_ret)
+ *psp_ret = reg & PSP_CMDRESP_ERR_MASK;
+@@ -776,6 +810,8 @@ void psp_pci_init(void)
+
+ psp_master = sp->psp_data;
+
++ psp_timeout = psp_probe_timeout;
++
+ /* Initialize the platform */
+ rc = sev_platform_init(&error);
+ if (rc) {
diff --git a/series.conf b/series.conf
index b3cdd95508..5c5e8026f0 100644
--- a/series.conf
+++ b/series.conf
@@ -17750,6 +17750,7 @@
patches.drivers/bnxt_en-Fix-VF-mac-address-regression.patch
patches.drivers/qmi_wwan-set-DTR-for-modems-in-forced-USB2-mode.patch
patches.drivers/platform-x86-alienware-wmi-Correct-a-memory-leak.patch
+ patches.drivers/crypto-ccp-add-timeout-support-in-the-sev-command.patch
patches.drivers/hwmon-nct6775-Set-weight-source-to-zero-correctly.patch
patches.drivers/ALSA-bebob-use-address-returned-by-kmalloc-instead-o.patch
patches.drivers/ALSA-fireface-fix-memory-leak-in-ff400_switch_fetchi.patch