]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 Apr 2023 09:10:27 +0000 (11:10 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 Apr 2023 09:10:27 +0000 (11:10 +0200)
added patches:
cxl-pci-fix-cdat-retrieval-on-big-endian.patch
cxl-pci-handle-excessive-cdat-length.patch
cxl-pci-handle-truncated-cdat-entries.patch
cxl-pci-handle-truncated-cdat-header.patch
pci-doe-fix-memory-leak-with-config_debug_objects-y.patch
pci-doe-silence-warn-splat-with-config_debug_objects-y.patch
usb-xhci-tegra-fix-sleep-in-atomic-call.patch
xhci-also-avoid-the-xhci_zero_64b_regs-quirk-with-a-passthrough-iommu.patch
xhci-free-the-command-allocated-for-setting-lpm-if-we-return-early.patch

queue-6.1/cxl-pci-fix-cdat-retrieval-on-big-endian.patch [new file with mode: 0644]
queue-6.1/cxl-pci-handle-excessive-cdat-length.patch [new file with mode: 0644]
queue-6.1/cxl-pci-handle-truncated-cdat-entries.patch [new file with mode: 0644]
queue-6.1/cxl-pci-handle-truncated-cdat-header.patch [new file with mode: 0644]
queue-6.1/pci-doe-fix-memory-leak-with-config_debug_objects-y.patch [new file with mode: 0644]
queue-6.1/pci-doe-silence-warn-splat-with-config_debug_objects-y.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/usb-xhci-tegra-fix-sleep-in-atomic-call.patch [new file with mode: 0644]
queue-6.1/xhci-also-avoid-the-xhci_zero_64b_regs-quirk-with-a-passthrough-iommu.patch [new file with mode: 0644]
queue-6.1/xhci-free-the-command-allocated-for-setting-lpm-if-we-return-early.patch [new file with mode: 0644]

diff --git a/queue-6.1/cxl-pci-fix-cdat-retrieval-on-big-endian.patch b/queue-6.1/cxl-pci-fix-cdat-retrieval-on-big-endian.patch
new file mode 100644 (file)
index 0000000..02b9f4f
--- /dev/null
@@ -0,0 +1,238 @@
+From fbaa38214cd9e150764ccaa82e04ecf42cc1140c Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Sat, 11 Mar 2023 15:40:01 +0100
+Subject: cxl/pci: Fix CDAT retrieval on big endian
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit fbaa38214cd9e150764ccaa82e04ecf42cc1140c upstream.
+
+The CDAT exposed in sysfs differs between little endian and big endian
+arches:  On big endian, every 4 bytes are byte-swapped.
+
+PCI Configuration Space is little endian (PCI r3.0 sec 6.1).  Accessors
+such as pci_read_config_dword() implicitly swap bytes on big endian.
+That way, the macros in include/uapi/linux/pci_regs.h work regardless of
+the arch's endianness.  For an example of implicit byte-swapping, see
+ppc4xx_pciex_read_config(), which calls in_le32(), which uses lwbrx
+(Load Word Byte-Reverse Indexed).
+
+DOE Read/Write Data Mailbox Registers are unlike other registers in
+Configuration Space in that they contain or receive a 4 byte portion of
+an opaque byte stream (a "Data Object" per PCIe r6.0 sec 7.9.24.5f).
+They need to be copied to or from the request/response buffer verbatim.
+So amend pci_doe_send_req() and pci_doe_recv_resp() to undo the implicit
+byte-swapping.
+
+The CXL_DOE_TABLE_ACCESS_* and PCI_DOE_DATA_OBJECT_DISC_* macros assume
+implicit byte-swapping.  Byte-swap requests after constructing them with
+those macros and byte-swap responses before parsing them.
+
+Change the request and response type to __le32 to avoid sparse warnings.
+Per a request from Jonathan, replace sizeof(u32) with sizeof(__le32) for
+consistency.
+
+Fixes: c97006046c79 ("cxl/port: Read CDAT table")
+Tested-by: Ira Weiny <ira.weiny@intel.com>
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Cc: stable@vger.kernel.org # v6.0+
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Link: https://lore.kernel.org/r/3051114102f41d19df3debbee123129118fc5e6d.1678543498.git.lukas@wunner.de
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/cxl/core/pci.c  |   26 +++++++++++++-------------
+ drivers/pci/doe.c       |   25 ++++++++++++++-----------
+ include/linux/pci-doe.h |    8 ++++++--
+ 3 files changed, 33 insertions(+), 26 deletions(-)
+
+--- a/drivers/cxl/core/pci.c
++++ b/drivers/cxl/core/pci.c
+@@ -483,7 +483,7 @@ static struct pci_doe_mb *find_cdat_doe(
+       return NULL;
+ }
+-#define CDAT_DOE_REQ(entry_handle)                                    \
++#define CDAT_DOE_REQ(entry_handle) cpu_to_le32                                \
+       (FIELD_PREP(CXL_DOE_TABLE_ACCESS_REQ_CODE,                      \
+                   CXL_DOE_TABLE_ACCESS_REQ_CODE_READ) |               \
+        FIELD_PREP(CXL_DOE_TABLE_ACCESS_TABLE_TYPE,                    \
+@@ -496,8 +496,8 @@ static void cxl_doe_task_complete(struct
+ }
+ struct cdat_doe_task {
+-      u32 request_pl;
+-      u32 response_pl[32];
++      __le32 request_pl;
++      __le32 response_pl[32];
+       struct completion c;
+       struct pci_doe_task task;
+ };
+@@ -531,10 +531,10 @@ static int cxl_cdat_get_length(struct de
+               return rc;
+       }
+       wait_for_completion(&t.c);
+-      if (t.task.rv < sizeof(u32))
++      if (t.task.rv < sizeof(__le32))
+               return -EIO;
+-      *length = t.response_pl[1];
++      *length = le32_to_cpu(t.response_pl[1]);
+       dev_dbg(dev, "CDAT length %zu\n", *length);
+       return 0;
+@@ -545,13 +545,13 @@ static int cxl_cdat_read_table(struct de
+                              struct cxl_cdat *cdat)
+ {
+       size_t length = cdat->length;
+-      u32 *data = cdat->table;
++      __le32 *data = cdat->table;
+       int entry_handle = 0;
+       do {
+               DECLARE_CDAT_DOE_TASK(CDAT_DOE_REQ(entry_handle), t);
+               size_t entry_dw;
+-              u32 *entry;
++              __le32 *entry;
+               int rc;
+               rc = pci_doe_submit_task(cdat_doe, &t.task);
+@@ -561,21 +561,21 @@ static int cxl_cdat_read_table(struct de
+               }
+               wait_for_completion(&t.c);
+               /* 1 DW header + 1 DW data min */
+-              if (t.task.rv < (2 * sizeof(u32)))
++              if (t.task.rv < (2 * sizeof(__le32)))
+                       return -EIO;
+               /* Get the CXL table access header entry handle */
+               entry_handle = FIELD_GET(CXL_DOE_TABLE_ACCESS_ENTRY_HANDLE,
+-                                       t.response_pl[0]);
++                                       le32_to_cpu(t.response_pl[0]));
+               entry = t.response_pl + 1;
+-              entry_dw = t.task.rv / sizeof(u32);
++              entry_dw = t.task.rv / sizeof(__le32);
+               /* Skip Header */
+               entry_dw -= 1;
+-              entry_dw = min(length / sizeof(u32), entry_dw);
++              entry_dw = min(length / sizeof(__le32), entry_dw);
+               /* Prevent length < 1 DW from causing a buffer overflow */
+               if (entry_dw) {
+-                      memcpy(data, entry, entry_dw * sizeof(u32));
+-                      length -= entry_dw * sizeof(u32);
++                      memcpy(data, entry, entry_dw * sizeof(__le32));
++                      length -= entry_dw * sizeof(__le32);
+                       data += entry_dw;
+               }
+       } while (entry_handle != CXL_DOE_TABLE_ACCESS_LAST_ENTRY);
+--- a/drivers/pci/doe.c
++++ b/drivers/pci/doe.c
+@@ -128,7 +128,7 @@ static int pci_doe_send_req(struct pci_d
+               return -EIO;
+       /* Length is 2 DW of header + length of payload in DW */
+-      length = 2 + task->request_pl_sz / sizeof(u32);
++      length = 2 + task->request_pl_sz / sizeof(__le32);
+       if (length > PCI_DOE_MAX_LENGTH)
+               return -EIO;
+       if (length == PCI_DOE_MAX_LENGTH)
+@@ -141,9 +141,9 @@ static int pci_doe_send_req(struct pci_d
+       pci_write_config_dword(pdev, offset + PCI_DOE_WRITE,
+                              FIELD_PREP(PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH,
+                                         length));
+-      for (i = 0; i < task->request_pl_sz / sizeof(u32); i++)
++      for (i = 0; i < task->request_pl_sz / sizeof(__le32); i++)
+               pci_write_config_dword(pdev, offset + PCI_DOE_WRITE,
+-                                     task->request_pl[i]);
++                                     le32_to_cpu(task->request_pl[i]));
+       pci_doe_write_ctrl(doe_mb, PCI_DOE_CTRL_GO);
+@@ -195,11 +195,11 @@ static int pci_doe_recv_resp(struct pci_
+       /* First 2 dwords have already been read */
+       length -= 2;
+-      payload_length = min(length, task->response_pl_sz / sizeof(u32));
++      payload_length = min(length, task->response_pl_sz / sizeof(__le32));
+       /* Read the rest of the response payload */
+       for (i = 0; i < payload_length; i++) {
+-              pci_read_config_dword(pdev, offset + PCI_DOE_READ,
+-                                    &task->response_pl[i]);
++              pci_read_config_dword(pdev, offset + PCI_DOE_READ, &val);
++              task->response_pl[i] = cpu_to_le32(val);
+               /* Prior to the last ack, ensure Data Object Ready */
+               if (i == (payload_length - 1) && !pci_doe_data_obj_ready(doe_mb))
+                       return -EIO;
+@@ -217,7 +217,7 @@ static int pci_doe_recv_resp(struct pci_
+       if (FIELD_GET(PCI_DOE_STATUS_ERROR, val))
+               return -EIO;
+-      return min(length, task->response_pl_sz / sizeof(u32)) * sizeof(u32);
++      return min(length, task->response_pl_sz / sizeof(__le32)) * sizeof(__le32);
+ }
+ static void signal_task_complete(struct pci_doe_task *task, int rv)
+@@ -317,14 +317,16 @@ static int pci_doe_discovery(struct pci_
+ {
+       u32 request_pl = FIELD_PREP(PCI_DOE_DATA_OBJECT_DISC_REQ_3_INDEX,
+                                   *index);
++      __le32 request_pl_le = cpu_to_le32(request_pl);
++      __le32 response_pl_le;
+       u32 response_pl;
+       DECLARE_COMPLETION_ONSTACK(c);
+       struct pci_doe_task task = {
+               .prot.vid = PCI_VENDOR_ID_PCI_SIG,
+               .prot.type = PCI_DOE_PROTOCOL_DISCOVERY,
+-              .request_pl = &request_pl,
++              .request_pl = &request_pl_le,
+               .request_pl_sz = sizeof(request_pl),
+-              .response_pl = &response_pl,
++              .response_pl = &response_pl_le,
+               .response_pl_sz = sizeof(response_pl),
+               .complete = pci_doe_task_complete,
+               .private = &c,
+@@ -340,6 +342,7 @@ static int pci_doe_discovery(struct pci_
+       if (task.rv != sizeof(response_pl))
+               return -EIO;
++      response_pl = le32_to_cpu(response_pl_le);
+       *vid = FIELD_GET(PCI_DOE_DATA_OBJECT_DISC_RSP_3_VID, response_pl);
+       *protocol = FIELD_GET(PCI_DOE_DATA_OBJECT_DISC_RSP_3_PROTOCOL,
+                             response_pl);
+@@ -533,8 +536,8 @@ int pci_doe_submit_task(struct pci_doe_m
+        * DOE requests must be a whole number of DW and the response needs to
+        * be big enough for at least 1 DW
+        */
+-      if (task->request_pl_sz % sizeof(u32) ||
+-          task->response_pl_sz < sizeof(u32))
++      if (task->request_pl_sz % sizeof(__le32) ||
++          task->response_pl_sz < sizeof(__le32))
+               return -EINVAL;
+       if (test_bit(PCI_DOE_FLAG_DEAD, &doe_mb->flags))
+--- a/include/linux/pci-doe.h
++++ b/include/linux/pci-doe.h
+@@ -34,6 +34,10 @@ struct pci_doe_mb;
+  * @work: Used internally by the mailbox
+  * @doe_mb: Used internally by the mailbox
+  *
++ * Payloads are treated as opaque byte streams which are transmitted verbatim,
++ * without byte-swapping.  If payloads contain little-endian register values,
++ * the caller is responsible for conversion with cpu_to_le32() / le32_to_cpu().
++ *
+  * The payload sizes and rv are specified in bytes with the following
+  * restrictions concerning the protocol.
+  *
+@@ -45,9 +49,9 @@ struct pci_doe_mb;
+  */
+ struct pci_doe_task {
+       struct pci_doe_protocol prot;
+-      u32 *request_pl;
++      __le32 *request_pl;
+       size_t request_pl_sz;
+-      u32 *response_pl;
++      __le32 *response_pl;
+       size_t response_pl_sz;
+       int rv;
+       void (*complete)(struct pci_doe_task *task);
diff --git a/queue-6.1/cxl-pci-handle-excessive-cdat-length.patch b/queue-6.1/cxl-pci-handle-excessive-cdat-length.patch
new file mode 100644 (file)
index 0000000..3296c4f
--- /dev/null
@@ -0,0 +1,42 @@
+From 4fe2c13d59d849be3b45371e3913ec5dc77fc0fb Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Sat, 11 Mar 2023 15:40:04 +0100
+Subject: cxl/pci: Handle excessive CDAT length
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 4fe2c13d59d849be3b45371e3913ec5dc77fc0fb upstream.
+
+If the length in the CDAT header is larger than the concatenation of the
+header and all table entries, then the CDAT exposed to user space
+contains trailing null bytes.
+
+Not every consumer may be able to handle that.  Per Postel's robustness
+principle, "be liberal in what you accept" and silently reduce the
+cached length to avoid exposing those null bytes.
+
+Fixes: c97006046c79 ("cxl/port: Read CDAT table")
+Tested-by: Ira Weiny <ira.weiny@intel.com>
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: stable@vger.kernel.org # v6.0+
+Link: https://lore.kernel.org/r/6d98b3c7da5343172bd3ccabfabbc1f31c079d74.1678543498.git.lukas@wunner.de
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/cxl/core/pci.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/cxl/core/pci.c
++++ b/drivers/cxl/core/pci.c
+@@ -585,6 +585,9 @@ static int cxl_cdat_read_table(struct de
+               }
+       } while (entry_handle != CXL_DOE_TABLE_ACCESS_LAST_ENTRY);
++      /* Length in CDAT header may exceed concatenation of CDAT entries */
++      cdat->length -= length;
++
+       return 0;
+ }
diff --git a/queue-6.1/cxl-pci-handle-truncated-cdat-entries.patch b/queue-6.1/cxl-pci-handle-truncated-cdat-entries.patch
new file mode 100644 (file)
index 0000000..503f229
--- /dev/null
@@ -0,0 +1,104 @@
+From b56faef2312057db20479b240eb71bd2e51fb51c Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Sat, 11 Mar 2023 15:40:03 +0100
+Subject: cxl/pci: Handle truncated CDAT entries
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit b56faef2312057db20479b240eb71bd2e51fb51c upstream.
+
+If truncated CDAT entries are received from a device, the concatenation
+of those entries constitutes a corrupt CDAT, yet is happily exposed to
+user space.
+
+Avoid by verifying response lengths and erroring out if truncation is
+detected.
+
+The last CDAT entry may still be truncated despite the checks introduced
+herein if the length in the CDAT header is too small.  However, that is
+easily detectable by user space because it reaches EOF prematurely.
+A subsequent commit which rightsizes the CDAT response allocation closes
+that remaining loophole.
+
+The two lines introduced here which exceed 80 chars are shortened to
+less than 80 chars by a subsequent commit which migrates to a
+synchronous DOE API and replaces "t.task.rv" by "rc".
+
+The existing acpi_cdat_header and acpi_table_cdat struct definitions
+provided by ACPICA cannot be used because they do not employ __le16 or
+__le32 types.  I believe that cannot be changed because those types are
+Linux-specific and ACPI is specified for little endian platforms only,
+hence doesn't care about endianness.  So duplicate the structs.
+
+Fixes: c97006046c79 ("cxl/port: Read CDAT table")
+Tested-by: Ira Weiny <ira.weiny@intel.com>
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: stable@vger.kernel.org # v6.0+
+Link: https://lore.kernel.org/r/bce3aebc0e8e18a1173425a7a865b232c3912963.1678543498.git.lukas@wunner.de
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/cxl/core/pci.c |   13 +++++++++----
+ drivers/cxl/cxlpci.h   |   14 ++++++++++++++
+ 2 files changed, 23 insertions(+), 4 deletions(-)
+
+--- a/drivers/cxl/core/pci.c
++++ b/drivers/cxl/core/pci.c
+@@ -550,8 +550,8 @@ static int cxl_cdat_read_table(struct de
+       do {
+               DECLARE_CDAT_DOE_TASK(CDAT_DOE_REQ(entry_handle), t);
++              struct cdat_entry_header *entry;
+               size_t entry_dw;
+-              __le32 *entry;
+               int rc;
+               rc = pci_doe_submit_task(cdat_doe, &t.task);
+@@ -560,14 +560,19 @@ static int cxl_cdat_read_table(struct de
+                       return rc;
+               }
+               wait_for_completion(&t.c);
+-              /* 1 DW header + 1 DW data min */
+-              if (t.task.rv < (2 * sizeof(__le32)))
++
++              /* 1 DW Table Access Response Header + CDAT entry */
++              entry = (struct cdat_entry_header *)(t.response_pl + 1);
++              if ((entry_handle == 0 &&
++                   t.task.rv != sizeof(__le32) + sizeof(struct cdat_header)) ||
++                  (entry_handle > 0 &&
++                   (t.task.rv < sizeof(__le32) + sizeof(*entry) ||
++                    t.task.rv != sizeof(__le32) + le16_to_cpu(entry->length))))
+                       return -EIO;
+               /* Get the CXL table access header entry handle */
+               entry_handle = FIELD_GET(CXL_DOE_TABLE_ACCESS_ENTRY_HANDLE,
+                                        le32_to_cpu(t.response_pl[0]));
+-              entry = t.response_pl + 1;
+               entry_dw = t.task.rv / sizeof(__le32);
+               /* Skip Header */
+               entry_dw -= 1;
+--- a/drivers/cxl/cxlpci.h
++++ b/drivers/cxl/cxlpci.h
+@@ -71,6 +71,20 @@ static inline resource_size_t cxl_regmap
+       return pci_resource_start(pdev, map->barno) + map->block_offset;
+ }
++struct cdat_header {
++      __le32 length;
++      u8 revision;
++      u8 checksum;
++      u8 reserved[6];
++      __le32 sequence;
++} __packed;
++
++struct cdat_entry_header {
++      u8 type;
++      u8 reserved;
++      __le16 length;
++} __packed;
++
+ int devm_cxl_port_enumerate_dports(struct cxl_port *port);
+ struct cxl_dev_state;
+ int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm);
diff --git a/queue-6.1/cxl-pci-handle-truncated-cdat-header.patch b/queue-6.1/cxl-pci-handle-truncated-cdat-header.patch
new file mode 100644 (file)
index 0000000..d30cfc5
--- /dev/null
@@ -0,0 +1,43 @@
+From 34bafc747c54fb58c1908ec3116fa6137393e596 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Sat, 11 Mar 2023 15:40:02 +0100
+Subject: cxl/pci: Handle truncated CDAT header
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 34bafc747c54fb58c1908ec3116fa6137393e596 upstream.
+
+cxl_cdat_get_length() only checks whether the DOE response size is
+sufficient for the Table Access response header (1 dword), but not the
+succeeding CDAT header (1 dword length plus other fields).
+
+It thus returns whatever uninitialized memory happens to be on the stack
+if a truncated DOE response with only 1 dword was received.  Fix it.
+
+Fixes: c97006046c79 ("cxl/port: Read CDAT table")
+Reported-by: Ming Li <ming4.li@intel.com>
+Tested-by: Ira Weiny <ira.weiny@intel.com>
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Ming Li <ming4.li@intel.com>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: stable@vger.kernel.org # v6.0+
+Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Link: https://lore.kernel.org/r/000e69cd163461c8b1bc2cf4155b6e25402c29c7.1678543498.git.lukas@wunner.de
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/cxl/core/pci.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/cxl/core/pci.c
++++ b/drivers/cxl/core/pci.c
+@@ -531,7 +531,7 @@ static int cxl_cdat_get_length(struct de
+               return rc;
+       }
+       wait_for_completion(&t.c);
+-      if (t.task.rv < sizeof(__le32))
++      if (t.task.rv < 2 * sizeof(__le32))
+               return -EIO;
+       *length = le32_to_cpu(t.response_pl[1]);
diff --git a/queue-6.1/pci-doe-fix-memory-leak-with-config_debug_objects-y.patch b/queue-6.1/pci-doe-fix-memory-leak-with-config_debug_objects-y.patch
new file mode 100644 (file)
index 0000000..6e170ae
--- /dev/null
@@ -0,0 +1,43 @@
+From abf04be0e7071f2bcd39bf97ba407e7d4439785e Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Sat, 11 Mar 2023 15:40:06 +0100
+Subject: PCI/DOE: Fix memory leak with CONFIG_DEBUG_OBJECTS=y
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit abf04be0e7071f2bcd39bf97ba407e7d4439785e upstream.
+
+After a pci_doe_task completes, its work_struct needs to be destroyed
+to avoid a memory leak with CONFIG_DEBUG_OBJECTS=y.
+
+Fixes: 9d24322e887b ("PCI/DOE: Add DOE mailbox support functions")
+Tested-by: Ira Weiny <ira.weiny@intel.com>
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Ira Weiny <ira.weiny@intel.com>
+Reviewed-by: Davidlohr Bueso <dave@stgolabs.net>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: stable@vger.kernel.org # v6.0+
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>
+Link: https://lore.kernel.org/r/775768b4912531c3b887d405fc51a50e465e1bf9.1678543498.git.lukas@wunner.de
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/doe.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pci/doe.c b/drivers/pci/doe.c
+index c14ffdf23f87..e5e9b287b976 100644
+--- a/drivers/pci/doe.c
++++ b/drivers/pci/doe.c
+@@ -224,6 +224,7 @@ static void signal_task_complete(struct pci_doe_task *task, int rv)
+ {
+       task->rv = rv;
+       task->complete(task);
++      destroy_work_on_stack(&task->work);
+ }
+ static void signal_task_abort(struct pci_doe_task *task, int rv)
+-- 
+2.40.0
+
diff --git a/queue-6.1/pci-doe-silence-warn-splat-with-config_debug_objects-y.patch b/queue-6.1/pci-doe-silence-warn-splat-with-config_debug_objects-y.patch
new file mode 100644 (file)
index 0000000..5949215
--- /dev/null
@@ -0,0 +1,84 @@
+From 92dc899c3b4927f3cfa23f55bf759171234b5802 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Sat, 11 Mar 2023 15:40:05 +0100
+Subject: PCI/DOE: Silence WARN splat with CONFIG_DEBUG_OBJECTS=y
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 92dc899c3b4927f3cfa23f55bf759171234b5802 upstream.
+
+Gregory Price reports a WARN splat with CONFIG_DEBUG_OBJECTS=y upon CXL
+probing because pci_doe_submit_task() invokes INIT_WORK() instead of
+INIT_WORK_ONSTACK() for a work_struct that was allocated on the stack.
+
+All callers of pci_doe_submit_task() allocate the work_struct on the
+stack, so replace INIT_WORK() with INIT_WORK_ONSTACK() as a backportable
+short-term fix.
+
+The long-term fix implemented by a subsequent commit is to move to a
+synchronous API which allocates the work_struct internally in the DOE
+library.
+
+Stacktrace for posterity:
+
+WARNING: CPU: 0 PID: 23 at lib/debugobjects.c:545 __debug_object_init.cold+0x18/0x183
+CPU: 0 PID: 23 Comm: kworker/u2:1 Not tainted 6.1.0-0.rc1.20221019gitaae703b02f92.17.fc38.x86_64 #1
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
+Call Trace:
+ pci_doe_submit_task+0x5d/0xd0
+ pci_doe_discovery+0xb4/0x100
+ pcim_doe_create_mb+0x219/0x290
+ cxl_pci_probe+0x192/0x430
+ local_pci_probe+0x41/0x80
+ pci_device_probe+0xb3/0x220
+ really_probe+0xde/0x380
+ __driver_probe_device+0x78/0x170
+ driver_probe_device+0x1f/0x90
+ __driver_attach_async_helper+0x5c/0xe0
+ async_run_entry_fn+0x30/0x130
+ process_one_work+0x294/0x5b0
+
+Fixes: 9d24322e887b ("PCI/DOE: Add DOE mailbox support functions")
+Link: https://lore.kernel.org/linux-cxl/Y1bOniJliOFszvIK@memverge.com/
+Reported-by: Gregory Price <gregory.price@memverge.com>
+Tested-by: Ira Weiny <ira.weiny@intel.com>
+Tested-by: Gregory Price <gregory.price@memverge.com>
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Ira Weiny <ira.weiny@intel.com>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Reviewed-by: Gregory Price <gregory.price@memverge.com>
+Cc: stable@vger.kernel.org # v6.0+
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>
+Link: https://lore.kernel.org/r/67a9117f463ecdb38a2dbca6a20391ce2f1e7a06.1678543498.git.lukas@wunner.de
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/doe.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/doe.c b/drivers/pci/doe.c
+index 6f097932ccbf..c14ffdf23f87 100644
+--- a/drivers/pci/doe.c
++++ b/drivers/pci/doe.c
+@@ -523,6 +523,8 @@ EXPORT_SYMBOL_GPL(pci_doe_supports_prot);
+  * task->complete will be called when the state machine is done processing this
+  * task.
+  *
++ * @task must be allocated on the stack.
++ *
+  * Excess data will be discarded.
+  *
+  * RETURNS: 0 when task has been successfully queued, -ERRNO on error
+@@ -544,7 +546,7 @@ int pci_doe_submit_task(struct pci_doe_mb *doe_mb, struct pci_doe_task *task)
+               return -EIO;
+       task->doe_mb = doe_mb;
+-      INIT_WORK(&task->work, doe_statemachine_work);
++      INIT_WORK_ONSTACK(&task->work, doe_statemachine_work);
+       queue_work(doe_mb->work_queue, &task->work);
+       return 0;
+ }
+-- 
+2.40.0
+
index eda125275f687c28b847da24cf1caf6b580301e9..9b02fb73434f3b4ad03d837e3587e9b1450ae0fe 100644 (file)
@@ -53,3 +53,12 @@ netlink-annotate-lockless-accesses-to-nlk-max_recvms.patch
 gve-secure-enough-bytes-in-the-first-tx-desc-for-all.patch
 arm64-compat-work-around-uninitialized-variable-warn.patch
 net-stmmac-check-fwnode-for-phy-device-before-scanni.patch
+cxl-pci-fix-cdat-retrieval-on-big-endian.patch
+cxl-pci-handle-truncated-cdat-header.patch
+cxl-pci-handle-truncated-cdat-entries.patch
+cxl-pci-handle-excessive-cdat-length.patch
+pci-doe-silence-warn-splat-with-config_debug_objects-y.patch
+pci-doe-fix-memory-leak-with-config_debug_objects-y.patch
+usb-xhci-tegra-fix-sleep-in-atomic-call.patch
+xhci-free-the-command-allocated-for-setting-lpm-if-we-return-early.patch
+xhci-also-avoid-the-xhci_zero_64b_regs-quirk-with-a-passthrough-iommu.patch
diff --git a/queue-6.1/usb-xhci-tegra-fix-sleep-in-atomic-call.patch b/queue-6.1/usb-xhci-tegra-fix-sleep-in-atomic-call.patch
new file mode 100644 (file)
index 0000000..03b3c5e
--- /dev/null
@@ -0,0 +1,76 @@
+From 4c7f9d2e413dc06a157c4e5dccde84aaf4655eb3 Mon Sep 17 00:00:00 2001
+From: Wayne Chang <waynec@nvidia.com>
+Date: Mon, 27 Mar 2023 17:55:48 +0800
+Subject: usb: xhci: tegra: fix sleep in atomic call
+
+From: Wayne Chang <waynec@nvidia.com>
+
+commit 4c7f9d2e413dc06a157c4e5dccde84aaf4655eb3 upstream.
+
+When we set the dual-role port to Host mode, we observed the following
+splat:
+[  167.057718] BUG: sleeping function called from invalid context at
+include/linux/sched/mm.h:229
+[  167.057872] Workqueue: events tegra_xusb_usb_phy_work
+[  167.057954] Call trace:
+[  167.057962]  dump_backtrace+0x0/0x210
+[  167.057996]  show_stack+0x30/0x50
+[  167.058020]  dump_stack_lvl+0x64/0x84
+[  167.058065]  dump_stack+0x14/0x34
+[  167.058100]  __might_resched+0x144/0x180
+[  167.058140]  __might_sleep+0x64/0xd0
+[  167.058171]  slab_pre_alloc_hook.constprop.0+0xa8/0x110
+[  167.058202]  __kmalloc_track_caller+0x74/0x2b0
+[  167.058233]  kvasprintf+0xa4/0x190
+[  167.058261]  kasprintf+0x58/0x90
+[  167.058285]  tegra_xusb_find_port_node.isra.0+0x58/0xd0
+[  167.058334]  tegra_xusb_find_port+0x38/0xa0
+[  167.058380]  tegra_xusb_padctl_get_usb3_companion+0x38/0xd0
+[  167.058430]  tegra_xhci_id_notify+0x8c/0x1e0
+[  167.058473]  notifier_call_chain+0x88/0x100
+[  167.058506]  atomic_notifier_call_chain+0x44/0x70
+[  167.058537]  tegra_xusb_usb_phy_work+0x60/0xd0
+[  167.058581]  process_one_work+0x1dc/0x4c0
+[  167.058618]  worker_thread+0x54/0x410
+[  167.058650]  kthread+0x188/0x1b0
+[  167.058672]  ret_from_fork+0x10/0x20
+
+The function tegra_xusb_padctl_get_usb3_companion eventually calls
+tegra_xusb_find_port and this in turn calls kasprintf which might sleep
+and so cannot be called from an atomic context.
+
+Fix this by moving the call to tegra_xusb_padctl_get_usb3_companion to
+the tegra_xhci_id_work function where it is really needed.
+
+Fixes: f836e7843036 ("usb: xhci-tegra: Add OTG support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Wayne Chang <waynec@nvidia.com>
+Signed-off-by: Haotien Hsu <haotienh@nvidia.com>
+Link: https://lore.kernel.org/r/20230327095548.1599470-1-haotienh@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-tegra.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/xhci-tegra.c
++++ b/drivers/usb/host/xhci-tegra.c
+@@ -1225,6 +1225,9 @@ static void tegra_xhci_id_work(struct wo
+       mutex_unlock(&tegra->lock);
++      tegra->otg_usb3_port = tegra_xusb_padctl_get_usb3_companion(tegra->padctl,
++                                                                  tegra->otg_usb2_port);
++
+       if (tegra->host_mode) {
+               /* switch to host mode */
+               if (tegra->otg_usb3_port >= 0) {
+@@ -1339,9 +1342,6 @@ static int tegra_xhci_id_notify(struct n
+       }
+       tegra->otg_usb2_port = tegra_xusb_get_usb2_port(tegra, usbphy);
+-      tegra->otg_usb3_port = tegra_xusb_padctl_get_usb3_companion(
+-                                                      tegra->padctl,
+-                                                      tegra->otg_usb2_port);
+       tegra->host_mode = (usbphy->last_event == USB_EVENT_ID) ? true : false;
diff --git a/queue-6.1/xhci-also-avoid-the-xhci_zero_64b_regs-quirk-with-a-passthrough-iommu.patch b/queue-6.1/xhci-also-avoid-the-xhci_zero_64b_regs-quirk-with-a-passthrough-iommu.patch
new file mode 100644 (file)
index 0000000..f01609b
--- /dev/null
@@ -0,0 +1,56 @@
+From ecaa4902439298f6b0e29f47424a86b310a9ff4f Mon Sep 17 00:00:00 2001
+From: D Scott Phillips <scott@os.amperecomputing.com>
+Date: Thu, 30 Mar 2023 17:30:54 +0300
+Subject: xhci: also avoid the XHCI_ZERO_64B_REGS quirk with a passthrough iommu
+
+From: D Scott Phillips <scott@os.amperecomputing.com>
+
+commit ecaa4902439298f6b0e29f47424a86b310a9ff4f upstream.
+
+Previously the quirk was skipped when no iommu was present. The same
+rationale for skipping the quirk also applies in the iommu.passthrough=1
+case.
+
+Skip applying the XHCI_ZERO_64B_REGS quirk if the device's iommu domain is
+passthrough.
+
+Fixes: 12de0a35c996 ("xhci: Add quirk to zero 64bit registers on Renesas PCIe controllers")
+Cc: stable <stable@kernel.org>
+Signed-off-by: D Scott Phillips <scott@os.amperecomputing.com>
+Acked-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20230330143056.1390020-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -9,6 +9,7 @@
+  */
+ #include <linux/pci.h>
++#include <linux/iommu.h>
+ #include <linux/iopoll.h>
+ #include <linux/irq.h>
+ #include <linux/log2.h>
+@@ -228,6 +229,7 @@ int xhci_reset(struct xhci_hcd *xhci, u6
+ static void xhci_zero_64b_regs(struct xhci_hcd *xhci)
+ {
+       struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
++      struct iommu_domain *domain;
+       int err, i;
+       u64 val;
+       u32 intrs;
+@@ -246,7 +248,9 @@ static void xhci_zero_64b_regs(struct xh
+        * an iommu. Doing anything when there is no iommu is definitely
+        * unsafe...
+        */
+-      if (!(xhci->quirks & XHCI_ZERO_64B_REGS) || !device_iommu_mapped(dev))
++      domain = iommu_get_domain_for_dev(dev);
++      if (!(xhci->quirks & XHCI_ZERO_64B_REGS) || !domain ||
++          domain->type == IOMMU_DOMAIN_IDENTITY)
+               return;
+       xhci_info(xhci, "Zeroing 64bit base registers, expecting fault\n");
diff --git a/queue-6.1/xhci-free-the-command-allocated-for-setting-lpm-if-we-return-early.patch b/queue-6.1/xhci-free-the-command-allocated-for-setting-lpm-if-we-return-early.patch
new file mode 100644 (file)
index 0000000..7f537b3
--- /dev/null
@@ -0,0 +1,35 @@
+From f6caea4855553a8b99ba3ec23ecdb5ed8262f26c Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Thu, 30 Mar 2023 17:30:56 +0300
+Subject: xhci: Free the command allocated for setting LPM if we return early
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit f6caea4855553a8b99ba3ec23ecdb5ed8262f26c upstream.
+
+The command allocated to set exit latency LPM values need to be freed in
+case the command is never queued. This would be the case if there is no
+change in exit latency values, or device is missing.
+
+Reported-by: Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>
+Link: https://lore.kernel.org/linux-usb/24263902-c9b3-ce29-237b-1c3d6918f4fe@alu.unizg.hr
+Tested-by: Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>
+Fixes: 5c2a380a5aa8 ("xhci: Allocate separate command structures for each LPM command")
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20230330143056.1390020-4-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -4406,6 +4406,7 @@ static int __maybe_unused xhci_change_ma
+       if (!virt_dev || max_exit_latency == virt_dev->current_mel) {
+               spin_unlock_irqrestore(&xhci->lock, flags);
++              xhci_free_command(xhci, command);
+               return 0;
+       }