[x86] crypto: ccp: add timeout support in the SEV command (Closes: #908248)
This commit is contained in:
parent
aa5e4662ed
commit
2943a959c9
|
@ -158,6 +158,7 @@ linux (4.18.7-1) UNRELEASED; urgency=medium
|
|||
|
||||
[ Romain Perier ]
|
||||
* [x86] Enable TI TPS6598x USB Power Delivery controller family
|
||||
* [x86] crypto: ccp: add timeout support in the SEV command (Closes: #908248)
|
||||
* [rt] Update to 4.18.7-rt5
|
||||
|
||||
-- Ben Hutchings <ben@decadent.org.uk> Sat, 08 Sep 2018 23:24:31 +0100
|
||||
|
|
121
debian/patches/bugfix/x86/crypto-ccp-add-timeout-support-in-the-SEV-command.patch
vendored
Normal file
121
debian/patches/bugfix/x86/crypto-ccp-add-timeout-support-in-the-SEV-command.patch
vendored
Normal file
|
@ -0,0 +1,121 @@
|
|||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Wed, 15 Aug 2018 16:11:25 -0500
|
||||
Subject: [PATCH] crypto: ccp - add timeout support in the SEV command
|
||||
Origin: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git/commit/?h=linus&id=3702a0585e64d70d5bf73bf3e943b8d6005b72c1
|
||||
|
||||
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>
|
||||
---
|
||||
drivers/crypto/ccp/psp-dev.c | 46 ++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 41 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
|
||||
index 051b8c6bae64..19dde2e866c9 100644
|
||||
--- a/drivers/crypto/ccp/psp-dev.c
|
||||
+++ b/drivers/crypto/ccp/psp-dev.c
|
||||
@@ -38,6 +38,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;
|
||||
@@ -82,10 +93,19 @@ static irqreturn_t psp_irq_handler(int irq, void *data)
|
||||
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)
|
||||
@@ -133,12 +153,15 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
|
||||
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);
|
||||
@@ -154,8 +177,18 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
|
||||
iowrite32(reg, psp->io_regs + PSP_CMDRESP);
|
||||
|
||||
/* wait for command completion */
|
||||
- sev_wait_cmd_ioc(psp, ®);
|
||||
+ ret = sev_wait_cmd_ioc(psp, ®, 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;
|
||||
|
||||
@@ -886,6 +919,9 @@ void psp_pci_init(void)
|
||||
|
||||
psp_master = sp->psp_data;
|
||||
|
||||
+ psp_timeout = psp_probe_timeout;
|
||||
+
|
||||
+
|
||||
if (sev_get_api_version())
|
||||
goto err;
|
||||
|
||||
--
|
||||
2.18.0
|
||||
|
|
@ -71,6 +71,7 @@ bugfix/x86/perf-tools-fix-unwind-build-on-i386.patch
|
|||
bugfix/sh/sh-boot-do-not-use-hyphen-in-exported-variable-name.patch
|
||||
bugfix/x86/mmap-remember-the-map_fixed-flag-as-vm_fixed.patch
|
||||
bugfix/x86/mmap-add-an-exception-to-the-stack-gap-for-hotspot-jvm.patch
|
||||
bugfix/x86/crypto-ccp-add-timeout-support-in-the-SEV-command.patch
|
||||
bugfix/powerpc/powerpc-lib-sstep-fix-building-for-powerpcspe.patch
|
||||
bugfix/powerpc/powerpc-lib-makefile-don-t-pull-in-quad.o-for-32-bit.patch
|
||||
bugfix/arm/arm-mm-export-__sync_icache_dcache-for-xen-privcmd.patch
|
||||
|
|
Loading…
Reference in New Issue