--- /dev/null
+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);
--- /dev/null
+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;
+ }
+
--- /dev/null
+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);
--- /dev/null
+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]);
--- /dev/null
+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
+
--- /dev/null
+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
+
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
--- /dev/null
+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;
+
--- /dev/null
+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");
--- /dev/null
+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;
+ }
+