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

Commit 40987cc0 authored by Kyle Piefer's avatar Kyle Piefer
Browse files

msm: camera: isp: Lock around every list access



When multiple threads access a list simulataneously, the
data can become corrupted. To prevent this, make sure
that every time the list is read or written we hold the lock.

CRs-Fixed: 2147202
Change-Id: I6883d1c08507b5a09fbd66ddfa264f79291f94ad
Signed-off-by: default avatarKyle Piefer <kpiefer@codeaurora.org>
parent 463b317f
Loading
Loading
Loading
Loading
+28 −18
Original line number Diff line number Diff line
@@ -316,14 +316,15 @@ int cam_irq_controller_subscribe_irq(void *irq_controller,
		cam_io_w_mb(irq_mask, controller->mem_base +
			controller->irq_register_arr[i].mask_reg_offset);
	}
	if (need_lock)
		spin_unlock_irqrestore(&controller->lock, flags);

	list_add_tail(&evt_handler->list_node,
		&controller->evt_handler_list_head);
	list_add_tail(&evt_handler->th_list_node,
		&controller->th_list_head[priority]);

	if (need_lock)
		spin_unlock_irqrestore(&controller->lock, flags);

	return evt_handler->index;

free_evt_handler:
@@ -348,6 +349,10 @@ int cam_irq_controller_enable_irq(void *irq_controller, uint32_t handle)
	if (!controller)
		return rc;

	need_lock = !in_irq();
	if (need_lock)
		spin_lock_irqsave(&controller->lock, flags);

	list_for_each_entry_safe(evt_handler, evt_handler_temp,
		&controller->evt_handler_list_head, list_node) {
		if (evt_handler->index == handle) {
@@ -358,12 +363,12 @@ int cam_irq_controller_enable_irq(void *irq_controller, uint32_t handle)
		}
	}

	if (!found)
	if (!found) {
		if (need_lock)
			spin_unlock_irqrestore(&controller->lock, flags);
		return rc;
	}

	need_lock = !in_irq();
	if (need_lock)
		spin_lock_irqsave(&controller->lock, flags);
	for (i = 0; i < controller->num_registers; i++) {
		controller->irq_register_arr[i].
		top_half_enable_mask[evt_handler->priority] |=
@@ -398,6 +403,10 @@ int cam_irq_controller_disable_irq(void *irq_controller, uint32_t handle)
	if (!controller)
		return rc;

	need_lock = !in_irq();
	if (need_lock)
		spin_lock_irqsave(&controller->lock, flags);

	list_for_each_entry_safe(evt_handler, evt_handler_temp,
		&controller->evt_handler_list_head, list_node) {
		if (evt_handler->index == handle) {
@@ -408,12 +417,12 @@ int cam_irq_controller_disable_irq(void *irq_controller, uint32_t handle)
		}
	}

	if (!found)
	if (!found) {
		if (need_lock)
			spin_unlock_irqrestore(&controller->lock, flags);
		return rc;
	}

	need_lock = !in_irq();
	if (need_lock)
		spin_lock_irqsave(&controller->lock, flags);
	for (i = 0; i < controller->num_registers; i++) {
		controller->irq_register_arr[i].
		top_half_enable_mask[evt_handler->priority] &=
@@ -459,6 +468,10 @@ int cam_irq_controller_unsubscribe_irq(void *irq_controller,
	int                         rc = -EINVAL;
	bool                        need_lock;

	need_lock = !in_irq();
	if (need_lock)
		spin_lock_irqsave(&controller->lock, flags);

	list_for_each_entry_safe(evt_handler, evt_handler_temp,
		&controller->evt_handler_list_head, list_node) {
		if (evt_handler->index == handle) {
@@ -471,11 +484,7 @@ int cam_irq_controller_unsubscribe_irq(void *irq_controller,
		}
	}

	need_lock = !in_irq();

	if (found) {
		if (need_lock)
			spin_lock_irqsave(&controller->lock, flags);
		for (i = 0; i < controller->num_registers; i++) {
			controller->irq_register_arr[i].
				top_half_enable_mask[evt_handler->priority] &=
@@ -501,13 +510,14 @@ int cam_irq_controller_unsubscribe_irq(void *irq_controller,
					controller->mem_base +
					controller->global_clear_offset);
		}
		if (need_lock)
			spin_unlock_irqrestore(&controller->lock, flags);

		kfree(evt_handler->evt_bit_mask_arr);
		kfree(evt_handler);
	}

	if (need_lock)
		spin_unlock_irqrestore(&controller->lock, flags);

	return rc;
}

@@ -630,8 +640,6 @@ irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv)
					i, j, need_th_processing[j]);
		}
	}
	CAM_DBG(CAM_ISP, "unlocked controller %pK name %s lock %pK",
		controller, controller->name, &controller->lock);

	CAM_DBG(CAM_ISP, "Status Registers read Successful");

@@ -649,6 +657,8 @@ irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv)
		}
	}
	spin_unlock(&controller->lock);
	CAM_DBG(CAM_ISP, "unlocked controller %pK name %s lock %pK",
		controller, controller->name, &controller->lock);

	return IRQ_HANDLED;
}