diff --git a/debian/changelog b/debian/changelog index ad543889e..a5e9fa85a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -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 Sat, 08 Sep 2018 23:24:31 +0100 diff --git a/debian/patches/bugfix/x86/crypto-ccp-add-timeout-support-in-the-SEV-command.patch b/debian/patches/bugfix/x86/crypto-ccp-add-timeout-support-in-the-SEV-command.patch new file mode 100644 index 000000000..e3a14c09f --- /dev/null +++ b/debian/patches/bugfix/x86/crypto-ccp-add-timeout-support-in-the-SEV-command.patch @@ -0,0 +1,121 @@ +From: Brijesh Singh +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 +Cc: Gary Hook +Cc: Herbert Xu +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Brijesh Singh +Signed-off-by: Herbert Xu +--- + 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 + diff --git a/debian/patches/series b/debian/patches/series index 01ec569b9..95e55a00a 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -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