diff --git a/drivers/amlogic/unifykey/v8/securitykey.c b/drivers/amlogic/unifykey/v8/securitykey.c index 5b6b23f6af70..c966772c672a 100644 --- a/drivers/amlogic/unifykey/v8/securitykey.c +++ b/drivers/amlogic/unifykey/v8/securitykey.c @@ -56,6 +56,8 @@ static unsigned long storage_version_func; static DEFINE_SPINLOCK(storage_lock); static unsigned long lockflags; +static int storage_init_status; + static uint64_t storage_smc_ops(uint64_t func) { register unsigned long x0 asm("x0") = func; @@ -111,16 +113,19 @@ int32_t secure_storage_write(uint8_t *keyname, uint8_t *keybuf, uint64_t ret; spin_lock_irqsave(&storage_lock, lockflags); - namelen = strlen((const char *)keyname); - input = (uint32_t *)storage_in_base; - *input++ = namelen; - *input++ = keylen; - *input++ = keyattr; - name = (uint8_t *)input; - memcpy(name, keyname, namelen); - keydata = name + namelen; - memcpy(keydata, keybuf, keylen); - ret = storage_smc_ops(storage_write_func); + if (storage_init_status == 1) { + namelen = strlen((const char *)keyname); + input = (uint32_t *)storage_in_base; + *input++ = namelen; + *input++ = keylen; + *input++ = keyattr; + name = (uint8_t *)input; + memcpy(name, keyname, namelen); + keydata = name + namelen; + memcpy(keydata, keybuf, keylen); + ret = storage_smc_ops(storage_write_func); + } else + ret = RET_EUND; spin_unlock_irqrestore(&storage_lock, lockflags); return smc_to_linux_errno(ret); } @@ -135,17 +140,20 @@ int32_t secure_storage_read(uint8_t *keyname, uint8_t *keybuf, uint64_t ret; spin_lock_irqsave(&storage_lock, lockflags); - namelen = strlen((const char *)keyname); - *input++ = namelen; - *input++ = keylen; - name = (uint8_t *)input; - memcpy(name, keyname, namelen); - ret = storage_smc_ops(storage_read_func); - if (ret == RET_OK) { - *readlen = *output; - buf = (uint8_t *)(output + 1); - memcpy(keybuf, buf, *readlen); - } + if (storage_init_status == 1) { + namelen = strlen((const char *)keyname); + *input++ = namelen; + *input++ = keylen; + name = (uint8_t *)input; + memcpy(name, keyname, namelen); + ret = storage_smc_ops(storage_read_func); + if (ret == RET_OK) { + *readlen = *output; + buf = (uint8_t *)(output + 1); + memcpy(keybuf, buf, *readlen); + } + } else + ret = RET_EUND; spin_unlock_irqrestore(&storage_lock, lockflags); return smc_to_linux_errno(ret); } @@ -159,13 +167,16 @@ int32_t secure_storage_verify(uint8_t *keyname, uint8_t *hashbuf) uint64_t ret; spin_lock_irqsave(&storage_lock, lockflags); - namelen = strlen((const char *)keyname); - *input++ = namelen; - name = (uint8_t *)input; - memcpy(name, keyname, namelen); - ret = storage_smc_ops(storage_verify_func); - if (ret == RET_OK) - memcpy(hashbuf, (uint8_t *)output, 32); + if (storage_init_status == 1) { + namelen = strlen((const char *)keyname); + *input++ = namelen; + name = (uint8_t *)input; + memcpy(name, keyname, namelen); + ret = storage_smc_ops(storage_verify_func); + if (ret == RET_OK) + memcpy(hashbuf, (uint8_t *)output, 32); + } else + ret = RET_EUND; spin_unlock_irqrestore(&storage_lock, lockflags); return smc_to_linux_errno(ret); @@ -180,13 +191,16 @@ int32_t secure_storage_query(uint8_t *keyname, uint32_t *retval) uint64_t ret; spin_lock_irqsave(&storage_lock, lockflags); - namelen = strlen((const char *)keyname); - *input++ = namelen; - name = (uint8_t *)input; - memcpy(name, keyname, namelen); - ret = storage_smc_ops(storage_query_func); - if (ret == RET_OK) - *retval = *output; + if (storage_init_status == 1) { + namelen = strlen((const char *)keyname); + *input++ = namelen; + name = (uint8_t *)input; + memcpy(name, keyname, namelen); + ret = storage_smc_ops(storage_query_func); + if (ret == RET_OK) + *retval = *output; + } else + ret = RET_EUND; spin_unlock_irqrestore(&storage_lock, lockflags); return smc_to_linux_errno(ret); @@ -201,13 +215,16 @@ int32_t secure_storage_tell(uint8_t *keyname, uint32_t *retval) uint64_t ret; spin_lock_irqsave(&storage_lock, lockflags); - namelen = strlen((const char *)keyname); - *input++ = namelen; - name = (uint8_t *)input; - memcpy(name, keyname, namelen); - ret = storage_smc_ops(storage_tell_func); - if (ret == RET_OK) - *retval = *output; + if (storage_init_status == 1) { + namelen = strlen((const char *)keyname); + *input++ = namelen; + name = (uint8_t *)input; + memcpy(name, keyname, namelen); + ret = storage_smc_ops(storage_tell_func); + if (ret == RET_OK) + *retval = *output; + } else + ret = RET_EUND; spin_unlock_irqrestore(&storage_lock, lockflags); return smc_to_linux_errno(ret); } @@ -221,13 +238,16 @@ int32_t secure_storage_status(uint8_t *keyname, uint32_t *retval) uint64_t ret; spin_lock_irqsave(&storage_lock, lockflags); - namelen = strlen((const char *)keyname); - *input++ = namelen; - name = (uint8_t *)input; - memcpy(name, keyname, namelen); - ret = storage_smc_ops(storage_status_func); - if (ret == RET_OK) - *retval = *output; + if (storage_init_status == 1) { + namelen = strlen((const char *)keyname); + *input++ = namelen; + name = (uint8_t *)input; + memcpy(name, keyname, namelen); + ret = storage_smc_ops(storage_status_func); + if (ret == RET_OK) + *retval = *output; + } else + ret = RET_EUND; spin_unlock_irqrestore(&storage_lock, lockflags); return smc_to_linux_errno(ret); } @@ -239,14 +259,17 @@ int32_t secure_storage_list(uint8_t *listbuf, uint64_t ret; spin_lock_irqsave(&storage_lock, lockflags); - ret = storage_smc_ops(storage_list_func); - if (ret == RET_OK) { - if (*output > buflen) - *readlen = buflen; - else - *readlen = *output; - memcpy(listbuf, (uint8_t *)(output+1), *readlen); - } + if (storage_init_status == 1) { + ret = storage_smc_ops(storage_list_func); + if (ret == RET_OK) { + if (*output > buflen) + *readlen = buflen; + else + *readlen = *output; + memcpy(listbuf, (uint8_t *)(output+1), *readlen); + } + } else + ret = RET_EUND; spin_unlock_irqrestore(&storage_lock, lockflags); return smc_to_linux_errno(ret); } @@ -259,11 +282,14 @@ int32_t secure_storage_remove(uint8_t *keyname) uint64_t ret; spin_lock_irqsave(&storage_lock, lockflags); - namelen = strlen((const char *)keyname); - *input++ = namelen; - name = (uint8_t *)input; - memcpy(name, keyname, namelen); - ret = storage_smc_ops(storage_remove_func); + if (storage_init_status == 1) { + namelen = strlen((const char *)keyname); + *input++ = namelen; + name = (uint8_t *)input; + memcpy(name, keyname, namelen); + ret = storage_smc_ops(storage_remove_func); + } else + ret = RET_EUND; spin_unlock_irqrestore(&storage_lock, lockflags); return smc_to_linux_errno(ret); } @@ -345,12 +371,22 @@ static int storage_probe(struct platform_device *pdev) return -1; } - storage_in_base = ioremap_cache(phy_storage_in_base, - storage_block_size); - storage_out_base = ioremap_cache(phy_storage_out_base, - storage_block_size); - storage_block_base = ioremap_cache(phy_storage_block_base, - storage_block_size); + if (phy_storage_in_base == SMC_UNK + || phy_storage_out_base == SMC_UNK + || phy_storage_block_base == SMC_UNK + || storage_block_size == SMC_UNK) { + storage_in_base = NULL; + storage_out_base = NULL; + storage_block_base = NULL; + } else { + storage_in_base = ioremap_cache(phy_storage_in_base, + storage_block_size); + storage_out_base = ioremap_cache(phy_storage_out_base, + storage_block_size); + storage_block_base = ioremap_cache(phy_storage_block_base, + storage_block_size); + } + pr_info("storage in base: 0x%lx\n", (long)storage_in_base); pr_info("storage out base: 0x%lx\n", (long)storage_out_base); pr_info("storage block base: 0x%lx\n", (long)storage_block_base); @@ -358,6 +394,11 @@ static int storage_probe(struct platform_device *pdev) ret = 0; if (!storage_in_base || !storage_out_base || !storage_block_base) ret = -1; + if (ret == 0) + storage_init_status = 1; + else + storage_init_status = -1; + pr_info("probe done!\n"); return ret; } diff --git a/include/linux/amlogic/unifykey/security_key.h b/include/linux/amlogic/unifykey/security_key.h index 04e57d0de95f..b73fd73b7e9f 100644 --- a/include/linux/amlogic/unifykey/security_key.h +++ b/include/linux/amlogic/unifykey/security_key.h @@ -24,6 +24,9 @@ #define RET_EINVAL 2 /*name length*/ #define RET_EMEM 3 /*no enough memory*/ +#define RET_EUND -1 +#define SMC_UNK 0xffffffff + /* keyattr: 0: normal, 1: secure*/ int32_t secure_storage_write(uint8_t *keyname, uint8_t *keybuf, uint32_t keylen, uint32_t keyattr);