summaryrefslogtreecommitdiffstats
path: root/drivers/tee
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tee')
-rw-r--r--drivers/tee/optee/core.c23
-rw-r--r--drivers/tee/optee/optee_smc.h10
-rw-r--r--drivers/tee/tee_core.c14
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;
}
OpenPOWER on IntegriCloud