diff options
Diffstat (limited to 'drivers/tee')
-rw-r--r-- | drivers/tee/optee/core.c | 23 | ||||
-rw-r--r-- | drivers/tee/optee/optee_smc.h | 10 | ||||
-rw-r--r-- | drivers/tee/tee_core.c | 14 |
3 files changed, 41 insertions, 6 deletions
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index e9843c53fe31..e5fd5ed217da 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -356,6 +356,27 @@ static bool optee_msg_api_uid_is_optee_api(optee_invoke_fn *invoke_fn) return false; } +static void optee_msg_get_os_revision(optee_invoke_fn *invoke_fn) +{ + union { + struct arm_smccc_res smccc; + struct optee_smc_call_get_os_revision_result result; + } res = { + .result = { + .build_id = 0 + } + }; + + invoke_fn(OPTEE_SMC_CALL_GET_OS_REVISION, 0, 0, 0, 0, 0, 0, 0, + &res.smccc); + + if (res.result.build_id) + pr_info("revision %lu.%lu (%08lx)", res.result.major, + res.result.minor, res.result.build_id); + else + pr_info("revision %lu.%lu", res.result.major, res.result.minor); +} + static bool optee_msg_api_revision_is_compatible(optee_invoke_fn *invoke_fn) { union { @@ -547,6 +568,8 @@ static struct optee *optee_probe(struct device_node *np) return ERR_PTR(-EINVAL); } + optee_msg_get_os_revision(invoke_fn); + if (!optee_msg_api_revision_is_compatible(invoke_fn)) { pr_warn("api revision mismatch\n"); return ERR_PTR(-EINVAL); diff --git a/drivers/tee/optee/optee_smc.h b/drivers/tee/optee/optee_smc.h index 7cd327243ada..bbf0cf028c16 100644 --- a/drivers/tee/optee/optee_smc.h +++ b/drivers/tee/optee/optee_smc.h @@ -112,12 +112,20 @@ struct optee_smc_calls_revision_result { * Trusted OS, not of the API. * * Returns revision in a0-1 in the same way as OPTEE_SMC_CALLS_REVISION - * described above. + * described above. May optionally return a 32-bit build identifier in a2, + * with zero meaning unspecified. */ #define OPTEE_SMC_FUNCID_GET_OS_REVISION OPTEE_MSG_FUNCID_GET_OS_REVISION #define OPTEE_SMC_CALL_GET_OS_REVISION \ OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_OS_REVISION) +struct optee_smc_call_get_os_revision_result { + unsigned long major; + unsigned long minor; + unsigned long build_id; + unsigned long reserved1; +}; + /* * Call with struct optee_msg_arg as argument * diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 6c4b200a4560..0124a91c8d71 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -693,7 +693,7 @@ struct tee_device *tee_device_alloc(const struct tee_desc *teedesc, { struct tee_device *teedev; void *ret; - int rc; + int rc, max_id; int offs = 0; if (!teedesc || !teedesc->name || !teedesc->ops || @@ -707,16 +707,20 @@ struct tee_device *tee_device_alloc(const struct tee_desc *teedesc, goto err; } - if (teedesc->flags & TEE_DESC_PRIVILEGED) + max_id = TEE_NUM_DEVICES / 2; + + if (teedesc->flags & TEE_DESC_PRIVILEGED) { offs = TEE_NUM_DEVICES / 2; + max_id = TEE_NUM_DEVICES; + } spin_lock(&driver_lock); - teedev->id = find_next_zero_bit(dev_mask, TEE_NUM_DEVICES, offs); - if (teedev->id < TEE_NUM_DEVICES) + teedev->id = find_next_zero_bit(dev_mask, max_id, offs); + if (teedev->id < max_id) set_bit(teedev->id, dev_mask); spin_unlock(&driver_lock); - if (teedev->id >= TEE_NUM_DEVICES) { + if (teedev->id >= max_id) { ret = ERR_PTR(-ENOMEM); goto err; } |