95 lines
3.2 KiB
Diff
95 lines
3.2 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: "Gopal, Puunithaaraj" <puunithaaraj.gopal@intel.com>
|
|
Date: Sat, 12 Jan 2019 00:05:13 +0800
|
|
Subject: [PATCH] intel-ipu4: ici: Move empty list check into spinlock to avoid
|
|
list get out of sync.
|
|
|
|
Under race condition, the list content can be modified to
|
|
become empty. This will cause invalid object access.
|
|
|
|
Change-Id: Ica5351c7f1b3e34fec7d2cbe8789062a2f42ff7d
|
|
Tracked-On: OAM-72430
|
|
Tracked-On: OOLI2-2387
|
|
Signed-off-by: Gopal, Puunithaaraj <puunithaaraj.gopal@intel.com>
|
|
---
|
|
.../media/pci/intel/ici/ici-isys-frame-buf.c | 26 ++++++++++++++++---
|
|
1 file changed, 22 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/drivers/media/pci/intel/ici/ici-isys-frame-buf.c b/drivers/media/pci/intel/ici/ici-isys-frame-buf.c
|
|
index 5d3c87612a7d..ff497f8fdd5e 100644
|
|
--- a/drivers/media/pci/intel/ici/ici-isys-frame-buf.c
|
|
+++ b/drivers/media/pci/intel/ici/ici-isys-frame-buf.c
|
|
@@ -698,10 +698,12 @@ void ici_isys_frame_buf_ready(struct ici_isys_pipeline
|
|
static void unmap_buf(struct ici_frame_buf_wrapper *buf)
|
|
{
|
|
int i;
|
|
-
|
|
+ dev_dbg(&buf->buf_list->strm_dev->dev, "buf: %p\n", buf);
|
|
for (i = 0; i < buf->frame_info.num_planes; i++) {
|
|
struct ici_kframe_plane *kframe_plane =
|
|
&buf->kframe_info.planes[i];
|
|
+ dev_dbg(&buf->buf_list->strm_dev->dev, "kframe_plane: %p\n",
|
|
+ kframe_plane);
|
|
switch (kframe_plane->mem_type) {
|
|
case ICI_MEM_USERPTR:
|
|
ici_put_userpages(kframe_plane->dev,
|
|
@@ -747,36 +749,52 @@ void ici_isys_frame_buf_stream_cancel(struct
|
|
struct ici_frame_buf_wrapper *buf;
|
|
unsigned long flags = 0;
|
|
|
|
- while (!list_empty(&buf_list->getbuf_list)) {
|
|
+ while (1) {
|
|
spin_lock_irqsave(&buf_list->lock, flags);
|
|
+ if (list_empty(&buf_list->getbuf_list)) {
|
|
+ spin_unlock_irqrestore(&buf_list->lock, flags);
|
|
+ break;
|
|
+ }
|
|
buf = list_entry(buf_list->getbuf_list.next,
|
|
struct ici_frame_buf_wrapper, node);
|
|
list_del(&buf->node);
|
|
spin_unlock_irqrestore(&buf_list->lock, flags);
|
|
+ dev_dbg(&buf_list->strm_dev->dev, "buf: %p\n", buf);
|
|
if (as->strm_dev.virt_dev_id < 0)
|
|
unmap_buf(buf);
|
|
else
|
|
unmap_buf_virt(buf);
|
|
}
|
|
|
|
- while (!list_empty(&buf_list->putbuf_list)) {
|
|
+ while (1) {
|
|
spin_lock_irqsave(&buf_list->lock, flags);
|
|
+ if (list_empty(&buf_list->putbuf_list)) {
|
|
+ spin_unlock_irqrestore(&buf_list->lock, flags);
|
|
+ break;
|
|
+ }
|
|
buf = list_entry(buf_list->putbuf_list.next,
|
|
struct ici_frame_buf_wrapper, node);
|
|
list_del(&buf->node);
|
|
spin_unlock_irqrestore(&buf_list->lock, flags);
|
|
+ dev_dbg(&buf_list->strm_dev->dev, "buf: %p\n", buf);
|
|
if (as->strm_dev.virt_dev_id < 0)
|
|
unmap_buf(buf);
|
|
else
|
|
unmap_buf_virt(buf);
|
|
}
|
|
|
|
- while (!list_empty(&buf_list->interlacebuf_list)) {
|
|
+ while (1) {
|
|
spin_lock_irqsave(&buf_list->short_packet_queue_lock, flags);
|
|
+ if (list_empty(&buf_list->interlacebuf_list)) {
|
|
+ spin_unlock_irqrestore
|
|
+ (&buf_list->short_packet_queue_lock, flags);
|
|
+ break;
|
|
+ }
|
|
buf = list_entry(buf_list->interlacebuf_list.next,
|
|
struct ici_frame_buf_wrapper, node);
|
|
list_del(&buf->node);
|
|
spin_unlock_irqrestore(&buf_list->short_packet_queue_lock, flags);
|
|
+ dev_dbg(&buf_list->strm_dev->dev, "buf: %p\n", buf);
|
|
unmap_buf(buf);
|
|
}
|
|
}
|
|
--
|
|
https://clearlinux.org
|
|
|