Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1328618 > unrolled thread

[char-misc-next 00/27] mei: fixes, improvements, and cleanups

Started byTomas Winkler <tomas.winkler@intel.com>
First post2016-02-07 22:50 +0100
Last post2016-02-07 22:50 +0100
Articles 7 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [char-misc-next 00/27] mei: fixes, improvements, and cleanups Tomas Winkler <tomas.winkler@intel.com> - 2016-02-07 22:50 +0100
    [char-misc-next 20/27] mei: discard replies from unconnected fixed address clients Tomas Winkler <tomas.winkler@intel.com> - 2016-02-07 22:50 +0100
    [char-misc-next 10/27] mei: amthif: replace amthif_rd_complete_list with rd_completed Tomas Winkler <tomas.winkler@intel.com> - 2016-02-07 22:50 +0100
    [char-misc-next 08/27] mei: rename variable names 'file_object' to fp Tomas Winkler <tomas.winkler@intel.com> - 2016-02-07 22:50 +0100
    [char-misc-next 11/27] mei: amthif: drop parameter validation from mei_amthif_write Tomas Winkler <tomas.winkler@intel.com> - 2016-02-07 22:50 +0100
    [char-misc-next 16/27] mei: bus: check if the device is enabled before data transfer Tomas Winkler <tomas.winkler@intel.com> - 2016-02-07 22:50 +0100
    [char-misc-next 03/27] mei: fix possible integer overflow issue Tomas Winkler <tomas.winkler@intel.com> - 2016-02-07 22:50 +0100

#1328618 — [char-misc-next 00/27] mei: fixes, improvements, and cleanups

FromTomas Winkler <tomas.winkler@intel.com>
Date2016-02-07 22:50 +0100
Subject[char-misc-next 00/27] mei: fixes, improvements, and cleanups
Message-ID<qZFdL-3BZ-3@gated-at.bofh.it>
The series contains:
1. BUS layer fixes
2. debugfs fixes
3. Support for accessing fixed address clients
4. Continuation of dissolving of amthif oddities.
5. Cleanups

Alexander Usyskin (20):
  mei: debugfs: adjust active clients print buffer
  mei: debugfs: allow hbm features list dump in earlier stages
  mei: call stop on failed char device register
  mei: amthif: don't copy from an empty buffer
  mei: amthif: don't drop read packets on timeout
  mei: amthif: allow only one request at a time
  mei: amthif: use rx_wait queue also for amthif client
  mei: amthif: interrupt reader on link reset
  mei: bus: check if the device is enabled before data transfer
  mei: drop superfluous closing bracket from write traces
  mei: wake blocked write on link reset
  mei: clean write queues and wake waiters on disconnect
  mei: discard replies from unconnected fixed address clients
  mei: fill file pointer in read cb for fixed address client
  mei: fixed address clients for the new platforms
  mei: hbm: warn about fw-initiated disconnect
  mei: drop reserved host client ids
  mei: bus: run rescan on me_clients list change
  mei: hbm: send immediate reply flag in enum request
  mei: split amthif client init from end of clients enumeration

Tomas Winkler (7):
  mei: fix possible integer overflow issue
  mei: constify struct file pointer
  mei: rename variable names 'file_object' to fp
  mei: amthif: replace amthif_rd_complete_list with rd_completed
  mei: amthif: drop parameter validation from mei_amthif_write
  mei: bus: fix RX event scheduling
  mei: bus: fix notification event delivery

 drivers/misc/mei/amthif.c    | 130 +++++---------
 drivers/misc/mei/bus-fixup.c |   2 +-
 drivers/misc/mei/bus.c       |  53 +++++-
 drivers/misc/mei/client.c    | 154 +++++++----------
 drivers/misc/mei/client.h    |  23 +--
 drivers/misc/mei/debugfs.c   |  65 +++++--
 drivers/misc/mei/hbm.c       |  24 ++-
 drivers/misc/mei/hw.h        |  32 +++-
 drivers/misc/mei/init.c      |  10 +-
 drivers/misc/mei/interrupt.c |  77 ++++-----
 drivers/misc/mei/main.c      |  50 +++---
 drivers/misc/mei/mei-trace.h |   4 +-
 drivers/misc/mei/mei_dev.h   |  46 ++---
 drivers/misc/mei/pci-me.c    |   4 +-
 drivers/misc/mei/pci-txe.c   |   4 +-
 drivers/misc/mei/wd.c        | 391 +++++++++++++++++++++++++++++++++++++++++++
 16 files changed, 747 insertions(+), 322 deletions(-)
 create mode 100644 drivers/misc/mei/wd.c

-- 
2.4.3

[toc] | [next] | [standalone]


#1328619 — [char-misc-next 20/27] mei: discard replies from unconnected fixed address clients

FromTomas Winkler <tomas.winkler@intel.com>
Date2016-02-07 22:50 +0100
Subject[char-misc-next 20/27] mei: discard replies from unconnected fixed address clients
Message-ID<qZFnr-3H1-11@gated-at.bofh.it>
In reply to#1328618
From: Alexander Usyskin <alexander.usyskin@intel.com>

A fixed address client in the FW doesn't have a notion of connection and
can send message after the file associated with it was already closed.
Silently discard such messages.
Add inline helpers to detect whether a message is hbm or intended for
a fixed address client

Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/interrupt.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 72806ef6efdd..06b744a503a3 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -239,6 +239,16 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb,
 	return 0;
 }
 
+static inline bool hdr_is_hbm(struct mei_msg_hdr *mei_hdr)
+{
+	return mei_hdr->host_addr == 0 && mei_hdr->me_addr == 0;
+}
+
+static inline bool hdr_is_fixed(struct mei_msg_hdr *mei_hdr)
+{
+	return mei_hdr->host_addr == 0 && mei_hdr->me_addr != 0;
+}
+
 /**
  * mei_irq_read_handler - bottom half read routine after ISR to
  * handle the read processing.
@@ -280,7 +290,7 @@ int mei_irq_read_handler(struct mei_device *dev,
 	}
 
 	/*  HBM message */
-	if (mei_hdr->host_addr == 0 && mei_hdr->me_addr == 0) {
+	if (hdr_is_hbm(mei_hdr)) {
 		ret = mei_hbm_dispatch(dev, mei_hdr);
 		if (ret) {
 			dev_dbg(dev->dev, "mei_hbm_dispatch failed ret = %d\n",
@@ -300,6 +310,14 @@ int mei_irq_read_handler(struct mei_device *dev,
 
 	/* if no recipient cl was found we assume corrupted header */
 	if (&cl->link == &dev->file_list) {
+		/* A message for not connected fixed address clients
+		 * should be silently discarded
+		 */
+		if (hdr_is_fixed(mei_hdr)) {
+			mei_irq_discard_msg(dev, mei_hdr);
+			ret = 0;
+			goto reset_slots;
+		}
 		dev_err(dev->dev, "no destination client found 0x%08X\n",
 				dev->rd_msg_hdr);
 		ret = -EBADMSG;
-- 
2.4.3

[toc] | [prev] | [next] | [standalone]


#1328620 — [char-misc-next 10/27] mei: amthif: replace amthif_rd_complete_list with rd_completed

FromTomas Winkler <tomas.winkler@intel.com>
Date2016-02-07 22:50 +0100
Subject[char-misc-next 10/27] mei: amthif: replace amthif_rd_complete_list with rd_completed
Message-ID<qZFns-3H1-23@gated-at.bofh.it>
In reply to#1328618
Now when we have per client rd_completed list we can remove
the amthif specific amthif_rd_complete_list.
In addition in the function mei_amthif_read do not loop over the
rd_completed list like the original code as the code path is unlocked.

Reviewed-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/amthif.c    | 39 +++++++++++----------------------------
 drivers/misc/mei/client.c    |  1 -
 drivers/misc/mei/init.c      |  1 -
 drivers/misc/mei/interrupt.c |  2 +-
 drivers/misc/mei/mei_dev.h   |  7 +------
 5 files changed, 13 insertions(+), 37 deletions(-)

diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 4383a9ad9208..058dd6917805 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -85,26 +85,6 @@ int mei_amthif_host_init(struct mei_device *dev, struct mei_me_client *me_cl)
 }
 
 /**
- * mei_amthif_find_read_list_entry - finds a amthilist entry for current file
- *
- * @dev: the device structure
- * @file: pointer to file object
- *
- * Return:   returned a list entry on success, NULL on failure.
- */
-struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev,
-						  const struct file *file)
-{
-	struct mei_cl_cb *cb;
-
-	list_for_each_entry(cb, &dev->amthif_rd_complete_list.list, list)
-		if (cb->fp == file)
-			return cb;
-	return NULL;
-}
-
-
-/**
  * mei_amthif_read - read data from AMTHIF client
  *
  * @dev: the device structure
@@ -123,12 +103,13 @@ struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev,
 int mei_amthif_read(struct mei_device *dev, struct file *file,
 	       char __user *ubuf, size_t length, loff_t *offset)
 {
+	struct mei_cl *cl = file->private_data;
 	struct mei_cl_cb *cb;
 	int rets;
 	int wait_ret;
 
 	dev_dbg(dev->dev, "checking amthif data\n");
-	cb = mei_amthif_find_read_list_entry(dev, file);
+	cb = mei_cl_read_cb(cl, file);
 
 	/* Check for if we can block or not*/
 	if (cb == NULL && file->f_flags & O_NONBLOCK)
@@ -141,7 +122,7 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
 		mutex_unlock(&dev->device_lock);
 
 		wait_ret = wait_event_interruptible(dev->iamthif_cl.wait,
-			(cb = mei_amthif_find_read_list_entry(dev, file)));
+					    !list_empty(&cl->rd_completed));
 
 		/* Locking again the Mutex */
 		mutex_lock(&dev->device_lock);
@@ -149,7 +130,7 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
 		if (wait_ret)
 			return -ERESTARTSYS;
 
-		dev_dbg(dev->dev, "woke up from sleep\n");
+		cb = mei_cl_read_cb(cl, file);
 	}
 
 	if (cb->status) {
@@ -420,11 +401,12 @@ int mei_amthif_irq_read_msg(struct mei_cl *cl,
 /**
  * mei_amthif_complete - complete amthif callback.
  *
- * @dev: the device structure.
+ * @cl: host client
  * @cb: callback block.
  */
-void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
+void mei_amthif_complete(struct mei_cl *cl, struct mei_cl_cb *cb)
 {
+	struct mei_device *dev = cl->dev;
 
 	if (cb->fop_type == MEI_FOP_WRITE) {
 		if (!cb->status) {
@@ -436,7 +418,7 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
 		 * in case of error enqueue the write cb to complete read list
 		 * so it can be propagated to the reader
 		 */
-		list_add_tail(&cb->list, &dev->amthif_rd_complete_list.list);
+		list_add_tail(&cb->list, &cl->rd_completed);
 		wake_up_interruptible(&dev->iamthif_cl.wait);
 		return;
 	}
@@ -444,7 +426,7 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
 	if (!dev->iamthif_canceled) {
 		dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE;
 		dev->iamthif_stall_timer = 0;
-		list_add_tail(&cb->list, &dev->amthif_rd_complete_list.list);
+		list_add_tail(&cb->list, &cl->rd_completed);
 		dev_dbg(dev->dev, "amthif read completed\n");
 	} else {
 		mei_amthif_run_next_cmd(dev);
@@ -506,10 +488,11 @@ static bool mei_clear_list(struct mei_device *dev,
 static bool mei_clear_lists(struct mei_device *dev, const struct file *file)
 {
 	bool removed = false;
+	struct mei_cl *cl = &dev->iamthif_cl;
 
 	/* remove callbacks associated with a file */
 	mei_clear_list(dev, file, &dev->amthif_cmd_list.list);
-	if (mei_clear_list(dev, file, &dev->amthif_rd_complete_list.list))
+	if (mei_clear_list(dev, file, &cl->rd_completed))
 		removed = true;
 
 	mei_clear_list(dev, file, &dev->ctrl_rd_list.list);
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index c57ac25ce8db..32991684563b 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -536,7 +536,6 @@ int mei_cl_flush_queues(struct mei_cl *cl, const struct file *fp)
 	mei_io_list_flush(&cl->dev->ctrl_wr_list, cl);
 	mei_io_list_flush(&cl->dev->ctrl_rd_list, cl);
 	mei_io_list_flush(&cl->dev->amthif_cmd_list, cl);
-	mei_io_list_flush(&cl->dev->amthif_rd_complete_list, cl);
 
 	mei_cl_read_cb_flush(cl, fp);
 
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 46a4302e5524..a1d978a82806 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -402,7 +402,6 @@ void mei_device_init(struct mei_device *dev,
 
 	INIT_LIST_HEAD(&dev->iamthif_cl.link);
 	mei_io_list_init(&dev->amthif_cmd_list);
-	mei_io_list_init(&dev->amthif_rd_complete_list);
 
 	bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
 	dev->open_handle_count = 0;
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 37c8f0e14387..72806ef6efdd 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -48,7 +48,7 @@ void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *compl_list)
 
 		dev_dbg(dev->dev, "completing call back.\n");
 		if (cl == &dev->iamthif_cl)
-			mei_amthif_complete(dev, cb);
+			mei_amthif_complete(cl, cb);
 		else
 			mei_cl_complete(cl, cb);
 	}
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 3acbbb49d08c..81901967911d 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -406,7 +406,6 @@ const char *mei_pg_state_str(enum mei_pg_state state);
  * @allow_fixed_address: allow user space to connect a fixed client
  *
  * @amthif_cmd_list : amthif list for cmd waiting
- * @amthif_rd_complete_list : amthif list for reading completed cmd data
  * @iamthif_fp : file for current amthif operation
  * @iamthif_cl  : amthif host client
  * @iamthif_current_cb : amthif current operation callback
@@ -496,7 +495,6 @@ struct mei_device {
 	/* amthif list for cmd waiting */
 	struct mei_cl_cb amthif_cmd_list;
 	/* driver managed amthif list for reading completed amthif cmd data */
-	struct mei_cl_cb amthif_rd_complete_list;
 	const struct file *iamthif_fp;
 	struct mei_cl iamthif_cl;
 	struct mei_cl_cb *iamthif_current_cb;
@@ -589,15 +587,12 @@ unsigned int mei_amthif_poll(struct mei_device *dev,
 
 int mei_amthif_release(struct mei_device *dev, struct file *file);
 
-struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev,
-						  const struct file *file);
-
 int mei_amthif_write(struct mei_cl *cl, struct mei_cl_cb *cb);
 int mei_amthif_run_next_cmd(struct mei_device *dev);
 int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
 			struct mei_cl_cb *cmpl_list);
 
-void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb);
+void mei_amthif_complete(struct mei_cl *cl, struct mei_cl_cb *cb);
 int mei_amthif_irq_read_msg(struct mei_cl *cl,
 			    struct mei_msg_hdr *mei_hdr,
 			    struct mei_cl_cb *complete_list);
-- 
2.4.3

[toc] | [prev] | [next] | [standalone]


#1328621 — [char-misc-next 08/27] mei: rename variable names 'file_object' to fp

FromTomas Winkler <tomas.winkler@intel.com>
Date2016-02-07 22:50 +0100
Subject[char-misc-next 08/27] mei: rename variable names 'file_object' to fp
Message-ID<qZFns-3H1-21@gated-at.bofh.it>
In reply to#1328618
The driver uses three names file, fp, and file_object for
struct file type. To improve code clarity and adjust to my taste
rename file_object to more common and shorter fp.

Reviewed-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/amthif.c    | 20 ++++++++++----------
 drivers/misc/mei/client.c    |  8 ++++----
 drivers/misc/mei/interrupt.c |  2 +-
 drivers/misc/mei/mei_dev.h   |  8 ++++----
 4 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 16cceedeed97..647edc68884f 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -98,7 +98,7 @@ struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev,
 	struct mei_cl_cb *cb;
 
 	list_for_each_entry(cb, &dev->amthif_rd_complete_list.list, list)
-		if (cb->file_object == file)
+		if (cb->fp == file)
 			return cb;
 	return NULL;
 }
@@ -224,7 +224,7 @@ static int mei_amthif_read_start(struct mei_cl *cl, const struct file *file)
 	list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
 
 	dev->iamthif_state = MEI_IAMTHIF_READING;
-	dev->iamthif_file_object = cb->file_object;
+	dev->iamthif_fp = cb->fp;
 	dev->iamthif_current_cb = cb;
 
 	return 0;
@@ -253,7 +253,7 @@ static int mei_amthif_send_cmd(struct mei_cl *cl, struct mei_cl_cb *cb)
 
 	dev->iamthif_state = MEI_IAMTHIF_WRITING;
 	dev->iamthif_current_cb = cb;
-	dev->iamthif_file_object = cb->file_object;
+	dev->iamthif_fp = cb->fp;
 	dev->iamthif_canceled = false;
 
 	ret = mei_cl_write(cl, cb, false);
@@ -261,7 +261,7 @@ static int mei_amthif_send_cmd(struct mei_cl *cl, struct mei_cl_cb *cb)
 		return ret;
 
 	if (cb->completed)
-		cb->status = mei_amthif_read_start(cl, cb->file_object);
+		cb->status = mei_amthif_read_start(cl, cb->fp);
 
 	return 0;
 }
@@ -280,7 +280,7 @@ int mei_amthif_run_next_cmd(struct mei_device *dev)
 
 	dev->iamthif_canceled = false;
 	dev->iamthif_state = MEI_IAMTHIF_IDLE;
-	dev->iamthif_file_object = NULL;
+	dev->iamthif_fp = NULL;
 
 	dev_dbg(dev->dev, "complete amthif cmd_list cb.\n");
 
@@ -338,7 +338,7 @@ unsigned int mei_amthif_poll(struct mei_device *dev,
 	poll_wait(file, &dev->iamthif_cl.wait, wait);
 
 	if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE &&
-	    dev->iamthif_file_object == file) {
+	    dev->iamthif_fp == file) {
 
 		mask |= POLLIN | POLLRDNORM;
 		mei_amthif_run_next_cmd(dev);
@@ -368,7 +368,7 @@ int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
 		return ret;
 
 	if (cb->completed)
-		cb->status = mei_amthif_read_start(cl, cb->file_object);
+		cb->status = mei_amthif_read_start(cl, cb->fp);
 
 	return 0;
 }
@@ -469,7 +469,7 @@ static bool mei_clear_list(struct mei_device *dev,
 	/* list all list member */
 	list_for_each_entry_safe(cb, next, mei_cb_list, list) {
 		/* check if list member associated with a file */
-		if (file == cb->file_object) {
+		if (file == cb->fp) {
 			/* check if cb equal to current iamthif cb */
 			if (dev->iamthif_current_cb == cb) {
 				dev->iamthif_current_cb = NULL;
@@ -518,7 +518,7 @@ static bool mei_clear_lists(struct mei_device *dev, const struct file *file)
 	/* check if iamthif_current_cb not NULL */
 	if (dev->iamthif_current_cb && !removed) {
 		/* check file and iamthif current cb association */
-		if (dev->iamthif_current_cb->file_object == file) {
+		if (dev->iamthif_current_cb->fp == file) {
 			/* remove cb */
 			mei_io_cb_free(dev->iamthif_current_cb);
 			dev->iamthif_current_cb = NULL;
@@ -541,7 +541,7 @@ int mei_amthif_release(struct mei_device *dev, struct file *file)
 	if (dev->iamthif_open_count > 0)
 		dev->iamthif_open_count--;
 
-	if (dev->iamthif_file_object == file &&
+	if (dev->iamthif_fp == file &&
 	    dev->iamthif_state != MEI_IAMTHIF_IDLE) {
 
 		dev_dbg(dev->dev, "amthif canceled iamthif state %d\n",
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 4c23caee04ab..c57ac25ce8db 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -368,7 +368,7 @@ struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type,
 		return NULL;
 
 	INIT_LIST_HEAD(&cb->list);
-	cb->file_object = fp;
+	cb->fp = fp;
 	cb->cl = cl;
 	cb->buf_idx = 0;
 	cb->fop_type = type;
@@ -486,7 +486,7 @@ struct mei_cl_cb *mei_cl_read_cb(const struct mei_cl *cl, const struct file *fp)
 	struct mei_cl_cb *cb;
 
 	list_for_each_entry(cb, &cl->rd_completed, list)
-		if (!fp || fp == cb->file_object)
+		if (!fp || fp == cb->fp)
 			return cb;
 
 	return NULL;
@@ -504,12 +504,12 @@ void mei_cl_read_cb_flush(const struct mei_cl *cl, const struct file *fp)
 	struct mei_cl_cb *cb, *next;
 
 	list_for_each_entry_safe(cb, next, &cl->rd_completed, list)
-		if (!fp || fp == cb->file_object)
+		if (!fp || fp == cb->fp)
 			mei_io_cb_free(cb);
 
 
 	list_for_each_entry_safe(cb, next, &cl->rd_pending, list)
-		if (!fp || fp == cb->file_object)
+		if (!fp || fp == cb->fp)
 			mei_io_cb_free(cb);
 }
 
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 78978193d19b..37c8f0e14387 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -506,7 +506,7 @@ void mei_timer(struct work_struct *work)
 			mei_io_cb_free(dev->iamthif_current_cb);
 			dev->iamthif_current_cb = NULL;
 
-			dev->iamthif_file_object = NULL;
+			dev->iamthif_fp = NULL;
 			mei_amthif_run_next_cmd(dev);
 		}
 	}
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 947e0a70577a..3acbbb49d08c 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -179,7 +179,7 @@ struct mei_cl;
  * @fop_type: file operation type
  * @buf: buffer for data associated with the callback
  * @buf_idx: last read index
- * @file_object: pointer to file structure
+ * @fp: pointer to file structure
  * @status: io status of the cb
  * @internal: communication between driver and FW flag
  * @completed: the transfer or reception has completed
@@ -190,7 +190,7 @@ struct mei_cl_cb {
 	enum mei_cb_file_ops fop_type;
 	struct mei_msg_data buf;
 	size_t buf_idx;
-	const struct file *file_object;
+	const struct file *fp;
 	int status;
 	u32 internal:1;
 	u32 completed:1;
@@ -407,7 +407,7 @@ const char *mei_pg_state_str(enum mei_pg_state state);
  *
  * @amthif_cmd_list : amthif list for cmd waiting
  * @amthif_rd_complete_list : amthif list for reading completed cmd data
- * @iamthif_file_object : file for current amthif operation
+ * @iamthif_fp : file for current amthif operation
  * @iamthif_cl  : amthif host client
  * @iamthif_current_cb : amthif current operation callback
  * @iamthif_open_count : number of opened amthif connections
@@ -497,7 +497,7 @@ struct mei_device {
 	struct mei_cl_cb amthif_cmd_list;
 	/* driver managed amthif list for reading completed amthif cmd data */
 	struct mei_cl_cb amthif_rd_complete_list;
-	const struct file *iamthif_file_object;
+	const struct file *iamthif_fp;
 	struct mei_cl iamthif_cl;
 	struct mei_cl_cb *iamthif_current_cb;
 	long iamthif_open_count;
-- 
2.4.3

[toc] | [prev] | [next] | [standalone]


#1328622 — [char-misc-next 11/27] mei: amthif: drop parameter validation from mei_amthif_write

FromTomas Winkler <tomas.winkler@intel.com>
Date2016-02-07 22:50 +0100
Subject[char-misc-next 11/27] mei: amthif: drop parameter validation from mei_amthif_write
Message-ID<qZFns-3H1-27@gated-at.bofh.it>
In reply to#1328618
Remove duplicated parameter validation from mei_amthif_write functions,
The parameter check is already performed by the caller function
mei_write

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
 drivers/misc/mei/amthif.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 058dd6917805..911b663a8fdb 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -285,15 +285,7 @@ int mei_amthif_run_next_cmd(struct mei_device *dev)
 int mei_amthif_write(struct mei_cl *cl, struct mei_cl_cb *cb)
 {
 
-	struct mei_device *dev;
-
-	if (WARN_ON(!cl || !cl->dev))
-		return -ENODEV;
-
-	if (WARN_ON(!cb))
-		return -EINVAL;
-
-	dev = cl->dev;
+	struct mei_device *dev = cl->dev;
 
 	list_add_tail(&cb->list, &dev->amthif_cmd_list.list);
 
-- 
2.4.3

[toc] | [prev] | [next] | [standalone]


#1328623 — [char-misc-next 16/27] mei: bus: check if the device is enabled before data transfer

FromTomas Winkler <tomas.winkler@intel.com>
Date2016-02-07 22:50 +0100
Subject[char-misc-next 16/27] mei: bus: check if the device is enabled before data transfer
Message-ID<qZFns-3H1-29@gated-at.bofh.it>
In reply to#1328618
From: Alexander Usyskin <alexander.usyskin@intel.com>

The bus data transfer interface was missing the check if the device is
in enabled state, this may lead to stack corruption during link reset.

Cc: <stable@vger.kernel.org> #4.0
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/bus.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 990f4f65c35e..83b084558ee5 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -53,6 +53,11 @@ ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
 	bus = cl->dev;
 
 	mutex_lock(&bus->device_lock);
+	if (bus->dev_state != MEI_DEV_ENABLED) {
+		rets = -ENODEV;
+		goto out;
+	}
+
 	if (!mei_cl_is_connected(cl)) {
 		rets = -ENODEV;
 		goto out;
@@ -109,6 +114,10 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
 	bus = cl->dev;
 
 	mutex_lock(&bus->device_lock);
+	if (bus->dev_state != MEI_DEV_ENABLED) {
+		rets = -ENODEV;
+		goto out;
+	}
 
 	cb = mei_cl_read_cb(cl, NULL);
 	if (cb)
-- 
2.4.3

[toc] | [prev] | [next] | [standalone]


#1328624 — [char-misc-next 03/27] mei: fix possible integer overflow issue

FromTomas Winkler <tomas.winkler@intel.com>
Date2016-02-07 22:50 +0100
Subject[char-misc-next 03/27] mei: fix possible integer overflow issue
Message-ID<qZFns-3H1-17@gated-at.bofh.it>
In reply to#1328618
There is a possible integer overflow following by a buffer overflow
when accumulating messages coming from the FW to compose a full payload.
Occurrence of wrap around has to be prevented for next message size
calculation.
For unsigned integer the addition overflow has occurred when the
result is smaller than one of the arguments.
To simplify the fix, the types of buf.size and buf_idx are set to the
same width, namely size_t also to be aligned with the type of length
parameter in file read/write ops.

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
 drivers/misc/mei/amthif.c    |  5 ++---
 drivers/misc/mei/client.c    |  2 +-
 drivers/misc/mei/interrupt.c | 21 ++++++++++++++++-----
 drivers/misc/mei/main.c      |  5 +++--
 drivers/misc/mei/mei_dev.h   |  4 ++--
 5 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index cd0403f09267..b753df98b476 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -195,9 +195,8 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
 		 * remove message from deletion list
 		 */
 
-	dev_dbg(dev->dev, "amthif cb->buf size - %d\n",
-	    cb->buf.size);
-	dev_dbg(dev->dev, "amthif cb->buf_idx - %lu\n", cb->buf_idx);
+	dev_dbg(dev->dev, "amthif cb->buf.size - %zd cb->buf_idx - %zd\n",
+		cb->buf.size, cb->buf_idx);
 
 	/* length is being truncated to PAGE_SIZE, however,
 	 * the buf_idx may point beyond */
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index e069fcaed7aa..738f3d703323 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -1569,7 +1569,7 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
 		return 0;
 	}
 
-	cl_dbg(dev, cl, "buf: size = %d idx = %lu\n",
+	cl_dbg(dev, cl, "buf: size = %zd idx = %zd\n",
 			cb->buf.size, cb->buf_idx);
 
 	rets = mei_write_message(dev, &mei_hdr, buf->data + cb->buf_idx);
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 6340dee33052..b8aa047ec258 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -104,6 +104,7 @@ int mei_cl_irq_read_msg(struct mei_cl *cl,
 	struct mei_device *dev = cl->dev;
 	struct mei_cl_cb *cb;
 	unsigned char *buffer = NULL;
+	size_t buf_sz;
 
 	cb = list_first_entry_or_null(&cl->rd_pending, struct mei_cl_cb, list);
 	if (!cb) {
@@ -124,11 +125,21 @@ int mei_cl_irq_read_msg(struct mei_cl *cl,
 		goto out;
 	}
 
-	if (cb->buf.size < mei_hdr->length + cb->buf_idx) {
-		cl_dbg(dev, cl, "message overflow. size %d len %d idx %ld\n",
+	buf_sz = mei_hdr->length + cb->buf_idx;
+	/* catch for integer overflow */
+	if (buf_sz < cb->buf_idx) {
+		cl_err(dev, cl, "message is too big len %d idx %ld\n",
+		       mei_hdr->length, cb->buf_idx);
+
+		list_move_tail(&cb->list, &complete_list->list);
+		cb->status = -EMSGSIZE;
+		goto out;
+	}
+
+	if (cb->buf.size < buf_sz) {
+		cl_dbg(dev, cl, "message overflow. size %zd len %d idx %zd\n",
 			cb->buf.size, mei_hdr->length, cb->buf_idx);
-		buffer = krealloc(cb->buf.data, mei_hdr->length + cb->buf_idx,
-				  GFP_KERNEL);
+		buffer = krealloc(cb->buf.data, buf_sz, GFP_KERNEL);
 
 		if (!buffer) {
 			cb->status = -ENOMEM;
@@ -136,7 +147,7 @@ int mei_cl_irq_read_msg(struct mei_cl *cl,
 			goto out;
 		}
 		cb->buf.data = buffer;
-		cb->buf.size = mei_hdr->length + cb->buf_idx;
+		cb->buf.size = buf_sz;
 	}
 
 	buffer = cb->buf.data + cb->buf_idx;
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 55ae4789c439..5c530bab97f1 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -226,7 +226,7 @@ copy_buffer:
 		goto free;
 	}
 
-	cl_dbg(dev, cl, "buf.size = %d buf.idx = %ld offset = %lld\n",
+	cl_dbg(dev, cl, "buf.size = %zd buf.idx = %zd offset = %lld\n",
 	       cb->buf.size, cb->buf_idx, *offset);
 	if (*offset >= cb->buf_idx) {
 		rets = 0;
@@ -245,7 +245,8 @@ copy_buffer:
 
 	rets = length;
 	*offset += length;
-	if ((unsigned long)*offset < cb->buf_idx)
+	/* not all data was read, keep the cb */
+	if (*offset < cb->buf_idx)
 		goto out;
 
 free:
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index da613268480c..9b793f87b7d4 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -126,7 +126,7 @@ enum mei_cb_file_ops {
  * Intel MEI message data struct
  */
 struct mei_msg_data {
-	u32 size;
+	size_t size;
 	unsigned char *data;
 };
 
@@ -190,7 +190,7 @@ struct mei_cl_cb {
 	struct mei_cl *cl;
 	enum mei_cb_file_ops fop_type;
 	struct mei_msg_data buf;
-	unsigned long buf_idx;
+	size_t buf_idx;
 	unsigned long read_time;
 	struct file *file_object;
 	int status;
-- 
2.4.3

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web