-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
firmware: qcom_scm: Add support for Qualcomm Secure Execution Environ…
…ment SCM interface Add support for SCM calls to Secure OS and the Secure Execution Environment (SEE) residing in the TrustZone (TZ) via the QSEECOM interface. This allows communication with Secure/TZ applications, for example 'uefisecapp' managing access to UEFI variables. For better separation, make qcom_scm spin up a dedicated child (platform) device in case QSEECOM support has been detected. The corresponding driver for this device is then responsible for managing any QSEECOM clients. Specifically, this driver attempts to automatically detect known and supported applications, creating a client (auxiliary) device for each one. The respective client/auxiliary driver is then responsible for managing and communicating with the application. While this patch introduces only a very basic interface without the more advanced features (such as re-entrant and blocking SCM calls and listeners/callbacks), this is enough to talk to the aforementioned 'uefisecapp'. Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> Reviewed-by: Johan Hovold <johan+linaro@kernel.org> Link: https://lore.kernel.org/r/20230827211408.689076-3-luzmaximilian@gmail.com Signed-off-by: Bjorn Andersson <andersson@kernel.org>
- Loading branch information
Maximilian Luz
authored and
Bjorn Andersson
committed
Sep 13, 2023
1 parent
e4c89f9
commit 00b1248
Showing
7 changed files
with
603 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
/* | ||
* Driver for Qualcomm Secure Execution Environment (SEE) interface (QSEECOM). | ||
* Responsible for setting up and managing QSEECOM client devices. | ||
* | ||
* Copyright (C) 2023 Maximilian Luz <luzmaximilian@gmail.com> | ||
*/ | ||
#include <linux/auxiliary_bus.h> | ||
#include <linux/module.h> | ||
#include <linux/platform_device.h> | ||
#include <linux/slab.h> | ||
#include <linux/types.h> | ||
|
||
#include <linux/firmware/qcom/qcom_qseecom.h> | ||
#include <linux/firmware/qcom/qcom_scm.h> | ||
|
||
struct qseecom_app_desc { | ||
const char *app_name; | ||
const char *dev_name; | ||
}; | ||
|
||
static void qseecom_client_release(struct device *dev) | ||
{ | ||
struct qseecom_client *client; | ||
|
||
client = container_of(dev, struct qseecom_client, aux_dev.dev); | ||
kfree(client); | ||
} | ||
|
||
static void qseecom_client_remove(void *data) | ||
{ | ||
struct qseecom_client *client = data; | ||
|
||
auxiliary_device_delete(&client->aux_dev); | ||
auxiliary_device_uninit(&client->aux_dev); | ||
} | ||
|
||
static int qseecom_client_register(struct platform_device *qseecom_dev, | ||
const struct qseecom_app_desc *desc) | ||
{ | ||
struct qseecom_client *client; | ||
u32 app_id; | ||
int ret; | ||
|
||
/* Try to find the app ID, skip device if not found */ | ||
ret = qcom_scm_qseecom_app_get_id(desc->app_name, &app_id); | ||
if (ret) | ||
return ret == -ENOENT ? 0 : ret; | ||
|
||
dev_info(&qseecom_dev->dev, "setting up client for %s\n", desc->app_name); | ||
|
||
/* Allocate and set-up the client device */ | ||
client = kzalloc(sizeof(*client), GFP_KERNEL); | ||
if (!client) | ||
return -ENOMEM; | ||
|
||
client->aux_dev.name = desc->dev_name; | ||
client->aux_dev.dev.parent = &qseecom_dev->dev; | ||
client->aux_dev.dev.release = qseecom_client_release; | ||
client->app_id = app_id; | ||
|
||
ret = auxiliary_device_init(&client->aux_dev); | ||
if (ret) { | ||
kfree(client); | ||
return ret; | ||
} | ||
|
||
ret = auxiliary_device_add(&client->aux_dev); | ||
if (ret) { | ||
auxiliary_device_uninit(&client->aux_dev); | ||
return ret; | ||
} | ||
|
||
ret = devm_add_action_or_reset(&qseecom_dev->dev, qseecom_client_remove, client); | ||
if (ret) | ||
return ret; | ||
|
||
return 0; | ||
} | ||
|
||
/* | ||
* List of supported applications. One client device will be created per entry, | ||
* assuming the app has already been loaded (usually by firmware bootloaders) | ||
* and its ID can be queried successfully. | ||
*/ | ||
static const struct qseecom_app_desc qcom_qseecom_apps[] = {}; | ||
|
||
static int qcom_qseecom_probe(struct platform_device *qseecom_dev) | ||
{ | ||
int ret; | ||
int i; | ||
|
||
/* Set up client devices for each base application */ | ||
for (i = 0; i < ARRAY_SIZE(qcom_qseecom_apps); i++) { | ||
ret = qseecom_client_register(qseecom_dev, &qcom_qseecom_apps[i]); | ||
if (ret) | ||
return ret; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static struct platform_driver qcom_qseecom_driver = { | ||
.driver = { | ||
.name = "qcom_qseecom", | ||
}, | ||
.probe = qcom_qseecom_probe, | ||
}; | ||
|
||
static int __init qcom_qseecom_init(void) | ||
{ | ||
return platform_driver_register(&qcom_qseecom_driver); | ||
} | ||
subsys_initcall(qcom_qseecom_init); | ||
|
||
MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>"); | ||
MODULE_DESCRIPTION("Driver for the Qualcomm SEE (QSEECOM) interface"); | ||
MODULE_LICENSE("GPL"); |
Oops, something went wrong.