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

Commit 48dc111f authored by sssanjee's avatar sssanjee
Browse files

msm: fastcvpd: adding hyp_assign to allow memory access to CDSP



Adding hyp_assign to ensure memory allocated by video driver is
accessible to CDSP on access control enabled builds.

Change-Id: I0fb73413b21c7b6433ea7c995bfb4baa657cfbea
Acked-by: default avatarAbhikrant Sharma <abhikran@qti.qualcomm.com>
Signed-off-by: default avatarSuman Voora <sssanjee@codeaurora.org>
parent ac121119
Loading
Loading
Loading
Loading
+89 −13
Original line number Diff line number Diff line
@@ -14,8 +14,12 @@
#include <linux/module.h>
#include <linux/rpmsg.h>
#include <linux/of_platform.h>
#include <soc/qcom/secure_buffer.h>
#include "linux/fastcvpd.h"

#define VMID_CDSP_Q6 (30)
#define SRC_VM_NUM 1
#define DEST_VM_NUM 2
#define FASTCVPD_VIDEO_SEND_HFI_CMD_QUEUE 0
#define FASTCVPD_VIDEO_SUSPEND 1
#define FASTCVPD_VIDEO_RESUME 2
@@ -28,14 +32,25 @@ struct fastcvpd_cmd_msg {
	uint32_t msg_ptr_len;
};

struct fastcvpd_cmd_msg_rsp {
	int ret_val;
};

struct fastcvpd_apps {
	struct rpmsg_device *chan;
	struct mutex smd_mutex;
	int rpmsg_register;
	spinlock_t hlock;
};

static struct completion work;

static struct fastcvpd_apps gfa_cv;

static struct fastcvpd_cmd_msg cmd_msg;

static struct fastcvpd_cmd_msg_rsp cmd_msg_rsp;

static int fastcvpd_send_cmd(void *msg, uint32_t len)
{
	struct fastcvpd_apps *me = &gfa_cv;
@@ -82,6 +97,14 @@ static void fastcvpd_rpmsg_remove(struct rpmsg_device *rpdev)
static int fastcvpd_rpmsg_callback(struct rpmsg_device *rpdev,
	void *data, int len, void *priv, u32 addr)
{
	int *rpmsg_resp = (int *)data;
	struct fastcvpd_apps *me = &gfa_cv;

	spin_lock(&me->hlock);
	cmd_msg_rsp.ret_val = *rpmsg_resp;
	spin_unlock(&me->hlock);
	complete(&work);

	return 0;
}

@@ -89,17 +112,39 @@ int fastcvpd_video_send_cmd_hfi_queue(phys_addr_t *phys_addr,
	uint32_t size_in_bytes)
{
	int err;
	struct fastcvpd_cmd_msg cmd_msg;
	struct fastcvpd_cmd_msg local_cmd_msg;
	struct fastcvpd_apps *me = &gfa_cv;
	int srcVM[SRC_VM_NUM] = {VMID_HLOS};
	int destVM[DEST_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6};
	int destVMperm[DEST_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC,
		PERM_READ | PERM_WRITE | PERM_EXEC };

	cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SEND_HFI_CMD_QUEUE;
	local_cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SEND_HFI_CMD_QUEUE;
	local_cmd_msg.msg_ptr = (uint64_t)phys_addr;
	local_cmd_msg.msg_ptr_len = size_in_bytes;
	mutex_lock(&me->smd_mutex);
	cmd_msg.msg_ptr = (uint64_t)phys_addr;
	cmd_msg.msg_ptr_len = size_in_bytes;
	cmd_msg.msg_ptr_len = (size_in_bytes);
	mutex_unlock(&me->smd_mutex);

	pr_debug("%s :: address of buffer, PA=0x%pK  size_buff=%d\n",
		__func__, phys_addr, size_in_bytes);

	err = hyp_assign_phys((uint64_t)local_cmd_msg.msg_ptr,
		local_cmd_msg.msg_ptr_len, srcVM, SRC_VM_NUM, destVM,
		destVMperm, DEST_VM_NUM);
	if (err) {
		pr_err("%s: Failed in hyp_assign. err=%d\n",
			__func__, err);
		return err;
	}

	err = fastcvpd_send_cmd
			 (&cmd_msg, sizeof(struct fastcvpd_cmd_msg));
			 (&local_cmd_msg, sizeof(struct fastcvpd_cmd_msg));
	if (err != 0)
		pr_err("%s: fastcvpd_send_cmd failed with err=%d\n",
			__func__, err);

	return err;
}
EXPORT_SYMBOL(fastcvpd_video_send_cmd_hfi_queue);
@@ -107,14 +152,15 @@ EXPORT_SYMBOL(fastcvpd_video_send_cmd_hfi_queue);
int fastcvpd_video_suspend(uint32_t session_flag)
{
	int err = 0;
	struct fastcvpd_cmd_msg cmd_msg;
	struct fastcvpd_cmd_msg local_cmd_msg;

	cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SUSPEND;
	local_cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SUSPEND;
	err = fastcvpd_send_cmd
			 (&cmd_msg, sizeof(struct fastcvpd_cmd_msg));
			 (&local_cmd_msg, sizeof(struct fastcvpd_cmd_msg));
	if (err != 0)
		pr_err("%s: fastcvpd_send_cmd failed with err=%d\n",
			__func__, err);

	return err;
}
EXPORT_SYMBOL(fastcvpd_video_suspend);
@@ -122,29 +168,56 @@ EXPORT_SYMBOL(fastcvpd_video_suspend);
int fastcvpd_video_resume(uint32_t session_flag)
{
	int err;
	struct fastcvpd_cmd_msg cmd_msg;
	struct fastcvpd_cmd_msg local_cmd_msg;

	cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_RESUME;
	local_cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_RESUME;
	err = fastcvpd_send_cmd
			 (&cmd_msg, sizeof(struct fastcvpd_cmd_msg));
			 (&local_cmd_msg, sizeof(struct fastcvpd_cmd_msg));
	if (err != 0)
		pr_err("%s: fastcvpd_send_cmd failed with err=%d\n",
			__func__, err);

	return err;
}
EXPORT_SYMBOL(fastcvpd_video_resume);

int fastcvpd_video_shutdown(uint32_t session_flag)
{
	struct fastcvpd_apps *me = &gfa_cv;
	int err;
	struct fastcvpd_cmd_msg cmd_msg;
	struct fastcvpd_cmd_msg local_cmd_msg;
	int srcVM[DEST_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6};
	int destVM[SRC_VM_NUM] = {VMID_HLOS};
	int destVMperm[SRC_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC };

	cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SHUTDOWN;
	local_cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SHUTDOWN;
	err = fastcvpd_send_cmd
			 (&cmd_msg, sizeof(struct fastcvpd_cmd_msg));
			 (&local_cmd_msg, sizeof(struct fastcvpd_cmd_msg));
	if (err != 0)
		pr_err("%s: fastcvpd_send_cmd failed with err=%d\n",
			__func__, err);

	wait_for_completion(&work);

	spin_lock(&me->hlock);
	local_cmd_msg.msg_ptr = cmd_msg.msg_ptr;
	local_cmd_msg.msg_ptr_len = cmd_msg.msg_ptr_len;
	if (cmd_msg_rsp.ret_val == 0) {
		err = hyp_assign_phys((uint64_t)local_cmd_msg.msg_ptr,
			local_cmd_msg.msg_ptr_len, srcVM, DEST_VM_NUM, destVM,
			destVMperm, SRC_VM_NUM);
		if (err) {
			pr_err("%s: Failed to hyp_assign. err=%d\n",
				__func__, err);
			spin_unlock(&me->hlock);
			return err;
		}
	} else {
		pr_err("%s: Skipping hyp_assign as CDSP sent invalid response=%d\n",
			__func__, cmd_msg_rsp.ret_val);
	}
	spin_unlock(&me->hlock);

	return err;
}
EXPORT_SYMBOL(fastcvpd_video_shutdown);
@@ -169,7 +242,9 @@ static int __init fastcvpd_device_init(void)
	struct fastcvpd_apps *me = &gfa_cv;
	int err;

	init_completion(&work);
	mutex_init(&me->smd_mutex);
	spin_lock_init(&me->hlock);
	err = register_rpmsg_driver(&fastcvpd_rpmsg_client);
	if (err) {
		pr_err("%s : register_rpmsg_driver failed with err %d\n",
@@ -187,6 +262,7 @@ static void __exit fastcvpd_device_exit(void)
{
	struct fastcvpd_apps *me = &gfa_cv;

	mutex_destroy(&me->smd_mutex);
	if (me->rpmsg_register == 1)
		unregister_rpmsg_driver(&fastcvpd_rpmsg_client);
}