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

Commit f1223c5c authored by Hai Li's avatar Hai Li Committed by Gerrit - the friendly Code Review server
Browse files

add retry logic and debug dump and paired mb to match read and write



fix hab message corruption and allow easy debugging

Change-Id: I7680bb2627febb9472e11846ed258e29aecb7b81
Signed-off-by: default avatarHai Li <hali@codeaurora.org>
parent 888efb8c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
#
config MSM_HAB
	bool "Enable Multimedia driver Hypervisor Abstraction Layer"
	select WANT_DEV_COREDUMP
	help
	  Multimedia driver hypervisor abstraction layer.
	  Required for drivers to use the HAB API to communicate with the host
+1 −2
Original line number Diff line number Diff line
@@ -114,8 +114,7 @@ void hab_ctx_free(struct kref *ref)
	int i;
	struct uhab_context *ctxdel, *ctxtmp;
	struct hab_open_node *node;
	struct export_desc *exp = NULL,
			*exp_tmp = NULL;
	struct export_desc *exp = NULL, *exp_tmp = NULL;

	/* garbage-collect exp/imp buffers */
	write_lock_bh(&ctx->exp_lock);
+7 −0
Original line number Diff line number Diff line
@@ -608,4 +608,11 @@ static inline void hab_write_unlock(rwlock_t *lock, int irqs_disabled)
/* Global singleton HAB instance */
extern struct hab_driver hab_driver;

int dump_hab_get_file_name(char *file_time, int ft_size);
int dump_hab_open(void);
void dump_hab_close(void);
int dump_hab_buf(void *buf, int size);
void hab_pipe_read_dump(struct physical_channel *pchan);
void dump_hab(void);
void dump_hab_wq(void *hyp_data);
#endif /* __HAB_H */
+47 −33
Original line number Diff line number Diff line
@@ -163,12 +163,12 @@ static int hab_receive_create_export_ack(struct physical_channel *pchan,
		return -ENOMEM;

	if (sizeof(ack_recvd->ack) != sizebytes)
		pr_err("exp ack size %zu is not as arrived %zu\n",
				  sizeof(ack_recvd->ack), sizebytes);
		pr_err("%s exp ack size %zu is not as arrived %zu\n",
			   pchan->name, sizeof(ack_recvd->ack), sizebytes);

	if (sizebytes > HAB_HEADER_SIZE_MASK) {
		pr_err("pchan %s read size too large %zd\n",
			pchan->name, sizebytes);
	if (sizebytes > sizeof(ack_recvd->ack)) {
		pr_err("pchan %s read size too large %zd %zd\n",
			pchan->name, sizebytes, sizeof(ack_recvd->ack));
		return -EINVAL;
	}

@@ -225,8 +225,10 @@ int hab_msg_recv(struct physical_channel *pchan,
		if (payload_type >= HAB_PAYLOAD_TYPE_MAX ||
			vchan_id > (HAB_HEADER_ID_MASK >> HAB_HEADER_ID_SHIFT)
			|| !vchan_id ||	!session_id) {
			pr_err("Invalid message received, payload type %d, vchan id %x, sizebytes %zx, session %d\n",
				payload_type, vchan_id, sizebytes, session_id);
			pr_err("@@ %s Invalid msg type %d vcid %x bytes %zx sn %d\n",
				pchan->name, payload_type,
				vchan_id, sizebytes, session_id);
			dump_hab_wq(pchan->hyp_data);
		}

		/*
@@ -240,29 +242,37 @@ int hab_msg_recv(struct physical_channel *pchan,

			if (sizebytes) {
				hab_msg_drop(pchan, sizebytes);
				pr_err("message %d dropped no vchan, session id %d\n",
					payload_type, session_id);
				pr_err("%s msg dropped type %d size %d vcid %X session id %d\n",
				pchan->name, payload_type,
				sizebytes, vchan_id,
				session_id);
			}
			return -EINVAL;
		} else if (vchan->otherend_closed) {
			hab_vchan_put(vchan);
			pr_info("vchan remote is closed payload type %d, vchan id %x, sizebytes %zx, session %d\n",
				payload_type, vchan_id, sizebytes, session_id);
				payload_type, vchan_id,
				sizebytes, session_id);
			if (sizebytes) {
				hab_msg_drop(pchan, sizebytes);
				pr_err("message %d dropped remote close, session id %d\n",
					   payload_type, session_id);
				pr_err("%s message %d dropped remote close, session id %d\n",
				pchan->name, payload_type,
				session_id);
			}
			return -ENODEV;
		}
	} else {
		if (sizebytes != sizeof(struct hab_open_send_data)) {
			pr_err("Invalid open request received type %d, vcid %x, szbytes %zx, session %d\n",
				payload_type, vchan_id, sizebytes, session_id);
			pr_err("%s Invalid open req type %d vcid %x bytes %zx session %d\n",
				pchan->name, payload_type, vchan_id,
				sizebytes, session_id);
			if (sizebytes) {
				hab_msg_drop(pchan, sizebytes);
				pr_err("message %d dropped unknown reason, session id %d\n",
					   payload_type, session_id);
				pr_err("%s msg %d dropped unknown reason session id %d\n",
					pchan->name,
					payload_type,
					session_id);
				dump_hab_wq(pchan->hyp_data);
			}
			return -ENODEV;
		}
@@ -284,8 +294,8 @@ int hab_msg_recv(struct physical_channel *pchan,
	case HAB_PAYLOAD_TYPE_INIT_DONE:
		ret = hab_open_request_add(pchan, sizebytes, payload_type);
		if (ret) {
			pr_err("open request add failed, ret %d, payload type %d, sizebytes %zx\n",
					ret, payload_type, sizebytes);
			pr_err("%s open request add failed, ret %d, payload type %d, sizebytes %zx\n",
				pchan->name, ret, payload_type, sizebytes);
			break;
		}
		wake_up_interruptible(&dev->openq);
@@ -297,14 +307,14 @@ int hab_msg_recv(struct physical_channel *pchan,
			pchan->vmid_remote);
		ret = hab_open_receive_cancel(pchan, sizebytes);
		if (ret)
			pr_err("open cancel handling failed ret %d vcid %X session %d\n",
				   ret, vchan_id, session_id);
			pr_err("%s open cancel handling failed ret %d vcid %X session %d\n",
				pchan->name, ret, vchan_id, session_id);
		break;

	case HAB_PAYLOAD_TYPE_EXPORT:
		if (sizebytes > HAB_HEADER_SIZE_MASK) {
			pr_err("%s exp size too large %zd\n",
					pchan->name, sizebytes);
			pr_err("%s exp size too large %zd header %zd\n",
				pchan->name, sizebytes, sizeof(*exp_desc));
			break;
		}

@@ -314,8 +324,8 @@ int hab_msg_recv(struct physical_channel *pchan,

		if (physical_channel_read(pchan, exp_desc, sizebytes) !=
			sizebytes) {
			pr_err("corrupted exp expect %zd bytes vcid %X remote %X open %d!\n",
					sizebytes, vchan->id,
			pr_err("%s corrupted exp expect %zd bytes vcid %X remote %X open %d!\n",
				pchan->name, sizebytes, vchan->id,
				vchan->otherend_id, vchan->session_id);
			kfree(exp_desc);
			break;
@@ -323,8 +333,8 @@ int hab_msg_recv(struct physical_channel *pchan,

		if (pchan->vmid_local != exp_desc->domid_remote ||
			pchan->vmid_remote != exp_desc->domid_local)
			pr_err("corrupted vmid %d != %d %d != %d\n",
				pchan->vmid_local, exp_desc->domid_remote,
			pr_err("%s corrupted vmid %d != %d %d != %d\n",
			pchan->name, pchan->vmid_local, exp_desc->domid_remote,
			pchan->vmid_remote, exp_desc->domid_local);
		exp_desc->domid_remote = pchan->vmid_remote;
		exp_desc->domid_local = pchan->vmid_local;
@@ -338,7 +348,8 @@ int hab_msg_recv(struct physical_channel *pchan,
		ret = hab_receive_create_export_ack(pchan, vchan->ctx,
				sizebytes);
		if (ret) {
			pr_err("failed to handled export ack %d\n", ret);
			pr_err("%s failed to handled export ack %d\n",
				pchan->name, ret);
			break;
		}
		wake_up_interruptible(&vchan->ctx->exp_wq);
@@ -357,7 +368,8 @@ int hab_msg_recv(struct physical_channel *pchan,
		/* pull down the incoming data */
		message = hab_msg_alloc(pchan, sizebytes);
		if (!message)
			pr_err("failed to allocate msg Arrived msg will be lost\n");
			pr_err("%s failed to allocate msg Arrived msg will be lost\n",
					pchan->name);
		else {
			struct habmm_xing_vm_stat *pstat =
				(struct habmm_xing_vm_stat *)message->data;
@@ -373,7 +385,8 @@ int hab_msg_recv(struct physical_channel *pchan,
		/* pull down the incoming data */
		message = hab_msg_alloc(pchan, sizebytes);
		if (!message)
			pr_err("failed to allocate msg Arrived msg will be lost\n");
			pr_err("%s failed to allocate msg Arrived msg will be lost\n",
					pchan->name);
		else {
			((unsigned long long *)message->data)[0] = rx_mpm_tv;
			hab_msg_queue(vchan, message);
@@ -381,8 +394,9 @@ int hab_msg_recv(struct physical_channel *pchan,
		break;

	default:
		pr_err("unknown msg received, payload type %d, vchan id %x, sizebytes %zx, session %d\n",
			   payload_type, vchan_id, sizebytes, session_id);
		pr_err("%s unknown msg received, payload type %d, vchan id %x, sizebytes %zx, session %d\n",
			pchan->name, payload_type, vchan_id,
			sizebytes, session_id);
		break;
	}
	if (vchan)
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@
#include <linux/sysfs.h>
#include <linux/delay.h>
#include <linux/version.h>
#include <linux/devcoredump.h>
#include <soc/qcom/boot_stats.h>

#endif /*__HAB_OS_H*/
Loading