Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6e110d2 authored by Siddharth Gupta's avatar Siddharth Gupta Committed by Elliot Berman
Browse files

soc: qcom: Migrate SCM calls in qtee_shmbridge



Adding APIs to create, delete, and enable shmbridge.
Migrating SCM calls in qtee_shmbridge to use the new APIs.

Change-Id: I038e7950d11cbf6bb38a8824a576f2d92f879454
Signed-off-by: default avatarSiddharth Gupta <sidgup@codeaurora.org>
Signed-off-by: default avatarElliot Berman <eberman@codeaurora.org>
parent 49ec350a
Loading
Loading
Loading
Loading
+63 −0
Original line number Diff line number Diff line
@@ -1137,6 +1137,69 @@ int __qcom_scm_kgsl_set_smmu_aperture(struct device *dev,
	return ret;
}

/**
 * The following shmbridge functions should be called before the SCM driver
 * has been initialized. If not, there could be errors that might cause the
 * system to crash.
 */
int __qcom_scm_enable_shm_bridge(struct device *dev)
{
	int ret;
	struct qcom_scm_desc desc = {
		.svc = QCOM_SCM_SVC_MP,
		.cmd = QCOM_SCM_MEMP_SHM_BRIDGE_ENABLE,
		.owner = ARM_SMCCC_OWNER_SIP
	};

	ret = qcom_scm_call(dev, &desc);

	return ret ? : desc.res[0];
}

int __qcom_scm_delete_shm_bridge(struct device *dev, u64 handle)
{
	int ret;
	struct qcom_scm_desc desc = {
		.svc = QCOM_SCM_SVC_MP,
		.cmd = QCOM_SCM_MEMP_SHM_BRIDGE_DELETE,
		.owner = ARM_SMCCC_OWNER_SIP
	};

	desc.args[0] = handle;
	desc.arginfo = QCOM_SCM_ARGS(1, QCOM_SCM_VAL);

	ret = qcom_scm_call(dev, &desc);

	return ret;
}

int __qcom_scm_create_shm_bridge(struct device *dev, u64 pfn_and_ns_perm_flags,
			u64 ipfn_and_s_perm_flags, u64 size_and_flags,
			u64 ns_vmids, u64 *handle)
{
	int ret;
	struct qcom_scm_desc desc = {
		.svc = QCOM_SCM_SVC_MP,
		.cmd = QCOM_SCM_MEMP_SHM_BRDIGE_CREATE,
		.owner = ARM_SMCCC_OWNER_SIP
	};

	desc.args[0] = pfn_and_ns_perm_flags;
	desc.args[1] = ipfn_and_s_perm_flags;
	desc.args[2] = size_and_flags;
	desc.args[3] = ns_vmids;

	desc.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_VAL, QCOM_SCM_VAL,
					QCOM_SCM_VAL, QCOM_SCM_VAL);

	ret = qcom_scm_call(dev, &desc);

	if (handle)
		*handle = desc.res[1];

	return ret ? : desc.res[0];
}

int __qcom_scm_smmu_prepare_atos_id(struct device *dev, u64 dev_id, int cb_num,
					int operation)
{
+22 −0
Original line number Diff line number Diff line
@@ -504,6 +504,28 @@ int qcom_scm_kgsl_set_smmu_aperture(unsigned int num_context_bank)
}
EXPORT_SYMBOL(qcom_scm_kgsl_set_smmu_aperture);

int qcom_scm_enable_shm_bridge(void)
{
	return __qcom_scm_enable_shm_bridge(__scm ? __scm->dev : NULL);
}
EXPORT_SYMBOL(qcom_scm_enable_shm_bridge);

int qcom_scm_delete_shm_bridge(u64 handle)
{
	return __qcom_scm_delete_shm_bridge(__scm ? __scm->dev : NULL, handle);
}
EXPORT_SYMBOL(qcom_scm_delete_shm_bridge);

int qcom_scm_create_shm_bridge(u64 pfn_and_ns_perm_flags,
	u64 ipfn_and_s_perm_flags, u64 size_and_flags, u64 ns_vmids,
	u64 *handle)
{
	return __qcom_scm_create_shm_bridge(__scm ? __scm->dev : NULL,
				pfn_and_ns_perm_flags, ipfn_and_s_perm_flags,
				size_and_flags, ns_vmids, handle);
}
EXPORT_SYMBOL(qcom_scm_create_shm_bridge);

int qcom_scm_smmu_prepare_atos_id(u64 dev_id, int cb_num, int operation)
{
	return __qcom_scm_smmu_prepare_atos_id(__scm->dev, dev_id, cb_num,
+8 −0
Original line number Diff line number Diff line
@@ -70,6 +70,9 @@ extern void __qcom_scm_mmu_sync(struct device *dev, bool sync);
#define QCOM_SCM_MP_IOMMU_SECURE_UNMAP2_FLAT	0x13
#define QCOM_SCM_MP_ASSIGN			0x16
#define QCOM_SCM_MP_CP_SMMU_APERTURE_ID		0x1b
#define QCOM_SCM_MEMP_SHM_BRIDGE_ENABLE		0x1c
#define QCOM_SCM_MEMP_SHM_BRIDGE_DELETE		0x1d
#define QCOM_SCM_MEMP_SHM_BRDIGE_CREATE		0x1e
#define QCOM_SCM_MP_SMMU_PREPARE_ATOS_ID	0x21
extern int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id,
				      u32 spare);
@@ -96,6 +99,11 @@ extern int __qcom_scm_assign_mem(struct device *dev,
				  phys_addr_t dest, size_t dest_sz);
extern int __qcom_scm_kgsl_set_smmu_aperture(struct device *dev,
						unsigned int num_context_bank);
extern int __qcom_scm_enable_shm_bridge(struct device *dev);
extern int __qcom_scm_delete_shm_bridge(struct device *dev, u64 handle);
extern int __qcom_scm_create_shm_bridge(struct device *dev,
			u64 pfn_and_ns_perm_flags, u64 ipfn_and_s_perm_flags,
			u64 size_and_flags, u64 ns_vmids, u64 *handle);
extern int __qcom_scm_smmu_prepare_atos_id(struct device *dev, u64 dev_id,
						int cb_num, int operation);
#define QCOM_SCM_IOMMU_TLBINVAL_FLAG    0x00000001
+28 −63
Original line number Diff line number Diff line
@@ -11,48 +11,13 @@
#include <linux/genalloc.h>
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
#include <soc/qcom/scm.h>
#include <linux/qcom_scm.h>
#include <soc/qcom/qseecomi.h>
#include <linux/qtee_shmbridge.h>

#include "qtee_shmbridge_internal.h"

#define DEFAULT_BRIDGE_SIZE	SZ_4M	/*4M*/
/*
 * tz_enable_shm_bridge
 * smc_id: 0x02000C1C
 */
#define TZ_SVC_MEMORY_PROTECTION  12

#define TZ_SHM_BRIDGE_ENABLE                   \
	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_MEMORY_PROTECTION, 0x1C)

#define TZ_SHM_BRIDGE_ENABLE_PARAM_ID          \
		TZ_SYSCALL_CREATE_PARAM_ID_0

/*
 * tz_create_shm_bridge
 * smc_id: 0x02000C1E
 */

#define TZ_SHM_BRIDGE_CREATE                   \
	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_MEMORY_PROTECTION, 0x1E)

#define TZ_SHM_BRIDGE_CREATE_PARAM_ID          \
	TZ_SYSCALL_CREATE_PARAM_ID_4( \
	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \
	TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL)

/**
 * tz_delete_shm_bridge
 * smc_id: 0x02000C1D
 */
#define TZ_SHM_BRIDGE_DELETE                   \
	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_MEMORY_PROTECTION, 0x1D)

#define TZ_SHM_BRIDGE_DELETE_PARAM_ID          \
	TZ_SYSCALL_CREATE_PARAM_ID_1( \
	TZ_SYSCALL_PARAM_TYPE_VAL)

#define MAXSHMVMS 4
#define PERM_BITS 3
@@ -118,7 +83,6 @@ static bool qtee_shmbridge_enabled;
static int32_t qtee_shmbridge_enable(bool enable)
{
	int32_t ret = 0;
	struct scm_desc desc = {0};

	qtee_shmbridge_enabled = false;
	if (!enable) {
@@ -126,14 +90,14 @@ static int32_t qtee_shmbridge_enable(bool enable)
		return ret;
	}

	desc.arginfo = TZ_SHM_BRIDGE_ENABLE_PARAM_ID;
	ret = scm_call2(TZ_SHM_BRIDGE_ENABLE, &desc);
	if (ret || desc.ret[0]) {
		pr_err("Failed to enable shmbridge, rsp = %lld, ret = %d\n",
			desc.ret[0], ret);
		if (ret == -EIO || desc.ret[0] == SHMBRIDGE_E_NOT_SUPPORTED)
	ret = qcom_scm_enable_shm_bridge();

	if (ret) {
		pr_err("Failed to enable shmbridge, ret = %d\n", ret);

		if (ret == -EIO || ret == SHMBRIDGE_E_NOT_SUPPORTED)
			pr_warn("shmbridge is not supported by this target\n");
		return ret | desc.ret[0];
		return ret;
	}
	qtee_shmbridge_enabled = true;
	pr_warn("shmbridge is enabled\n");
@@ -210,9 +174,11 @@ int32_t qtee_shmbridge_register(

{
	int32_t ret = 0;
	uint64_t pfn_and_ns_perm_flags = 0;
	uint64_t ipfn_and_s_perm_flags = 0;
	uint64_t size_and_flags = 0;
	uint64_t ns_perms = 0;
	uint64_t ns_vmids = 0;
	struct scm_desc desc = {0};
	int i = 0;

	if (!qtee_shmbridge_enabled)
@@ -234,23 +200,23 @@ int32_t qtee_shmbridge_register(
		ns_vmids = UPDATE_NS_VMIDS(ns_vmids, ns_vmid_list[i]);
	}

	desc.arginfo = TZ_SHM_BRIDGE_CREATE_PARAM_ID;
	desc.args[0] = UPDATE_PFN_AND_NS_PERM_FLAGS(paddr, ns_perms);
	desc.args[1] = UPDATE_IPFN_AND_S_PERM_FLAGS(paddr, tz_perm);
	desc.args[2] = UPDATE_SIZE_AND_FLAGS(size, ns_vmid_num);
	desc.args[3] = ns_vmids;

	pr_debug("%s: arginfo %x, desc.args[0] %llx, args[1] %llx, args[2] %llx, args[3] %llx\n",
			__func__, desc.arginfo, desc.args[0],
			desc.args[1], desc.args[2], desc.args[3]);
	ret = scm_call2(TZ_SHM_BRIDGE_CREATE, &desc);
	if (ret || desc.ret[0]) {
		pr_err("create shmbridge failed, ret = %d, status = %llx\n",
				ret, desc.ret[0]);
	pfn_and_ns_perm_flags = UPDATE_PFN_AND_NS_PERM_FLAGS(paddr, ns_perms);
	ipfn_and_s_perm_flags = UPDATE_IPFN_AND_S_PERM_FLAGS(paddr, tz_perm);
	size_and_flags = UPDATE_SIZE_AND_FLAGS(size, ns_vmid_num);

	pr_debug("%s: desc.args[0] %llx, args[1] %llx, args[2] %llx, args[3] %llx\n",
		__func__, pfn_and_ns_perm_flags, ipfn_and_s_perm_flags,
		size_and_flags, ns_vmids);

	ret = qcom_scm_create_shm_bridge(pfn_and_ns_perm_flags,
			ipfn_and_s_perm_flags, size_and_flags, ns_vmids,
			handle);

	if (ret) {
		pr_err("create shmbridge failed, ret = %d\n", ret);
		ret = -EINVAL;
		goto exit;
	}
	*handle = desc.ret[1];

	ret = qtee_shmbridge_list_add_nolock(paddr, *handle);
exit:
@@ -263,15 +229,14 @@ EXPORT_SYMBOL(qtee_shmbridge_register);
int32_t qtee_shmbridge_deregister(uint64_t handle)
{
	int32_t ret = 0;
	struct scm_desc desc = {0};

	if (!qtee_shmbridge_enabled)
		return 0;

	mutex_lock(&bridge_list_head.lock);
	desc.arginfo = TZ_SHM_BRIDGE_DELETE_PARAM_ID;
	desc.args[0] = handle;
	ret = scm_call2(TZ_SHM_BRIDGE_DELETE, &desc);

	ret = qcom_scm_delete_shm_bridge(handle);

	if (ret) {
		pr_err("Failed to del bridge %lld, ret = %d\n", handle, ret);
		goto exit;
+10 −0
Original line number Diff line number Diff line
@@ -75,6 +75,11 @@ extern int qcom_scm_smmu_prepare_atos_id(u64 dev_id, int cb_num, int operation);
extern bool qcom_scm_hdcp_available(void);
extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
			     u32 *resp);
extern int qcom_scm_enable_shm_bridge(void);
extern int qcom_scm_delete_shm_bridge(u64 handle);
extern int qcom_scm_create_shm_bridge(u64 pfn_and_ns_perm_flags,
			u64 ipfn_and_s_perm_flags, u64 size_and_flags,
			u64 ns_vmids, u64 *handle);
extern int qcom_scm_smmu_change_pgtbl_format(u64 dev_id, int cbndx);
extern int qcom_scm_qsmmu500_wait_safe_toggle(bool en);
extern int qcom_scm_ice_restore_cfg(void);
@@ -139,6 +144,11 @@ static inline int qcom_scm_smmu_prepare_atos_id(u64 dev_id, int cb_num,
static inline bool qcom_scm_hdcp_available(void) { return false; }
static inline int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
				    u32 *resp) { return -ENODEV; }
static inline int qcom_scm_enable_shm_bridge(void) { return -ENODEV; }
static inline int qcom_scm_delete_shm_bridge(u64 handle) { return -ENODEV; }
static inline int qcom_scm_create_shm_bridge(u64 pfn_and_ns_perm_flags,
			u64 ipfn_and_s_perm_flags, u64 size_and_flags,
			u64 ns_vmids, u64 *handle) { return -ENODEV; }
static inline  int qcom_scm_smmu_change_pgtbl_format(u64 dev_id, int cbndx)
		{ return -ENODEV; }
static inline int qcom_scm_qsmmu500_wait_safe_toggle(bool en)