]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 6 Jul 2022 07:08:18 +0000 (09:08 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 6 Jul 2022 07:08:18 +0000 (09:08 +0200)
added patches:
fsi-occ-force-sequence-numbering-per-occ.patch

queue-5.15/fsi-occ-force-sequence-numbering-per-occ.patch [new file with mode: 0644]
queue-5.15/series

diff --git a/queue-5.15/fsi-occ-force-sequence-numbering-per-occ.patch b/queue-5.15/fsi-occ-force-sequence-numbering-per-occ.patch
new file mode 100644 (file)
index 0000000..d8fb482
--- /dev/null
@@ -0,0 +1,153 @@
+From 62f79f3d0eb9f4c224bcc3c7f6fa758515a0a7fa Mon Sep 17 00:00:00 2001
+From: Eddie James <eajames@linux.ibm.com>
+Date: Wed, 21 Jul 2021 14:02:29 -0500
+Subject: fsi: occ: Force sequence numbering per OCC
+
+From: Eddie James <eajames@linux.ibm.com>
+
+commit 62f79f3d0eb9f4c224bcc3c7f6fa758515a0a7fa upstream.
+
+Set and increment the sequence number during the submit operation.
+This prevents sequence number conflicts between different users of
+the interface. A sequence number conflict may result in a user
+getting an OCC response meant for a different command. Since the
+sequence number is now modified, the checksum must be calculated and
+set before submitting the command.
+
+Signed-off-by: Eddie James <eajames@linux.ibm.com>
+Reviewed-by: Joel Stanley <joel@jms.id.au>
+Link: https://lore.kernel.org/r/20210721190231.117185-2-eajames@linux.ibm.com
+Signed-off-by: Joel Stanley <joel@jms.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fsi/fsi-occ.c |   54 ++++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 37 insertions(+), 17 deletions(-)
+
+--- a/drivers/fsi/fsi-occ.c
++++ b/drivers/fsi/fsi-occ.c
+@@ -50,6 +50,7 @@ struct occ {
+       struct device *sbefifo;
+       char name[32];
+       int idx;
++      u8 sequence_number;
+       enum versions version;
+       struct miscdevice mdev;
+       struct mutex occ_lock;
+@@ -141,8 +142,7 @@ static ssize_t occ_write(struct file *fi
+ {
+       struct occ_client *client = file->private_data;
+       size_t rlen, data_length;
+-      u16 checksum = 0;
+-      ssize_t rc, i;
++      ssize_t rc;
+       u8 *cmd;
+       if (!client)
+@@ -156,9 +156,6 @@ static ssize_t occ_write(struct file *fi
+       /* Construct the command */
+       cmd = client->buffer;
+-      /* Sequence number (we could increment and compare with response) */
+-      cmd[0] = 1;
+-
+       /*
+        * Copy the user command (assume user data follows the occ command
+        * format)
+@@ -178,14 +175,7 @@ static ssize_t occ_write(struct file *fi
+               goto done;
+       }
+-      /* Calculate checksum */
+-      for (i = 0; i < data_length + 4; ++i)
+-              checksum += cmd[i];
+-
+-      cmd[data_length + 4] = checksum >> 8;
+-      cmd[data_length + 5] = checksum & 0xFF;
+-
+-      /* Submit command */
++      /* Submit command; 4 bytes before the data and 2 bytes after */
+       rlen = PAGE_SIZE;
+       rc = fsi_occ_submit(client->occ->dev, cmd, data_length + 6, cmd,
+                           &rlen);
+@@ -314,11 +304,13 @@ free:
+       return rc;
+ }
+-static int occ_putsram(struct occ *occ, const void *data, ssize_t len)
++static int occ_putsram(struct occ *occ, const void *data, ssize_t len,
++                     u8 seq_no, u16 checksum)
+ {
+       size_t cmd_len, buf_len, resp_len, resp_data_len;
+       u32 data_len = ((len + 7) / 8) * 8;     /* must be multiples of 8 B */
+       __be32 *buf;
++      u8 *byte_buf;
+       int idx = 0, rc;
+       cmd_len = (occ->version == occ_p10) ? 6 : 5;
+@@ -358,6 +350,15 @@ static int occ_putsram(struct occ *occ,
+       buf[4 + idx] = cpu_to_be32(data_len);
+       memcpy(&buf[5 + idx], data, len);
++      byte_buf = (u8 *)&buf[5 + idx];
++      /*
++       * Overwrite the first byte with our sequence number and the last two
++       * bytes with the checksum.
++       */
++      byte_buf[0] = seq_no;
++      byte_buf[len - 2] = checksum >> 8;
++      byte_buf[len - 1] = checksum & 0xff;
++
+       rc = sbefifo_submit(occ->sbefifo, buf, cmd_len, buf, &resp_len);
+       if (rc)
+               goto free;
+@@ -467,9 +468,12 @@ int fsi_occ_submit(struct device *dev, c
+       struct occ *occ = dev_get_drvdata(dev);
+       struct occ_response *resp = response;
+       u8 seq_no;
++      u16 checksum = 0;
+       u16 resp_data_length;
++      const u8 *byte_request = (const u8 *)request;
+       unsigned long start;
+       int rc;
++      size_t i;
+       if (!occ)
+               return -ENODEV;
+@@ -479,11 +483,26 @@ int fsi_occ_submit(struct device *dev, c
+               return -EINVAL;
+       }
++      /* Checksum the request, ignoring first byte (sequence number). */
++      for (i = 1; i < req_len - 2; ++i)
++              checksum += byte_request[i];
++
+       mutex_lock(&occ->occ_lock);
+-      /* Extract the seq_no from the command (first byte) */
+-      seq_no = *(const u8 *)request;
+-      rc = occ_putsram(occ, request, req_len);
++      /*
++       * Get a sequence number and update the counter. Avoid a sequence
++       * number of 0 which would pass the response check below even if the
++       * OCC response is uninitialized. Any sequence number the user is
++       * trying to send is overwritten since this function is the only common
++       * interface to the OCC and therefore the only place we can guarantee
++       * unique sequence numbers.
++       */
++      seq_no = occ->sequence_number++;
++      if (!occ->sequence_number)
++              occ->sequence_number = 1;
++      checksum += seq_no;
++
++      rc = occ_putsram(occ, request, req_len, seq_no, checksum);
+       if (rc)
+               goto done;
+@@ -574,6 +593,7 @@ static int occ_probe(struct platform_dev
+       occ->version = (uintptr_t)of_device_get_match_data(dev);
+       occ->dev = dev;
+       occ->sbefifo = dev->parent;
++      occ->sequence_number = 1;
+       mutex_init(&occ->occ_lock);
+       if (dev->of_node) {
index d246e699e3680f60178f7f7b932786e34b6edbb4..7552589f0bd6c14322885a64a608157054d38429 100644 (file)
@@ -83,6 +83,7 @@ xen-netfront-restore-__skb_queue_tail-positioning-in-xennet_get_responses.patch
 xen-arm-fix-race-in-rb-tree-based-p2m-accounting.patch
 net-usb-qmi_wwan-add-telit-0x1070-composition.patch
 clocksource-drivers-ixp4xx-remove-export_symbol_gpl-from-ixp4xx_timer_setup.patch
+fsi-occ-force-sequence-numbering-per-occ.patch
 net-fix-iff_tx_skb_no_linear-definition.patch
 drm-i915-gem-add-missing-else.patch
 drm-msm-gem-fix-error-return-on-fence-id-alloc-fail.patch