Commit 88482878 authored by Dan Williams's avatar Dan Williams
Browse files

Merge branch 'for-6.9/cxl-fixes' into for-6.9/cxl

Pick up a parsing fix for the CDAT SSLBIS structure for v6.9.
parents 75f4d93e 99b52aac
Loading
Loading
Loading
Loading
+15 −15
Original line number Diff line number Diff line
@@ -398,36 +398,38 @@ EXPORT_SYMBOL_NS_GPL(cxl_endpoint_parse_cdat, CXL);
static int cdat_sslbis_handler(union acpi_subtable_headers *header, void *arg,
			       const unsigned long end)
{
	struct acpi_cdat_sslbis_table {
		struct acpi_cdat_header header;
		struct acpi_cdat_sslbis sslbis_header;
		struct acpi_cdat_sslbe entries[];
	} *tbl = (struct acpi_cdat_sslbis_table *)header;
	int size = sizeof(header->cdat) + sizeof(tbl->sslbis_header);
	struct acpi_cdat_sslbis *sslbis;
	int size = sizeof(header->cdat) + sizeof(*sslbis);
	struct cxl_port *port = arg;
	struct device *dev = &port->dev;
	struct acpi_cdat_sslbe *entry;
	int remain, entries, i;
	u16 len;

	len = le16_to_cpu((__force __le16)header->cdat.length);
	remain = len - size;
	if (!remain || remain % sizeof(*entry) ||
	if (!remain || remain % sizeof(tbl->entries[0]) ||
	    (unsigned long)header + len > end) {
		dev_warn(dev, "Malformed SSLBIS table length: (%u)\n", len);
		return -EINVAL;
	}

	/* Skip common header */
	sslbis = (struct acpi_cdat_sslbis *)((unsigned long)header +
					     sizeof(header->cdat));

	sslbis = &tbl->sslbis_header;
	/* Unrecognized data type, we can skip */
	if (sslbis->data_type > ACPI_HMAT_WRITE_BANDWIDTH)
		return 0;

	entries = remain / sizeof(*entry);
	entry = (struct acpi_cdat_sslbe *)((unsigned long)header + sizeof(*sslbis));
	entries = remain / sizeof(tbl->entries[0]);
	if (struct_size(tbl, entries, entries) != len)
		return -EINVAL;

	for (i = 0; i < entries; i++) {
		u16 x = le16_to_cpu((__force __le16)entry->portx_id);
		u16 y = le16_to_cpu((__force __le16)entry->porty_id);
		u16 x = le16_to_cpu((__force __le16)tbl->entries[i].portx_id);
		u16 y = le16_to_cpu((__force __le16)tbl->entries[i].porty_id);
		__le64 le_base;
		__le16 le_val;
		struct cxl_dport *dport;
@@ -457,8 +459,8 @@ static int cdat_sslbis_handler(union acpi_subtable_headers *header, void *arg,
			break;
		}

		le_base = (__force __le64)sslbis->entry_base_unit;
		le_val = (__force __le16)entry->latency_or_bandwidth;
		le_base = (__force __le64)tbl->sslbis_header.entry_base_unit;
		le_val = (__force __le16)tbl->entries[i].latency_or_bandwidth;

		if (check_mul_overflow(le64_to_cpu(le_base),
				       le16_to_cpu(le_val), &val))
@@ -471,8 +473,6 @@ static int cdat_sslbis_handler(union acpi_subtable_headers *header, void *arg,
							  sslbis->data_type,
							  val);
		}

		entry++;
	}

	return 0;