diff options
Diffstat (limited to 'drivers/crypto/ccp/psp-dev.c')
| -rw-r--r-- | drivers/crypto/ccp/psp-dev.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c index 218739b961fe..72790d88236d 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); | |||
| 38 | static struct sev_misc_dev *misc_dev; | 38 | static struct sev_misc_dev *misc_dev; |
| 39 | static struct psp_device *psp_master; | 39 | static struct psp_device *psp_master; |
| 40 | 40 | ||
| 41 | static int psp_cmd_timeout = 100; | ||
| 42 | module_param(psp_cmd_timeout, int, 0644); | ||
| 43 | MODULE_PARM_DESC(psp_cmd_timeout, " default timeout value, in seconds, for PSP commands"); | ||
| 44 | |||
| 45 | static int psp_probe_timeout = 5; | ||
| 46 | module_param(psp_probe_timeout, int, 0644); | ||
| 47 | MODULE_PARM_DESC(psp_probe_timeout, " default timeout value, in seconds, during PSP device probe"); | ||
| 48 | |||
| 49 | static bool psp_dead; | ||
| 50 | static int psp_timeout; | ||
| 51 | |||
| 41 | static struct psp_device *psp_alloc_struct(struct sp_device *sp) | 52 | static struct psp_device *psp_alloc_struct(struct sp_device *sp) |
| 42 | { | 53 | { |
| 43 | struct device *dev = sp->dev; | 54 | struct device *dev = sp->dev; |
| @@ -82,10 +93,19 @@ done: | |||
| 82 | return IRQ_HANDLED; | 93 | return IRQ_HANDLED; |
| 83 | } | 94 | } |
| 84 | 95 | ||
| 85 | static void sev_wait_cmd_ioc(struct psp_device *psp, unsigned int *reg) | 96 | static int sev_wait_cmd_ioc(struct psp_device *psp, |
| 97 | unsigned int *reg, unsigned int timeout) | ||
| 86 | { | 98 | { |
| 87 | wait_event(psp->sev_int_queue, psp->sev_int_rcvd); | 99 | int ret; |
| 100 | |||
| 101 | ret = wait_event_timeout(psp->sev_int_queue, | ||
| 102 | psp->sev_int_rcvd, timeout * HZ); | ||
| 103 | if (!ret) | ||
| 104 | return -ETIMEDOUT; | ||
| 105 | |||
| 88 | *reg = ioread32(psp->io_regs + psp->vdata->cmdresp_reg); | 106 | *reg = ioread32(psp->io_regs + psp->vdata->cmdresp_reg); |
| 107 | |||
| 108 | return 0; | ||
| 89 | } | 109 | } |
| 90 | 110 | ||
| 91 | static int sev_cmd_buffer_len(int cmd) | 111 | 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) | |||
| 133 | if (!psp) | 153 | if (!psp) |
| 134 | return -ENODEV; | 154 | return -ENODEV; |
| 135 | 155 | ||
| 156 | if (psp_dead) | ||
| 157 | return -EBUSY; | ||
| 158 | |||
| 136 | /* Get the physical address of the command buffer */ | 159 | /* Get the physical address of the command buffer */ |
| 137 | phys_lsb = data ? lower_32_bits(__psp_pa(data)) : 0; | 160 | phys_lsb = data ? lower_32_bits(__psp_pa(data)) : 0; |
| 138 | phys_msb = data ? upper_32_bits(__psp_pa(data)) : 0; | 161 | phys_msb = data ? upper_32_bits(__psp_pa(data)) : 0; |
| 139 | 162 | ||
| 140 | dev_dbg(psp->dev, "sev command id %#x buffer 0x%08x%08x\n", | 163 | dev_dbg(psp->dev, "sev command id %#x buffer 0x%08x%08x timeout %us\n", |
| 141 | cmd, phys_msb, phys_lsb); | 164 | cmd, phys_msb, phys_lsb, psp_timeout); |
| 142 | 165 | ||
| 143 | print_hex_dump_debug("(in): ", DUMP_PREFIX_OFFSET, 16, 2, data, | 166 | print_hex_dump_debug("(in): ", DUMP_PREFIX_OFFSET, 16, 2, data, |
| 144 | sev_cmd_buffer_len(cmd), false); | 167 | sev_cmd_buffer_len(cmd), false); |
| @@ -154,7 +177,18 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) | |||
| 154 | iowrite32(reg, psp->io_regs + psp->vdata->cmdresp_reg); | 177 | iowrite32(reg, psp->io_regs + psp->vdata->cmdresp_reg); |
| 155 | 178 | ||
| 156 | /* wait for command completion */ | 179 | /* wait for command completion */ |
| 157 | sev_wait_cmd_ioc(psp, ®); | 180 | ret = sev_wait_cmd_ioc(psp, ®, psp_timeout); |
| 181 | if (ret) { | ||
| 182 | if (psp_ret) | ||
| 183 | *psp_ret = 0; | ||
| 184 | |||
| 185 | dev_err(psp->dev, "sev command %#x timed out, disabling PSP \n", cmd); | ||
| 186 | psp_dead = true; | ||
| 187 | |||
| 188 | return ret; | ||
| 189 | } | ||
| 190 | |||
| 191 | psp_timeout = psp_cmd_timeout; | ||
| 158 | 192 | ||
| 159 | if (psp_ret) | 193 | if (psp_ret) |
| 160 | *psp_ret = reg & PSP_CMDRESP_ERR_MASK; | 194 | *psp_ret = reg & PSP_CMDRESP_ERR_MASK; |
| @@ -888,6 +922,8 @@ void psp_pci_init(void) | |||
| 888 | 922 | ||
| 889 | psp_master = sp->psp_data; | 923 | psp_master = sp->psp_data; |
| 890 | 924 | ||
| 925 | psp_timeout = psp_probe_timeout; | ||
| 926 | |||
| 891 | if (sev_get_api_version()) | 927 | if (sev_get_api_version()) |
| 892 | goto err; | 928 | goto err; |
| 893 | 929 | ||
