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

Commit 74c2d1f6 authored by Ionut Nicu's avatar Ionut Nicu Committed by Omar Ramirez Luna
Browse files

staging: tidspbridge: fix kernel oops in bridge_io_get_proc_load



The DSP shared memory area gets initialized only when
a COFF file is loaded.

If bridge_io_get_proc_load is called before loading a base
image into the DSP, the shared_mem member of the io manager
will be NULL, resulting in a kernel oops when it's dereferenced.

Also made some coding style changes to bridge_io_create.

Signed-off-by: default avatarIonut Nicu <ionut.nicu@mindbit.ro>
Signed-off-by: default avatarOmar Ramirez Luna <omar.ramirez@ti.com>
parent 59403c21
Loading
Loading
Loading
Loading
+30 −48
Original line number Diff line number Diff line
@@ -167,57 +167,41 @@ int bridge_io_create(struct io_mgr **io_man,
			    struct dev_object *hdev_obj,
			    const struct io_attrs *mgr_attrts)
{
	int status = 0;
	struct io_mgr *pio_mgr = NULL;
	struct shm *shared_mem = NULL;
	struct bridge_dev_context *hbridge_context = NULL;
	struct cfg_devnode *dev_node_obj;
	struct chnl_mgr *hchnl_mgr;
	u8 dev_type;

	/* Check requirements */
	if (!io_man || !mgr_attrts || mgr_attrts->word_size == 0) {
		status = -EFAULT;
		goto func_end;
	}
	if (!io_man || !mgr_attrts || mgr_attrts->word_size == 0)
		return -EFAULT;

	*io_man = NULL;

	dev_get_chnl_mgr(hdev_obj, &hchnl_mgr);
	if (!hchnl_mgr || hchnl_mgr->hio_mgr) {
		status = -EFAULT;
		goto func_end;
	}
	if (!hchnl_mgr || hchnl_mgr->hio_mgr)
		return -EFAULT;

	/*
	 * Message manager will be created when a file is loaded, since
	 * size of message buffer in shared memory is configurable in
	 * the base image.
	 */
	dev_get_bridge_context(hdev_obj, &hbridge_context);
	if (!hbridge_context) {
		status = -EFAULT;
		goto func_end;
	}
	if (!hbridge_context)
		return -EFAULT;

	dev_get_dev_type(hdev_obj, &dev_type);
	/*
	 * DSP shared memory area will get set properly when
	 * a program is loaded. They are unknown until a COFF file is
	 * loaded. I chose the value -1 because it was less likely to be
	 * a valid address than 0.
	 */
	shared_mem = (struct shm *)-1;

	/* Allocate IO manager object */
	pio_mgr = kzalloc(sizeof(struct io_mgr), GFP_KERNEL);
	if (pio_mgr == NULL) {
		status = -ENOMEM;
		goto func_end;
	}
	if (!pio_mgr)
		return -ENOMEM;

	/* Initialize chnl_mgr object */
#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG)
	pio_mgr->pmsg = NULL;
#endif
	pio_mgr->hchnl_mgr = hchnl_mgr;
	pio_mgr->word_size = mgr_attrts->word_size;
	pio_mgr->shared_mem = shared_mem;

	if (dev_type == DSP_UNIT) {
		/* Create an IO DPC */
@@ -229,29 +213,24 @@ int bridge_io_create(struct io_mgr **io_man,

		spin_lock_init(&pio_mgr->dpc_lock);

		status = dev_get_dev_node(hdev_obj, &dev_node_obj);
		if (dev_get_dev_node(hdev_obj, &dev_node_obj)) {
			bridge_io_destroy(pio_mgr);
			return -EIO;
		}
	}

	if (!status) {
	pio_mgr->hbridge_context = hbridge_context;
	pio_mgr->shared_irq = mgr_attrts->irq_shared;
		if (dsp_wdt_init())
			status = -EPERM;
	} else {
		status = -EIO;
	}
func_end:
	if (status) {
		/* Cleanup */
	if (dsp_wdt_init()) {
		bridge_io_destroy(pio_mgr);
		if (io_man)
			*io_man = NULL;
	} else {
		return -EPERM;
	}

	/* Return IO manager object to caller... */
	hchnl_mgr->hio_mgr = pio_mgr;
	*io_man = pio_mgr;
	}
	return status;

	return 0;
}

/*
@@ -1714,6 +1693,9 @@ int io_sh_msetting(struct io_mgr *hio_mgr, u8 desc, void *pargs)
int bridge_io_get_proc_load(struct io_mgr *hio_mgr,
				struct dsp_procloadstat *proc_lstat)
{
	if (!hio_mgr->shared_mem)
		return -EFAULT;

	proc_lstat->curr_load =
			hio_mgr->shared_mem->load_mon_info.curr_dsp_load;
	proc_lstat->predicted_load =