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

Commit 08530d89 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "diag: Free the mask update client buf in exit case"

parents adde8aa8 4bf95907
Loading
Loading
Loading
Loading
+158 −43
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@

#define DIAG_SET_FEATURE_MASK(x) (feature_bytes[(x)/8] |= (1 << (x & 0x7)))

#define MAX_USERSPACE_BUF_SIZ	100000

struct diag_mask_info msg_mask;
struct diag_mask_info msg_bt_mask;
struct diag_mask_info log_mask;
@@ -61,6 +63,9 @@ static const struct diag_ssid_range_t msg_mask_tbl[] = {
	{ .ssid_first = MSG_SSID_25, .ssid_last = MSG_SSID_25_LAST }
};

static int diag_save_user_msg_mask(struct diag_md_session_t *info);
static int diag_save_user_log_mask(struct diag_md_session_t *info);

static int diag_check_update(int md_peripheral, int pid)
{
	int ret;
@@ -779,7 +784,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
{
	uint32_t mask_size = 0, offset = 0;
	uint32_t *temp = NULL;
	int write_len = 0, i = 0, found = 0, peripheral;
	int write_len = 0, i = 0, found = 0, peripheral, ret_val = 0;
	int header_len = sizeof(struct diag_msg_build_mask_t);
	struct diag_msg_mask_t *mask = NULL;
	struct diag_msg_build_mask_t *req = NULL;
@@ -888,8 +893,6 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
	mutex_unlock(&driver->msg_mask_lock);
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&driver->md_session_lock);
	if (diag_check_update(APPS_DATA, pid))
		diag_update_userspace_clients(MSG_MASKS_TYPE);

	/*
	 * Apps processor must send the response to this command. Frame the
@@ -911,8 +914,19 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
		memcpy(dest_buf + write_len, src_buf + header_len, mask_size);
	write_len += mask_size;
	for (i = 0; i < NUM_MD_SESSIONS; i++) {
		if (i == APPS_DATA)
		if (i == APPS_DATA) {
			mutex_lock(&driver->md_session_lock);
			info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
								APPS_DATA);
			ret_val = diag_save_user_msg_mask(info);
			if (ret_val < 0)
				pr_err("diag: unable to save msg mask to update userspace clients err:%d\n",
					ret_val);
			mutex_unlock(&driver->md_session_lock);
			if (diag_check_update(APPS_DATA, pid))
				diag_update_userspace_clients(MSG_MASKS_TYPE);
			continue;
		}
		if (!diag_check_update(i, pid))
			continue;
		if (i > NUM_PERIPHERALS)
@@ -931,7 +945,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
			unsigned char *dest_buf, int dest_len, int pid)
{
	int i, write_len = 0, peripheral;
	int i, write_len = 0, peripheral, ret_val = 0;
	int header_len = sizeof(struct diag_msg_config_rsp_t);
	struct diag_msg_config_rsp_t rsp;
	struct diag_msg_config_rsp_t *req = NULL;
@@ -988,8 +1002,6 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
	mutex_unlock(&driver->msg_mask_lock);
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&driver->md_session_lock);
	if (diag_check_update(APPS_DATA, pid))
		diag_update_userspace_clients(MSG_MASKS_TYPE);

	/*
	 * Apps processor must send the response to this command. Frame the
@@ -1004,8 +1016,19 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
	write_len += header_len;

	for (i = 0; i < NUM_MD_SESSIONS; i++) {
		if (i == APPS_DATA)
		if (i == APPS_DATA) {
			mutex_lock(&driver->md_session_lock);
			info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
								APPS_DATA);
			ret_val = diag_save_user_msg_mask(info);
			if (ret_val)
				pr_err("diag: unable to save msg mask to update userspace clients err:%d\n",
					ret_val);
			mutex_unlock(&driver->md_session_lock);
			if (diag_check_update(APPS_DATA, pid))
				diag_update_userspace_clients(MSG_MASKS_TYPE);
			continue;
		}
		if (!diag_check_update(i, pid))
			continue;
		if (i > NUM_PERIPHERALS)
@@ -1343,7 +1366,7 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
{
	int i, peripheral, write_len = 0;
	int status = LOG_STATUS_SUCCESS;
	int read_len = 0, payload_len = 0;
	int read_len = 0, payload_len = 0, ret_val = 0;
	int req_header_len = sizeof(struct diag_log_config_req_t);
	int rsp_header_len = sizeof(struct diag_log_config_set_rsp_t);
	uint32_t mask_size = 0;
@@ -1445,8 +1468,6 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
	}
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&driver->md_session_lock);
	if (diag_check_update(APPS_DATA, pid))
		diag_update_userspace_clients(LOG_MASKS_TYPE);

	/*
	 * Apps processor must send the response to this command. Frame the
@@ -1474,8 +1495,19 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
	write_len += payload_len;

	for (i = 0; i < NUM_MD_SESSIONS; i++) {
		if (i == APPS_DATA)
		if (i == APPS_DATA) {
			mutex_lock(&driver->md_session_lock);
			info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
								APPS_DATA);
			ret_val = diag_save_user_log_mask(info);
			if (ret_val < 0)
				pr_err("diag: unable to save log mask to update userspace clients err:%d\n",
					ret_val);
			mutex_unlock(&driver->md_session_lock);
			if (diag_check_update(APPS_DATA, pid))
				diag_update_userspace_clients(LOG_MASKS_TYPE);
			continue;
		}
		if (!diag_check_update(i, pid))
			continue;
		if (i > NUM_PERIPHERALS)
@@ -1496,7 +1528,7 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len,
	struct diag_mask_info *mask_info = NULL;
	struct diag_log_mask_t *mask = NULL;
	struct diag_log_config_rsp_t header;
	int write_len = 0, i, peripheral;
	int write_len = 0, i, peripheral, ret_val = 0;
	struct diag_md_session_t *info = NULL;

	mutex_lock(&driver->md_session_lock);
@@ -1533,8 +1565,6 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len,
	}
	mask_info->status = DIAG_CTRL_MASK_ALL_DISABLED;
	mutex_unlock(&driver->md_session_lock);
	if (diag_check_update(APPS_DATA, pid))
		diag_update_userspace_clients(LOG_MASKS_TYPE);

	/*
	 * Apps processor must send the response to this command. Frame the
@@ -1549,8 +1579,19 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len,
	memcpy(dest_buf, &header, sizeof(struct diag_log_config_rsp_t));
	write_len += sizeof(struct diag_log_config_rsp_t);
	for (i = 0; i < NUM_MD_SESSIONS; i++) {
		if (i == APPS_DATA)
		if (i == APPS_DATA) {
			mutex_lock(&driver->md_session_lock);
			info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
								APPS_DATA);
			ret_val = diag_save_user_log_mask(info);
			if (ret_val < 0)
				pr_err("diag: unable to save log  mask to update userspace clients err:%d\n",
					ret_val);
			mutex_unlock(&driver->md_session_lock);
			if (diag_check_update(APPS_DATA, pid))
				diag_update_userspace_clients(LOG_MASKS_TYPE);
			continue;
		}
		if (!diag_check_update(i, pid))
			continue;
		if (i > NUM_PERIPHERALS)
@@ -1792,6 +1833,17 @@ static int __diag_mask_init(struct diag_mask_info *mask_info, int mask_len,
			return -ENOMEM;
		}
		kmemleak_not_leak(mask_info->update_buf);
		mask_info->update_buf_client = kzalloc(MAX_USERSPACE_BUF_SIZ,
							GFP_KERNEL);
		if (!mask_info->update_buf_client) {
			kfree(mask_info->update_buf);
			mask_info->update_buf = NULL;
			kfree(mask_info->ptr);
			mask_info->ptr = NULL;
			return -ENOMEM;
		}
		kmemleak_not_leak(mask_info->update_buf_client);
		mask_info->update_buf_client_len = 0;
	}
	return 0;
}
@@ -1806,6 +1858,8 @@ static void __diag_mask_exit(struct diag_mask_info *mask_info)
	mask_info->ptr = NULL;
	kfree(mask_info->update_buf);
	mask_info->update_buf = NULL;
	kfree(mask_info->update_buf_client);
	mask_info->update_buf_client = NULL;
	mutex_unlock(&mask_info->lock);
}

@@ -1879,6 +1933,7 @@ void diag_log_mask_free(struct diag_mask_info *mask_info)
static int diag_msg_mask_init(void)
{
	int err = 0, i;
	struct diag_md_session_t *session_info = NULL;

	mutex_init(&msg_mask.lock);
	err = __diag_mask_init(&msg_mask, MSG_MASK_SIZE, APPS_BUF_SIZE);
@@ -1896,6 +1951,14 @@ static int diag_msg_mask_init(void)
		driver->max_ssid_count[i] = 0;
	mutex_unlock(&driver->msg_mask_lock);

	mutex_lock(&driver->md_session_lock);
	session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
							APPS_DATA);
	err = diag_save_user_msg_mask(session_info);
	if (err < 0)
		pr_err("diag: unable to save msg mask to update userspace clients err:%d\n",
			err);
	mutex_unlock(&driver->md_session_lock);
	return 0;
}

@@ -1993,6 +2056,8 @@ static void diag_msg_mask_exit(void)
	}
	kfree(msg_mask.update_buf);
	msg_mask.update_buf = NULL;
	kfree(msg_mask.update_buf_client);
	msg_mask.update_buf_client = NULL;
	mutex_unlock(&driver->msg_mask_lock);
}

@@ -2034,6 +2099,7 @@ static void diag_build_time_mask_exit(void)
static int diag_log_mask_init(void)
{
	int err = 0, i;
	struct diag_md_session_t *session_info = NULL;

	mutex_init(&log_mask.lock);
	err = __diag_mask_init(&log_mask, LOG_MASK_SIZE, APPS_BUF_SIZE);
@@ -2046,7 +2112,14 @@ static int diag_log_mask_init(void)

	for (i = 0; i < NUM_PERIPHERALS; i++)
		driver->num_equip_id[i] = 0;

	mutex_lock(&driver->md_session_lock);
	session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
							APPS_DATA);
	err = diag_save_user_log_mask(session_info);
	if (err < 0)
		pr_err("diag: unable to save log  mask to update userspace clients err:%d\n",
			err);
	mutex_unlock(&driver->md_session_lock);
	return 0;
}

@@ -2063,6 +2136,8 @@ static void diag_log_mask_exit(void)
	}

	kfree(log_mask.update_buf);
	kfree(log_mask.update_buf_client);
	log_mask.update_buf_client = NULL;
}

static int diag_event_mask_init(void)
@@ -2121,6 +2196,59 @@ static void diag_event_mask_exit(void)

int diag_copy_to_user_msg_mask(char __user *buf, size_t count,
			       struct diag_md_session_t *info)
{
	struct diag_mask_info *mask_info = NULL;
	int err = 0;

	if (!buf || count == 0)
		return -EINVAL;
	mask_info = (!info) ? &msg_mask : info->msg_mask;
	if (!mask_info)
		return -EIO;

	if (!mask_info->ptr || !mask_info->update_buf_client) {
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK, mask_info->update_buf_client: %pK\n",
			__func__, mask_info->ptr, mask_info->update_buf_client);
		return -EINVAL;
	}

	err = copy_to_user(buf, mask_info->update_buf_client,
				mask_info->update_buf_client_len);
	if (err) {
		pr_err("diag: In %s Unable to send msg masks to user space clients, err: %d\n",
		       __func__, err);
	}
	return err ? err : mask_info->update_buf_client_len;
}

int diag_copy_to_user_log_mask(char __user *buf, size_t count,
			       struct diag_md_session_t *info)
{
	struct diag_mask_info *mask_info = NULL;
	int err = 0;

	if (!buf || count == 0)
		return -EINVAL;
	mask_info = (!info) ? &log_mask : info->log_mask;
	if (!mask_info)
		return -EIO;

	if (!mask_info->ptr || !mask_info->update_buf_client) {
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK, mask_info->update_buf_client: %pK\n",
			__func__, mask_info->ptr, mask_info->update_buf_client);
		return -EINVAL;
	}

	err = copy_to_user(buf, mask_info->update_buf_client,
				mask_info->update_buf_client_len);
	if (err) {
		pr_err("diag: In %s Unable to send msg masks to user space clients, err: %d\n",
		       __func__, err);
	}
	return err ? err : mask_info->update_buf_client_len;
}

static int diag_save_user_msg_mask(struct diag_md_session_t *info)
{
	int i, err = 0, len = 0;
	int copy_len = 0, total_len = 0;
@@ -2130,9 +2258,6 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count,
	unsigned char *ptr = NULL;
	uint8_t msg_mask_tbl_count = 0;

	if (!buf || count == 0)
		return -EINVAL;

	mask_info = (!info) ? &msg_mask : info->msg_mask;
	if (!mask_info)
		return -EIO;
@@ -2178,27 +2303,23 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count,
		len += copy_len;
		mutex_unlock(&mask->lock);
		/* + sizeof(int) to account for data_type already in buf */
		if (total_len + sizeof(int) + len > count) {
			pr_err("diag: In %s, unable to send msg masks to user space, total_len: %d, count: %zu\n",
			       __func__, total_len, count);
		if (total_len + sizeof(int) + len > MAX_USERSPACE_BUF_SIZ) {
			pr_err("diag: In %s, unable to send msg masks to user space, total_len: %d,\n",
			       __func__, total_len);
			err = -ENOMEM;
			break;
		}
		err = copy_to_user(buf + total_len, (void *)ptr, len);
		if (err) {
			pr_err("diag: In %s Unable to send msg masks to user space clients, err: %d\n",
			       __func__, err);
			break;
		}
		memcpy(mask_info->update_buf_client + total_len,
			(void *)ptr, len);
		total_len += len;
	}
	mask_info->update_buf_client_len = total_len;
	mutex_unlock(&driver->msg_mask_lock);
	mutex_unlock(&mask_info->lock);
	return err ? err : total_len;
}

int diag_copy_to_user_log_mask(char __user *buf, size_t count,
			       struct diag_md_session_t *info)
static int diag_save_user_log_mask(struct diag_md_session_t *info)
{
	int i, err = 0, len = 0;
	int copy_len = 0, total_len = 0;
@@ -2207,9 +2328,6 @@ int diag_copy_to_user_log_mask(char __user *buf, size_t count,
	struct diag_mask_info *mask_info = NULL;
	unsigned char *ptr = NULL;

	if (!buf || count == 0)
		return -EINVAL;

	mask_info = (!info) ? &log_mask : info->log_mask;
	if (!mask_info)
		return -EIO;
@@ -2249,20 +2367,17 @@ int diag_copy_to_user_log_mask(char __user *buf, size_t count,
		len += copy_len;
		mutex_unlock(&mask->lock);
		/* + sizeof(int) to account for data_type already in buf */
		if (total_len + sizeof(int) + len > count) {
			pr_err("diag: In %s, unable to send log masks to user space, total_len: %d, count: %zu\n",
			       __func__, total_len, count);
		if (total_len + sizeof(int) + len > MAX_USERSPACE_BUF_SIZ) {
			pr_err("diag: In %s, unable to send log masks to user space, total_len: %d\n",
			       __func__, total_len);
			err = -ENOMEM;
			break;
		}
		err = copy_to_user(buf + total_len, (void *)ptr, len);
		if (err) {
			pr_err("diag: In %s Unable to send log masks to user space clients, err: %d\n",
			       __func__, err);
			break;
		}
		memcpy(mask_info->update_buf_client + total_len,
			(void *)ptr, len);
		total_len += len;
	}
	mask_info->update_buf_client_len = total_len;
	mutex_unlock(&mask_info->lock);

	return err ? err : total_len;
+2 −0
Original line number Diff line number Diff line
@@ -550,6 +550,8 @@ struct diag_mask_info {
	int mask_len;
	uint8_t *update_buf;
	int update_buf_len;
	uint8_t *update_buf_client;
	int update_buf_client_len;
	uint8_t status;
	struct mutex lock;
};
+19 −8
Original line number Diff line number Diff line
@@ -3701,19 +3701,24 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
	if (driver->data_ready[index] & MSG_MASKS_TYPE) {
		/*Copy the type of data being passed*/
		data_type = driver->data_ready[index] & MSG_MASKS_TYPE;
		mutex_unlock(&driver->diagchar_mutex);
		mutex_lock(&driver->md_session_lock);
		session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
								APPS_DATA);
		COPY_USER_SPACE_OR_ERR(buf, data_type, sizeof(int));
		if (ret == -EFAULT) {
			mutex_unlock(&driver->md_session_lock);
			goto exit;
			goto end;
		}
		if (!session_info)
			mutex_unlock(&driver->md_session_lock);
		write_len = diag_copy_to_user_msg_mask(buf + ret, count,
						       session_info);
		if (session_info)
			mutex_unlock(&driver->md_session_lock);
		if (write_len > 0)
			ret += write_len;
		mutex_lock(&driver->diagchar_mutex);
		driver->data_ready[index] ^= MSG_MASKS_TYPE;
		atomic_dec(&driver->data_ready_notif[index]);
		goto exit;
@@ -3722,13 +3727,14 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
	if (driver->data_ready[index] & EVENT_MASKS_TYPE) {
		/*Copy the type of data being passed*/
		data_type = driver->data_ready[index] & EVENT_MASKS_TYPE;
		mutex_unlock(&driver->diagchar_mutex);
		mutex_lock(&driver->md_session_lock);
		session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
								APPS_DATA);
		COPY_USER_SPACE_OR_ERR(buf, data_type, 4);
		if (ret == -EFAULT) {
			mutex_unlock(&driver->md_session_lock);
			goto exit;
			goto end;
		}
		if (session_info && session_info->event_mask &&
		    session_info->event_mask->ptr) {
@@ -3737,7 +3743,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
					session_info->event_mask->mask_len);
			if (ret == -EFAULT) {
				mutex_unlock(&driver->md_session_lock);
				goto exit;
				goto end;
			}
		} else {
			COPY_USER_SPACE_OR_ERR(buf + sizeof(int),
@@ -3745,10 +3751,11 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
						event_mask.mask_len);
			if (ret == -EFAULT) {
				mutex_unlock(&driver->md_session_lock);
				goto exit;
				goto end;
			}
		}
		mutex_unlock(&driver->md_session_lock);
		mutex_lock(&driver->diagchar_mutex);
		driver->data_ready[index] ^= EVENT_MASKS_TYPE;
		atomic_dec(&driver->data_ready_notif[index]);
		goto exit;
@@ -3757,20 +3764,24 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
	if (driver->data_ready[index] & LOG_MASKS_TYPE) {
		/*Copy the type of data being passed*/
		data_type = driver->data_ready[index] & LOG_MASKS_TYPE;
		mutex_unlock(&driver->diagchar_mutex);
		mutex_lock(&driver->md_session_lock);
		session_info = diag_md_session_get_peripheral(DIAG_LOCAL_PROC,
								APPS_DATA);
		COPY_USER_SPACE_OR_ERR(buf, data_type, sizeof(int));
		if (ret == -EFAULT) {
			mutex_unlock(&driver->md_session_lock);
			goto exit;
			goto end;
		}

		if (!session_info)
			mutex_unlock(&driver->md_session_lock);
		write_len = diag_copy_to_user_log_mask(buf + ret, count,
						       session_info);
		if (session_info)
			mutex_unlock(&driver->md_session_lock);
		if (write_len > 0)
			ret += write_len;
		mutex_lock(&driver->diagchar_mutex);
		driver->data_ready[index] ^= LOG_MASKS_TYPE;
		atomic_dec(&driver->data_ready_notif[index]);
		goto exit;