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

Commit 28831d88 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: avoid OOB write while accessing memory"

parents 9d98cc80 383812f8
Loading
Loading
Loading
Loading
+10 −15
Original line number Original line Diff line number Diff line
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -2893,23 +2893,22 @@ static int __halt_axi(struct venus_hfi_device *device)
	return rc;
	return rc;
}
}


static void __process_sys_error(struct venus_hfi_device *device)
static void print_sfr_message(struct venus_hfi_device *device)
{
{
	struct hfi_sfr_struct *vsfr = NULL;
	struct hfi_sfr_struct *vsfr = NULL;
	u32 vsfr_size = 0;
	void *p = NULL;


	if (__halt_axi(device))
	if (__halt_axi(device))
		dprintk(VIDC_WARN, "Failed to halt AXI after SYS_ERROR\n");
		dprintk(VIDC_WARN, "Failed to halt AXI after SYS_ERROR\n");


	vsfr = (struct hfi_sfr_struct *)device->sfr.align_virtual_addr;
	vsfr = (struct hfi_sfr_struct *)device->sfr.align_virtual_addr;
	if (vsfr) {
	if (vsfr) {
		void *p = memchr(vsfr->rg_data, '\0', vsfr->bufSize);
		vsfr_size = vsfr->bufSize - sizeof(u32);
		/*
		p = memchr(vsfr->rg_data, '\0', vsfr_size);
		 * SFR isn't guaranteed to be NULL terminated
		/* SFR isn't guaranteed to be NULL terminated */
		 * since SYS_ERROR indicates that Venus is in the
		 * process of crashing.
		 */
		if (p == NULL)
		if (p == NULL)
			vsfr->rg_data[vsfr->bufSize - 1] = '\0';
			vsfr->rg_data[vsfr_size - 1] = '\0';


		dprintk(VIDC_ERR, "SFR Message from FW: %s\n",
		dprintk(VIDC_ERR, "SFR Message from FW: %s\n",
				vsfr->rg_data);
				vsfr->rg_data);
@@ -3051,8 +3050,6 @@ static int __response_handler(struct venus_hfi_device *device)
	}
	}


	if (device->intr_status & VIDC_WRAPPER_INTR_CLEAR_A2HWD_BMSK) {
	if (device->intr_status & VIDC_WRAPPER_INTR_CLEAR_A2HWD_BMSK) {
		struct hfi_sfr_struct *vsfr = (struct hfi_sfr_struct *)
			device->sfr.align_virtual_addr;
		struct msm_vidc_cb_info info = {
		struct msm_vidc_cb_info info = {
			.response_type = HAL_SYS_WATCHDOG_TIMEOUT,
			.response_type = HAL_SYS_WATCHDOG_TIMEOUT,
			.response.cmd = {
			.response.cmd = {
@@ -3060,9 +3057,7 @@ static int __response_handler(struct venus_hfi_device *device)
			}
			}
		};
		};


		if (vsfr)
		print_sfr_message(device);
			dprintk(VIDC_ERR, "SFR Message from FW: %s\n",
					vsfr->rg_data);


		dprintk(VIDC_ERR, "Received watchdog timeout\n");
		dprintk(VIDC_ERR, "Received watchdog timeout\n");
		packets[packet_count++] = info;
		packets[packet_count++] = info;
@@ -3088,7 +3083,7 @@ static int __response_handler(struct venus_hfi_device *device)
		/* Process the packet types that we're interested in */
		/* Process the packet types that we're interested in */
		switch (info->response_type) {
		switch (info->response_type) {
		case HAL_SYS_ERROR:
		case HAL_SYS_ERROR:
			__process_sys_error(device);
			print_sfr_message(device);
			break;
			break;
		case HAL_SYS_RELEASE_RESOURCE_DONE:
		case HAL_SYS_RELEASE_RESOURCE_DONE:
			dprintk(VIDC_DBG, "Received SYS_RELEASE_RESOURCE\n");
			dprintk(VIDC_DBG, "Received SYS_RELEASE_RESOURCE\n");
+11 −14
Original line number Original line Diff line number Diff line
/* Copyright (c) 2012-2016, 2018-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2016, 2018-2020, The Linux Foundation.
 * All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -3306,9 +3307,11 @@ static void __dump_venus_debug_registers(struct venus_hfi_device *device)
	dprintk(VIDC_ERR, "VIDC_CPU_CS_SCIACMDARG0: 0x%x\n", reg);
	dprintk(VIDC_ERR, "VIDC_CPU_CS_SCIACMDARG0: 0x%x\n", reg);
}
}


static void __process_sys_error(struct venus_hfi_device *device)
static void print_sfr_message(struct venus_hfi_device *device)
{
{
	struct hfi_sfr_struct *vsfr = NULL;
	struct hfi_sfr_struct *vsfr = NULL;
	u32 vsfr_size = 0;
	void *p = NULL;


	/* Once SYS_ERROR received from HW, it is safe to halt the AXI.
	/* Once SYS_ERROR received from HW, it is safe to halt the AXI.
	 * With SYS_ERROR, Venus FW may have crashed and HW might be
	 * With SYS_ERROR, Venus FW may have crashed and HW might be
@@ -3320,13 +3323,11 @@ static void __process_sys_error(struct venus_hfi_device *device)


	vsfr = (struct hfi_sfr_struct *)device->sfr.align_virtual_addr;
	vsfr = (struct hfi_sfr_struct *)device->sfr.align_virtual_addr;
	if (vsfr) {
	if (vsfr) {
		void *p = memchr(vsfr->rg_data, '\0', vsfr->bufSize);
		vsfr_size = vsfr->bufSize - sizeof(u32);
		/* SFR isn't guaranteed to be NULL terminated
		p = memchr(vsfr->rg_data, '\0', vsfr_size);
		 * since SYS_ERROR indicates that Venus is in the
		/* SFR isn't guaranteed to be NULL terminated */
		 * process of crashing.
		 */
		if (p == NULL)
		if (p == NULL)
			vsfr->rg_data[vsfr->bufSize - 1] = '\0';
			vsfr->rg_data[vsfr_size - 1] = '\0';


		dprintk(VIDC_ERR, "SFR Message from FW: %s\n",
		dprintk(VIDC_ERR, "SFR Message from FW: %s\n",
				vsfr->rg_data);
				vsfr->rg_data);
@@ -3440,8 +3441,6 @@ static int __response_handler(struct venus_hfi_device *device)
	}
	}


	if (device->intr_status & VIDC_WRAPPER_INTR_CLEAR_A2HWD_BMSK) {
	if (device->intr_status & VIDC_WRAPPER_INTR_CLEAR_A2HWD_BMSK) {
		struct hfi_sfr_struct *vsfr = (struct hfi_sfr_struct *)
			device->sfr.align_virtual_addr;
		struct msm_vidc_cb_info info = {
		struct msm_vidc_cb_info info = {
			.response_type = HAL_SYS_WATCHDOG_TIMEOUT,
			.response_type = HAL_SYS_WATCHDOG_TIMEOUT,
			.response.cmd = {
			.response.cmd = {
@@ -3449,9 +3448,7 @@ static int __response_handler(struct venus_hfi_device *device)
			}
			}
		};
		};


		if (vsfr)
		print_sfr_message(device);
			dprintk(VIDC_ERR, "SFR Message from FW: %s\n",
					vsfr->rg_data);


		__dump_venus_debug_registers(device);
		__dump_venus_debug_registers(device);
		dprintk(VIDC_ERR, "Received watchdog timeout\n");
		dprintk(VIDC_ERR, "Received watchdog timeout\n");
@@ -3479,7 +3476,7 @@ static int __response_handler(struct venus_hfi_device *device)
		switch (info->response_type) {
		switch (info->response_type) {
		case HAL_SYS_ERROR:
		case HAL_SYS_ERROR:
			__dump_venus_debug_registers(device);
			__dump_venus_debug_registers(device);
			__process_sys_error(device);
			print_sfr_message(device);
			break;
			break;
		case HAL_SYS_RELEASE_RESOURCE_DONE:
		case HAL_SYS_RELEASE_RESOURCE_DONE:
			dprintk(VIDC_DBG, "Received SYS_RELEASE_RESOURCE\n");
			dprintk(VIDC_DBG, "Received SYS_RELEASE_RESOURCE\n");