crypto: ccp - Verify access to device registers before initializing
authorHook, Gary <Gary.Hook@amd.com>
Mon, 21 Oct 2019 13:44:44 +0000 (13:44 +0000)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 25 Oct 2019 15:09:59 +0000 (02:09 +1100)
Check early whether device registers can be accessed. Some BIOSes have
a broken security policy that prevents access to the device registers,
and return values from ioread() can be misinterpreted. If a read of
a feature register returns a -1, we may not be able to access
any device register, so report the problem and suggestion, and return.

For the PSP, the feature register is checked. For the CCP, the queue
register is checked.

Signed-off-by: Gary R Hook <gary.hook@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/ccp/ccp-dev-v5.c
drivers/crypto/ccp/psp-dev.c

index 2937ba3afb7b57635c8f8feed0dc68a4b6c40ef7..82ac4c14c04c55942ed92d8b7b896b133358783d 100644 (file)
@@ -789,6 +789,18 @@ static int ccp5_init(struct ccp_device *ccp)
 
        /* Find available queues */
        qmr = ioread32(ccp->io_regs + Q_MASK_REG);
+       /*
+        * Check for a access to the registers.  If this read returns
+        * 0xffffffff, it's likely that the system is running a broken
+        * BIOS which disallows access to the device. Stop here and fail
+        * the initialization (but not the load, as the PSP could get
+        * properly initialized).
+        */
+       if (qmr == 0xffffffff) {
+               dev_notice(dev, "ccp: unable to access the device: you might be running a broken BIOS.\n");
+               return 1;
+       }
+
        for (i = 0; (i < MAX_HW_QUEUES) && (ccp->cmd_q_count < ccp->max_q_count); i++) {
                if (!(qmr & (1 << i)))
                        continue;
index f9318d4482f2043b6c1d7cf9571dc8e71ad8ed97..c4da8d1a9abcbfdb3717e322f96270a2ca5c4d2c 100644 (file)
@@ -929,8 +929,22 @@ static int sev_misc_init(struct psp_device *psp)
 
 static int psp_check_sev_support(struct psp_device *psp)
 {
-       /* Check if device supports SEV feature */
-       if (!(ioread32(psp->io_regs + psp->vdata->feature_reg) & 1)) {
+       unsigned int val = ioread32(psp->io_regs + psp->vdata->feature_reg);
+
+       /*
+        * Check for a access to the registers.  If this read returns
+        * 0xffffffff, it's likely that the system is running a broken
+        * BIOS which disallows access to the device. Stop here and
+        * fail the PSP initialization (but not the load, as the CCP
+        * could get properly initialized).
+        */
+       if (val == 0xffffffff) {
+               dev_notice(psp->dev, "psp: unable to access the device: you might be running a broken BIOS.\n");
+               return -ENODEV;
+       }
+
+       if (!(val & 1)) {
+               /* Device does not support the SEV feature */
                dev_dbg(psp->dev, "psp does not support SEV\n");
                return -ENODEV;
        }