Commit 38d9dff1 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'optee-bus-for-v5.9' of...

Merge tag 'optee-bus-for-v5.9' of git://git.linaro.org/people/jens.wiklander/linux-tee into arm/drivers

Enable multi-stage OP-TEE bus enumeration

Probes drivers on the OP-TEE bus in two steps. First for drivers which
do not depend on tee-supplicant. After tee-supplicant has been started
probe the devices which do depend on tee-supplicant.

Also introduces driver which uses an OP-TEE based fTPM Trusted
Application depends on tee-supplicant NV RAM implementation based on
RPMB secure storage.

* tag 'optee-bus-for-v5.9' of git://git.linaro.org/people/jens.wiklander/linux-tee:
  tpm_ftpm_tee: register driver on TEE bus
  optee: enable support for multi-stage bus enumeration
  optee: use uuid for sysfs driver entry

Link: https://lore.kernel.org/r/20200710085230.GA1312913@jade


Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 86aa1608 9f1944c2
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
What:		/sys/bus/tee/devices/optee-ta-<uuid>/
Date:           May 2020
KernelVersion   5.8
Contact:        op-tee@lists.trustedfirmware.org
Description:
		OP-TEE bus provides reference to registered drivers under this directory. The <uuid>
		matches Trusted Application (TA) driver and corresponding TA in secure OS. Drivers
		are free to create needed API under optee-ta-<uuid> directory.
+1 −0
Original line number Diff line number Diff line
@@ -12697,6 +12697,7 @@ OP-TEE DRIVER
M:	Jens Wiklander <jens.wiklander@linaro.org>
L:	tee-dev@lists.linaro.org
S:	Maintained
F:	Documentation/ABI/testing/sysfs-bus-optee-devices
F:	drivers/tee/optee/
OP-TEE RANDOM NUMBER GENERATOR (RNG) DRIVER
+60 −10
Original line number Diff line number Diff line
@@ -214,11 +214,10 @@ static int ftpm_tee_match(struct tee_ioctl_version_data *ver, const void *data)
 * Return:
 *	On success, 0. On failure, -errno.
 */
static int ftpm_tee_probe(struct platform_device *pdev)
static int ftpm_tee_probe(struct device *dev)
{
	int rc;
	struct tpm_chip *chip;
	struct device *dev = &pdev->dev;
	struct ftpm_tee_private *pvt_data = NULL;
	struct tee_ioctl_open_session_arg sess_arg;

@@ -297,6 +296,13 @@ out_tee_session:
	return rc;
}

static int ftpm_plat_tee_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;

	return ftpm_tee_probe(dev);
}

/**
 * ftpm_tee_remove() - remove the TPM device
 * @pdev: the platform_device description.
@@ -304,9 +310,9 @@ out_tee_session:
 * Return:
 *	0 always.
 */
static int ftpm_tee_remove(struct platform_device *pdev)
static int ftpm_tee_remove(struct device *dev)
{
	struct ftpm_tee_private *pvt_data = dev_get_drvdata(&pdev->dev);
	struct ftpm_tee_private *pvt_data = dev_get_drvdata(dev);

	/* Release the chip */
	tpm_chip_unregister(pvt_data->chip);
@@ -328,11 +334,18 @@ static int ftpm_tee_remove(struct platform_device *pdev)
	return 0;
}

static int ftpm_plat_tee_remove(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;

	return ftpm_tee_remove(dev);
}

/**
 * ftpm_tee_shutdown() - shutdown the TPM device
 * @pdev: the platform_device description.
 */
static void ftpm_tee_shutdown(struct platform_device *pdev)
static void ftpm_plat_tee_shutdown(struct platform_device *pdev)
{
	struct ftpm_tee_private *pvt_data = dev_get_drvdata(&pdev->dev);

@@ -347,17 +360,54 @@ static const struct of_device_id of_ftpm_tee_ids[] = {
};
MODULE_DEVICE_TABLE(of, of_ftpm_tee_ids);

static struct platform_driver ftpm_tee_driver = {
static struct platform_driver ftpm_tee_plat_driver = {
	.driver = {
		.name = "ftpm-tee",
		.of_match_table = of_match_ptr(of_ftpm_tee_ids),
	},
	.shutdown = ftpm_plat_tee_shutdown,
	.probe = ftpm_plat_tee_probe,
	.remove = ftpm_plat_tee_remove,
};

/* UUID of the fTPM TA */
static const struct tee_client_device_id optee_ftpm_id_table[] = {
	{UUID_INIT(0xbc50d971, 0xd4c9, 0x42c4,
		   0x82, 0xcb, 0x34, 0x3f, 0xb7, 0xf3, 0x78, 0x96)},
	{}
};

MODULE_DEVICE_TABLE(tee, optee_ftpm_id_table);

static struct tee_client_driver ftpm_tee_driver = {
	.id_table	= optee_ftpm_id_table,
	.driver		= {
		.name		= "optee-ftpm",
		.bus		= &tee_bus_type,
		.probe		= ftpm_tee_probe,
		.remove		= ftpm_tee_remove,
	.shutdown = ftpm_tee_shutdown,
	},
};

module_platform_driver(ftpm_tee_driver);
static int __init ftpm_mod_init(void)
{
	int rc;

	rc = platform_driver_register(&ftpm_tee_plat_driver);
	if (rc)
		return rc;

	return driver_register(&ftpm_tee_driver.driver);
}

static void __exit ftpm_mod_exit(void)
{
	platform_driver_unregister(&ftpm_tee_plat_driver);
	driver_unregister(&ftpm_tee_driver.driver);
}

module_init(ftpm_mod_init);
module_exit(ftpm_mod_exit);

MODULE_AUTHOR("Thirupathaiah Annapureddy <thiruan@microsoft.com>");
MODULE_DESCRIPTION("TPM Driver for fTPM TA in TEE");
+24 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/tee_drv.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/workqueue.h>
#include "optee_private.h"
#include "optee_smc.h"
#include "shm_pool.h"
@@ -218,6 +219,11 @@ static void optee_get_version(struct tee_device *teedev,
	*vers = v;
}

static void optee_bus_scan(struct work_struct *work)
{
	WARN_ON(optee_enumerate_devices(PTA_CMD_GET_DEVICES_SUPP));
}

static int optee_open(struct tee_context *ctx)
{
	struct optee_context_data *ctxdata;
@@ -241,8 +247,18 @@ static int optee_open(struct tee_context *ctx)
			kfree(ctxdata);
			return -EBUSY;
		}
	}

		if (!optee->scan_bus_done) {
			INIT_WORK(&optee->scan_bus_work, optee_bus_scan);
			optee->scan_bus_wq = create_workqueue("optee_bus_scan");
			if (!optee->scan_bus_wq) {
				kfree(ctxdata);
				return -ECHILD;
			}
			queue_work(optee->scan_bus_wq, &optee->scan_bus_work);
			optee->scan_bus_done = true;
		}
	}
	mutex_init(&ctxdata->mutex);
	INIT_LIST_HEAD(&ctxdata->sess_list);

@@ -296,9 +312,14 @@ static void optee_release(struct tee_context *ctx)

	ctx->data = NULL;

	if (teedev == optee->supp_teedev)
	if (teedev == optee->supp_teedev) {
		if (optee->scan_bus_wq) {
			destroy_workqueue(optee->scan_bus_wq);
			optee->scan_bus_wq = NULL;
		}
		optee_supp_release(&optee->supp);
	}
}

static const struct tee_driver_ops optee_ops = {
	.get_version = optee_get_version,
@@ -675,7 +696,7 @@ static int optee_probe(struct platform_device *pdev)

	platform_set_drvdata(pdev, optee);

	rc = optee_enumerate_devices();
	rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
	if (rc) {
		optee_remove(pdev);
		return rc;
+17 −21
Original line number Diff line number Diff line
@@ -11,18 +11,6 @@
#include <linux/uuid.h>
#include "optee_private.h"

/*
 * Get device UUIDs
 *
 * [out]     memref[0]        Array of device UUIDs
 *
 * Return codes:
 * TEE_SUCCESS - Invoke command success
 * TEE_ERROR_BAD_PARAMETERS - Incorrect input param
 * TEE_ERROR_SHORT_BUFFER - Output buffer size less than required
 */
#define PTA_CMD_GET_DEVICES		0x0

static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
{
	if (ver->impl_id == TEE_IMPL_ID_OPTEE)
@@ -32,7 +20,8 @@ static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
}

static int get_devices(struct tee_context *ctx, u32 session,
		       struct tee_shm *device_shm, u32 *shm_size)
		       struct tee_shm *device_shm, u32 *shm_size,
		       u32 func)
{
	int ret = 0;
	struct tee_ioctl_invoke_arg inv_arg;
@@ -41,8 +30,7 @@ static int get_devices(struct tee_context *ctx, u32 session,
	memset(&inv_arg, 0, sizeof(inv_arg));
	memset(&param, 0, sizeof(param));

	/* Invoke PTA_CMD_GET_DEVICES function */
	inv_arg.func = PTA_CMD_GET_DEVICES;
	inv_arg.func = func;
	inv_arg.session = session;
	inv_arg.num_params = 4;

@@ -65,7 +53,7 @@ static int get_devices(struct tee_context *ctx, u32 session,
	return 0;
}

static int optee_register_device(const uuid_t *device_uuid, u32 device_id)
static int optee_register_device(const uuid_t *device_uuid)
{
	struct tee_client_device *optee_device = NULL;
	int rc;
@@ -75,7 +63,10 @@ static int optee_register_device(const uuid_t *device_uuid, u32 device_id)
		return -ENOMEM;

	optee_device->dev.bus = &tee_bus_type;
	dev_set_name(&optee_device->dev, "optee-clnt%u", device_id);
	if (dev_set_name(&optee_device->dev, "optee-ta-%pUb", device_uuid)) {
		kfree(optee_device);
		return -ENOMEM;
	}
	uuid_copy(&optee_device->id.uuid, device_uuid);

	rc = device_register(&optee_device->dev);
@@ -87,7 +78,7 @@ static int optee_register_device(const uuid_t *device_uuid, u32 device_id)
	return rc;
}

int optee_enumerate_devices(void)
static int __optee_enumerate_devices(u32 func)
{
	const uuid_t pta_uuid =
		UUID_INIT(0x7011a688, 0xddde, 0x4053,
@@ -118,7 +109,7 @@ int optee_enumerate_devices(void)
		goto out_ctx;
	}

	rc = get_devices(ctx, sess_arg.session, NULL, &shm_size);
	rc = get_devices(ctx, sess_arg.session, NULL, &shm_size, func);
	if (rc < 0 || !shm_size)
		goto out_sess;

@@ -130,7 +121,7 @@ int optee_enumerate_devices(void)
		goto out_sess;
	}

	rc = get_devices(ctx, sess_arg.session, device_shm, &shm_size);
	rc = get_devices(ctx, sess_arg.session, device_shm, &shm_size, func);
	if (rc < 0)
		goto out_shm;

@@ -144,7 +135,7 @@ int optee_enumerate_devices(void)
	num_devices = shm_size / sizeof(uuid_t);

	for (idx = 0; idx < num_devices; idx++) {
		rc = optee_register_device(&device_uuid[idx], idx);
		rc = optee_register_device(&device_uuid[idx]);
		if (rc)
			goto out_shm;
	}
@@ -158,3 +149,8 @@ out_ctx:

	return rc;
}

int optee_enumerate_devices(u32 func)
{
	return  __optee_enumerate_devices(func);
}
Loading