From: Sasha Levin Date: Fri, 10 Nov 2023 17:34:42 +0000 (-0500) Subject: Fixes for 6.6 X-Git-Tag: v4.14.330~71 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b8fee1f5b60d8bb8a1b17863f7ffe6f3c63c6c3a;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.6 Signed-off-by: Sasha Levin --- diff --git a/queue-6.6/9p-net-fix-possible-memory-leak-in-p9_check_errors.patch b/queue-6.6/9p-net-fix-possible-memory-leak-in-p9_check_errors.patch new file mode 100644 index 00000000000..1acee83ee5b --- /dev/null +++ b/queue-6.6/9p-net-fix-possible-memory-leak-in-p9_check_errors.patch @@ -0,0 +1,47 @@ +From 31b9b3f2b4f670b6d83b6897f6375dc30bf52bdd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Oct 2023 11:03:02 +0800 +Subject: 9p/net: fix possible memory leak in p9_check_errors() + +From: Hangyu Hua + +[ Upstream commit ce07087964208eee2ca2f9ee4a98f8b5d9027fe6 ] + +When p9pdu_readf() is called with "s?d" attribute, it allocates a pointer +that will store a string. But when p9pdu_readf() fails while handling "d" +then this pointer will not be freed in p9_check_errors(). + +Fixes: 51a87c552dfd ("9p: rework client code to use new protocol support functions") +Reviewed-by: Christian Schoenebeck +Signed-off-by: Hangyu Hua +Message-ID: <20231027030302.11927-1-hbh25y@gmail.com> +Signed-off-by: Dominique Martinet +Signed-off-by: Sasha Levin +--- + net/9p/client.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/9p/client.c b/net/9p/client.c +index 86bbc7147fc14..b0e7cb7e1a54a 100644 +--- a/net/9p/client.c ++++ b/net/9p/client.c +@@ -540,12 +540,14 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req) + return 0; + + if (!p9_is_proto_dotl(c)) { +- char *ename; ++ char *ename = NULL; + + err = p9pdu_readf(&req->rc, c->proto_version, "s?d", + &ename, &ecode); +- if (err) ++ if (err) { ++ kfree(ename); + goto out_err; ++ } + + if (p9_is_proto_dotu(c) && ecode < 512) + err = -ecode; +-- +2.42.0 + diff --git a/queue-6.6/accel-habanalabs-gaudi2-fix-incorrect-string-length-.patch b/queue-6.6/accel-habanalabs-gaudi2-fix-incorrect-string-length-.patch new file mode 100644 index 00000000000..9b943113449 --- /dev/null +++ b/queue-6.6/accel-habanalabs-gaudi2-fix-incorrect-string-length-.patch @@ -0,0 +1,48 @@ +From 3ca3c1b302ebed08fa72b14d1bddb0fe1a6abba1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 21:18:36 +0200 +Subject: accel/habanalabs/gaudi2: Fix incorrect string length computation in + gaudi2_psoc_razwi_get_engines() + +From: Christophe JAILLET + +[ Upstream commit 90f3de616259cbb5666f00f8daf5420cd7d71d18 ] + +snprintf() returns the "number of characters which *would* be generated for +the given input", not the size *really* generated. + +In order to avoid too large values for 'str_size' (and potential negative +values for "PSOC_RAZWI_ENG_STR_SIZE - str_size") use scnprintf() +instead of snprintf(). + +Fixes: c0e6df916050 ("accel/habanalabs: fix address decode RAZWI handling") +Signed-off-by: Christophe JAILLET +Reviewed-by: Stanislaw Gruszka +Reviewed-by: Oded Gabbay +Signed-off-by: Oded Gabbay +Signed-off-by: Sasha Levin +--- + drivers/accel/habanalabs/gaudi2/gaudi2.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/accel/habanalabs/gaudi2/gaudi2.c b/drivers/accel/habanalabs/gaudi2/gaudi2.c +index 20c4583f12b0d..31c74ca70a2e5 100644 +--- a/drivers/accel/habanalabs/gaudi2/gaudi2.c ++++ b/drivers/accel/habanalabs/gaudi2/gaudi2.c +@@ -8149,11 +8149,11 @@ static int gaudi2_psoc_razwi_get_engines(struct gaudi2_razwi_info *razwi_info, u + eng_id[num_of_eng] = razwi_info[i].eng_id; + base[num_of_eng] = razwi_info[i].rtr_ctrl; + if (!num_of_eng) +- str_size += snprintf(eng_name + str_size, ++ str_size += scnprintf(eng_name + str_size, + PSOC_RAZWI_ENG_STR_SIZE - str_size, "%s", + razwi_info[i].eng_name); + else +- str_size += snprintf(eng_name + str_size, ++ str_size += scnprintf(eng_name + str_size, + PSOC_RAZWI_ENG_STR_SIZE - str_size, " or %s", + razwi_info[i].eng_name); + num_of_eng++; +-- +2.42.0 + diff --git a/queue-6.6/acpi-numa-apply-srat-proximity-domain-to-entire-cfmw.patch b/queue-6.6/acpi-numa-apply-srat-proximity-domain-to-entire-cfmw.patch new file mode 100644 index 00000000000..d8244eb7dee --- /dev/null +++ b/queue-6.6/acpi-numa-apply-srat-proximity-domain-to-entire-cfmw.patch @@ -0,0 +1,73 @@ +From 28b8e1c75603cb0c49f3d626d6460c5cebe15712 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Jul 2023 13:02:59 -0700 +Subject: ACPI/NUMA: Apply SRAT proximity domain to entire CFMWS window + +From: Alison Schofield + +[ Upstream commit 8f1004679987302b155f14b966ca6d4335814fcb ] + +Commit fd49f99c1809 ("ACPI: NUMA: Add a node and memblk for each +CFMWS not in SRAT") did not account for the case where the BIOS +only partially describes a CFMWS Window in the SRAT. That means +the omitted address ranges, of a partially described CFMWS Window, +do not get assigned to a NUMA node. + +Replace the call to phys_to_target_node() with numa_add_memblks(). +Numa_add_memblks() searches an HPA range for existing memblk(s) +and extends those memblk(s) to fill the entire CFMWS Window. + +Extending the existing memblks is a simple strategy that reuses +SRAT defined proximity domains from part of a window to fill out +the entire window, based on the knowledge* that all of a CFMWS +window is of a similar performance class. + +*Note that this heuristic will evolve when CFMWS Windows present +a wider range of characteristics. The extension of the proximity +domain, implemented here, is likely a step in developing a more +sophisticated performance profile in the future. + +There is no change in behavior when the SRAT does not describe +the CFMWS Window at all. In that case, a new NUMA node with a +single memblk covering the entire CFMWS Window is created. + +Fixes: fd49f99c1809 ("ACPI: NUMA: Add a node and memblk for each CFMWS not in SRAT") +Reported-by: Derick Marks +Suggested-by: Dan Williams +Signed-off-by: Alison Schofield +Signed-off-by: Dave Hansen +Reviewed-by: Dan Williams +Tested-by: Derick Marks +Link: https://lore.kernel.org/all/eaa0b7cffb0951a126223eef3cbe7b55b8300ad9.1689018477.git.alison.schofield%40intel.com +Signed-off-by: Sasha Levin +--- + drivers/acpi/numa/srat.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c +index 1f4fc5f8a819d..12f330b0eac01 100644 +--- a/drivers/acpi/numa/srat.c ++++ b/drivers/acpi/numa/srat.c +@@ -310,11 +310,16 @@ static int __init acpi_parse_cfmws(union acpi_subtable_headers *header, + start = cfmws->base_hpa; + end = cfmws->base_hpa + cfmws->window_size; + +- /* Skip if the SRAT already described the NUMA details for this HPA */ +- node = phys_to_target_node(start); +- if (node != NUMA_NO_NODE) ++ /* ++ * The SRAT may have already described NUMA details for all, ++ * or a portion of, this CFMWS HPA range. Extend the memblks ++ * found for any portion of the window to cover the entire ++ * window. ++ */ ++ if (!numa_fill_memblks(start, end)) + return 0; + ++ /* No SRAT description. Create a new node. */ + node = acpi_map_pxm_to_node(*fake_pxm); + + if (node == NUMA_NO_NODE) { +-- +2.42.0 + diff --git a/queue-6.6/acpi-property-allow-_dsd-buffer-data-only-for-byte-a.patch b/queue-6.6/acpi-property-allow-_dsd-buffer-data-only-for-byte-a.patch new file mode 100644 index 00000000000..861e52deab5 --- /dev/null +++ b/queue-6.6/acpi-property-allow-_dsd-buffer-data-only-for-byte-a.patch @@ -0,0 +1,70 @@ +From e9f6aa28ae35d7413d265cd29c83f3e6533de27c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Oct 2023 16:46:29 +0300 +Subject: ACPI: property: Allow _DSD buffer data only for byte accessors + +From: Andy Shevchenko + +[ Upstream commit 046ece773cc77ef5d2a1431b188ac3d0840ed150 ] + +In accordance with ACPI specificication and _DSD data buffer +representation the data there is an array of bytes. Hence, +accessing it with something longer will create a sparse data +which is against of how device property APIs work in general +and also not defined in the ACPI specification (see [1]). +Fix the code to emit an error if non-byte accessor is used to +retrieve _DSD buffer data. + +Fixes: 369af6bf2c28 ("ACPI: property: Read buffer properties as integers") +Link: https://uefi.org/specs/ACPI/6.5/19_ASL_Reference.html#buffer-declare-buffer-object # [1] +Signed-off-by: Andy Shevchenko +[ rjw: Add missing braces ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/property.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index 413e4fcadcaf7..99b4e33554355 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1102,25 +1102,26 @@ static int acpi_data_prop_read(const struct acpi_device_data *data, + switch (proptype) { + case DEV_PROP_STRING: + break; +- case DEV_PROP_U8 ... DEV_PROP_U64: ++ default: + if (obj->type == ACPI_TYPE_BUFFER) { + if (nval > obj->buffer.length) + return -EOVERFLOW; +- break; ++ } else { ++ if (nval > obj->package.count) ++ return -EOVERFLOW; + } +- fallthrough; +- default: +- if (nval > obj->package.count) +- return -EOVERFLOW; + break; + } + if (nval == 0) + return -EINVAL; + +- if (obj->type != ACPI_TYPE_BUFFER) +- items = obj->package.elements; +- else ++ if (obj->type == ACPI_TYPE_BUFFER) { ++ if (proptype != DEV_PROP_U8) ++ return -EPROTO; + items = obj; ++ } else { ++ items = obj->package.elements; ++ } + + switch (proptype) { + case DEV_PROP_U8: +-- +2.42.0 + diff --git a/queue-6.6/acpi-sysfs-fix-create_pnp_modalias-and-create_of_mod.patch b/queue-6.6/acpi-sysfs-fix-create_pnp_modalias-and-create_of_mod.patch new file mode 100644 index 00000000000..de8b9ec219d --- /dev/null +++ b/queue-6.6/acpi-sysfs-fix-create_pnp_modalias-and-create_of_mod.patch @@ -0,0 +1,62 @@ +From acbd1c006fb2edcb51f7f873ea53399b6c2e7ed2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Oct 2023 20:32:54 +0200 +Subject: ACPI: sysfs: Fix create_pnp_modalias() and create_of_modalias() + +From: Christophe JAILLET + +[ Upstream commit 48cf49d31994ff97b33c4044e618560ec84d35fb ] + +snprintf() does not return negative values on error. + +To know if the buffer was too small, the returned value needs to be +compared with the length of the passed buffer. If it is greater or +equal, the output has been truncated, so add checks for the truncation +to create_pnp_modalias() and create_of_modalias(). Also make them +return -ENOMEM in that case, as they already do that elsewhere. + +Moreover, the remaining size of the buffer used by snprintf() needs to +be updated after the first write to avoid out-of-bounds access as +already done correctly in create_pnp_modalias(), but not in +create_of_modalias(), so change the latter accordingly. + +Fixes: 8765c5ba1949 ("ACPI / scan: Rework modalias creation when "compatible" is present") +Signed-off-by: Christophe JAILLET +[ rjw: Merge two patches into one, combine changelogs, add subject ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/device_sysfs.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c +index b9bbf07461992..a34d8578b3da6 100644 +--- a/drivers/acpi/device_sysfs.c ++++ b/drivers/acpi/device_sysfs.c +@@ -158,8 +158,8 @@ static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalia + return 0; + + len = snprintf(modalias, size, "acpi:"); +- if (len <= 0) +- return len; ++ if (len >= size) ++ return -ENOMEM; + + size -= len; + +@@ -212,8 +212,10 @@ static int create_of_modalias(const struct acpi_device *acpi_dev, char *modalias + len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer); + ACPI_FREE(buf.pointer); + +- if (len <= 0) +- return len; ++ if (len >= size) ++ return -ENOMEM; ++ ++ size -= len; + + of_compatible = acpi_dev->data.of_compatible; + if (of_compatible->type == ACPI_TYPE_PACKAGE) { +-- +2.42.0 + diff --git a/queue-6.6/acpi-video-add-acpi_backlight-vendor-quirk-for-toshi.patch b/queue-6.6/acpi-video-add-acpi_backlight-vendor-quirk-for-toshi.patch new file mode 100644 index 00000000000..7142b9f5bf9 --- /dev/null +++ b/queue-6.6/acpi-video-add-acpi_backlight-vendor-quirk-for-toshi.patch @@ -0,0 +1,77 @@ +From 8492491eefbbdfd070f436f4b91c451a8b2b01a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 22:20:55 +0200 +Subject: =?UTF-8?q?ACPI:=20video:=20Add=20acpi=5Fbacklight=3Dvendor=20quir?= + =?UTF-8?q?k=20for=20Toshiba=20Port=C3=A9g=C3=A9=20R100?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ondrej Zary + +[ Upstream commit 35a341c9b25da6a479bd8013bcb11a680a7233e3 ] + +Toshiba Portégé R100 has both acpi_video and toshiba_acpi vendor +backlight driver working. But none of them gets activated as it has +a VGA with no kernel driver (Trident CyberBlade XP4m32). + +The DMI strings are very generic ("Portable PC") so add a custom +callback function to check for Trident CyberBlade XP4m32 PCI device +before enabling the vendor backlight driver (better than acpi_video +as it has more brightness steps). + +Fixes: 5aa9d943e9b6 ("ACPI: video: Don't enable fallback path for creating ACPI backlight by default") +Signed-off-by: Ondrej Zary +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/video_detect.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c +index 442396f6ed1f9..31205fee59d4a 100644 +--- a/drivers/acpi/video_detect.c ++++ b/drivers/acpi/video_detect.c +@@ -130,6 +130,16 @@ static int video_detect_force_native(const struct dmi_system_id *d) + return 0; + } + ++static int video_detect_portege_r100(const struct dmi_system_id *d) ++{ ++ struct pci_dev *dev; ++ /* Search for Trident CyberBlade XP4m32 to confirm Portégé R100 */ ++ dev = pci_get_device(PCI_VENDOR_ID_TRIDENT, 0x2100, NULL); ++ if (dev) ++ acpi_backlight_dmi = acpi_backlight_vendor; ++ return 0; ++} ++ + static const struct dmi_system_id video_detect_dmi_table[] = { + /* + * Models which should use the vendor backlight interface, +@@ -270,6 +280,22 @@ static const struct dmi_system_id video_detect_dmi_table[] = { + }, + }, + ++ /* ++ * Toshiba Portégé R100 has working both acpi_video and toshiba_acpi ++ * vendor driver. But none of them gets activated as it has a VGA with ++ * no kernel driver (Trident CyberBlade XP4m32). ++ * The DMI strings are generic so check for the VGA chip in callback. ++ */ ++ { ++ .callback = video_detect_portege_r100, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Version 1.0"), ++ DMI_MATCH(DMI_BOARD_NAME, "Portable PC") ++ }, ++ }, ++ + /* + * Models which need acpi_video backlight control where the GPU drivers + * do not call acpi_video_register_backlight() because no internal panel +-- +2.42.0 + diff --git a/queue-6.6/alsa-hda-cs35l41-fix-unbalanced-pm_runtime_get.patch b/queue-6.6/alsa-hda-cs35l41-fix-unbalanced-pm_runtime_get.patch new file mode 100644 index 00000000000..1eda7e091e4 --- /dev/null +++ b/queue-6.6/alsa-hda-cs35l41-fix-unbalanced-pm_runtime_get.patch @@ -0,0 +1,42 @@ +From 74ae639772777655a17765737e639ec6c16d3598 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 20:10:08 +0300 +Subject: ALSA: hda: cs35l41: Fix unbalanced pm_runtime_get() + +From: Cristian Ciocaltea + +[ Upstream commit 486465508f8a5fe441939a7d97607f4460a60891 ] + +If component_add() fails, probe() returns without calling +pm_runtime_put(), which leaves the runtime PM usage counter incremented. + +Fix the issue by jumping to err_pm label and drop the now unnecessary +pm_runtime_disable() call. + +Fixes: 7b2f3eb492da ("ALSA: hda: cs35l41: Add support for CS35L41 in HDA systems") +Signed-off-by: Cristian Ciocaltea +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/20230907171010.1447274-10-cristian.ciocaltea@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/pci/hda/cs35l41_hda.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index 055ebfc237352..ebf9ddbb26052 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -1668,8 +1668,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + ret = component_add(cs35l41->dev, &cs35l41_hda_comp_ops); + if (ret) { + dev_err(cs35l41->dev, "Register component failed: %d\n", ret); +- pm_runtime_disable(cs35l41->dev); +- goto err; ++ goto err_pm; + } + + dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n", regid, reg_revid); +-- +2.42.0 + diff --git a/queue-6.6/alsa-hda-cs35l41-undo-runtime-pm-changes-at-driver-e.patch b/queue-6.6/alsa-hda-cs35l41-undo-runtime-pm-changes-at-driver-e.patch new file mode 100644 index 00000000000..40c2f15b7fb --- /dev/null +++ b/queue-6.6/alsa-hda-cs35l41-undo-runtime-pm-changes-at-driver-e.patch @@ -0,0 +1,48 @@ +From 1aba14d8e98831b981932a4da6639d477204a233 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 20:10:09 +0300 +Subject: ALSA: hda: cs35l41: Undo runtime PM changes at driver exit time + +From: Cristian Ciocaltea + +[ Upstream commit 85a1bf86fac0c195929768b4e92c78cad107523b ] + +According to the documentation, drivers are responsible for undoing at +removal time all runtime PM changes done during probing. + +Hence, add the missing calls to pm_runtime_dont_use_autosuspend(), which +are necessary for undoing pm_runtime_use_autosuspend(). + +Fixes: 1873ebd30cc8 ("ALSA: hda: cs35l41: Support Hibernation during Suspend") +Signed-off-by: Cristian Ciocaltea +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/20230907171010.1447274-11-cristian.ciocaltea@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/pci/hda/cs35l41_hda.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index ebf9ddbb26052..3c157b006a5a2 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -1676,6 +1676,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i + return 0; + + err_pm: ++ pm_runtime_dont_use_autosuspend(cs35l41->dev); + pm_runtime_disable(cs35l41->dev); + pm_runtime_put_noidle(cs35l41->dev); + +@@ -1694,6 +1695,7 @@ void cs35l41_hda_remove(struct device *dev) + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + + pm_runtime_get_sync(cs35l41->dev); ++ pm_runtime_dont_use_autosuspend(cs35l41->dev); + pm_runtime_disable(cs35l41->dev); + + if (cs35l41->halo_initialized) +-- +2.42.0 + diff --git a/queue-6.6/apparmor-fix-invalid-reference-on-profile-disconnect.patch b/queue-6.6/apparmor-fix-invalid-reference-on-profile-disconnect.patch new file mode 100644 index 00000000000..4844cdd2011 --- /dev/null +++ b/queue-6.6/apparmor-fix-invalid-reference-on-profile-disconnect.patch @@ -0,0 +1,60 @@ +From a8589a5ee2ea99cca3704a6a35c1ab9555818363 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Aug 2023 15:37:24 -0300 +Subject: apparmor: fix invalid reference on profile->disconnected + +From: Georgia Garcia + +[ Upstream commit 8884ba07786c718771cf7b78cb3024924b27ec2b ] + +profile->disconnected was storing an invalid reference to the +disconnected path. Fix it by duplicating the string using +aa_unpack_strdup and freeing accordingly. + +Fixes: 72c8a768641d ("apparmor: allow profiles to provide info to disconnected paths") +Signed-off-by: Georgia Garcia +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/policy.c | 1 + + security/apparmor/policy_unpack.c | 5 +++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c +index b38f7b2a5e1d5..ec695a6caac7d 100644 +--- a/security/apparmor/policy.c ++++ b/security/apparmor/policy.c +@@ -255,6 +255,7 @@ void aa_free_profile(struct aa_profile *profile) + + aa_put_ns(profile->ns); + kfree_sensitive(profile->rename); ++ kfree_sensitive(profile->disconnected); + + free_attachment(&profile->attach); + +diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c +index 8b8846073e142..b49201306753c 100644 +--- a/security/apparmor/policy_unpack.c ++++ b/security/apparmor/policy_unpack.c +@@ -807,7 +807,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) + const char *info = "failed to unpack profile"; + size_t ns_len; + struct rhashtable_params params = { 0 }; +- char *key = NULL; ++ char *key = NULL, *disconnected = NULL; + struct aa_data *data; + int error = -EPROTO; + kernel_cap_t tmpcap; +@@ -873,7 +873,8 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) + } + + /* disconnected attachment string is optional */ +- (void) aa_unpack_str(e, &profile->disconnected, "disconnected"); ++ (void) aa_unpack_strdup(e, &disconnected, "disconnected"); ++ profile->disconnected = disconnected; + + /* per profile debug flags (complain, audit) */ + if (!aa_unpack_nameX(e, AA_STRUCT, "flags")) { +-- +2.42.0 + diff --git a/queue-6.6/arm-9321-1-memset-cast-the-constant-byte-to-unsigned.patch b/queue-6.6/arm-9321-1-memset-cast-the-constant-byte-to-unsigned.patch new file mode 100644 index 00000000000..14c4bb8ddb5 --- /dev/null +++ b/queue-6.6/arm-9321-1-memset-cast-the-constant-byte-to-unsigned.patch @@ -0,0 +1,63 @@ +From bfed07efe398aa430716a7e88b1040b60ad06ec7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Aug 2023 15:06:06 +0100 +Subject: ARM: 9321/1: memset: cast the constant byte to unsigned char + +From: Kursad Oney + +[ Upstream commit c0e824661f443b8cab3897006c1bbc69fd0e7bc4 ] + +memset() description in ISO/IEC 9899:1999 (and elsewhere) says: + + The memset function copies the value of c (converted to an + unsigned char) into each of the first n characters of the + object pointed to by s. + +The kernel's arm32 memset does not cast c to unsigned char. This results +in the following code to produce erroneous output: + + char a[128]; + memset(a, -128, sizeof(a)); + +This is because gcc will generally emit the following code before +it calls memset() : + + mov r0, r7 + mvn r1, #127 ; 0x7f + bl 00000000 + +r1 ends up with 0xffffff80 before being used by memset() and the +'a' array will have -128 once in every four bytes while the other +bytes will be set incorrectly to -1 like this (printing the first +8 bytes) : + + test_module: -128 -1 -1 -1 + test_module: -1 -1 -1 -128 + +The change here is to 'and' r1 with 255 before it is used. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reviewed-by: Ard Biesheuvel +Reviewed-by: Linus Walleij +Signed-off-by: Kursad Oney +Signed-off-by: Russell King (Oracle) +Signed-off-by: Sasha Levin +--- + arch/arm/lib/memset.S | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S +index d71ab61430b26..de75ae4d5ab41 100644 +--- a/arch/arm/lib/memset.S ++++ b/arch/arm/lib/memset.S +@@ -17,6 +17,7 @@ ENTRY(__memset) + ENTRY(mmioset) + WEAK(memset) + UNWIND( .fnstart ) ++ and r1, r1, #255 @ cast to unsigned char + ands r3, r0, #3 @ 1 unaligned? + mov ip, r0 @ preserve r0 as return value + bne 6f @ 1 +-- +2.42.0 + diff --git a/queue-6.6/arm-9323-1-mm-fix-arch_low_address_limit-when-config.patch b/queue-6.6/arm-9323-1-mm-fix-arch_low_address_limit-when-config.patch new file mode 100644 index 00000000000..706d948446f --- /dev/null +++ b/queue-6.6/arm-9323-1-mm-fix-arch_low_address_limit-when-config.patch @@ -0,0 +1,43 @@ +From 8eb5a24e25cb84ec5b7eaba79f52f9af68d79859 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 22:40:12 +0100 +Subject: ARM: 9323/1: mm: Fix ARCH_LOW_ADDRESS_LIMIT when CONFIG_ZONE_DMA + +From: wahrenst + +[ Upstream commit 399da29ff5eb3f675c71423bec4cf2208f218576 ] + +Configuring VMSPLIT_2G + LPAE on Raspberry Pi 4 leads to SWIOTLB +buffer allocation beyond platform dma_zone_size of SZ_1G, which +results in broken SD card boot. + +So fix this be setting ARCH_LOW_ADDRESS_LIMIT in CONFIG_ZONE_DMA +case. + +Suggested-by: Russell King +Fixes: e9faf9b0b07a ("ARM: add multi_v7_lpae_defconfig") +Signed-off-by: Stefan Wahren +Reviewed-by: Arnd Bergmann +Signed-off-by: Russell King (Oracle) +Signed-off-by: Sasha Levin +--- + arch/arm/include/asm/dma.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h +index c6aded1b069cf..e2a1916013e75 100644 +--- a/arch/arm/include/asm/dma.h ++++ b/arch/arm/include/asm/dma.h +@@ -12,6 +12,9 @@ + extern phys_addr_t arm_dma_zone_size; \ + arm_dma_zone_size && arm_dma_zone_size < (0x100000000ULL - PAGE_OFFSET) ? \ + (PAGE_OFFSET + arm_dma_zone_size) : 0xffffffffUL; }) ++ ++extern phys_addr_t arm_dma_limit; ++#define ARCH_LOW_ADDRESS_LIMIT arm_dma_limit + #endif + + #ifdef CONFIG_ISA_DMA_API +-- +2.42.0 + diff --git a/queue-6.6/arm-dts-am3517-evm-fix-led3-4-pinmux.patch b/queue-6.6/arm-dts-am3517-evm-fix-led3-4-pinmux.patch new file mode 100644 index 00000000000..8de28ed3b1f --- /dev/null +++ b/queue-6.6/arm-dts-am3517-evm-fix-led3-4-pinmux.patch @@ -0,0 +1,57 @@ +From dc9fffdf06ebffa7b642c16bae627f5fbb38c709 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 19:04:01 -0500 +Subject: ARM: dts: am3517-evm: Fix LED3/4 pinmux + +From: Adam Ford + +[ Upstream commit 2ab6b437c65233f06bdd2988fd5913baeca5f159 ] + +The pinmux for LED3 and LED4 are incorrectly attached to the +omap3_pmx_core when they should be connected to the omap3_pmx_wkup +pin mux. This was likely masked by the fact that the bootloader +used to do all the pinmuxing. + +Fixes: 0dbf99542caf ("ARM: dts: am3517-evm: Add User LEDs and Pushbutton") +Signed-off-by: Adam Ford +Message-ID: <20231005000402.50879-1-aford173@gmail.com> +Signed-off-by: Tony Lindgren +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/ti/omap/am3517-evm.dts | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/arch/arm/boot/dts/ti/omap/am3517-evm.dts b/arch/arm/boot/dts/ti/omap/am3517-evm.dts +index af9df15274bed..866f68c5b504d 100644 +--- a/arch/arm/boot/dts/ti/omap/am3517-evm.dts ++++ b/arch/arm/boot/dts/ti/omap/am3517-evm.dts +@@ -271,13 +271,6 @@ OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */ + >; + }; + +- leds_pins: leds-pins { +- pinctrl-single,pins = < +- OMAP3_WKUP_IOPAD(0x2a24, PIN_OUTPUT_PULLUP | MUX_MODE4) /* jtag_emu0.gpio_11 */ +- OMAP3_WKUP_IOPAD(0x2a26, PIN_OUTPUT_PULLUP | MUX_MODE4) /* jtag_emu1.gpio_31 */ +- >; +- }; +- + mmc1_pins: mmc1-pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */ +@@ -355,3 +348,12 @@ OMAP3430_CORE2_IOPAD(0x25e2, PIN_INPUT | MUX_MODE3) /* etk_d3.hsusb1_data7 */ + >; + }; + }; ++ ++&omap3_pmx_wkup { ++ leds_pins: leds-pins { ++ pinctrl-single,pins = < ++ OMAP3_WKUP_IOPAD(0x2a24, PIN_OUTPUT_PULLUP | MUX_MODE4) /* jtag_emu0.gpio_11 */ ++ OMAP3_WKUP_IOPAD(0x2a26, PIN_OUTPUT_PULLUP | MUX_MODE4) /* jtag_emu1.gpio_31 */ ++ >; ++ }; ++}; +-- +2.42.0 + diff --git a/queue-6.6/arm-dts-bcm5301x-explicitly-disable-unused-switch-cp.patch b/queue-6.6/arm-dts-bcm5301x-explicitly-disable-unused-switch-cp.patch new file mode 100644 index 00000000000..f8dfc60832a --- /dev/null +++ b/queue-6.6/arm-dts-bcm5301x-explicitly-disable-unused-switch-cp.patch @@ -0,0 +1,424 @@ +From aaaa77b6fb1241bb1b77e1496bda6b44306a4392 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Oct 2023 12:33:13 +0200 +Subject: ARM: dts: BCM5301X: Explicitly disable unused switch CPU ports +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rafał Miłecki + +[ Upstream commit 473baeab929444295b0530f8766e4becb6a08973 ] + +When redescribing ports I assumed that missing "label" (like "cpu") +means switch port isn't used. That was incorrect and I realized my +change made Linux always use the first (5) CPU port (there are 3 of +them). + +While above should technically be possible it often isn't correct: +1. Non-default switch ports are often connected to Ethernet interfaces + not fully covered by vendor setup (they may miss MACs) +2. On some devices non-default ports require specifying fixed link + +This fixes network connectivity for some devices. It was reported & +tested for Netgear R8000. It also affects Linksys EA9200 with its +downstream DTS. + +Fixes: ba4aebce23b2 ("ARM: dts: BCM5301X: Describe switch ports in the main DTS") +Signed-off-by: Rafał Miłecki +Link: https://lore.kernel.org/r/20231013103314.10306-1-zajec5@gmail.com +Signed-off-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + .../dts/broadcom/bcm4708-buffalo-wzr-1166dhp-common.dtsi | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm4708-luxul-xap-1510.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm4708-luxul-xwc-1000.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm4708-netgear-r6250.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm4708-smartrg-sr400ac.dts | 8 ++++++++ + .../boot/dts/broadcom/bcm47081-buffalo-wzr-600dhp2.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm47081-luxul-xap-1410.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm47081-luxul-xwr-1200.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm47094-luxul-abr-4500.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm47094-luxul-xap-1610.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm47094-luxul-xbr-4500.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm47094-luxul-xwc-2000.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3100.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3150-v1.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm53015-meraki-mr26.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm53016-meraki-mr32.dts | 8 ++++++++ + arch/arm/boot/dts/broadcom/bcm953012er.dts | 8 ++++++++ + 20 files changed, 160 insertions(+) + +diff --git a/arch/arm/boot/dts/broadcom/bcm4708-buffalo-wzr-1166dhp-common.dtsi b/arch/arm/boot/dts/broadcom/bcm4708-buffalo-wzr-1166dhp-common.dtsi +index 42bcbf10957c4..9f9084269ef58 100644 +--- a/arch/arm/boot/dts/broadcom/bcm4708-buffalo-wzr-1166dhp-common.dtsi ++++ b/arch/arm/boot/dts/broadcom/bcm4708-buffalo-wzr-1166dhp-common.dtsi +@@ -181,5 +181,13 @@ port@4 { + port@5 { + label = "cpu"; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/broadcom/bcm4708-luxul-xap-1510.dts b/arch/arm/boot/dts/broadcom/bcm4708-luxul-xap-1510.dts +index e04d2e5ea51aa..72e960c888ac8 100644 +--- a/arch/arm/boot/dts/broadcom/bcm4708-luxul-xap-1510.dts ++++ b/arch/arm/boot/dts/broadcom/bcm4708-luxul-xap-1510.dts +@@ -85,5 +85,13 @@ port@4 { + port@5 { + label = "cpu"; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/broadcom/bcm4708-luxul-xwc-1000.dts b/arch/arm/boot/dts/broadcom/bcm4708-luxul-xwc-1000.dts +index a399800139d9c..750e17482371c 100644 +--- a/arch/arm/boot/dts/broadcom/bcm4708-luxul-xwc-1000.dts ++++ b/arch/arm/boot/dts/broadcom/bcm4708-luxul-xwc-1000.dts +@@ -88,5 +88,13 @@ port@4 { + port@5 { + label = "cpu"; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/broadcom/bcm4708-netgear-r6250.dts b/arch/arm/boot/dts/broadcom/bcm4708-netgear-r6250.dts +index fad3473810a2e..2bdbc7d18b0eb 100644 +--- a/arch/arm/boot/dts/broadcom/bcm4708-netgear-r6250.dts ++++ b/arch/arm/boot/dts/broadcom/bcm4708-netgear-r6250.dts +@@ -122,5 +122,13 @@ port@4 { + port@5 { + label = "cpu"; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/broadcom/bcm4708-smartrg-sr400ac.dts b/arch/arm/boot/dts/broadcom/bcm4708-smartrg-sr400ac.dts +index 5b2b7b8b3b123..b226bef3369cf 100644 +--- a/arch/arm/boot/dts/broadcom/bcm4708-smartrg-sr400ac.dts ++++ b/arch/arm/boot/dts/broadcom/bcm4708-smartrg-sr400ac.dts +@@ -145,6 +145,14 @@ port@4 { + port@5 { + label = "cpu"; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; + +diff --git a/arch/arm/boot/dts/broadcom/bcm47081-buffalo-wzr-600dhp2.dts b/arch/arm/boot/dts/broadcom/bcm47081-buffalo-wzr-600dhp2.dts +index d0a26b643b82f..192b8db5a89c3 100644 +--- a/arch/arm/boot/dts/broadcom/bcm47081-buffalo-wzr-600dhp2.dts ++++ b/arch/arm/boot/dts/broadcom/bcm47081-buffalo-wzr-600dhp2.dts +@@ -145,5 +145,13 @@ port@4 { + port@5 { + label = "cpu"; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/broadcom/bcm47081-luxul-xap-1410.dts b/arch/arm/boot/dts/broadcom/bcm47081-luxul-xap-1410.dts +index 9f21d6d6d35b7..0198b5f9e4a75 100644 +--- a/arch/arm/boot/dts/broadcom/bcm47081-luxul-xap-1410.dts ++++ b/arch/arm/boot/dts/broadcom/bcm47081-luxul-xap-1410.dts +@@ -81,5 +81,13 @@ port@4 { + port@5 { + label = "cpu"; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/broadcom/bcm47081-luxul-xwr-1200.dts b/arch/arm/boot/dts/broadcom/bcm47081-luxul-xwr-1200.dts +index 2561072917021..73ff1694a4a0b 100644 +--- a/arch/arm/boot/dts/broadcom/bcm47081-luxul-xwr-1200.dts ++++ b/arch/arm/boot/dts/broadcom/bcm47081-luxul-xwr-1200.dts +@@ -148,5 +148,13 @@ port@4 { + port@5 { + label = "cpu"; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts b/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts +index 707c561703ed8..55fc9f44cbc7f 100644 +--- a/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts ++++ b/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts +@@ -227,6 +227,14 @@ port@4 { + label = "wan"; + }; + ++ port@5 { ++ status = "disabled"; ++ }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ + port@8 { + label = "cpu"; + }; +diff --git a/arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts b/arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts +index c914569ddd5ec..e6d26987865d0 100644 +--- a/arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts ++++ b/arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts +@@ -144,6 +144,14 @@ port@4 { + label = "wan"; + }; + ++ port@5 { ++ status = "disabled"; ++ }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ + port@8 { + label = "cpu"; + }; +diff --git a/arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts b/arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts +index f050acbea0b20..3124dfd01b944 100644 +--- a/arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts ++++ b/arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts +@@ -192,6 +192,14 @@ port@4 { + label = "wan"; + }; + ++ port@5 { ++ status = "disabled"; ++ }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ + port@8 { + label = "cpu"; + phy-mode = "rgmii"; +diff --git a/arch/arm/boot/dts/broadcom/bcm47094-luxul-abr-4500.dts b/arch/arm/boot/dts/broadcom/bcm47094-luxul-abr-4500.dts +index e8991d4e248ce..e374062eb5b76 100644 +--- a/arch/arm/boot/dts/broadcom/bcm47094-luxul-abr-4500.dts ++++ b/arch/arm/boot/dts/broadcom/bcm47094-luxul-abr-4500.dts +@@ -107,5 +107,13 @@ port@4 { + port@5 { + label = "cpu"; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xap-1610.dts b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xap-1610.dts +index afc635c8cdebb..badafa024d24c 100644 +--- a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xap-1610.dts ++++ b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xap-1610.dts +@@ -120,5 +120,13 @@ port@1 { + port@5 { + label = "cpu"; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xbr-4500.dts b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xbr-4500.dts +index 7cfa4607ef311..cf95af9db1e66 100644 +--- a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xbr-4500.dts ++++ b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xbr-4500.dts +@@ -107,5 +107,13 @@ port@4 { + port@5 { + label = "cpu"; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwc-2000.dts b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwc-2000.dts +index d55e10095eae7..992c19e1cfa17 100644 +--- a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwc-2000.dts ++++ b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwc-2000.dts +@@ -75,5 +75,13 @@ port@0 { + port@5 { + label = "cpu"; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3100.dts b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3100.dts +index ccf031c0e276d..4d0ba315a2049 100644 +--- a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3100.dts ++++ b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3100.dts +@@ -147,5 +147,13 @@ port@4 { + port@5 { + label = "cpu"; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3150-v1.dts b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3150-v1.dts +index e28f7a3501179..83c429afc2974 100644 +--- a/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3150-v1.dts ++++ b/arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3150-v1.dts +@@ -158,5 +158,13 @@ port@4 { + port@5 { + label = "cpu"; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; +diff --git a/arch/arm/boot/dts/broadcom/bcm53015-meraki-mr26.dts b/arch/arm/boot/dts/broadcom/bcm53015-meraki-mr26.dts +index 03ad614e6b721..0bf5106f7012c 100644 +--- a/arch/arm/boot/dts/broadcom/bcm53015-meraki-mr26.dts ++++ b/arch/arm/boot/dts/broadcom/bcm53015-meraki-mr26.dts +@@ -124,6 +124,14 @@ fixed-link { + full-duplex; + }; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; + +diff --git a/arch/arm/boot/dts/broadcom/bcm53016-meraki-mr32.dts b/arch/arm/boot/dts/broadcom/bcm53016-meraki-mr32.dts +index 26c12bfb0bdd4..25eeacf6a2484 100644 +--- a/arch/arm/boot/dts/broadcom/bcm53016-meraki-mr32.dts ++++ b/arch/arm/boot/dts/broadcom/bcm53016-meraki-mr32.dts +@@ -185,6 +185,14 @@ fixed-link { + full-duplex; + }; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; + +diff --git a/arch/arm/boot/dts/broadcom/bcm953012er.dts b/arch/arm/boot/dts/broadcom/bcm953012er.dts +index 4fe3b36533767..d939ec9f4a9e7 100644 +--- a/arch/arm/boot/dts/broadcom/bcm953012er.dts ++++ b/arch/arm/boot/dts/broadcom/bcm953012er.dts +@@ -84,6 +84,14 @@ port@5 { + label = "cpu"; + ethernet = <&gmac0>; + }; ++ ++ port@7 { ++ status = "disabled"; ++ }; ++ ++ port@8 { ++ status = "disabled"; ++ }; + }; + }; + +-- +2.42.0 + diff --git a/queue-6.6/arm-dts-qcom-apq8026-samsung-matisse-wifi-fix-invert.patch b/queue-6.6/arm-dts-qcom-apq8026-samsung-matisse-wifi-fix-invert.patch new file mode 100644 index 00000000000..053d5add418 --- /dev/null +++ b/queue-6.6/arm-dts-qcom-apq8026-samsung-matisse-wifi-fix-invert.patch @@ -0,0 +1,47 @@ +From dc1119d9172f8723e0ada9a142f73b9d49ec254a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 04:12:11 +0300 +Subject: ARM: dts: qcom: apq8026-samsung-matisse-wifi: Fix inverted hall + sensor +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Matti Lehtimäki + +[ Upstream commit 0b73519790d29e4bc71afc4882a9aa9ea649bcf7 ] + +Fix hall sensor GPIO polarity and also allow disabling the sensor. +Remove unneeded interrupt. + +Fixes: f15623bda1dc ("ARM: dts: qcom: Add support for Samsung Galaxy Tab 4 10.1 (SM-T530)") +Signed-off-by: Matti Lehtimäki +Reviewed-by: Luca Weiss +Link: https://lore.kernel.org/r/20230922011211.115234-1-matti.lehtimaki@gmail.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts b/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts +index 884d99297d4cf..f516e0426bb9e 100644 +--- a/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts ++++ b/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts +@@ -45,11 +45,11 @@ gpio-hall-sensor { + + event-hall-sensor { + label = "Hall Effect Sensor"; +- gpios = <&tlmm 110 GPIO_ACTIVE_HIGH>; +- interrupts = <&tlmm 110 IRQ_TYPE_EDGE_FALLING>; ++ gpios = <&tlmm 110 GPIO_ACTIVE_LOW>; + linux,input-type = ; + linux,code = ; + debounce-interval = <15>; ++ linux,can-disable; + wakeup-source; + }; + }; +-- +2.42.0 + diff --git a/queue-6.6/arm-dts-qcom-mdm9615-populate-vsdcc-fixed-regulator.patch b/queue-6.6/arm-dts-qcom-mdm9615-populate-vsdcc-fixed-regulator.patch new file mode 100644 index 00000000000..f13fe3598af --- /dev/null +++ b/queue-6.6/arm-dts-qcom-mdm9615-populate-vsdcc-fixed-regulator.patch @@ -0,0 +1,51 @@ +From 3a693dc504fc4fbfe912c28ed7045a8f451fa52f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Sep 2023 20:39:13 +0200 +Subject: ARM: dts: qcom: mdm9615: populate vsdcc fixed regulator + +From: Krzysztof Kozlowski + +[ Upstream commit 09f8ee81b6da5f76de8b83c8bfc4475b54e101e0 ] + +Fixed regulator put under "regulators" node will not be populated, +unless simple-bus or something similar is used. Drop the "regulators" +wrapper node to fix this. + +Fixes: 2c5e596524e7 ("ARM: dts: Add MDM9615 dtsi") +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20230924183914.51414-3-krzysztof.kozlowski@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi b/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi +index fc4f52f9e9f7d..63e21aa236429 100644 +--- a/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi ++++ b/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi +@@ -47,14 +47,12 @@ cxo_board: cxo_board { + }; + }; + +- regulators { +- vsdcc_fixed: vsdcc-regulator { +- compatible = "regulator-fixed"; +- regulator-name = "SDCC Power"; +- regulator-min-microvolt = <2700000>; +- regulator-max-microvolt = <2700000>; +- regulator-always-on; +- }; ++ vsdcc_fixed: vsdcc-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "SDCC Power"; ++ regulator-min-microvolt = <2700000>; ++ regulator-max-microvolt = <2700000>; ++ regulator-always-on; + }; + + soc: soc { +-- +2.42.0 + diff --git a/queue-6.6/arm-dts-renesas-blanche-fix-typo-in-gp_11_2-pin-name.patch b/queue-6.6/arm-dts-renesas-blanche-fix-typo-in-gp_11_2-pin-name.patch new file mode 100644 index 00000000000..45d1359d11f --- /dev/null +++ b/queue-6.6/arm-dts-renesas-blanche-fix-typo-in-gp_11_2-pin-name.patch @@ -0,0 +1,39 @@ +From c606442df4a23649ee77ef7b4094ead7c6e794ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Aug 2023 17:21:38 +0200 +Subject: ARM: dts: renesas: blanche: Fix typo in GP_11_2 pin name + +From: Geert Uytterhoeven + +[ Upstream commit edc6ef026fe69154bb6b70dd6e7f278cfd7d6919 ] + +On blanche, the GPIO keyboard fails to probe with: + + sh-pfc e6060000.pinctrl: could not map pin config for "GP_11_02" + +Fix this by correcting the name for this pin to "GP_11_2". + +Fixes: 1f27fedead91eb60 ("ARM: dts: blanche: Configure pull-up for SOFT_SW and SW25 GPIO keys") +Signed-off-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/203128eca2261ffc33b83637818dd39c488f42b0.1693408326.git.geert+renesas@glider.be +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/renesas/r8a7792-blanche.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/renesas/r8a7792-blanche.dts b/arch/arm/boot/dts/renesas/r8a7792-blanche.dts +index c66de9dd12dfc..6a83923aa4612 100644 +--- a/arch/arm/boot/dts/renesas/r8a7792-blanche.dts ++++ b/arch/arm/boot/dts/renesas/r8a7792-blanche.dts +@@ -239,7 +239,7 @@ du1_pins: du1 { + }; + + keyboard_pins: keyboard { +- pins = "GP_3_10", "GP_3_11", "GP_3_12", "GP_3_15", "GP_11_02"; ++ pins = "GP_3_10", "GP_3_11", "GP_3_12", "GP_3_15", "GP_11_2"; + bias-pull-up; + }; + +-- +2.42.0 + diff --git a/queue-6.6/arm-dts-stm32-stm32f7-pinctrl-don-t-use-multiple-bla.patch b/queue-6.6/arm-dts-stm32-stm32f7-pinctrl-don-t-use-multiple-bla.patch new file mode 100644 index 00000000000..c7ff0de3524 --- /dev/null +++ b/queue-6.6/arm-dts-stm32-stm32f7-pinctrl-don-t-use-multiple-bla.patch @@ -0,0 +1,40 @@ +From b122d1a35ba97721026f9845c72fa6aa99a052ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 20:03:41 +0200 +Subject: ARM: dts: stm32: stm32f7-pinctrl: don't use multiple blank lines +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Dario Binacchi + +[ Upstream commit 88bb50edb61068c4416df2e55677fb3159f647f1 ] + +The patch fixes the following warning: + +arch/arm/dts/stm32f7-pinctrl.dtsi:380: check: Please don't use multiple blank lines + +Fixes: ba287d1a0137 ("ARM: dts: stm32: add pin map for LTDC on stm32f7") +Signed-off-by: Dario Binacchi +Reviewed-by: Raphaël Gallais-Pou +Signed-off-by: Alexandre Torgue +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/st/stm32f7-pinctrl.dtsi | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm/boot/dts/st/stm32f7-pinctrl.dtsi b/arch/arm/boot/dts/st/stm32f7-pinctrl.dtsi +index 65480a9f5cc4e..842f2b17c4a81 100644 +--- a/arch/arm/boot/dts/st/stm32f7-pinctrl.dtsi ++++ b/arch/arm/boot/dts/st/stm32f7-pinctrl.dtsi +@@ -376,7 +376,6 @@ pins2 { + }; + }; + +- + ltdc_pins_a: ltdc-0 { + pins { + pinmux = , /* LCD_B0 */ +-- +2.42.0 + diff --git a/queue-6.6/arm64-arm-xen-enlighten-fix-kpti-checks.patch b/queue-6.6/arm64-arm-xen-enlighten-fix-kpti-checks.patch new file mode 100644 index 00000000000..dd97a62c24e --- /dev/null +++ b/queue-6.6/arm64-arm-xen-enlighten-fix-kpti-checks.patch @@ -0,0 +1,128 @@ +From fbd8a5d6cfa1f772f7fe6e593cfdcf884099ba0c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Oct 2023 11:24:25 +0100 +Subject: arm64/arm: xen: enlighten: Fix KPTI checks + +From: Mark Rutland + +[ Upstream commit 20f3b8eafe0ba5d3c69d5011a9b07739e9645132 ] + +When KPTI is in use, we cannot register a runstate region as XEN +requires that this is always a valid VA, which we cannot guarantee. Due +to this, xen_starting_cpu() must avoid registering each CPU's runstate +region, and xen_guest_init() must avoid setting up features that depend +upon it. + +We tried to ensure that in commit: + + f88af7229f6f22ce (" xen/arm: do not setup the runstate info page if kpti is enabled") + +... where we added checks for xen_kernel_unmapped_at_usr(), which wraps +arm64_kernel_unmapped_at_el0() on arm64 and is always false on 32-bit +arm. + +Unfortunately, as xen_guest_init() is an early_initcall, this happens +before secondary CPUs are booted and arm64 has finalized the +ARM64_UNMAP_KERNEL_AT_EL0 cpucap which backs +arm64_kernel_unmapped_at_el0(), and so this can subsequently be set as +secondary CPUs are onlined. On a big.LITTLE system where the boot CPU +does not require KPTI but some secondary CPUs do, this will result in +xen_guest_init() intializing features that depend on the runstate +region, and xen_starting_cpu() registering the runstate region on some +CPUs before KPTI is subsequent enabled, resulting the the problems the +aforementioned commit tried to avoid. + +Handle this more robsutly by deferring the initialization of the +runstate region until secondary CPUs have been initialized and the +ARM64_UNMAP_KERNEL_AT_EL0 cpucap has been finalized. The per-cpu work is +moved into a new hotplug starting function which is registered later +when we're certain that KPTI will not be used. + +Fixes: f88af7229f6f ("xen/arm: do not setup the runstate info page if kpti is enabled") +Signed-off-by: Mark Rutland +Cc: Bertrand Marquis +Cc: Boris Ostrovsky +Cc: Juergen Gross +Cc: Stefano Stabellini +Cc: Suzuki K Poulose +Cc: Will Deacon +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + arch/arm/xen/enlighten.c | 25 ++++++++++++++++--------- + include/linux/cpuhotplug.h | 1 + + 2 files changed, 17 insertions(+), 9 deletions(-) + +diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c +index c392e18f1e431..9afdc4c4a5dc1 100644 +--- a/arch/arm/xen/enlighten.c ++++ b/arch/arm/xen/enlighten.c +@@ -164,9 +164,6 @@ static int xen_starting_cpu(unsigned int cpu) + BUG_ON(err); + per_cpu(xen_vcpu, cpu) = vcpup; + +- if (!xen_kernel_unmapped_at_usr()) +- xen_setup_runstate_info(cpu); +- + after_register_vcpu_info: + enable_percpu_irq(xen_events_irq, 0); + return 0; +@@ -523,9 +520,6 @@ static int __init xen_guest_init(void) + return -EINVAL; + } + +- if (!xen_kernel_unmapped_at_usr()) +- xen_time_setup_guest(); +- + if (xen_initial_domain()) + pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier); + +@@ -535,7 +529,13 @@ static int __init xen_guest_init(void) + } + early_initcall(xen_guest_init); + +-static int __init xen_pm_init(void) ++static int xen_starting_runstate_cpu(unsigned int cpu) ++{ ++ xen_setup_runstate_info(cpu); ++ return 0; ++} ++ ++static int __init xen_late_init(void) + { + if (!xen_domain()) + return -ENODEV; +@@ -548,9 +548,16 @@ static int __init xen_pm_init(void) + do_settimeofday64(&ts); + } + +- return 0; ++ if (xen_kernel_unmapped_at_usr()) ++ return 0; ++ ++ xen_time_setup_guest(); ++ ++ return cpuhp_setup_state(CPUHP_AP_ARM_XEN_RUNSTATE_STARTING, ++ "arm/xen_runstate:starting", ++ xen_starting_runstate_cpu, NULL); + } +-late_initcall(xen_pm_init); ++late_initcall(xen_late_init); + + + /* empty stubs */ +diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h +index 068f7738be22a..28c1d3d77b70f 100644 +--- a/include/linux/cpuhotplug.h ++++ b/include/linux/cpuhotplug.h +@@ -189,6 +189,7 @@ enum cpuhp_state { + /* Must be the last timer callback */ + CPUHP_AP_DUMMY_TIMER_STARTING, + CPUHP_AP_ARM_XEN_STARTING, ++ CPUHP_AP_ARM_XEN_RUNSTATE_STARTING, + CPUHP_AP_ARM_CORESIGHT_STARTING, + CPUHP_AP_ARM_CORESIGHT_CTI_STARTING, + CPUHP_AP_ARM64_ISNDEP_STARTING, +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-imx8mm-add-sound-dai-cells-to-micfil-node.patch b/queue-6.6/arm64-dts-imx8mm-add-sound-dai-cells-to-micfil-node.patch new file mode 100644 index 00000000000..53529ac515d --- /dev/null +++ b/queue-6.6/arm64-dts-imx8mm-add-sound-dai-cells-to-micfil-node.patch @@ -0,0 +1,36 @@ +From 0843290763effdf6d9d8c80f6ca7b176d35245eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 18:01:58 -0500 +Subject: arm64: dts: imx8mm: Add sound-dai-cells to micfil node + +From: Adam Ford + +[ Upstream commit 0e6cc2b8bb7d67733f4a47720787eff1ce2666f2 ] + +Per the DT bindings, the micfil node should have a sound-dai-cells +entry. + +Fixes: 3bd0788c43d9 ("arm64: dts: imx8mm: Add support for micfil") +Signed-off-by: Adam Ford +Reviewed-by: Fabio Estevam +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/freescale/imx8mm.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi +index 236fe44f779df..738024baaa578 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi +@@ -399,6 +399,7 @@ micfil: audio-controller@30080000 { + "pll8k", "pll11k", "clkext3"; + dmas = <&sdma2 24 25 0x80000000>; + dma-names = "rx"; ++ #sound-dai-cells = <0>; + status = "disabled"; + }; + +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-imx8mn-add-sound-dai-cells-to-micfil-node.patch b/queue-6.6/arm64-dts-imx8mn-add-sound-dai-cells-to-micfil-node.patch new file mode 100644 index 00000000000..94f5dbd0d43 --- /dev/null +++ b/queue-6.6/arm64-dts-imx8mn-add-sound-dai-cells-to-micfil-node.patch @@ -0,0 +1,36 @@ +From 39d837f061f3abc84884ec14fd0be3d8a8bcd04d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 18:01:59 -0500 +Subject: arm64: dts: imx8mn: Add sound-dai-cells to micfil node + +From: Adam Ford + +[ Upstream commit db1925454a2e7cadcac8756442ca7c3198332336 ] + +Per the DT bindings, the micfil node should have a sound-dai-cells +entry. + +Fixes: cca69ef6eba5 ("arm64: dts: imx8mn: Add support for micfil") +Signed-off-by: Adam Ford +Reviewed-by: Fabio Estevam +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/freescale/imx8mn.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi +index aa38dd6dc9ba5..1bb1d0c1bae4d 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi +@@ -371,6 +371,7 @@ micfil: audio-controller@30080000 { + "pll8k", "pll11k", "clkext3"; + dmas = <&sdma2 24 25 0x80000000>; + dma-names = "rx"; ++ #sound-dai-cells = <0>; + status = "disabled"; + }; + +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-imx8mp-debix-model-a-remove-usb-hub-reset-.patch b/queue-6.6/arm64-dts-imx8mp-debix-model-a-remove-usb-hub-reset-.patch new file mode 100644 index 00000000000..1995871bc35 --- /dev/null +++ b/queue-6.6/arm64-dts-imx8mp-debix-model-a-remove-usb-hub-reset-.patch @@ -0,0 +1,62 @@ +From ddab5431f187eb70ca25a2a041d3be0a627e1419 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 10:11:23 -0300 +Subject: arm64: dts: imx8mp-debix-model-a: Remove USB hub reset-gpios + +From: Fabio Estevam + +[ Upstream commit 0ce9a2c121e3ab354cf66aeecd3ed0758f3c5067 ] + +The SAI2_TXC pin is left unconnected per the imx8mp-debix-model-a +schematics: + +https://debix.io/Uploads/Temp/file/20230331/DEBIX%20Model%20A%20Schematics.pdf + +Also, the RTS5411E USB hub chip does not have a reset pin. + +Remove this pin description to properly describe the hardware. + +This also fixes the following schema warning: + +hub@1: 'reset-gpios' does not match any of the regexes: 'pinctrl-[0-9]+' +from schema $id: http://devicetree.org/schemas/usb/realtek,rts5411.yaml# + +Fixes: 0253e1cb6300 ("arm64: dts: imx8mp-debix: add USB host support") +Signed-off-by: Fabio Estevam +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts b/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts +index 28db9349ed62c..267ceffc02d84 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts ++++ b/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts +@@ -284,7 +284,6 @@ &usb_dwc3_1 { + usb_hub_2_x: hub@1 { + compatible = "usbbda,5411"; + reg = <1>; +- reset-gpios = <&gpio4 25 GPIO_ACTIVE_LOW>; + vdd-supply = <®_usb_hub>; + peer-hub = <&usb_hub_3_x>; + }; +@@ -293,7 +292,6 @@ usb_hub_2_x: hub@1 { + usb_hub_3_x: hub@2 { + compatible = "usbbda,411"; + reg = <2>; +- reset-gpios = <&gpio4 25 GPIO_ACTIVE_LOW>; + vdd-supply = <®_usb_hub>; + peer-hub = <&usb_hub_2_x>; + }; +@@ -443,7 +441,6 @@ MX8MP_IOMUXC_UART4_TXD__UART4_DCE_TX 0x49 + pinctrl_usb1: usb1grp { + fsl,pins = < + MX8MP_IOMUXC_GPIO1_IO14__USB2_OTG_PWR 0x10 +- MX8MP_IOMUXC_SAI2_TXC__GPIO4_IO25 0x19 + >; + }; + +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-imx8qm-ss-img-fix-jpegenc-compatible-entry.patch b/queue-6.6/arm64-dts-imx8qm-ss-img-fix-jpegenc-compatible-entry.patch new file mode 100644 index 00000000000..548f9e989de --- /dev/null +++ b/queue-6.6/arm64-dts-imx8qm-ss-img-fix-jpegenc-compatible-entry.patch @@ -0,0 +1,42 @@ +From 30bafaaa95bac1bb6ed3dbdc9fa929c7432aa875 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Sep 2023 11:27:36 -0300 +Subject: arm64: dts: imx8qm-ss-img: Fix jpegenc compatible entry + +From: Fabio Estevam + +[ Upstream commit 1d33cd614d89b0ec024d25ec45acf4632211b5a7 ] + +The first compatible entry for the jpegenc should be 'nxp,imx8qm-jpgenc'. + +Change it accordingly to fix the following schema warning: + +imx8qm-apalis-eval.dtb: jpegenc@58450000: compatible: 'oneOf' conditional failed, one must be fixed: + 'nxp,imx8qm-jpgdec' is not one of ['nxp,imx8qxp-jpgdec', 'nxp,imx8qxp-jpgenc'] + 'nxp,imx8qm-jpgenc' was expected + 'nxp,imx8qxp-jpgdec' was expected + +Fixes: 5bb279171afc ("arm64: dts: imx8: Add jpeg encoder/decoder nodes") +Signed-off-by: Fabio Estevam +Reviewed-by: Mirela Rabulea +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi +index 7764b4146e0ab..2bbdacb1313f9 100644 +--- a/arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi +@@ -8,5 +8,5 @@ &jpegdec { + }; + + &jpegenc { +- compatible = "nxp,imx8qm-jpgdec", "nxp,imx8qxp-jpgenc"; ++ compatible = "nxp,imx8qm-jpgenc", "nxp,imx8qxp-jpgenc"; + }; +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-marvell-cn9310-use-appropriate-label-for-s.patch b/queue-6.6/arm64-dts-marvell-cn9310-use-appropriate-label-for-s.patch new file mode 100644 index 00000000000..f7454a606bc --- /dev/null +++ b/queue-6.6/arm64-dts-marvell-cn9310-use-appropriate-label-for-s.patch @@ -0,0 +1,72 @@ +From a75574a2ac2535f5b1a2f793cdf3579126092138 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Aug 2023 10:51:25 +1200 +Subject: ARM64: dts: marvell: cn9310: Use appropriate label for spi1 pins + +From: Chris Packham + +[ Upstream commit 0878fd86f554ab98aa493996c7e0c72dff58437f ] + +Both the CN9130-CRB and CN9130-DB use the SPI1 interface but had the +pinctrl node labelled as "cp0_spi0_pins". Use the label "cp0_spi1_pins" +and update the node name to "cp0-spi-pins-1" to avoid confusion with the +pinctrl options for SPI0. + +Fixes: 4c43a41e5b8c ("arm64: dts: cn913x: add device trees for topology B boards") +Fixes: 5c0ee54723f3 ("arm64: dts: add support for Marvell cn9130-crb platform") +Signed-off-by: Chris Packham +Reviewed-by: Andrew Lunn +Signed-off-by: Gregory CLEMENT +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/marvell/cn9130-crb.dtsi | 4 ++-- + arch/arm64/boot/dts/marvell/cn9130-db.dtsi | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi b/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi +index 32cfb3e2efc3a..47d45ff3d6f57 100644 +--- a/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi ++++ b/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi +@@ -120,7 +120,7 @@ cp0_sdhci_pins: cp0-sdhi-pins-0 { + "mpp59", "mpp60", "mpp61"; + marvell,function = "sdio"; + }; +- cp0_spi0_pins: cp0-spi-pins-0 { ++ cp0_spi1_pins: cp0-spi-pins-1 { + marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16"; + marvell,function = "spi1"; + }; +@@ -170,7 +170,7 @@ &cp0_sdhci0 { + + &cp0_spi1 { + pinctrl-names = "default"; +- pinctrl-0 = <&cp0_spi0_pins>; ++ pinctrl-0 = <&cp0_spi1_pins>; + reg = <0x700680 0x50>, /* control */ + <0x2000000 0x1000000>; /* CS0 */ + status = "okay"; +diff --git a/arch/arm64/boot/dts/marvell/cn9130-db.dtsi b/arch/arm64/boot/dts/marvell/cn9130-db.dtsi +index c7de1ea0d470a..6eb6a175de38d 100644 +--- a/arch/arm64/boot/dts/marvell/cn9130-db.dtsi ++++ b/arch/arm64/boot/dts/marvell/cn9130-db.dtsi +@@ -307,7 +307,7 @@ &cp0_sdhci0 { + &cp0_spi1 { + status = "disabled"; + pinctrl-names = "default"; +- pinctrl-0 = <&cp0_spi0_pins>; ++ pinctrl-0 = <&cp0_spi1_pins>; + reg = <0x700680 0x50>; + + flash@0 { +@@ -371,7 +371,7 @@ cp0_sdhci_pins: cp0-sdhi-pins-0 { + "mpp59", "mpp60", "mpp61"; + marvell,function = "sdio"; + }; +- cp0_spi0_pins: cp0-spi-pins-0 { ++ cp0_spi1_pins: cp0-spi-pins-1 { + marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16"; + marvell,function = "spi1"; + }; +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-apq8016-sbc-add-missing-adv7533-regul.patch b/queue-6.6/arm64-dts-qcom-apq8016-sbc-add-missing-adv7533-regul.patch new file mode 100644 index 00000000000..e2ea84a37f7 --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-apq8016-sbc-add-missing-adv7533-regul.patch @@ -0,0 +1,45 @@ +From 0a1de5246fb8d205c2b62f2f649ea875c56746b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 12:49:55 +0200 +Subject: arm64: dts: qcom: apq8016-sbc: Add missing ADV7533 regulators + +From: Stephan Gerhold + +[ Upstream commit 33e9032a1875bb1aee3c68a4540f5a577ff44130 ] + +Add the missing regulator supplies to the ADV7533 HDMI bridge to fix +the following dtbs_check warnings. They are all also supplied by +pm8916_l6 so there is no functional difference. + +apq8016-sbc.dtb: bridge@39: 'dvdd-supply' is a required property +apq8016-sbc.dtb: bridge@39: 'pvdd-supply' is a required property +apq8016-sbc.dtb: bridge@39: 'a2vdd-supply' is a required property + from schema display/bridge/adi,adv7533.yaml + +Fixes: 28546b095511 ("arm64: dts: apq8016-sbc: Add HDMI display support") +Signed-off-by: Stephan Gerhold +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20230922-db410c-adv7533-regulators-v1-1-68aba71e529b@gerhold.net +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts +index 4f5541e9be0e9..dabe9f42a63ad 100644 +--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts ++++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts +@@ -172,6 +172,9 @@ adv_bridge: bridge@39 { + pd-gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>; + + avdd-supply = <&pm8916_l6>; ++ a2vdd-supply = <&pm8916_l6>; ++ dvdd-supply = <&pm8916_l6>; ++ pvdd-supply = <&pm8916_l6>; + v1p2-supply = <&pm8916_l6>; + v3p3-supply = <&pm8916_l17>; + +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-msm8916-fix-iommu-local-address-range.patch b/queue-6.6/arm64-dts-qcom-msm8916-fix-iommu-local-address-range.patch new file mode 100644 index 00000000000..0a1e5aefadd --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-msm8916-fix-iommu-local-address-range.patch @@ -0,0 +1,40 @@ +From 5ad4a35d02752d6f76fe1241ea619278aee81edb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 20:03:04 +0530 +Subject: arm64: dts: qcom: msm8916: Fix iommu local address range + +From: Gaurav Kohli + +[ Upstream commit 2de8ee9f58fa51f707c71f8fbcd8470ab0078102 ] + +Fix the apps iommu local address space range as per data sheet. + +Fixes: 6a6729f38436 ("arm64: dts: qcom: msm8916: Add IOMMU support") +Reviewed-by: Bryan O'Donoghue +Tested-by: Bryan O'Donoghue +Signed-off-by: Gaurav Kohli +Reviewed-by: Stephan Gerhold +Acked-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230915143304.477-1-quic_gkohli@quicinc.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi +index 33fb65d731046..3c934363368c3 100644 +--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi +@@ -1813,7 +1813,7 @@ apps_iommu: iommu@1ef0000 { + #size-cells = <1>; + #iommu-cells = <1>; + compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; +- ranges = <0 0x01e20000 0x40000>; ++ ranges = <0 0x01e20000 0x20000>; + reg = <0x01ef0000 0x3000>; + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_APSS_TCU_CLK>; +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-msm8939-fix-iommu-local-address-range.patch b/queue-6.6/arm64-dts-qcom-msm8939-fix-iommu-local-address-range.patch new file mode 100644 index 00000000000..a9fe1b75025 --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-msm8939-fix-iommu-local-address-range.patch @@ -0,0 +1,37 @@ +From 14ec859d0158cb9f1f7121a18d6e4230c285e8af Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 17 Sep 2023 19:30:39 +0530 +Subject: arm64: dts: qcom: msm8939: Fix iommu local address range + +From: Gaurav Kohli + +[ Upstream commit d40291e52d5ac4d0ff18ca433e84e6ddccc13427 ] + +Fix the apps iommu local address space range as per data sheet. + +Fixes: 61550c6c156c ("arm64: dts: qcom: Add msm8939 SoC") +Signed-off-by: Gaurav Kohli +Reviewed-by: Stephan Gerhold +Link: https://lore.kernel.org/r/20230917140039.25283-1-quic_gkohli@quicinc.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/msm8939.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/msm8939.dtsi b/arch/arm64/boot/dts/qcom/msm8939.dtsi +index 6e24f0f2374fe..5a6b1942cfaa5 100644 +--- a/arch/arm64/boot/dts/qcom/msm8939.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8939.dtsi +@@ -1447,7 +1447,7 @@ opp-19200000 { + apps_iommu: iommu@1ef0000 { + compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; + reg = <0x01ef0000 0x3000>; +- ranges = <0 0x01e20000 0x40000>; ++ ranges = <0 0x01e20000 0x20000>; + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_APSS_TCU_CLK>; + clock-names = "iface", "bus"; +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-msm8976-fix-ipc-bit-shifts.patch b/queue-6.6/arm64-dts-qcom-msm8976-fix-ipc-bit-shifts.patch new file mode 100644 index 00000000000..2586c12c3fa --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-msm8976-fix-ipc-bit-shifts.patch @@ -0,0 +1,57 @@ +From 2921f9598c10777359f2d4ff9088b32686ae1cb2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Aug 2023 13:24:50 +0200 +Subject: arm64: dts: qcom: msm8976: Fix ipc bit shifts + +From: Adam Skladowski + +[ Upstream commit 684277525c70f329300cc687e27248e405a4ff9e ] + +Update bits to match downstream irq-bitmask values. + +Fixes: 0484d3ce0902 ("arm64: dts: qcom: Add DTS for MSM8976 and MSM8956 SoCs") +Signed-off-by: Adam Skladowski +Link: https://lore.kernel.org/r/20230812112534.8610-8-a39.skl@gmail.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/msm8976.dtsi | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/msm8976.dtsi b/arch/arm64/boot/dts/qcom/msm8976.dtsi +index f9f5afbcc52bb..4c5be22b47fee 100644 +--- a/arch/arm64/boot/dts/qcom/msm8976.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8976.dtsi +@@ -379,7 +379,7 @@ adsp_smp2p_in: slave-kernel { + smp2p-modem { + compatible = "qcom,smp2p"; + interrupts = ; +- qcom,ipc = <&apcs 8 13>; ++ qcom,ipc = <&apcs 8 14>; + + qcom,local-pid = <0>; + qcom,remote-pid = <1>; +@@ -402,7 +402,7 @@ modem_smp2p_in: slave-kernel { + smp2p-wcnss { + compatible = "qcom,smp2p"; + interrupts = ; +- qcom,ipc = <&apcs 8 17>; ++ qcom,ipc = <&apcs 8 18>; + + qcom,local-pid = <0>; + qcom,remote-pid = <4>; +@@ -428,9 +428,9 @@ smsm { + #address-cells = <1>; + #size-cells = <0>; + +- qcom,ipc-1 = <&apcs 8 12>; ++ qcom,ipc-1 = <&apcs 8 13>; + qcom,ipc-2 = <&apcs 8 9>; +- qcom,ipc-3 = <&apcs 8 18>; ++ qcom,ipc-3 = <&apcs 8 19>; + + apps_smsm: apps@0 { + reg = <0>; +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-msm8992-libra-drop-duplicated-reserve.patch b/queue-6.6/arm64-dts-qcom-msm8992-libra-drop-duplicated-reserve.patch new file mode 100644 index 00000000000..92c7ea46fbb --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-msm8992-libra-drop-duplicated-reserve.patch @@ -0,0 +1,42 @@ +From c31af8b50de834b97394697a98167ed81048247d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Jul 2023 09:20:48 +0200 +Subject: arm64: dts: qcom: msm8992-libra: drop duplicated reserved memory + +From: Krzysztof Kozlowski + +[ Upstream commit f32096602c19e68fb9bf04b494d13f1190602554 ] + +There are two entries for similar reserved memory: qseecom@cb400000 and +audio@cb400000. Keep the qseecom as it is longer. + + Warning (unique_unit_address_if_enabled): /reserved-memory/audio@cb400000: duplicate unit-address (also used in node /reserved-memory/qseecom@cb400000) + +Fixes: 69876bc6fd4d ("arm64: dts: qcom: msm8992-libra: Fix the memory map") +Signed-off-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20230720072048.10093-2-krzysztof.kozlowski@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts +index fcca1ba94da69..5fe5de9ceef99 100644 +--- a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts ++++ b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts +@@ -109,11 +109,6 @@ rmtfs_mem: rmtfs@ca100000 { + qcom,client-id = <1>; + }; + +- audio_mem: audio@cb400000 { +- reg = <0 0xcb000000 0 0x400000>; +- no-mem; +- }; +- + qseecom_mem: qseecom@cb400000 { + reg = <0 0xcb400000 0 0x1c00000>; + no-mem; +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-qrb2210-rb1-fix-regulators.patch b/queue-6.6/arm64-dts-qcom-qrb2210-rb1-fix-regulators.patch new file mode 100644 index 00000000000..d4d63a53058 --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-qrb2210-rb1-fix-regulators.patch @@ -0,0 +1,239 @@ +From c5c9d5930ab1fb12bc773562c3ebf79893a8e47e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 11:24:56 +0200 +Subject: arm64: dts: qcom: qrb2210-rb1: Fix regulators + +From: Konrad Dybcio + +[ Upstream commit 31bee70793b67f4b428825434542afc72ddb2b3b ] + +Commit b4fe47d12f1f ("arm64: dts: qcom: qrb2210-rb1: Add regulators") +introduced regulator settings that were never put in place, as all of the +properties ended 'microvolts' instead of 'microvolt' (which dt schema did +not check for back then). + +Fix the microvolts-microvolt typo and adjust voltage ranges where it's +necessary to fit within the volt = base + n*step formula. + +Reported-by: Vladimir Zapolskiy +Reported-by: Dmitry Baryshkov +Fixes: b4fe47d12f1f ("arm64: dts: qcom: qrb2210-rb1: Add regulators") +Signed-off-by: Konrad Dybcio +Reviewed-by: Dmitry Baryshkov +Reviewed-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20230906-topic-rb1_features_sans_icc-v1-2-e92ce6fbde16@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/qrb2210-rb1.dts | 86 ++++++++++++------------ + 1 file changed, 43 insertions(+), 43 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts +index 5cda5b761455b..0f7c591878962 100644 +--- a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts ++++ b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts +@@ -150,15 +150,15 @@ regulators { + + pm2250_s3: s3 { + /* 0.4V-1.6625V -> 1.3V (Power tree requirements) */ +- regulator-min-microvolts = <1350000>; +- regulator-max-microvolts = <1350000>; ++ regulator-min-microvolt = <1352000>; ++ regulator-max-microvolt = <1352000>; + regulator-boot-on; + }; + + pm2250_s4: s4 { + /* 1.2V-2.35V -> 2.05V (Power tree requirements) */ +- regulator-min-microvolts = <2072000>; +- regulator-max-microvolts = <2072000>; ++ regulator-min-microvolt = <2072000>; ++ regulator-max-microvolt = <2072000>; + regulator-boot-on; + }; + +@@ -166,47 +166,47 @@ pm2250_s4: s4 { + + pm2250_l2: l2 { + /* LPDDR4X VDD2 */ +- regulator-min-microvolts = <1136000>; +- regulator-max-microvolts = <1136000>; ++ regulator-min-microvolt = <1136000>; ++ regulator-max-microvolt = <1136000>; + regulator-always-on; + regulator-boot-on; + }; + + pm2250_l3: l3 { + /* LPDDR4X VDDQ */ +- regulator-min-microvolts = <616000>; +- regulator-max-microvolts = <616000>; ++ regulator-min-microvolt = <616000>; ++ regulator-max-microvolt = <616000>; + regulator-always-on; + regulator-boot-on; + }; + + pm2250_l4: l4 { +- /* max = 3.05V -> max = just below 3V (SDHCI2) */ +- regulator-min-microvolts = <1648000>; +- regulator-max-microvolts = <2992000>; ++ /* max = 3.05V -> max = 2.7 to disable 3V signaling (SDHCI2) */ ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <2700000>; + regulator-allow-set-load; + }; + + pm2250_l5: l5 { + /* CSI/DSI */ +- regulator-min-microvolts = <1232000>; +- regulator-max-microvolts = <1232000>; ++ regulator-min-microvolt = <1232000>; ++ regulator-max-microvolt = <1232000>; + regulator-allow-set-load; + regulator-boot-on; + }; + + pm2250_l6: l6 { + /* DRAM PLL */ +- regulator-min-microvolts = <928000>; +- regulator-max-microvolts = <928000>; ++ regulator-min-microvolt = <928000>; ++ regulator-max-microvolt = <928000>; + regulator-always-on; + regulator-boot-on; + }; + + pm2250_l7: l7 { + /* Wi-Fi CX/MX */ +- regulator-min-microvolts = <664000>; +- regulator-max-microvolts = <664000>; ++ regulator-min-microvolt = <664000>; ++ regulator-max-microvolt = <664000>; + }; + + /* +@@ -216,37 +216,37 @@ pm2250_l7: l7 { + + pm2250_l10: l10 { + /* Wi-Fi RFA */ +- regulator-min-microvolts = <1300000>; +- regulator-max-microvolts = <1300000>; ++ regulator-min-microvolt = <1304000>; ++ regulator-max-microvolt = <1304000>; + }; + + pm2250_l11: l11 { + /* GPS RF1 */ +- regulator-min-microvolts = <1000000>; +- regulator-max-microvolts = <1000000>; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; + regulator-boot-on; + }; + + pm2250_l12: l12 { + /* USB PHYs */ +- regulator-min-microvolts = <928000>; +- regulator-max-microvolts = <928000>; ++ regulator-min-microvolt = <928000>; ++ regulator-max-microvolt = <928000>; + regulator-allow-set-load; + regulator-boot-on; + }; + + pm2250_l13: l13 { + /* USB/QFPROM/PLLs */ +- regulator-min-microvolts = <1800000>; +- regulator-max-microvolts = <1800000>; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; + regulator-allow-set-load; + regulator-boot-on; + }; + + pm2250_l14: l14 { + /* SDHCI1 VQMMC */ +- regulator-min-microvolts = <1800000>; +- regulator-max-microvolts = <1800000>; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; + regulator-allow-set-load; + /* Broken hardware, never turn it off! */ + regulator-always-on; +@@ -254,8 +254,8 @@ pm2250_l14: l14 { + + pm2250_l15: l15 { + /* WCD/DSI/BT VDDIO */ +- regulator-min-microvolts = <1800000>; +- regulator-max-microvolts = <1800000>; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; + regulator-allow-set-load; + regulator-always-on; + regulator-boot-on; +@@ -263,47 +263,47 @@ pm2250_l15: l15 { + + pm2250_l16: l16 { + /* GPS RF2 */ +- regulator-min-microvolts = <1800000>; +- regulator-max-microvolts = <1800000>; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; + regulator-boot-on; + }; + + pm2250_l17: l17 { +- regulator-min-microvolts = <3000000>; +- regulator-max-microvolts = <3000000>; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; + }; + + pm2250_l18: l18 { + /* VDD_PXn */ +- regulator-min-microvolts = <1800000>; +- regulator-max-microvolts = <1800000>; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; + }; + + pm2250_l19: l19 { + /* VDD_PXn */ +- regulator-min-microvolts = <1800000>; +- regulator-max-microvolts = <1800000>; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; + }; + + pm2250_l20: l20 { + /* SDHCI1 VMMC */ +- regulator-min-microvolts = <2856000>; +- regulator-max-microvolts = <2856000>; ++ regulator-min-microvolt = <2400000>; ++ regulator-max-microvolt = <3600000>; + regulator-allow-set-load; + }; + + pm2250_l21: l21 { + /* SDHCI2 VMMC */ +- regulator-min-microvolts = <2960000>; +- regulator-max-microvolts = <3300000>; ++ regulator-min-microvolt = <2960000>; ++ regulator-max-microvolt = <3300000>; + regulator-allow-set-load; + regulator-boot-on; + }; + + pm2250_l22: l22 { + /* Wi-Fi */ +- regulator-min-microvolts = <3312000>; +- regulator-max-microvolts = <3312000>; ++ regulator-min-microvolt = <3312000>; ++ regulator-max-microvolt = <3312000>; + }; + }; + }; +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-qrb2210-rb1-swap-uart-index.patch b/queue-6.6/arm64-dts-qcom-qrb2210-rb1-swap-uart-index.patch new file mode 100644 index 00000000000..dff3c9b9263 --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-qrb2210-rb1-swap-uart-index.patch @@ -0,0 +1,51 @@ +From 0c8ebc77f20558194c11a4e07d8f3c51f81c7043 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 11:24:55 +0200 +Subject: arm64: dts: qcom: qrb2210-rb1: Swap UART index + +From: Konrad Dybcio + +[ Upstream commit 973c015facabcbd320063648010942c51992c1a1 ] + +Newer RB1 board revisions have a debug UART on QUP0. Sadly, it looks +like even when ordering one in retail, customers receive prototype +boards with "Enginering Sample" written on them. + +Use QUP4 for UART to make all known RB1 boards boot. + +Fixes: e18771961336 ("arm64: dts: qcom: Add initial QTI RB1 device tree") +Signed-off-by: Konrad Dybcio +Reviewed-by: Dmitry Baryshkov +Reported-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20230906-topic-rb1_features_sans_icc-v1-1-e92ce6fbde16@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/qrb2210-rb1.dts | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts +index eadba066972e8..5cda5b761455b 100644 +--- a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts ++++ b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts +@@ -13,7 +13,7 @@ / { + compatible = "qcom,qrb2210-rb1", "qcom,qrb2210", "qcom,qcm2290"; + + aliases { +- serial0 = &uart0; ++ serial0 = &uart4; + sdhc1 = &sdhc_1; + sdhc2 = &sdhc_2; + }; +@@ -357,7 +357,7 @@ key_volp_n: key-volp-n-state { + }; + + /* UART connected to the Micro-USB port via a FTDI chip */ +-&uart0 { ++&uart4 { + compatible = "qcom,geni-debug-uart"; + status = "okay"; + }; +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-sc7280-add-missing-lmh-interrupts.patch b/queue-6.6/arm64-dts-qcom-sc7280-add-missing-lmh-interrupts.patch new file mode 100644 index 00000000000..f8517403dbf --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sc7280-add-missing-lmh-interrupts.patch @@ -0,0 +1,43 @@ +From 7194b8c8f6041781da85e29cd2f2cf3c967343d3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Aug 2023 22:58:22 +0200 +Subject: arm64: dts: qcom: sc7280: Add missing LMH interrupts + +From: Konrad Dybcio + +[ Upstream commit 3f93d119c9d6e1744d55cd48af764160a1a3aca3 ] + +Hook up the interrupts that signal the Limits Management Hardware has +started some sort of throttling action. + +Fixes: 7dbd121a2c58 ("arm64: dts: qcom: sc7280: Add cpufreq hw node") +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230811-topic-7280_lmhirq-v1-1-c262b6a25c8f@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sc7280.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi +index 2870fe8fd5263..20231d80c504b 100644 +--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi +@@ -5364,6 +5364,14 @@ cpufreq_hw: cpufreq@18591000 { + reg = <0 0x18591000 0 0x1000>, + <0 0x18592000 0 0x1000>, + <0 0x18593000 0 0x1000>; ++ ++ interrupts = , ++ , ++ ; ++ interrupt-names = "dcvsh-irq-0", ++ "dcvsh-irq-1", ++ "dcvsh-irq-2"; ++ + clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>; + clock-names = "xo", "alternate"; + #freq-domain-cells = <1>; +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-sc7280-drop-incorrect-eud-port-on-soc.patch b/queue-6.6/arm64-dts-qcom-sc7280-drop-incorrect-eud-port-on-soc.patch new file mode 100644 index 00000000000..8e422f0eec8 --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sc7280-drop-incorrect-eud-port-on-soc.patch @@ -0,0 +1,90 @@ +From 1fa9d3d90305cd5237e100017864cfc51f5022ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 20 Aug 2023 09:56:26 +0200 +Subject: arm64: dts: qcom: sc7280: drop incorrect EUD port on SoC side + +From: Krzysztof Kozlowski + +[ Upstream commit 39c8af78cbefb8c71a5ad1fa088e761ef418f0a0 ] + +Qualcomm Embedded USB Debugger (EUD) second port should point to Type-C +USB connector. Such connector was defined directly in root node of +sc7280.dtsi which is clearly wrong. SC7280 is a chip, so physically it +does not have USB Type-C port. The connector is usually accessible +through some USB switch or controller. + +Doug Anderson said that he wasn't ever able to use EUD on Herobrine +boards, probably because of invalid or missing DTS description - DTS is +saying EUD is on usb_2 node, which is connected to a USB Hub, not to the +Type-C port. + +Correct the EUD/USB connector topology by removing the top-level fake +USB connector and EUD port pointing to it, and disabling the incomplete +EUD device node. + +This fixes also dtbs_check warnings: + + sc7280-herobrine-crd.dtb: connector: ports:port@0: 'reg' is a required property + +Link: https://lore.kernel.org/all/CAD=FV=Xt26=rBf99mzkAuwwtb2f-jnKtnHaEhXnthz0a5zke4Q@mail.gmail.com/ +Fixes: 9ee402ccfeb1 ("arm64: dts: qcom: sc7280: Fix EUD dt node syntax") +Cc: Souradeep Chowdhury +Cc: Bhupesh Sharma +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Douglas Anderson +Link: https://lore.kernel.org/r/20230820075626.22600-1-krzysztof.kozlowski@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sc7280.dtsi | 21 ++------------------- + 1 file changed, 2 insertions(+), 19 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi +index 20231d80c504b..91bb58c6b1a61 100644 +--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi +@@ -649,18 +649,6 @@ cpu7_opp_3014mhz: opp-3014400000 { + }; + }; + +- eud_typec: connector { +- compatible = "usb-c-connector"; +- +- ports { +- port@0 { +- con_eud: endpoint { +- remote-endpoint = <&eud_con>; +- }; +- }; +- }; +- }; +- + memory@80000000 { + device_type = "memory"; + /* We expect the bootloader to fill in the size */ +@@ -3625,6 +3613,8 @@ eud: eud@88e0000 { + <0 0x88e2000 0 0x1000>; + interrupts-extended = <&pdc 11 IRQ_TYPE_LEVEL_HIGH>; + ++ status = "disabled"; ++ + ports { + #address-cells = <1>; + #size-cells = <0>; +@@ -3635,13 +3625,6 @@ eud_ep: endpoint { + remote-endpoint = <&usb2_role_switch>; + }; + }; +- +- port@1 { +- reg = <1>; +- eud_con: endpoint { +- remote-endpoint = <&con_eud>; +- }; +- }; + }; + }; + +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-sc7280-link-usb3_phy_wrapper_gcc_usb3.patch b/queue-6.6/arm64-dts-qcom-sc7280-link-usb3_phy_wrapper_gcc_usb3.patch new file mode 100644 index 00000000000..b931ab910a1 --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sc7280-link-usb3_phy_wrapper_gcc_usb3.patch @@ -0,0 +1,39 @@ +From 63e91c21307e6ac630d8b1e37406c8c5b03a86cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Jul 2023 15:09:12 +0300 +Subject: arm64: dts: qcom: sc7280: link usb3_phy_wrapper_gcc_usb30_pipe_clk + +From: Dmitry Baryshkov + +[ Upstream commit 70c4a1ca13b333b00e01266d299605fa1041b0d5 ] + +Use usb_1_ssphy's clock as gcc's usb3_phy_wrapper_gcc_usb30_pipe_clk +clock source. + +Suggested-by: Neil Armstrong +Fixes: 1c39e6f9b534 ("arm64: dts: qcom: sc7280: Add USB related nodes") +Signed-off-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20230711120916.4165894-7-dmitry.baryshkov@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sc7280.dtsi | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi +index 925428a5f6aea..2870fe8fd5263 100644 +--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi +@@ -869,7 +869,8 @@ gcc: clock-controller@100000 { + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>, + <0>, <&pcie1_lane>, +- <0>, <0>, <0>, <0>; ++ <0>, <0>, <0>, ++ <&usb_1_ssphy>; + clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk", + "pcie_0_pipe_clk", "pcie_1_pipe_clk", + "ufs_phy_rx_symbol_0_clk", "ufs_phy_rx_symbol_1_clk", +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-sdm670-fix-pdc-mapping.patch b/queue-6.6/arm64-dts-qcom-sdm670-fix-pdc-mapping.patch new file mode 100644 index 00000000000..0e3f82f3878 --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sdm670-fix-pdc-mapping.patch @@ -0,0 +1,40 @@ +From 82261c2f0a35fe4372305ae4e634664dc06bf6e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Aug 2023 13:19:09 +0200 +Subject: arm64: dts: qcom: sdm670: Fix pdc mapping + +From: Konrad Dybcio + +[ Upstream commit ad75cda991f7b335d3b2417f82db07680f92648a ] + +As pointed out by Richard, I missed a non-continuity in one of the ranges. +Fix it. + +Reported-by: Richard Acayan +Fixes: b51ee205dc4f ("arm64: dts: qcom: sdm670: Add PDC") +Signed-off-by: Konrad Dybcio +Acked-by: Richard Acayan +Link: https://lore.kernel.org/r/20230818-topic-670_pdc_fix-v1-1-1ba025041de7@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdm670.dtsi | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi +index 84cd2e39266fe..ba2043d67370a 100644 +--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi +@@ -1328,7 +1328,8 @@ pdc: interrupt-controller@b220000 { + compatible = "qcom,sdm670-pdc", "qcom,pdc"; + reg = <0 0x0b220000 0 0x30000>; + qcom,pdc-ranges = <0 480 40>, <41 521 7>, <49 529 4>, +- <54 534 24>, <79 559 30>, <115 630 7>; ++ <54 534 24>, <79 559 15>, <94 609 15>, ++ <115 630 7>; + #interrupt-cells = <2>; + interrupt-parent = <&intc>; + interrupt-controller; +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-sdm845-cheza-doesn-t-support-lmh-node.patch b/queue-6.6/arm64-dts-qcom-sdm845-cheza-doesn-t-support-lmh-node.patch new file mode 100644 index 00000000000..50ba42e230e --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sdm845-cheza-doesn-t-support-lmh-node.patch @@ -0,0 +1,56 @@ +From 7dcc99785e589fe6b9df1b0efe38c5e377fc3197 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 12:42:04 +0530 +Subject: arm64: dts: qcom: sdm845: cheza doesn't support LMh node + +From: David Heidelberg + +[ Upstream commit 197ae69d1caedb3203e0b189a39efb820675fd5c ] + +Cheza firmware doesn't allow controlling LMh from the operating system. + +Fixes: 36c6581214c4 ("arm64: dts: qcom: sdm845: Add support for LMh node") +Suggested-by: Dmitry Baryshkov +Signed-off-by: David Heidelberg +Reviewed-by: Douglas Anderson +Reviewed-by: Stephen Boyd +Link: https://lore.kernel.org/r/20230912071205.11502-2-david@ixit.cz +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi +index c118d61f34dec..0ab5e8f53ac9f 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi +@@ -143,6 +143,10 @@ panel_in_edp: endpoint { + }; + }; + ++&cpufreq_hw { ++ /delete-property/ interrupts-extended; /* reference to lmh_cluster[01] */ ++}; ++ + &psci { + /delete-node/ power-domain-cpu0; + /delete-node/ power-domain-cpu1; +@@ -275,6 +279,14 @@ &BIG_CPU_SLEEP_1 + &CLUSTER_SLEEP_0>; + }; + ++&lmh_cluster0 { ++ status = "disabled"; ++}; ++ ++&lmh_cluster1 { ++ status = "disabled"; ++}; ++ + /* + * Reserved memory changes + * +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-sdm845-fix-psci-power-domain-names.patch b/queue-6.6/arm64-dts-qcom-sdm845-fix-psci-power-domain-names.patch new file mode 100644 index 00000000000..15dea11efca --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sdm845-fix-psci-power-domain-names.patch @@ -0,0 +1,66 @@ +From 50af35b9661867e75f5cebaaabc66ea58f4505ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 12:42:03 +0530 +Subject: arm64: dts: qcom: sdm845: Fix PSCI power domain names + +From: David Heidelberg + +[ Upstream commit a5f01673d3946e424091e6b8ff274716f9c21454 ] + +The original commit hasn't been updated according to +refactoring done in sdm845.dtsi. + +Fixes: a1ade6cac5a2 ("arm64: dts: qcom: sdm845: Switch PSCI cpu idle states from PC to OSI") +Suggested-by: Dmitry Baryshkov +Reviewed-by: Douglas Anderson +Signed-off-by: David Heidelberg +Reviewed-by: Stephen Boyd +Reviewed-by: Abel Vesa +Link: https://lore.kernel.org/r/20230912071205.11502-1-david@ixit.cz +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi +index f86e7acdfd99f..c118d61f34dec 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi +@@ -144,15 +144,15 @@ panel_in_edp: endpoint { + }; + + &psci { +- /delete-node/ cpu0; +- /delete-node/ cpu1; +- /delete-node/ cpu2; +- /delete-node/ cpu3; +- /delete-node/ cpu4; +- /delete-node/ cpu5; +- /delete-node/ cpu6; +- /delete-node/ cpu7; +- /delete-node/ cpu-cluster0; ++ /delete-node/ power-domain-cpu0; ++ /delete-node/ power-domain-cpu1; ++ /delete-node/ power-domain-cpu2; ++ /delete-node/ power-domain-cpu3; ++ /delete-node/ power-domain-cpu4; ++ /delete-node/ power-domain-cpu5; ++ /delete-node/ power-domain-cpu6; ++ /delete-node/ power-domain-cpu7; ++ /delete-node/ power-domain-cluster; + }; + + &cpus { +@@ -338,6 +338,8 @@ flash@0 { + + + &apps_rsc { ++ /delete-property/ power-domains; ++ + regulators-0 { + compatible = "qcom,pm8998-rpmh-regulators"; + qcom,pmic-id = "a"; +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-sdm845-mtp-fix-wifi-configuration.patch b/queue-6.6/arm64-dts-qcom-sdm845-mtp-fix-wifi-configuration.patch new file mode 100644 index 00000000000..c956e01a1e3 --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sdm845-mtp-fix-wifi-configuration.patch @@ -0,0 +1,37 @@ +From 1a1058aece4cb7a4deb9f2f4941f7f714cb46c77 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 27 Aug 2023 01:19:11 +0300 +Subject: arm64: dts: qcom: sdm845-mtp: fix WiFi configuration + +From: Dmitry Baryshkov + +[ Upstream commit b33868a52f342d9b1f20aa5bffe40cbd69bd0a4b ] + +Enable the host-cap-8bit quirk on this device. It is required for the +WiFi to function properly. + +Fixes: 022bccb840b7 ("arm64: dts: sdm845: Add WCN3990 WLAN module device node") +Signed-off-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20230826221915.846937-2-dmitry.baryshkov@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts +index b3c27a5247429..1516113391edc 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts +@@ -716,6 +716,8 @@ &wifi { + vdd-1.8-xo-supply = <&vreg_l7a_1p8>; + vdd-1.3-rfa-supply = <&vreg_l17a_1p3>; + vdd-3.3-ch0-supply = <&vreg_l25a_3p3>; ++ ++ qcom,snoc-host-cap-8bit-quirk; + }; + + /* PINCTRL - additions to nodes defined in sdm845.dtsi */ +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-sdx75-idp-align-rpmh-regulator-nodes-.patch b/queue-6.6/arm64-dts-qcom-sdx75-idp-align-rpmh-regulator-nodes-.patch new file mode 100644 index 00000000000..7f96dbc5e7e --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sdx75-idp-align-rpmh-regulator-nodes-.patch @@ -0,0 +1,40 @@ +From 390db3b38486858056cdc149552107f0e75b525b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Sep 2023 18:31:03 +0200 +Subject: arm64: dts: qcom: sdx75-idp: align RPMh regulator nodes with bindings + +From: Krzysztof Kozlowski + +[ Upstream commit 815ea491460766dbd4b39a3c9904b44b5880c41c ] + +Device node names should be generic and bindings expect certain pattern +for RPMh regulator nodes: + + sdx75-idp.dtb: rsc@17a00000: 'pmx75-rpmh-regulators' does not match any of the regexes: '^regulators(-[0-9])?$', 'pinctrl-[0-9]+' + +Fixes: 8a2dc39d1043 ("arm64: dts: qcom: sdx75-idp: Add regulator nodes") +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230905163103.257412-1-krzysztof.kozlowski@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdx75-idp.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdx75-idp.dts b/arch/arm64/boot/dts/qcom/sdx75-idp.dts +index 10d15871f2c48..a14e0650c4a8a 100644 +--- a/arch/arm64/boot/dts/qcom/sdx75-idp.dts ++++ b/arch/arm64/boot/dts/qcom/sdx75-idp.dts +@@ -44,7 +44,7 @@ vreg_bob_3p3: pmx75-bob { + }; + + &apps_rsc { +- pmx75-rpmh-regulators { ++ regulators-0 { + compatible = "qcom,pmx75-rpmh-regulators"; + qcom,pmic-id = "b"; + +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-sm6125-pad-apps-iommu-address-to-8-ch.patch b/queue-6.6/arm64-dts-qcom-sm6125-pad-apps-iommu-address-to-8-ch.patch new file mode 100644 index 00000000000..7693ea9eee5 --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sm6125-pad-apps-iommu-address-to-8-ch.patch @@ -0,0 +1,37 @@ +From 81c3b6780bfa76daea4632408c317edc8c77e835 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 23 Jul 2023 18:08:40 +0200 +Subject: arm64: dts: qcom: sm6125: Pad APPS IOMMU address to 8 characters + +From: Marijn Suijten + +[ Upstream commit 310cdafc4a56827d1aeda7cc297939034adb8f99 ] + +APPS IOMMU is the only node in sm6125.dtsi that doesn't have its +address padded to 8 hexadecimals; fix this by prepending a 0. + +Fixes: 8ddb4bc3d3b5 ("arm64: dts: qcom: sm6125: Configure APPS SMMU") +Signed-off-by: Marijn Suijten +Link: https://lore.kernel.org/r/20230723-sm6125-dpu-v4-2-a3f287dd6c07@somainline.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm6125.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi +index d7c1a40617c64..197f8fed19a29 100644 +--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi +@@ -1208,7 +1208,7 @@ spmi_bus: spmi@1c40000 { + + apps_smmu: iommu@c600000 { + compatible = "qcom,sm6125-smmu-500", "qcom,smmu-500", "arm,mmu-500"; +- reg = <0xc600000 0x80000>; ++ reg = <0x0c600000 0x80000>; + interrupts = , + , + , +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-sm8150-add-ref-clock-to-pcie-phys.patch b/queue-6.6/arm64-dts-qcom-sm8150-add-ref-clock-to-pcie-phys.patch new file mode 100644 index 00000000000..3e1e0cb7298 --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sm8150-add-ref-clock-to-pcie-phys.patch @@ -0,0 +1,56 @@ +From f777a338d4f798f9b6136a811ce555fd8ebe6d7f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 20 Aug 2023 17:20:31 +0300 +Subject: arm64: dts: qcom: sm8150: add ref clock to PCIe PHYs + +From: Dmitry Baryshkov + +[ Upstream commit c204b3709409279ac019f3d374e444bb0b1424f0 ] + +Follow the rest of the platforms and add "ref" clocks to both PCIe PHYs +found on the Qualcomm SM8150 platform. + +Fixes: a1c86c680533 ("arm64: dts: qcom: sm8150: Add PCIe nodes") +Signed-off-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20230820142035.89903-15-dmitry.baryshkov@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm8150.dtsi | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi +index 06c53000bb74d..19c6003dca153 100644 +--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi +@@ -1893,8 +1893,12 @@ pcie0_phy: phy@1c06000 { + ranges; + clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, + <&gcc GCC_PCIE_0_CFG_AHB_CLK>, ++ <&gcc GCC_PCIE_0_CLKREF_CLK>, + <&gcc GCC_PCIE0_PHY_REFGEN_CLK>; +- clock-names = "aux", "cfg_ahb", "refgen"; ++ clock-names = "aux", ++ "cfg_ahb", ++ "ref", ++ "refgen"; + + resets = <&gcc GCC_PCIE_0_PHY_BCR>; + reset-names = "phy"; +@@ -1991,8 +1995,12 @@ pcie1_phy: phy@1c0e000 { + ranges; + clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, + <&gcc GCC_PCIE_1_CFG_AHB_CLK>, ++ <&gcc GCC_PCIE_1_CLKREF_CLK>, + <&gcc GCC_PCIE1_PHY_REFGEN_CLK>; +- clock-names = "aux", "cfg_ahb", "refgen"; ++ clock-names = "aux", ++ "cfg_ahb", ++ "ref", ++ "refgen"; + + resets = <&gcc GCC_PCIE_1_PHY_BCR>; + reset-names = "phy"; +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-qcom-sm8350-fix-pinctrl-for-uart18.patch b/queue-6.6/arm64-dts-qcom-sm8350-fix-pinctrl-for-uart18.patch new file mode 100644 index 00000000000..933075f18fb --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sm8350-fix-pinctrl-for-uart18.patch @@ -0,0 +1,38 @@ +From 9acdab064c0ac1e0044aeabd464e4660fba9a006 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Aug 2023 00:45:48 +0300 +Subject: arm64: dts: qcom: sm8350: fix pinctrl for UART18 + +From: Dmitry Baryshkov + +[ Upstream commit c1efa960114f743924b884da098298512a7e9983 ] + +On sm8350 QUP18 uses GPIO 68/69, not 58/59. Fix correponding UART18 +pinconf configuraion. + +Fixes: 98374e6925b8 ("arm64: dts: qcom: sm8350: Set up WRAP2 QUPs") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230825214550.1650938-1-dmitry.baryshkov@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm8350.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi +index 00604bf7724f4..a94e069da83d5 100644 +--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi +@@ -2964,7 +2964,7 @@ qup_uart6_default: qup-uart6-default-state { + }; + + qup_uart18_default: qup-uart18-default-state { +- pins = "gpio58", "gpio59"; ++ pins = "gpio68", "gpio69"; + function = "qup18"; + drive-strength = <2>; + bias-disable; +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-ti-fix-hdmi-audio-overlay-in-makefile.patch b/queue-6.6/arm64-dts-ti-fix-hdmi-audio-overlay-in-makefile.patch new file mode 100644 index 00000000000..ed3bb20045a --- /dev/null +++ b/queue-6.6/arm64-dts-ti-fix-hdmi-audio-overlay-in-makefile.patch @@ -0,0 +1,48 @@ +From abd16b272847379d7f19e75c8404d3897ab57a6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Oct 2023 14:52:59 +0530 +Subject: arm64: dts: ti: Fix HDMI Audio overlay in Makefile + +From: Aradhya Bhatia + +[ Upstream commit 69c570ebc3964534c19dc4438d3b96f55d489fc3 ] + +Apply HDMI audio overlay to AM625 and AM62-LP SK-EVMs DT binaries, +instead of leaving it in a floating state. + +Fixes: b50ccab9e07c ("arm64: dts: ti: am62x-sk: Add overlay for HDMI audio") +Reported-by: Rob Herring +Signed-off-by: Aradhya Bhatia +Link: https://lore.kernel.org/r/20231003092259.28103-1-a-bhatia1@ti.com +Signed-off-by: Vignesh Raghavendra +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/ti/Makefile | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile +index 51dab9499cd0b..8bd5acc6d6835 100644 +--- a/arch/arm64/boot/dts/ti/Makefile ++++ b/arch/arm64/boot/dts/ti/Makefile +@@ -9,6 +9,8 @@ + # alphabetically. + + # Boards with AM62x SoC ++k3-am625-sk-hdmi-audio-dtbs := k3-am625-sk.dtb k3-am62x-sk-hdmi-audio.dtbo ++k3-am62-lp-sk-hdmi-audio-dtbs := k3-am62-lp-sk.dtb k3-am62x-sk-hdmi-audio.dtbo + dtb-$(CONFIG_ARCH_K3) += k3-am625-beagleplay.dtb + dtb-$(CONFIG_ARCH_K3) += k3-am625-phyboard-lyra-rdk.dtb + dtb-$(CONFIG_ARCH_K3) += k3-am625-sk.dtb +@@ -19,7 +21,8 @@ dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dahlia.dtb + dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-dev.dtb + dtb-$(CONFIG_ARCH_K3) += k3-am625-verdin-wifi-yavia.dtb + dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk.dtb +-dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-hdmi-audio.dtbo ++dtb-$(CONFIG_ARCH_K3) += k3-am625-sk-hdmi-audio.dtb ++dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk-hdmi-audio.dtb + + # Boards with AM62Ax SoC + dtb-$(CONFIG_ARCH_K3) += k3-am62a7-sk.dtb +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-ti-k3-am625-beagleplay-fix-typo-in-ramoops.patch b/queue-6.6/arm64-dts-ti-k3-am625-beagleplay-fix-typo-in-ramoops.patch new file mode 100644 index 00000000000..29f130b1d02 --- /dev/null +++ b/queue-6.6/arm64-dts-ti-k3-am625-beagleplay-fix-typo-in-ramoops.patch @@ -0,0 +1,38 @@ +From a03bc64530158a0b73f628f8172bbbbf62279f48 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Sep 2023 17:14:44 +0200 +Subject: arm64: dts: ti: k3-am625-beagleplay: Fix typo in ramoops reg + +From: Wadim Egorov + +[ Upstream commit 33269ac0b768b07da017df173d52952625c57870 ] + +Seems like the address value of the reg property was mistyped. +Update reg to 0x9ca00000 to match node's definition. + +Fixes: f5a731f0787f ("arm64: dts: ti: Add k3-am625-beagleplay") +Signed-off-by: Wadim Egorov +Reviewed-by: Nishanth Menon +Link: https://lore.kernel.org/r/20230925151444.1856852-1-w.egorov@phytec.de +Signed-off-by: Vignesh Raghavendra +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts +index 7cfdf562b53bf..2de74428a8bde 100644 +--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts ++++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts +@@ -58,7 +58,7 @@ reserved-memory { + + ramoops: ramoops@9ca00000 { + compatible = "ramoops"; +- reg = <0x00 0x9c700000 0x00 0x00100000>; ++ reg = <0x00 0x9ca00000 0x00 0x00100000>; + record-size = <0x8000>; + console-size = <0x8000>; + ftrace-size = <0x00>; +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-ti-k3-am62a7-sk-drop-i2c-1-to-100khz.patch b/queue-6.6/arm64-dts-ti-k3-am62a7-sk-drop-i2c-1-to-100khz.patch new file mode 100644 index 00000000000..8a0d8c39dd3 --- /dev/null +++ b/queue-6.6/arm64-dts-ti-k3-am62a7-sk-drop-i2c-1-to-100khz.patch @@ -0,0 +1,44 @@ +From 55e04dc385f5ea4bef0020a698f14a75fbe44278 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Oct 2023 14:41:32 +0530 +Subject: arm64: dts: ti: k3-am62a7-sk: Drop i2c-1 to 100Khz + +From: Jai Luthra + +[ Upstream commit 63e5aa69b821472a3203a29e17c025329c1b151f ] + +The TLV320AIC3106 audio codec is interfaced on the i2c-1 bus. With the +default rate of 400Khz the i2c register writes fail to sync: + +[ 36.026387] tlv320aic3x 1-001b: Unable to sync registers 0x16-0x16. -110 +[ 38.101130] omap_i2c 20010000.i2c: controller timed out + +Dropping the rate to 100Khz fixes the issue. + +Fixes: 38c4a08c820c ("arm64: dts: ti: Add support for AM62A7-SK") +Reviewed-by: Devarsh Thakkar +Reviewed-by: Aradhya Bhatia +Signed-off-by: Jai Luthra +Link: https://lore.kernel.org/r/20231003-mcasp_am62a-v3-3-2b631ff319ca@ti.com +Signed-off-by: Vignesh Raghavendra +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/ti/k3-am62a7-sk.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts +index cff283c75f8ec..99f2878de4c67 100644 +--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts ++++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts +@@ -250,7 +250,7 @@ &main_i2c1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&main_i2c1_pins_default>; +- clock-frequency = <400000>; ++ clock-frequency = <100000>; + + exp1: gpio@22 { + compatible = "ti,tca6424"; +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-ti-k3-j721s2-evm-gesi-specify-base-dtb-for.patch b/queue-6.6/arm64-dts-ti-k3-j721s2-evm-gesi-specify-base-dtb-for.patch new file mode 100644 index 00000000000..f9373d965f8 --- /dev/null +++ b/queue-6.6/arm64-dts-ti-k3-j721s2-evm-gesi-specify-base-dtb-for.patch @@ -0,0 +1,39 @@ +From e475378a97385a1f595cd51980a3d1b3227315e6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 10:03:08 +0530 +Subject: arm64: dts: ti: k3-j721s2-evm-gesi: Specify base dtb for overlay file + +From: Siddharth Vadapalli + +[ Upstream commit 35be6ac964450687ab39b846d65ee1cb2a352280 ] + +Specify the base dtb file k3-j721s2-common-proc-board.dtb on which the +k3-j721s2-evm-gesi-exp-board.dtbo overlay has to be applied. Name the +resulting dtb as k3-j721s2-evm.dtb. + +Fixes: cac04e27f093 ("arm64: dts: ti: k3-j721s2: Add overlay to enable main CPSW2G with GESI") +Reported-by: Rob Herring +Signed-off-by: Siddharth Vadapalli +Link: https://lore.kernel.org/r/20230912043308.20629-1-s-vadapalli@ti.com +Signed-off-by: Vignesh Raghavendra +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/ti/Makefile | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile +index e7b8e2e7f083d..51dab9499cd0b 100644 +--- a/arch/arm64/boot/dts/ti/Makefile ++++ b/arch/arm64/boot/dts/ti/Makefile +@@ -66,6 +66,8 @@ dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk.dtb + dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-base-board.dtb + dtb-$(CONFIG_ARCH_K3) += k3-j721s2-common-proc-board.dtb + dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-gesi-exp-board.dtbo ++k3-j721s2-evm-dtbs := k3-j721s2-common-proc-board.dtb k3-j721s2-evm-gesi-exp-board.dtbo ++dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm.dtb + + # Boards with J784s4 SoC + dtb-$(CONFIG_ARCH_K3) += k3-am69-sk.dtb +-- +2.42.0 + diff --git a/queue-6.6/arm64-dts-ti-verdin-am62-disable-mipi-dsi-bridge.patch b/queue-6.6/arm64-dts-ti-verdin-am62-disable-mipi-dsi-bridge.patch new file mode 100644 index 00000000000..b03a3566e3d --- /dev/null +++ b/queue-6.6/arm64-dts-ti-verdin-am62-disable-mipi-dsi-bridge.patch @@ -0,0 +1,42 @@ +From 89a81f0319c855d5ed553810b571d0c2bdf6f164 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 14:30:03 +0200 +Subject: arm64: dts: ti: verdin-am62: disable MIPI DSI bridge + +From: Francesco Dolcini + +[ Upstream commit 664e2852aa9142193c2e241327631f032b966742 ] + +Keep the DPI to MIPI-DSI bridge disabled in the SoM dtsi file. + +The display chain is not wholly described in the device tree file, on +Verdin product family the displays are additional accessories that are +configured/enabled using DT overlays. + +With this enabled we have issues when a display is enabled on +TIDSS port1 (LVDS) and port0 (DSI) is not used. + +Fixes: 9e77200356ba ("arm64: dts: ti: verdin-am62: Add DSI display support") +Signed-off-by: Francesco Dolcini +Link: https://lore.kernel.org/r/20230922123003.25002-1-francesco@dolcini.it +Signed-off-by: Vignesh Raghavendra +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi +index 40992e7e4c308..5db52f2372534 100644 +--- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi +@@ -1061,6 +1061,7 @@ dsi_bridge: dsi@e { + vddc-supply = <®_1v2_dsi>; + vddmipi-supply = <®_1v2_dsi>; + vddio-supply = <®_1v8_dsi>; ++ status = "disabled"; + + dsi_bridge_ports: ports { + #address-cells = <1>; +-- +2.42.0 + diff --git a/queue-6.6/arm64-tegra-fix-p3767-card-detect-polarity.patch b/queue-6.6/arm64-tegra-fix-p3767-card-detect-polarity.patch new file mode 100644 index 00000000000..dc0ee7adcc3 --- /dev/null +++ b/queue-6.6/arm64-tegra-fix-p3767-card-detect-polarity.patch @@ -0,0 +1,36 @@ +From 39d0c7e43b2cd40d03755eb5852af1ac58f88bf2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Jun 2023 18:09:19 +0000 +Subject: arm64: tegra: Fix P3767 card detect polarity + +From: Brad Griffis + +[ Upstream commit c6b7a1d11d0fa6333078141251908f48042016e1 ] + +The SD card detect pin is active-low on all Orin Nano and NX SKUs that +have an SD card slot. + +Fixes: 13b0aca303e9 ("arm64: tegra: Support Jetson Orin NX") +Signed-off-by: Brad Griffis +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi +index 5f592f1d81e2e..99dd648038ecb 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi ++++ b/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi +@@ -42,7 +42,7 @@ flash@0 { + mmc@3400000 { + status = "okay"; + bus-width = <4>; +- cd-gpios = <&gpio TEGRA234_MAIN_GPIO(G, 7) GPIO_ACTIVE_HIGH>; ++ cd-gpios = <&gpio TEGRA234_MAIN_GPIO(G, 7) GPIO_ACTIVE_LOW>; + disable-wp; + }; + +-- +2.42.0 + diff --git a/queue-6.6/arm64-tegra-fix-p3767-qspi-speed.patch b/queue-6.6/arm64-tegra-fix-p3767-qspi-speed.patch new file mode 100644 index 00000000000..b3c0d7f9744 --- /dev/null +++ b/queue-6.6/arm64-tegra-fix-p3767-qspi-speed.patch @@ -0,0 +1,37 @@ +From ee0a07256a1d5a76ecfa7b36628b2727db1301b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Jun 2023 18:09:20 +0000 +Subject: arm64: tegra: Fix P3767 QSPI speed + +From: Brad Griffis + +[ Upstream commit 57ea99ba176913c325fc8324a24a1b5e8a6cf520 ] + +The QSPI device used on Jetson Orin NX and Nano modules (p3767) is +the same as Jetson AGX Orin (p3701) and should have a maximum speed of +102 MHz. + +Fixes: 13b0aca303e9 ("arm64: tegra: Support Jetson Orin NX") +Signed-off-by: Brad Griffis +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi +index 99dd648038ecb..fe08e131b7b9e 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi ++++ b/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi +@@ -28,7 +28,7 @@ spi@3270000 { + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; +- spi-max-frequency = <136000000>; ++ spi-max-frequency = <102000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + }; +-- +2.42.0 + diff --git a/queue-6.6/arm64-tegra-use-correct-interrupts-for-tegra234-tke.patch b/queue-6.6/arm64-tegra-use-correct-interrupts-for-tegra234-tke.patch new file mode 100644 index 00000000000..2322ab182fb --- /dev/null +++ b/queue-6.6/arm64-tegra-use-correct-interrupts-for-tegra234-tke.patch @@ -0,0 +1,49 @@ +From 4e44c34f5cee5586777087d43dd9921c81007f22 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Oct 2023 14:43:11 +0200 +Subject: arm64: tegra: Use correct interrupts for Tegra234 TKE + +From: Thierry Reding + +[ Upstream commit c0b80988eb78d6423249ab530bfbc6b238790a26 ] + +The shared interrupts 0-9 of the TKE are mapped to interrupts 0-9, but +shared interrupts 10-15 are mapped to 256-261. Correct the mapping for +the final 6 interrupts. This prevents the TKE from requesting the RTC +interrupt (along with several GTE and watchdog interrupts). + +Reported-by: Shubhi Garg +Fixes: 28d860ed02c2 ("arm64: tegra: Enable native timers on Tegra234") +Reviewed-by: Jon Hunter +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/nvidia/tegra234.dtsi | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi +index 95524e5bce826..ac69eacf8a6ba 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi ++++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi +@@ -43,12 +43,12 @@ timer@2080000 { + , + , + , +- , +- , +- , +- , +- , +- ; ++ , ++ , ++ , ++ , ++ , ++ ; + status = "okay"; + }; + +-- +2.42.0 + diff --git a/queue-6.6/asoc-ams-delta.c-use-component-after-check.patch b/queue-6.6/asoc-ams-delta.c-use-component-after-check.patch new file mode 100644 index 00000000000..ad9670b025d --- /dev/null +++ b/queue-6.6/asoc-ams-delta.c-use-component-after-check.patch @@ -0,0 +1,56 @@ +From c843ad3da899a62428de1d5dea9e7662061dc339 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Oct 2023 00:09:56 +0000 +Subject: ASoC: ams-delta.c: use component after check + +From: Kuninori Morimoto + +[ Upstream commit bd0f7498bc9084d8cccc5484cd004b40f314b763 ] + + static void cx81801_close() + { + ... +(A) struct snd_soc_dapm_context *dapm = &component->card->dapm; + ... +(B) if (!component) + return; + } + +(A) uses component before NULL check (B). This patch moves it after (B). + +Fixes: d0fdfe34080c ("ASoC: cx20442: replace codec to component") +Reported-by: Dan Carpenter +Closes: https://lore.kernel.org/r/3e608474-e99a-4866-ae98-3054a4221f09@moroto.mountain +Signed-off-by: Kuninori Morimoto +Link: https://lore.kernel.org/r/87ttqdq623.wl-kuninori.morimoto.gx@renesas.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/ti/ams-delta.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/ti/ams-delta.c b/sound/soc/ti/ams-delta.c +index 666057d50ea0d..dd3f59bb72faf 100644 +--- a/sound/soc/ti/ams-delta.c ++++ b/sound/soc/ti/ams-delta.c +@@ -303,7 +303,7 @@ static int cx81801_open(struct tty_struct *tty) + static void cx81801_close(struct tty_struct *tty) + { + struct snd_soc_component *component = tty->disc_data; +- struct snd_soc_dapm_context *dapm = &component->card->dapm; ++ struct snd_soc_dapm_context *dapm; + + del_timer_sync(&cx81801_timer); + +@@ -315,6 +315,8 @@ static void cx81801_close(struct tty_struct *tty) + + v253_ops.close(tty); + ++ dapm = &component->card->dapm; ++ + /* Revert back to default audio input/output constellation */ + snd_soc_dapm_mutex_lock(dapm); + +-- +2.42.0 + diff --git a/queue-6.6/asoc-cs35l41-fix-broken-shared-boost-activation.patch b/queue-6.6/asoc-cs35l41-fix-broken-shared-boost-activation.patch new file mode 100644 index 00000000000..d0dec8097d0 --- /dev/null +++ b/queue-6.6/asoc-cs35l41-fix-broken-shared-boost-activation.patch @@ -0,0 +1,272 @@ +From 2ece4ae747e8acaadff3a6308f515296d6c4a610 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 20:10:03 +0300 +Subject: ASoC: cs35l41: Fix broken shared boost activation + +From: Cristian Ciocaltea + +[ Upstream commit 77bf613f0bf08c021309cdb5f84b5f630b829261 ] + +Enabling the active/passive shared boosts requires setting SYNC_EN, but +*not* before receiving the PLL Lock signal. + +Due to improper error handling, it was not obvious that waiting for the +completion operation times out and, consequently, the shared boost is +never activated. + +Further investigations revealed the signal is triggered while +snd_pcm_start() is executed, right after receiving the +SNDRV_PCM_TRIGGER_START command, which happens long after the +SND_SOC_DAPM_PRE_PMU event handler is invoked as part of +snd_pcm_prepare(). That is where cs35l41_global_enable() is called +from. + +Increasing the wait duration doesn't help, as it only causes an +unnecessary delay in the invocation of snd_pcm_start(). Moving the wait +and the subsequent regmap operations to the SNDRV_PCM_TRIGGER_START +callback is not a solution either, since they would be executed in an +IRQ-off atomic context. + +Solve the issue by setting the SYNC_EN bit in PWR_CTRL3 register right +after receiving the PLL Lock interrupt. + +Additionally, drop the unnecessary writes to PWR_CTRL1 register, part of +the original mdsync_up_seq, which would have toggled GLOBAL_EN with +unwanted consequences on PLL locking behavior. + +Fixes: f5030564938b ("ALSA: cs35l41: Add shared boost feature") +Signed-off-by: Cristian Ciocaltea +Reviewed-by: David Rhodes +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/20230907171010.1447274-5-cristian.ciocaltea@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + include/sound/cs35l41.h | 4 +-- + sound/pci/hda/cs35l41_hda.c | 4 +-- + sound/soc/codecs/cs35l41-lib.c | 61 ++++++++++++++++++++-------------- + sound/soc/codecs/cs35l41.c | 24 ++++++++----- + sound/soc/codecs/cs35l41.h | 1 - + 5 files changed, 55 insertions(+), 39 deletions(-) + +diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h +index 1bf757901d024..2fe8c6b0d4cf3 100644 +--- a/include/sound/cs35l41.h ++++ b/include/sound/cs35l41.h +@@ -11,7 +11,6 @@ + #define __CS35L41_H + + #include +-#include + #include + + #define CS35L41_FIRSTREG 0x00000000 +@@ -902,7 +901,8 @@ int cs35l41_exit_hibernate(struct device *dev, struct regmap *regmap); + int cs35l41_init_boost(struct device *dev, struct regmap *regmap, + struct cs35l41_hw_cfg *hw_cfg); + bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type); ++int cs35l41_mdsync_up(struct regmap *regmap); + int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l41_boost_type b_type, +- int enable, struct completion *pll_lock, bool firmware_running); ++ int enable, bool firmware_running); + + #endif /* __CS35L41_H */ +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index c6031f7440996..055ebfc237352 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -570,7 +570,7 @@ static void cs35l41_hda_play_done(struct device *dev) + + dev_dbg(dev, "Play (Complete)\n"); + +- cs35l41_global_enable(dev, reg, cs35l41->hw_cfg.bst_type, 1, NULL, ++ cs35l41_global_enable(dev, reg, cs35l41->hw_cfg.bst_type, 1, + cs35l41->firmware_running); + if (cs35l41->firmware_running) { + regmap_multi_reg_write(reg, cs35l41_hda_unmute_dsp, +@@ -589,7 +589,7 @@ static void cs35l41_hda_pause_start(struct device *dev) + dev_dbg(dev, "Pause (Start)\n"); + + regmap_multi_reg_write(reg, cs35l41_hda_mute, ARRAY_SIZE(cs35l41_hda_mute)); +- cs35l41_global_enable(dev, reg, cs35l41->hw_cfg.bst_type, 0, NULL, ++ cs35l41_global_enable(dev, reg, cs35l41->hw_cfg.bst_type, 0, + cs35l41->firmware_running); + } + +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index a6c6bb23b9574..2ec5fdc875b13 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -1192,8 +1192,28 @@ bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type) + } + EXPORT_SYMBOL_GPL(cs35l41_safe_reset); + ++/* ++ * Enabling the CS35L41_SHD_BOOST_ACTV and CS35L41_SHD_BOOST_PASS shared boosts ++ * does also require a call to cs35l41_mdsync_up(), but not before getting the ++ * PLL Lock signal. ++ * ++ * PLL Lock seems to be triggered soon after snd_pcm_start() is executed and ++ * SNDRV_PCM_TRIGGER_START command is processed, which happens (long) after the ++ * SND_SOC_DAPM_PRE_PMU event handler is invoked as part of snd_pcm_prepare(). ++ * ++ * This event handler is where cs35l41_global_enable() is normally called from, ++ * but waiting for PLL Lock here will time out. Increasing the wait duration ++ * will not help, as the only consequence of it would be to add an unnecessary ++ * delay in the invocation of snd_pcm_start(). ++ * ++ * Trying to move the wait in the SNDRV_PCM_TRIGGER_START callback is not a ++ * solution either, as the trigger is executed in an IRQ-off atomic context. ++ * ++ * The current approach is to invoke cs35l41_mdsync_up() right after receiving ++ * the PLL Lock interrupt, in the IRQ handler. ++ */ + int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l41_boost_type b_type, +- int enable, struct completion *pll_lock, bool firmware_running) ++ int enable, bool firmware_running) + { + int ret; + unsigned int gpio1_func, pad_control, pwr_ctrl1, pwr_ctrl3, int_status, pup_pdn_mask; +@@ -1203,11 +1223,6 @@ int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l4 + {CS35L41_GPIO_PAD_CONTROL, 0}, + {CS35L41_PWR_CTRL1, 0, 3000}, + }; +- struct reg_sequence cs35l41_mdsync_up_seq[] = { +- {CS35L41_PWR_CTRL3, 0}, +- {CS35L41_PWR_CTRL1, 0x00000000, 3000}, +- {CS35L41_PWR_CTRL1, 0x00000001, 3000}, +- }; + + pup_pdn_mask = enable ? CS35L41_PUP_DONE_MASK : CS35L41_PDN_DONE_MASK; + +@@ -1241,26 +1256,11 @@ int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l4 + cs35l41_mdsync_down_seq[0].def = pwr_ctrl3; + cs35l41_mdsync_down_seq[1].def = pad_control; + cs35l41_mdsync_down_seq[2].def = pwr_ctrl1; ++ + ret = regmap_multi_reg_write(regmap, cs35l41_mdsync_down_seq, + ARRAY_SIZE(cs35l41_mdsync_down_seq)); +- if (ret || !enable) +- break; +- +- if (!pll_lock) +- return -EINVAL; +- +- ret = wait_for_completion_timeout(pll_lock, msecs_to_jiffies(1000)); +- if (ret == 0) { +- dev_err(dev, "Timed out waiting for pll_lock\n"); +- return -ETIMEDOUT; +- } +- +- regmap_read(regmap, CS35L41_PWR_CTRL3, &pwr_ctrl3); +- pwr_ctrl3 |= CS35L41_SYNC_EN_MASK; +- cs35l41_mdsync_up_seq[0].def = pwr_ctrl3; +- ret = regmap_multi_reg_write(regmap, cs35l41_mdsync_up_seq, +- ARRAY_SIZE(cs35l41_mdsync_up_seq)); +- if (ret) ++ /* Activation to be completed later via cs35l41_mdsync_up() */ ++ if (ret || enable) + return ret; + + ret = regmap_read_poll_timeout(regmap, CS35L41_IRQ1_STATUS1, +@@ -1269,7 +1269,7 @@ int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l4 + if (ret) + dev_err(dev, "Enable(%d) failed: %d\n", enable, ret); + +- // Clear PUP/PDN status ++ /* Clear PUP/PDN status */ + regmap_write(regmap, CS35L41_IRQ1_STATUS1, pup_pdn_mask); + break; + case CS35L41_INT_BOOST: +@@ -1351,6 +1351,17 @@ int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l4 + } + EXPORT_SYMBOL_GPL(cs35l41_global_enable); + ++/* ++ * To be called after receiving the IRQ Lock interrupt, in order to complete ++ * any shared boost activation initiated by cs35l41_global_enable(). ++ */ ++int cs35l41_mdsync_up(struct regmap *regmap) ++{ ++ return regmap_update_bits(regmap, CS35L41_PWR_CTRL3, ++ CS35L41_SYNC_EN_MASK, CS35L41_SYNC_EN_MASK); ++} ++EXPORT_SYMBOL_GPL(cs35l41_mdsync_up); ++ + int cs35l41_gpio_config(struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg) + { + struct cs35l41_gpio_cfg *gpio1 = &hw_cfg->gpio1; +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index fe5376b3e01b9..12327b4c3d563 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -459,7 +459,19 @@ static irqreturn_t cs35l41_irq(int irq, void *data) + + if (status[2] & CS35L41_PLL_LOCK) { + regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS3, CS35L41_PLL_LOCK); +- complete(&cs35l41->pll_lock); ++ ++ if (cs35l41->hw_cfg.bst_type == CS35L41_SHD_BOOST_ACTV || ++ cs35l41->hw_cfg.bst_type == CS35L41_SHD_BOOST_PASS) { ++ ret = cs35l41_mdsync_up(cs35l41->regmap); ++ if (ret) ++ dev_err(cs35l41->dev, "MDSYNC-up failed: %d\n", ret); ++ else ++ dev_dbg(cs35l41->dev, "MDSYNC-up done\n"); ++ ++ dev_dbg(cs35l41->dev, "PUP-done status: %d\n", ++ !!(status[0] & CS35L41_PUP_DONE_MASK)); ++ } ++ + ret = IRQ_HANDLED; + } + +@@ -500,11 +512,11 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, + ARRAY_SIZE(cs35l41_pup_patch)); + + ret = cs35l41_global_enable(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type, +- 1, &cs35l41->pll_lock, cs35l41->dsp.cs_dsp.running); ++ 1, cs35l41->dsp.cs_dsp.running); + break; + case SND_SOC_DAPM_POST_PMD: + ret = cs35l41_global_enable(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type, +- 0, &cs35l41->pll_lock, cs35l41->dsp.cs_dsp.running); ++ 0, cs35l41->dsp.cs_dsp.running); + + regmap_multi_reg_write_bypassed(cs35l41->regmap, + cs35l41_pdn_patch, +@@ -802,10 +814,6 @@ static const struct snd_pcm_hw_constraint_list cs35l41_constraints = { + static int cs35l41_pcm_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) + { +- struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component); +- +- reinit_completion(&cs35l41->pll_lock); +- + if (substream->runtime) + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, +@@ -1273,8 +1281,6 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg * + regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK3, CS35L41_INT3_PLL_LOCK_MASK, + 0 << CS35L41_INT3_PLL_LOCK_SHIFT); + +- init_completion(&cs35l41->pll_lock); +- + ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, cs35l41_irq, + IRQF_ONESHOT | IRQF_SHARED | irq_pol, + "cs35l41", cs35l41); +diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h +index 34d967d4372b2..c85cbc1dd333b 100644 +--- a/sound/soc/codecs/cs35l41.h ++++ b/sound/soc/codecs/cs35l41.h +@@ -33,7 +33,6 @@ struct cs35l41_private { + int irq; + /* GPIO for /RST */ + struct gpio_desc *reset_gpio; +- struct completion pll_lock; + }; + + int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *hw_cfg); +-- +2.42.0 + diff --git a/queue-6.6/asoc-cs35l41-handle-mdsync_down-reg-write-errors.patch b/queue-6.6/asoc-cs35l41-handle-mdsync_down-reg-write-errors.patch new file mode 100644 index 00000000000..964a4f0ff18 --- /dev/null +++ b/queue-6.6/asoc-cs35l41-handle-mdsync_down-reg-write-errors.patch @@ -0,0 +1,44 @@ +From 47470bc62f92c94b7e52ce9b69fc5bb9c791deff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 20:10:00 +0300 +Subject: ASoC: cs35l41: Handle mdsync_down reg write errors + +From: Cristian Ciocaltea + +[ Upstream commit a9a3f54a23d844971c274f352500dddeadb4412c ] + +The return code of regmap_multi_reg_write() call related to "MDSYNC +down" sequence is shadowed by the subsequent +wait_for_completion_timeout() invocation, which is expected to time +timeout in case the write operation failed. + +Let cs35l41_global_enable() return the correct error code instead of +-ETIMEDOUT. + +Fixes: f5030564938b ("ALSA: cs35l41: Add shared boost feature") +Signed-off-by: Cristian Ciocaltea +Acked-by: Charles Keepax +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/20230907171010.1447274-2-cristian.ciocaltea@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/cs35l41-lib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index 4ec306cd2f476..a018f1d984286 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -1243,7 +1243,7 @@ int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l4 + cs35l41_mdsync_down_seq[2].def = pwr_ctrl1; + ret = regmap_multi_reg_write(regmap, cs35l41_mdsync_down_seq, + ARRAY_SIZE(cs35l41_mdsync_down_seq)); +- if (!enable) ++ if (ret || !enable) + break; + + if (!pll_lock) +-- +2.42.0 + diff --git a/queue-6.6/asoc-cs35l41-handle-mdsync_up-reg-write-errors.patch b/queue-6.6/asoc-cs35l41-handle-mdsync_up-reg-write-errors.patch new file mode 100644 index 00000000000..0b5bccfbf6c --- /dev/null +++ b/queue-6.6/asoc-cs35l41-handle-mdsync_up-reg-write-errors.patch @@ -0,0 +1,66 @@ +From ec3faa4925c5d0b865a87ee5173280138c6d3ba6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 20:10:01 +0300 +Subject: ASoC: cs35l41: Handle mdsync_up reg write errors + +From: Cristian Ciocaltea + +[ Upstream commit 4bb5870ab60abca6ad18196090831b5e4cf82d93 ] + +The return code of regmap_multi_reg_write() call related to "MDSYNC up" +sequence is shadowed by the subsequent regmap_read_poll_timeout() +invocation, which will hit a timeout in case the write operation above +fails. + +Make sure cs35l41_global_enable() returns the correct error code instead +of -ETIMEDOUT. + +Additionally, to be able to distinguish between the timeouts of +wait_for_completion_timeout() and regmap_read_poll_timeout(), print an +error message for the former and return immediately. This also avoids +having to wait unnecessarily for the second time. + +Fixes: f8264c759208 ("ALSA: cs35l41: Poll for Power Up/Down rather than waiting a fixed delay") +Signed-off-by: Cristian Ciocaltea +Acked-by: Charles Keepax +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/20230907171010.1447274-3-cristian.ciocaltea@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/cs35l41-lib.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c +index a018f1d984286..a6c6bb23b9574 100644 +--- a/sound/soc/codecs/cs35l41-lib.c ++++ b/sound/soc/codecs/cs35l41-lib.c +@@ -1251,15 +1251,18 @@ int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l4 + + ret = wait_for_completion_timeout(pll_lock, msecs_to_jiffies(1000)); + if (ret == 0) { +- ret = -ETIMEDOUT; +- } else { +- regmap_read(regmap, CS35L41_PWR_CTRL3, &pwr_ctrl3); +- pwr_ctrl3 |= CS35L41_SYNC_EN_MASK; +- cs35l41_mdsync_up_seq[0].def = pwr_ctrl3; +- ret = regmap_multi_reg_write(regmap, cs35l41_mdsync_up_seq, +- ARRAY_SIZE(cs35l41_mdsync_up_seq)); ++ dev_err(dev, "Timed out waiting for pll_lock\n"); ++ return -ETIMEDOUT; + } + ++ regmap_read(regmap, CS35L41_PWR_CTRL3, &pwr_ctrl3); ++ pwr_ctrl3 |= CS35L41_SYNC_EN_MASK; ++ cs35l41_mdsync_up_seq[0].def = pwr_ctrl3; ++ ret = regmap_multi_reg_write(regmap, cs35l41_mdsync_up_seq, ++ ARRAY_SIZE(cs35l41_mdsync_up_seq)); ++ if (ret) ++ return ret; ++ + ret = regmap_read_poll_timeout(regmap, CS35L41_IRQ1_STATUS1, + int_status, int_status & pup_pdn_mask, + 1000, 100000); +-- +2.42.0 + diff --git a/queue-6.6/asoc-cs35l41-initialize-completion-object-before-req.patch b/queue-6.6/asoc-cs35l41-initialize-completion-object-before-req.patch new file mode 100644 index 00000000000..ffcc1f42682 --- /dev/null +++ b/queue-6.6/asoc-cs35l41-initialize-completion-object-before-req.patch @@ -0,0 +1,49 @@ +From 7acaee76e3f9b5e4d7f57dfa757139c6c0b758ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 20:10:02 +0300 +Subject: ASoC: cs35l41: Initialize completion object before requesting IRQ + +From: Cristian Ciocaltea + +[ Upstream commit 5ad668a9ce83d819701fb7abc1c2236049ec15c2 ] + +Technically, an interrupt handler can be called before probe() finishes +its execution, hence ensure the pll_lock completion object is always +initialized before being accessed in cs35l41_irq(). + +Fixes: f5030564938b ("ALSA: cs35l41: Add shared boost feature") +Signed-off-by: Cristian Ciocaltea +Acked-by: Charles Keepax +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/20230907171010.1447274-4-cristian.ciocaltea@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/cs35l41.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 722b69a6de26c..fe5376b3e01b9 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -1273,6 +1273,8 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg * + regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK3, CS35L41_INT3_PLL_LOCK_MASK, + 0 << CS35L41_INT3_PLL_LOCK_SHIFT); + ++ init_completion(&cs35l41->pll_lock); ++ + ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, cs35l41_irq, + IRQF_ONESHOT | IRQF_SHARED | irq_pol, + "cs35l41", cs35l41); +@@ -1295,8 +1297,6 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg * + if (ret < 0) + goto err; + +- init_completion(&cs35l41->pll_lock); +- + pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000); + pm_runtime_use_autosuspend(cs35l41->dev); + pm_runtime_mark_last_busy(cs35l41->dev); +-- +2.42.0 + diff --git a/queue-6.6/asoc-cs35l41-undo-runtime-pm-changes-at-driver-exit-.patch b/queue-6.6/asoc-cs35l41-undo-runtime-pm-changes-at-driver-exit-.patch new file mode 100644 index 00000000000..734ce7d672d --- /dev/null +++ b/queue-6.6/asoc-cs35l41-undo-runtime-pm-changes-at-driver-exit-.patch @@ -0,0 +1,53 @@ +From 23bce1fef2ebd5f57c8ebb28b012e8bac8ed6b35 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 20:10:05 +0300 +Subject: ASoC: cs35l41: Undo runtime PM changes at driver exit time + +From: Cristian Ciocaltea + +[ Upstream commit 2d5661e6008ae1a1cd6df7cc844908fb8b982c58 ] + +According to the documentation, drivers are responsible for undoing at +removal time all runtime PM changes done during probing. + +Hence, add the missing calls to pm_runtime_dont_use_autosuspend(), which +are necessary for undoing pm_runtime_use_autosuspend(). + +Note this would have been handled implicitly by +devm_pm_runtime_enable(), but there is a need to continue using +pm_runtime_enable()/pm_runtime_disable() in order to ensure the runtime +PM is disabled as soon as the remove() callback is entered. + +Fixes: f517ba4924ad ("ASoC: cs35l41: Add support for hibernate memory retention mode") +Signed-off-by: Cristian Ciocaltea +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/20230907171010.1447274-7-cristian.ciocaltea@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/cs35l41.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index a31cb9ba7f7de..5456e6bfa242f 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -1334,6 +1334,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg * + return 0; + + err_pm: ++ pm_runtime_dont_use_autosuspend(cs35l41->dev); + pm_runtime_disable(cs35l41->dev); + pm_runtime_put_noidle(cs35l41->dev); + +@@ -1350,6 +1351,7 @@ EXPORT_SYMBOL_GPL(cs35l41_probe); + void cs35l41_remove(struct cs35l41_private *cs35l41) + { + pm_runtime_get_sync(cs35l41->dev); ++ pm_runtime_dont_use_autosuspend(cs35l41->dev); + pm_runtime_disable(cs35l41->dev); + + regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF); +-- +2.42.0 + diff --git a/queue-6.6/asoc-cs35l41-verify-pm-runtime-resume-errors-in-irq-.patch b/queue-6.6/asoc-cs35l41-verify-pm-runtime-resume-errors-in-irq-.patch new file mode 100644 index 00000000000..b9e10cd5e2a --- /dev/null +++ b/queue-6.6/asoc-cs35l41-verify-pm-runtime-resume-errors-in-irq-.patch @@ -0,0 +1,55 @@ +From 1a4fd579a05fc5a2541c7ccab075474df6e20074 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 20:10:04 +0300 +Subject: ASoC: cs35l41: Verify PM runtime resume errors in IRQ handler + +From: Cristian Ciocaltea + +[ Upstream commit 9f8948db9849d202dee3570507d3a0642f92d632 ] + +The interrupt handler invokes pm_runtime_get_sync() without checking the +returned error code. + +Add a proper verification and switch to pm_runtime_resume_and_get(), to +avoid the need to call pm_runtime_put_noidle() for decrementing the PM +usage counter before returning from the error condition. + +Fixes: f517ba4924ad ("ASoC: cs35l41: Add support for hibernate memory retention mode") +Signed-off-by: Cristian Ciocaltea +Acked-by: Charles Keepax +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/20230907171010.1447274-6-cristian.ciocaltea@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/cs35l41.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c +index 12327b4c3d563..a31cb9ba7f7de 100644 +--- a/sound/soc/codecs/cs35l41.c ++++ b/sound/soc/codecs/cs35l41.c +@@ -386,10 +386,18 @@ static irqreturn_t cs35l41_irq(int irq, void *data) + struct cs35l41_private *cs35l41 = data; + unsigned int status[4] = { 0, 0, 0, 0 }; + unsigned int masks[4] = { 0, 0, 0, 0 }; +- int ret = IRQ_NONE; + unsigned int i; ++ int ret; + +- pm_runtime_get_sync(cs35l41->dev); ++ ret = pm_runtime_resume_and_get(cs35l41->dev); ++ if (ret < 0) { ++ dev_err(cs35l41->dev, ++ "pm_runtime_resume_and_get failed in %s: %d\n", ++ __func__, ret); ++ return IRQ_NONE; ++ } ++ ++ ret = IRQ_NONE; + + for (i = 0; i < ARRAY_SIZE(status); i++) { + regmap_read(cs35l41->regmap, +-- +2.42.0 + diff --git a/queue-6.6/asoc-fsl-asoc-card-add-comment-for-mclk-in-the-codec.patch b/queue-6.6/asoc-fsl-asoc-card-add-comment-for-mclk-in-the-codec.patch new file mode 100644 index 00000000000..f3d59ae3595 --- /dev/null +++ b/queue-6.6/asoc-fsl-asoc-card-add-comment-for-mclk-in-the-codec.patch @@ -0,0 +1,37 @@ +From c9ad5ecfb56c60963f1ad707152d2a00618212e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Oct 2023 12:01:17 +0800 +Subject: ASoC: fsl-asoc-card: Add comment for mclk in the codec_priv + +From: Hui Wang + +[ Upstream commit fbfe616ad40c06d68b83b657a94cd2e709dda37b ] + +Otherwise a warning will be detected as below: +warning: Function parameter or member 'mclk' not described in +'codec_priv' + +Fixes: 1075df4bdeb3 ("ASoC: fsl-asoc-card: add nau8822 support") +Signed-off-by: Hui Wang +Link: https://lore.kernel.org/r/20231007040117.22446-1-hui.wang@canonical.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl-asoc-card.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c +index bab7d34cf585b..5f181b89838ac 100644 +--- a/sound/soc/fsl/fsl-asoc-card.c ++++ b/sound/soc/fsl/fsl-asoc-card.c +@@ -41,6 +41,7 @@ + + /** + * struct codec_priv - CODEC private data ++ * @mclk: Main clock of the CODEC + * @mclk_freq: Clock rate of MCLK + * @free_freq: Clock rate of MCLK for hw_free() + * @mclk_id: MCLK (or main clock) id for set_sysclk() +-- +2.42.0 + diff --git a/queue-6.6/asoc-fsl-fix-pm-disable-depth-imbalance-in-fsl_easrc.patch b/queue-6.6/asoc-fsl-fix-pm-disable-depth-imbalance-in-fsl_easrc.patch new file mode 100644 index 00000000000..11df2accee6 --- /dev/null +++ b/queue-6.6/asoc-fsl-fix-pm-disable-depth-imbalance-in-fsl_easrc.patch @@ -0,0 +1,54 @@ +From add55bd59a10a3427e4eaefa17eb0ab202615204 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Oct 2023 21:03:15 +0800 +Subject: ASoC: fsl: Fix PM disable depth imbalance in fsl_easrc_probe + +From: Zhang Shurong + +[ Upstream commit 9e630efb5a4af56fdb15aa10405f5cfd3f5f5b83 ] + +The pm_runtime_enable will increase power disable depth. Thus +a pairing decrement is needed on the error handling path to +keep it balanced according to context. We fix it by calling +pm_runtime_disable when error returns. + +Fixes: 955ac624058f ("ASoC: fsl_easrc: Add EASRC ASoC CPU DAI drivers") +Signed-off-by: Zhang Shurong +Link: https://lore.kernel.org/r/tencent_C0D62E6D89818179A02A04A0C248F0DDC40A@qq.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_easrc.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c +index ba62995c909ac..ec53bda46a467 100644 +--- a/sound/soc/fsl/fsl_easrc.c ++++ b/sound/soc/fsl/fsl_easrc.c +@@ -1966,17 +1966,21 @@ static int fsl_easrc_probe(struct platform_device *pdev) + &fsl_easrc_dai, 1); + if (ret) { + dev_err(dev, "failed to register ASoC DAI\n"); +- return ret; ++ goto err_pm_disable; + } + + ret = devm_snd_soc_register_component(dev, &fsl_asrc_component, + NULL, 0); + if (ret) { + dev_err(&pdev->dev, "failed to register ASoC platform\n"); +- return ret; ++ goto err_pm_disable; + } + + return 0; ++ ++err_pm_disable: ++ pm_runtime_disable(&pdev->dev); ++ return ret; + } + + static void fsl_easrc_remove(struct platform_device *pdev) +-- +2.42.0 + diff --git a/queue-6.6/asoc-fsl-mpc5200_dma.c-fix-warning-of-function-param.patch b/queue-6.6/asoc-fsl-mpc5200_dma.c-fix-warning-of-function-param.patch new file mode 100644 index 00000000000..c6ec30062f4 --- /dev/null +++ b/queue-6.6/asoc-fsl-mpc5200_dma.c-fix-warning-of-function-param.patch @@ -0,0 +1,45 @@ +From df1d588ce9b83b6850ae8469cd6c12dc3b009889 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 23:39:43 +0000 +Subject: ASoC: fsl: mpc5200_dma.c: Fix warning of Function parameter or member + not described + +From: Kuninori Morimoto + +[ Upstream commit 4a221b2e3340f4a3c2b414c46c846a26c6caf820 ] + +This patch fixes the warnings of "Function parameter or member 'xxx' +not described". + +>> sound/soc/fsl/mpc5200_dma.c:116: warning: Function parameter or member 'component' not described in 'psc_dma_trigger' + sound/soc/fsl/mpc5200_dma.c:116: warning: Function parameter or member 'substream' not described in 'psc_dma_trigger' + sound/soc/fsl/mpc5200_dma.c:116: warning: Function parameter or member 'cmd' not described in 'psc_dma_trigger' + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202310061914.jJuekdHs-lkp@intel.com/ +Signed-off-by: Kuninori Morimoto +Fixes: 6d1048bc1152 ("ASoC: fsl: mpc5200_dma: remove snd_pcm_ops") +Link: https://lore.kernel.org/r/87il7fcqm8.wl-kuninori.morimoto.gx@renesas.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/mpc5200_dma.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c +index 9014978100207..3f7ccae3f6b1a 100644 +--- a/sound/soc/fsl/mpc5200_dma.c ++++ b/sound/soc/fsl/mpc5200_dma.c +@@ -100,6 +100,9 @@ static irqreturn_t psc_dma_bcom_irq(int irq, void *_psc_dma_stream) + + /** + * psc_dma_trigger: start and stop the DMA transfer. ++ * @component: triggered component ++ * @substream: triggered substream ++ * @cmd: triggered command + * + * This function is called by ALSA to start, stop, pause, and resume the DMA + * transfer of data. +-- +2.42.0 + diff --git a/queue-6.6/asoc-intel-skylake-fix-mem-leak-when-parsing-uuids-f.patch b/queue-6.6/asoc-intel-skylake-fix-mem-leak-when-parsing-uuids-f.patch new file mode 100644 index 00000000000..33a0d7de81d --- /dev/null +++ b/queue-6.6/asoc-intel-skylake-fix-mem-leak-when-parsing-uuids-f.patch @@ -0,0 +1,40 @@ +From d750bc3f54078fdd64e63c6fb68fd4e30c31b1de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Oct 2023 10:25:58 +0200 +Subject: ASoC: Intel: Skylake: Fix mem leak when parsing UUIDs fails +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Cezary Rojewski + +[ Upstream commit 168d97844a61db302dec76d44406e9d4d7106b8e ] + +Error path in snd_skl_parse_uuids() shall free last allocated module if +its instance_id allocation fails. + +Fixes: f8e066521192 ("ASoC: Intel: Skylake: Fix uuid_module memory leak in failure case") +Signed-off-by: Cezary Rojewski +Signed-off-by: Amadeusz Sławiński +Link: https://lore.kernel.org/r/20231026082558.1864910-1-amadeuszx.slawinski@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/skylake/skl-sst-utils.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c +index 57ea815d3f041..b776c58dcf47a 100644 +--- a/sound/soc/intel/skylake/skl-sst-utils.c ++++ b/sound/soc/intel/skylake/skl-sst-utils.c +@@ -299,6 +299,7 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw, + module->instance_id = devm_kzalloc(ctx->dev, size, GFP_KERNEL); + if (!module->instance_id) { + ret = -ENOMEM; ++ kfree(module); + goto free_uuid_list; + } + +-- +2.42.0 + diff --git a/queue-6.6/asoc-intel-sof_sdw-stop-processing-codecs-when-enoug.patch b/queue-6.6/asoc-intel-sof_sdw-stop-processing-codecs-when-enoug.patch new file mode 100644 index 00000000000..0b67e50c300 --- /dev/null +++ b/queue-6.6/asoc-intel-sof_sdw-stop-processing-codecs-when-enoug.patch @@ -0,0 +1,52 @@ +From 3f596aabfd2067e7ec3f4e9f70c17c787db07fe0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Oct 2023 12:34:02 -0500 +Subject: ASoC: intel: sof_sdw: Stop processing CODECs when enough are found + +From: Charles Keepax + +[ Upstream commit 28809aaeabdf2c01ffe597553146527d1fba3589 ] + +When adding CODECs to a DAI link, the code should stop processing more +CODECs when the expected number of CODECs are discovered. This fixes a +small corner case issue introduced when support for different devices +on the same SoundWire link was added. In the case of aggregated +devices everything is fine, as all devices intended for the DAI link +will be marked with the same group and any not intended for that DAI +are skipped by the group check. However for non-aggregated devices the +group check is bypassed and the current code does not stop after it +has found the first device. Meaning if additional non-aggregated devices +are present on the same SoundWire link they will be erroneously added +into the DAI link. + +Fix this issue, and provide a small optimisation by ceasing to process +devices once we have reached the required number of devices for the +current DAI link. + +Fixes: 317dcdecaf7a ("ASoC: intel: sof_sdw: Allow different devices on the same link") +Signed-off-by: Charles Keepax +Reviewed-by: Bard Liao +Signed-off-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20231019173411.166759-2-pierre-louis.bossart@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/boards/sof_sdw.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c +index 842649501e303..47d22cab5af62 100644 +--- a/sound/soc/intel/boards/sof_sdw.c ++++ b/sound/soc/intel/boards/sof_sdw.c +@@ -1374,7 +1374,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, + continue; + + /* j reset after loop, adr_index only applies to first link */ +- for (; j < adr_link_next->num_adr; j++) { ++ for (; j < adr_link_next->num_adr && codec_dlc_index < codec_num; j++) { + const struct snd_soc_acpi_endpoint *endpoints; + + endpoints = adr_link_next->adr_d[j].endpoints; +-- +2.42.0 + diff --git a/queue-6.6/asoc-intel-sof_sdw_rt_sdca_jack_common-add-rt713-sup.patch b/queue-6.6/asoc-intel-sof_sdw_rt_sdca_jack_common-add-rt713-sup.patch new file mode 100644 index 00000000000..9e2cbcc43c7 --- /dev/null +++ b/queue-6.6/asoc-intel-sof_sdw_rt_sdca_jack_common-add-rt713-sup.patch @@ -0,0 +1,50 @@ +From 59fdb57bc88a714e6a034c0b94e33bc669ba98c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Oct 2023 15:08:07 -0400 +Subject: ASoC: Intel: sof_sdw_rt_sdca_jack_common: add rt713 support + +From: Bard Liao + +[ Upstream commit b6d6e5abf64562985fdbbdbdfe8088cde634d834 ] + +Adding rt713 support to sof_sdw_rt_sdca_jack_common.c. + +Fixes: fbaaf80d8cf6 ("ASoC: Intel: sof_sdw: add rt713 support") +Signed-off-by: Bard Liao +Signed-off-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20231012190826.142619-5-pierre-louis.bossart@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c b/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c +index 623e3bebb8884..4360b9f5ff2c7 100644 +--- a/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c ++++ b/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c +@@ -58,6 +58,11 @@ static const struct snd_soc_dapm_route rt712_sdca_map[] = { + { "rt712 MIC2", NULL, "Headset Mic" }, + }; + ++static const struct snd_soc_dapm_route rt713_sdca_map[] = { ++ { "Headphone", NULL, "rt713 HP" }, ++ { "rt713 MIC2", NULL, "Headset Mic" }, ++}; ++ + static const struct snd_kcontrol_new rt_sdca_jack_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +@@ -109,6 +114,9 @@ static int rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd) + } else if (strstr(component->name_prefix, "rt712")) { + ret = snd_soc_dapm_add_routes(&card->dapm, rt712_sdca_map, + ARRAY_SIZE(rt712_sdca_map)); ++ } else if (strstr(component->name_prefix, "rt713")) { ++ ret = snd_soc_dapm_add_routes(&card->dapm, rt713_sdca_map, ++ ARRAY_SIZE(rt713_sdca_map)); + } else { + dev_err(card->dev, "%s is not supported\n", component->name_prefix); + return -EINVAL; +-- +2.42.0 + diff --git a/queue-6.6/asoc-soc-pcm.c-make-sure-dai-parameters-cleared-if-t.patch b/queue-6.6/asoc-soc-pcm.c-make-sure-dai-parameters-cleared-if-t.patch new file mode 100644 index 00000000000..8a180cabf24 --- /dev/null +++ b/queue-6.6/asoc-soc-pcm.c-make-sure-dai-parameters-cleared-if-t.patch @@ -0,0 +1,84 @@ +From 45810fd6ad9c36ebbc8cae977a4b2bcb63e4d8ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Sep 2023 23:36:21 +0800 +Subject: ASoC: soc-pcm.c: Make sure DAI parameters cleared if the DAI becomes + inactive + +From: Chancel Liu + +[ Upstream commit 3efcb471f871cc095841d411f98c593228ecbac6 ] + +The commit 1da681e52853 ("ASoC: soc-pcm.c: Clear DAIs parameters after +stream_active is updated") tries to make sure DAI parameters can be +cleared properly through moving the cleanup to the place where stream +active status is updated. However, it will cause the cleanup only +happening in soc_pcm_close(). + +Suppose a case: aplay -Dhw:0 44100.wav 48000.wav. The case calls +soc_pcm_open()->soc_pcm_hw_params()->soc_pcm_hw_free()-> +soc_pcm_hw_params()->soc_pcm_hw_free()->soc_pcm_close() in order. The +parameters would be remained in the system even if the playback of +44100.wav is finished. + +The case requires us clearing parameters in phase of soc_pcm_hw_free(). +However, moving the DAI parameters cleanup back to soc_pcm_hw_free() +has the risk that DAIs parameters never be cleared if there're more +than one stream, see commit 1da681e52853 ("ASoC: soc-pcm.c: Clear DAIs +parameters after stream_active is updated") for more details. + +To meet all these requirements, in addition to do DAI parameters +cleanup in soc_pcm_hw_free(), also check it in soc_pcm_close() to make +sure DAI parameters cleared if the DAI becomes inactive. + +Fixes: 1da681e52853 ("ASoC: soc-pcm.c: Clear DAIs parameters after stream_active is updated") +Signed-off-by: Chancel Liu +Link: https://lore.kernel.org/r/20230920153621.711373-2-chancel.liu@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/soc-pcm.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c +index 54704250c0a2c..0a20122b3e555 100644 +--- a/sound/soc/soc-pcm.c ++++ b/sound/soc/soc-pcm.c +@@ -698,14 +698,12 @@ static int soc_pcm_clean(struct snd_soc_pcm_runtime *rtd, + + if (!rollback) { + snd_soc_runtime_deactivate(rtd, substream->stream); +- /* clear the corresponding DAIs parameters when going to be inactive */ +- for_each_rtd_dais(rtd, i, dai) { +- if (snd_soc_dai_active(dai) == 0) +- soc_pcm_set_dai_params(dai, NULL); + +- if (snd_soc_dai_stream_active(dai, substream->stream) == 0) +- snd_soc_dai_digital_mute(dai, 1, substream->stream); +- } ++ /* Make sure DAI parameters cleared if the DAI becomes inactive */ ++ for_each_rtd_dais(rtd, i, dai) ++ if (snd_soc_dai_active(dai) == 0 && ++ (dai->rate || dai->channels || dai->sample_bits)) ++ soc_pcm_set_dai_params(dai, NULL); + } + + for_each_rtd_dais(rtd, i, dai) +@@ -936,6 +934,15 @@ static int soc_pcm_hw_clean(struct snd_soc_pcm_runtime *rtd, + + snd_soc_dpcm_mutex_assert_held(rtd); + ++ /* clear the corresponding DAIs parameters when going to be inactive */ ++ for_each_rtd_dais(rtd, i, dai) { ++ if (snd_soc_dai_active(dai) == 1) ++ soc_pcm_set_dai_params(dai, NULL); ++ ++ if (snd_soc_dai_stream_active(dai, substream->stream) == 1) ++ snd_soc_dai_digital_mute(dai, 1, substream->stream); ++ } ++ + /* run the stream event */ + snd_soc_dapm_stream_stop(rtd, substream->stream); + +-- +2.42.0 + diff --git a/queue-6.6/asoc-sof-core-ensure-sof_ops_free-is-still-called-wh.patch b/queue-6.6/asoc-sof-core-ensure-sof_ops_free-is-still-called-wh.patch new file mode 100644 index 00000000000..121a0c27cb3 --- /dev/null +++ b/queue-6.6/asoc-sof-core-ensure-sof_ops_free-is-still-called-wh.patch @@ -0,0 +1,57 @@ +From 4c0585a51d0cc3b65d84042df960e75b54ec268b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 13:54:25 +0200 +Subject: ASoC: SOF: core: Ensure sof_ops_free() is still called when probe + never ran. + +From: Maarten Lankhorst + +[ Upstream commit f549a82aff57865c47b5abd17336b23cd9bb2d2c ] + +In an effort to not call sof_ops_free twice, we stopped running it when +probe was aborted. + +Check the result of cancel_work_sync to see if this was the case. + +Fixes: 31bb7bd9ffee ("ASoC: SOF: core: Only call sof_ops_free() on remove if the probe was successful") +Cc: Peter Ujfalusi +Acked-by: Mark Brown +Reviewed-by: Peter Ujfalusi +Acked-by: Peter Ujfalusi +Signed-off-by: Maarten Lankhorst +Link: https://lore.kernel.org/r/20231009115437.99976-2-maarten.lankhorst@linux.intel.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/soc/sof/core.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c +index 2d1616b81485c..0938b259f7034 100644 +--- a/sound/soc/sof/core.c ++++ b/sound/soc/sof/core.c +@@ -459,9 +459,10 @@ int snd_sof_device_remove(struct device *dev) + struct snd_sof_dev *sdev = dev_get_drvdata(dev); + struct snd_sof_pdata *pdata = sdev->pdata; + int ret; ++ bool aborted = false; + + if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) +- cancel_work_sync(&sdev->probe_work); ++ aborted = cancel_work_sync(&sdev->probe_work); + + /* + * Unregister any registered client device first before IPC and debugfs +@@ -487,6 +488,9 @@ int snd_sof_device_remove(struct device *dev) + snd_sof_free_debug(sdev); + snd_sof_remove(sdev); + sof_ops_free(sdev); ++ } else if (aborted) { ++ /* probe_work never ran */ ++ sof_ops_free(sdev); + } + + /* release firmware */ +-- +2.42.0 + diff --git a/queue-6.6/asoc-sof-ipc4-topology-use-size_add-in-call-to-struc.patch b/queue-6.6/asoc-sof-ipc4-topology-use-size_add-in-call-to-struc.patch new file mode 100644 index 00000000000..5aad55f608d --- /dev/null +++ b/queue-6.6/asoc-sof-ipc4-topology-use-size_add-in-call-to-struc.patch @@ -0,0 +1,41 @@ +From 76a8c65440182aada54142945c2fa76137e90f01 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 13:09:11 -0600 +Subject: ASoC: SOF: ipc4-topology: Use size_add() in call to struct_size() + +From: Gustavo A. R. Silva + +[ Upstream commit 3746284c233d5cf5f456400e61cd4a46a69c6e8c ] + +If, for any reason, the open-coded arithmetic causes a wraparound, +the protection that `struct_size()` adds against potential integer +overflows is defeated. Fix this by hardening call to `struct_size()` +with `size_add()`. + +Fixes: f9efae954905 ("ASoC: SOF: ipc4-topology: Add support for base config extension") +Signed-off-by: "Gustavo A. R. Silva" +Reviewed-by: Kees Cook +Link: https://lore.kernel.org/r/ZQSr15AYJpDpipg6@work +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sof/ipc4-topology.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c +index 7cb63e6b24dc9..c9c1d2ec7af25 100644 +--- a/sound/soc/sof/ipc4-topology.c ++++ b/sound/soc/sof/ipc4-topology.c +@@ -895,7 +895,8 @@ static int sof_ipc4_widget_setup_comp_process(struct snd_sof_widget *swidget) + if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) { + struct sof_ipc4_base_module_cfg_ext *base_cfg_ext; + u32 ext_size = struct_size(base_cfg_ext, pin_formats, +- swidget->num_input_pins + swidget->num_output_pins); ++ size_add(swidget->num_input_pins, ++ swidget->num_output_pins)); + + base_cfg_ext = kzalloc(ext_size, GFP_KERNEL); + if (!base_cfg_ext) { +-- +2.42.0 + diff --git a/queue-6.6/backlight-pwm_bl-disable-pwm-on-shutdown-suspend-and.patch b/queue-6.6/backlight-pwm_bl-disable-pwm-on-shutdown-suspend-and.patch new file mode 100644 index 00000000000..904050ebfb0 --- /dev/null +++ b/queue-6.6/backlight-pwm_bl-disable-pwm-on-shutdown-suspend-and.patch @@ -0,0 +1,93 @@ +From 7a44a09ad18ba33228fcb32a1271336f1b9a5dba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 11:32:23 +0200 +Subject: backlight: pwm_bl: Disable PWM on shutdown, suspend and remove +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit 40da4737717b252fd01d92ff38d3b95a491167cc ] + +Since commit 00e7e698bff1 ("backlight: pwm_bl: Configure pwm only once +per backlight toggle") calling pwm_backlight_power_off() doesn't disable +the PWM any more. However this is necessary to suspend because PWM +drivers usually refuse to suspend if they are still enabled. + +Also adapt shutdown and remove callbacks to disable the PWM for similar +reasons. + +Fixes: 00e7e698bff1 ("backlight: pwm_bl: Configure pwm only once per backlight toggle") +Reported-by: Aisheng Dong +Tested-by: Aisheng Dong +Signed-off-by: Uwe Kleine-König +Reviewed-by: Daniel Thompson +Link: https://lore.kernel.org/r/20231009093223.227286-1-u.kleine-koenig@pengutronix.de +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/video/backlight/pwm_bl.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c +index a51fbab963680..289bd9ce4d36d 100644 +--- a/drivers/video/backlight/pwm_bl.c ++++ b/drivers/video/backlight/pwm_bl.c +@@ -626,9 +626,14 @@ static void pwm_backlight_remove(struct platform_device *pdev) + { + struct backlight_device *bl = platform_get_drvdata(pdev); + struct pwm_bl_data *pb = bl_get_data(bl); ++ struct pwm_state state; + + backlight_device_unregister(bl); + pwm_backlight_power_off(pb); ++ pwm_get_state(pb->pwm, &state); ++ state.duty_cycle = 0; ++ state.enabled = false; ++ pwm_apply_state(pb->pwm, &state); + + if (pb->exit) + pb->exit(&pdev->dev); +@@ -638,8 +643,13 @@ static void pwm_backlight_shutdown(struct platform_device *pdev) + { + struct backlight_device *bl = platform_get_drvdata(pdev); + struct pwm_bl_data *pb = bl_get_data(bl); ++ struct pwm_state state; + + pwm_backlight_power_off(pb); ++ pwm_get_state(pb->pwm, &state); ++ state.duty_cycle = 0; ++ state.enabled = false; ++ pwm_apply_state(pb->pwm, &state); + } + + #ifdef CONFIG_PM_SLEEP +@@ -647,12 +657,24 @@ static int pwm_backlight_suspend(struct device *dev) + { + struct backlight_device *bl = dev_get_drvdata(dev); + struct pwm_bl_data *pb = bl_get_data(bl); ++ struct pwm_state state; + + if (pb->notify) + pb->notify(pb->dev, 0); + + pwm_backlight_power_off(pb); + ++ /* ++ * Note that disabling the PWM doesn't guarantee that the output stays ++ * at its inactive state. However without the PWM disabled, the PWM ++ * driver refuses to suspend. So disable here even though this might ++ * enable the backlight on poorly designed boards. ++ */ ++ pwm_get_state(pb->pwm, &state); ++ state.duty_cycle = 0; ++ state.enabled = false; ++ pwm_apply_state(pb->pwm, &state); ++ + if (pb->notify_after) + pb->notify_after(pb->dev, 0); + +-- +2.42.0 + diff --git a/queue-6.6/bluetooth-hci_sync-fix-opcode-prints-in-bt_dev_dbg-e.patch b/queue-6.6/bluetooth-hci_sync-fix-opcode-prints-in-bt_dev_dbg-e.patch new file mode 100644 index 00000000000..e353253a308 --- /dev/null +++ b/queue-6.6/bluetooth-hci_sync-fix-opcode-prints-in-bt_dev_dbg-e.patch @@ -0,0 +1,51 @@ +From ea16f973eb1c5bb6077e597d8175df96930f137c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Oct 2023 16:47:35 +0200 +Subject: Bluetooth: hci_sync: Fix Opcode prints in bt_dev_dbg/err + +From: Marcel Ziswiler + +[ Upstream commit 530886897c789cf77c9a0d4a7cc5549f0768b5f8 ] + +Printed Opcodes may be missing leading zeros: + + Bluetooth: hci0: Opcode 0x c03 failed: -110 + +Fix this by always printing leading zeros: + + Bluetooth: hci0: Opcode 0x0c03 failed: -110 + +Fixes: d0b137062b2d ("Bluetooth: hci_sync: Rework init stages") +Fixes: 6a98e3836fa2 ("Bluetooth: Add helper for serialized HCI command execution") +Signed-off-by: Marcel Ziswiler +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/hci_sync.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c +index a15ab0b874a9d..9e71362c04b48 100644 +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -152,7 +152,7 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen, + struct sk_buff *skb; + int err = 0; + +- bt_dev_dbg(hdev, "Opcode 0x%4x", opcode); ++ bt_dev_dbg(hdev, "Opcode 0x%4.4x", opcode); + + hci_req_init(&req, hdev); + +@@ -248,7 +248,7 @@ int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen, + skb = __hci_cmd_sync_sk(hdev, opcode, plen, param, event, timeout, sk); + if (IS_ERR(skb)) { + if (!event) +- bt_dev_err(hdev, "Opcode 0x%4x failed: %ld", opcode, ++ bt_dev_err(hdev, "Opcode 0x%4.4x failed: %ld", opcode, + PTR_ERR(skb)); + return PTR_ERR(skb); + } +-- +2.42.0 + diff --git a/queue-6.6/bluetooth-iso-pass-big-encryption-info-through-qos.patch b/queue-6.6/bluetooth-iso-pass-big-encryption-info-through-qos.patch new file mode 100644 index 00000000000..d4b0229df57 --- /dev/null +++ b/queue-6.6/bluetooth-iso-pass-big-encryption-info-through-qos.patch @@ -0,0 +1,280 @@ +From c85cd68be9594aa02b101c9d89043da89d68f54d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 17:01:03 +0300 +Subject: Bluetooth: ISO: Pass BIG encryption info through QoS + +From: Iulia Tanasescu + +[ Upstream commit 1d11d70d1f6b23e7d3fc00396c17b90b876162a4 ] + +This enables a broadcast sink to be informed if the PA +it has synced with is associated with an encrypted BIG, +by retrieving the socket QoS and checking the encryption +field. + +After PA sync has been successfully established and the +first BIGInfo advertising report is received, a new hcon +is added and notified to the ISO layer. The ISO layer +sets the encryption field of the socket and hcon QoS +according to the encryption parameter of the BIGInfo +advertising report event. + +After that, the userspace is woken up, and the QoS of the +new PA sync socket can be read, to inspect the encryption +field and follow up accordingly. + +Signed-off-by: Iulia Tanasescu +Signed-off-by: Luiz Augusto von Dentz +Stable-dep-of: 181a42edddf5 ("Bluetooth: Make handle of hci_conn be unique") +Signed-off-by: Sasha Levin +--- + include/net/bluetooth/hci.h | 3 ++ + include/net/bluetooth/hci_core.h | 25 ++++++++++++++- + net/bluetooth/hci_conn.c | 1 + + net/bluetooth/hci_event.c | 54 +++++++++++++++++++++++--------- + net/bluetooth/iso.c | 19 ++++++++--- + 5 files changed, 82 insertions(+), 20 deletions(-) + +diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h +index 87d92accc26ea..bdee5d649cc61 100644 +--- a/include/net/bluetooth/hci.h ++++ b/include/net/bluetooth/hci.h +@@ -1,6 +1,7 @@ + /* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated ++ Copyright 2023 NXP + + Written 2000,2001 by Maxim Krasnyansky + +@@ -673,6 +674,8 @@ enum { + #define HCI_TX_POWER_INVALID 127 + #define HCI_RSSI_INVALID 127 + ++#define HCI_SYNC_HANDLE_INVALID 0xffff ++ + #define HCI_ROLE_MASTER 0x00 + #define HCI_ROLE_SLAVE 0x01 + +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index c33348ba1657e..f36c1fd5d64ed 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -1314,7 +1314,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_big_any_dst(struct hci_dev * + } + + static inline struct hci_conn * +-hci_conn_hash_lookup_pa_sync(struct hci_dev *hdev, __u8 big) ++hci_conn_hash_lookup_pa_sync_big_handle(struct hci_dev *hdev, __u8 big) + { + struct hci_conn_hash *h = &hdev->conn_hash; + struct hci_conn *c; +@@ -1336,6 +1336,29 @@ hci_conn_hash_lookup_pa_sync(struct hci_dev *hdev, __u8 big) + return NULL; + } + ++static inline struct hci_conn * ++hci_conn_hash_lookup_pa_sync_handle(struct hci_dev *hdev, __u16 sync_handle) ++{ ++ struct hci_conn_hash *h = &hdev->conn_hash; ++ struct hci_conn *c; ++ ++ rcu_read_lock(); ++ ++ list_for_each_entry_rcu(c, &h->list, list) { ++ if (c->type != ISO_LINK || ++ !test_bit(HCI_CONN_PA_SYNC, &c->flags)) ++ continue; ++ ++ if (c->sync_handle == sync_handle) { ++ rcu_read_unlock(); ++ return c; ++ } ++ } ++ rcu_read_unlock(); ++ ++ return NULL; ++} ++ + static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev, + __u8 type, __u16 state) + { +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index 73470cc3518a7..c476154f3a5d2 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -973,6 +973,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, + conn->rssi = HCI_RSSI_INVALID; + conn->tx_power = HCI_TX_POWER_INVALID; + conn->max_tx_power = HCI_TX_POWER_INVALID; ++ conn->sync_handle = HCI_SYNC_HANDLE_INVALID; + + set_bit(HCI_CONN_POWER_SAVE, &conn->flags); + conn->disc_timeout = HCI_DISCONN_TIMEOUT; +diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c +index 1e1c9147356c3..9b34c9f8ee02c 100644 +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -6603,7 +6603,7 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data, + struct hci_ev_le_pa_sync_established *ev = data; + int mask = hdev->link_mode; + __u8 flags = 0; +- struct hci_conn *bis; ++ struct hci_conn *pa_sync; + + bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); + +@@ -6620,20 +6620,19 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data, + if (!(flags & HCI_PROTO_DEFER)) + goto unlock; + +- /* Add connection to indicate the PA sync event */ +- bis = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY, +- HCI_ROLE_SLAVE); ++ if (ev->status) { ++ /* Add connection to indicate the failed PA sync event */ ++ pa_sync = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY, ++ HCI_ROLE_SLAVE); + +- if (!bis) +- goto unlock; ++ if (!pa_sync) ++ goto unlock; + +- if (ev->status) +- set_bit(HCI_CONN_PA_SYNC_FAILED, &bis->flags); +- else +- set_bit(HCI_CONN_PA_SYNC, &bis->flags); ++ set_bit(HCI_CONN_PA_SYNC_FAILED, &pa_sync->flags); + +- /* Notify connection to iso layer */ +- hci_connect_cfm(bis, ev->status); ++ /* Notify iso layer */ ++ hci_connect_cfm(pa_sync, ev->status); ++ } + + unlock: + hci_dev_unlock(hdev); +@@ -7125,7 +7124,7 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, + hci_dev_lock(hdev); + + if (!ev->status) { +- pa_sync = hci_conn_hash_lookup_pa_sync(hdev, ev->handle); ++ pa_sync = hci_conn_hash_lookup_pa_sync_big_handle(hdev, ev->handle); + if (pa_sync) + /* Also mark the BIG sync established event on the + * associated PA sync hcon +@@ -7186,15 +7185,42 @@ static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data, + struct hci_evt_le_big_info_adv_report *ev = data; + int mask = hdev->link_mode; + __u8 flags = 0; ++ struct hci_conn *pa_sync; + + bt_dev_dbg(hdev, "sync_handle 0x%4.4x", le16_to_cpu(ev->sync_handle)); + + hci_dev_lock(hdev); + + mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK, &flags); +- if (!(mask & HCI_LM_ACCEPT)) ++ if (!(mask & HCI_LM_ACCEPT)) { + hci_le_pa_term_sync(hdev, ev->sync_handle); ++ goto unlock; ++ } + ++ if (!(flags & HCI_PROTO_DEFER)) ++ goto unlock; ++ ++ pa_sync = hci_conn_hash_lookup_pa_sync_handle ++ (hdev, ++ le16_to_cpu(ev->sync_handle)); ++ ++ if (pa_sync) ++ goto unlock; ++ ++ /* Add connection to indicate the PA sync event */ ++ pa_sync = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY, ++ HCI_ROLE_SLAVE); ++ ++ if (!pa_sync) ++ goto unlock; ++ ++ pa_sync->sync_handle = le16_to_cpu(ev->sync_handle); ++ set_bit(HCI_CONN_PA_SYNC, &pa_sync->flags); ++ ++ /* Notify iso layer */ ++ hci_connect_cfm(pa_sync, 0x00); ++ ++unlock: + hci_dev_unlock(hdev); + } + +diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c +index 71248163ce9a5..2132a16be93cd 100644 +--- a/net/bluetooth/iso.c ++++ b/net/bluetooth/iso.c +@@ -77,6 +77,7 @@ static struct bt_iso_qos default_qos; + static bool check_ucast_qos(struct bt_iso_qos *qos); + static bool check_bcast_qos(struct bt_iso_qos *qos); + static bool iso_match_sid(struct sock *sk, void *data); ++static bool iso_match_sync_handle(struct sock *sk, void *data); + static void iso_sock_disconn(struct sock *sk); + + /* ---- ISO timers ---- */ +@@ -1202,7 +1203,6 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg, + test_bit(HCI_CONN_PA_SYNC, &pi->conn->hcon->flags)) { + iso_conn_big_sync(sk); + sk->sk_state = BT_LISTEN; +- set_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags); + } else { + iso_conn_defer_accept(pi->conn->hcon); + sk->sk_state = BT_CONFIG; +@@ -1579,6 +1579,7 @@ static void iso_conn_ready(struct iso_conn *conn) + struct sock *sk = conn->sk; + struct hci_ev_le_big_sync_estabilished *ev = NULL; + struct hci_ev_le_pa_sync_established *ev2 = NULL; ++ struct hci_evt_le_big_info_adv_report *ev3 = NULL; + struct hci_conn *hcon; + + BT_DBG("conn %p", conn); +@@ -1603,14 +1604,20 @@ static void iso_conn_ready(struct iso_conn *conn) + parent = iso_get_sock_listen(&hcon->src, + &hcon->dst, + iso_match_big, ev); +- } else if (test_bit(HCI_CONN_PA_SYNC, &hcon->flags) || +- test_bit(HCI_CONN_PA_SYNC_FAILED, &hcon->flags)) { ++ } else if (test_bit(HCI_CONN_PA_SYNC_FAILED, &hcon->flags)) { + ev2 = hci_recv_event_data(hcon->hdev, + HCI_EV_LE_PA_SYNC_ESTABLISHED); + if (ev2) + parent = iso_get_sock_listen(&hcon->src, + &hcon->dst, + iso_match_sid, ev2); ++ } else if (test_bit(HCI_CONN_PA_SYNC, &hcon->flags)) { ++ ev3 = hci_recv_event_data(hcon->hdev, ++ HCI_EVT_LE_BIG_INFO_ADV_REPORT); ++ if (ev3) ++ parent = iso_get_sock_listen(&hcon->src, ++ &hcon->dst, ++ iso_match_sync_handle, ev3); + } + + if (!parent) +@@ -1650,11 +1657,13 @@ static void iso_conn_ready(struct iso_conn *conn) + hcon->sync_handle = iso_pi(parent)->sync_handle; + } + +- if (ev2 && !ev2->status) { +- iso_pi(sk)->sync_handle = iso_pi(parent)->sync_handle; ++ if (ev3) { + iso_pi(sk)->qos = iso_pi(parent)->qos; ++ iso_pi(sk)->qos.bcast.encryption = ev3->encryption; ++ hcon->iso_qos = iso_pi(sk)->qos; + iso_pi(sk)->bc_num_bis = iso_pi(parent)->bc_num_bis; + memcpy(iso_pi(sk)->bc_bis, iso_pi(parent)->bc_bis, ISO_MAX_NUM_BIS); ++ set_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags); + } + + bacpy(&iso_pi(sk)->dst, &hcon->dst); +-- +2.42.0 + diff --git a/queue-6.6/bluetooth-make-handle-of-hci_conn-be-unique.patch b/queue-6.6/bluetooth-make-handle-of-hci_conn-be-unique.patch new file mode 100644 index 00000000000..7b7bf6621fa --- /dev/null +++ b/queue-6.6/bluetooth-make-handle-of-hci_conn-be-unique.patch @@ -0,0 +1,362 @@ +From dc5aa311dcd06571dd8b48c778c43e5134f8c75c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 17:57:31 +0800 +Subject: Bluetooth: Make handle of hci_conn be unique + +From: Ziyang Xuan + +[ Upstream commit 181a42edddf51d5d9697ecdf365d72ebeab5afb0 ] + +The handle of new hci_conn is always HCI_CONN_HANDLE_MAX + 1 if +the handle of the first hci_conn entry in hci_dev->conn_hash->list +is not HCI_CONN_HANDLE_MAX + 1. Use ida to manage the allocation of +hci_conn->handle to make it be unique. + +Fixes: 9f78191cc9f1 ("Bluetooth: hci_conn: Always allocate unique handles") +Signed-off-by: Ziyang Xuan +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + include/net/bluetooth/hci_core.h | 6 +++- + net/bluetooth/amp.c | 3 +- + net/bluetooth/hci_conn.c | 57 ++++++++++++++++++-------------- + net/bluetooth/hci_core.c | 3 ++ + net/bluetooth/hci_event.c | 38 +++++++++------------ + 5 files changed, 56 insertions(+), 51 deletions(-) + +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index f36c1fd5d64ed..7fa95b72e5c85 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -350,6 +350,8 @@ struct hci_dev { + struct list_head list; + struct mutex lock; + ++ struct ida unset_handle_ida; ++ + const char *name; + unsigned long flags; + __u16 id; +@@ -1449,7 +1451,9 @@ int hci_le_create_cis_pending(struct hci_dev *hdev); + int hci_conn_check_create_cis(struct hci_conn *conn); + + struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, +- u8 role); ++ u8 role, u16 handle); ++struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type, ++ bdaddr_t *dst, u8 role); + void hci_conn_del(struct hci_conn *conn); + void hci_conn_hash_flush(struct hci_dev *hdev); + void hci_conn_check_pending(struct hci_dev *hdev); +diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c +index 2134f92bd7ac2..5d698f19868c5 100644 +--- a/net/bluetooth/amp.c ++++ b/net/bluetooth/amp.c +@@ -109,7 +109,7 @@ struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr, + struct hci_conn *hcon; + u8 role = out ? HCI_ROLE_MASTER : HCI_ROLE_SLAVE; + +- hcon = hci_conn_add(hdev, AMP_LINK, dst, role); ++ hcon = hci_conn_add(hdev, AMP_LINK, dst, role, __next_handle(mgr)); + if (!hcon) + return NULL; + +@@ -117,7 +117,6 @@ struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr, + + hcon->state = BT_CONNECT; + hcon->attempt++; +- hcon->handle = __next_handle(mgr); + hcon->remote_id = remote_id; + hcon->amp_mgr = amp_mgr_get(mgr); + +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index c476154f3a5d2..7450b550cff6d 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -153,6 +153,9 @@ static void hci_conn_cleanup(struct hci_conn *conn) + + hci_conn_hash_del(hdev, conn); + ++ if (HCI_CONN_HANDLE_UNSET(conn->handle)) ++ ida_free(&hdev->unset_handle_ida, conn->handle); ++ + if (conn->cleanup) + conn->cleanup(conn); + +@@ -928,31 +931,18 @@ static void cis_cleanup(struct hci_conn *conn) + hci_le_remove_cig(hdev, conn->iso_qos.ucast.cig); + } + +-static u16 hci_conn_hash_alloc_unset(struct hci_dev *hdev) ++static int hci_conn_hash_alloc_unset(struct hci_dev *hdev) + { +- struct hci_conn_hash *h = &hdev->conn_hash; +- struct hci_conn *c; +- u16 handle = HCI_CONN_HANDLE_MAX + 1; +- +- rcu_read_lock(); +- +- list_for_each_entry_rcu(c, &h->list, list) { +- /* Find the first unused handle */ +- if (handle == 0xffff || c->handle != handle) +- break; +- handle++; +- } +- rcu_read_unlock(); +- +- return handle; ++ return ida_alloc_range(&hdev->unset_handle_ida, HCI_CONN_HANDLE_MAX + 1, ++ U16_MAX, GFP_ATOMIC); + } + + struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, +- u8 role) ++ u8 role, u16 handle) + { + struct hci_conn *conn; + +- BT_DBG("%s dst %pMR", hdev->name, dst); ++ bt_dev_dbg(hdev, "dst %pMR handle 0x%4.4x", dst, handle); + + conn = kzalloc(sizeof(*conn), GFP_KERNEL); + if (!conn) +@@ -960,7 +950,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, + + bacpy(&conn->dst, dst); + bacpy(&conn->src, &hdev->bdaddr); +- conn->handle = hci_conn_hash_alloc_unset(hdev); ++ conn->handle = handle; + conn->hdev = hdev; + conn->type = type; + conn->role = role; +@@ -1045,6 +1035,20 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, + return conn; + } + ++struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type, ++ bdaddr_t *dst, u8 role) ++{ ++ int handle; ++ ++ bt_dev_dbg(hdev, "dst %pMR", dst); ++ ++ handle = hci_conn_hash_alloc_unset(hdev); ++ if (unlikely(handle < 0)) ++ return NULL; ++ ++ return hci_conn_add(hdev, type, dst, role, handle); ++} ++ + static void hci_conn_cleanup_child(struct hci_conn *conn, u8 reason) + { + if (!reason) +@@ -1275,6 +1279,9 @@ u8 hci_conn_set_handle(struct hci_conn *conn, u16 handle) + if (conn->abort_reason) + return conn->abort_reason; + ++ if (HCI_CONN_HANDLE_UNSET(conn->handle)) ++ ida_free(&hdev->unset_handle_ida, conn->handle); ++ + conn->handle = handle; + + return 0; +@@ -1382,7 +1389,7 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, + if (conn) { + bacpy(&conn->dst, dst); + } else { +- conn = hci_conn_add(hdev, LE_LINK, dst, role); ++ conn = hci_conn_add_unset(hdev, LE_LINK, dst, role); + if (!conn) + return ERR_PTR(-ENOMEM); + hci_conn_hold(conn); +@@ -1547,7 +1554,7 @@ static struct hci_conn *hci_add_bis(struct hci_dev *hdev, bdaddr_t *dst, + memcmp(conn->le_per_adv_data, base, base_len))) + return ERR_PTR(-EADDRINUSE); + +- conn = hci_conn_add(hdev, ISO_LINK, dst, HCI_ROLE_MASTER); ++ conn = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_MASTER); + if (!conn) + return ERR_PTR(-ENOMEM); + +@@ -1591,7 +1598,7 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst, + + BT_DBG("requesting refresh of dst_addr"); + +- conn = hci_conn_add(hdev, LE_LINK, dst, HCI_ROLE_MASTER); ++ conn = hci_conn_add_unset(hdev, LE_LINK, dst, HCI_ROLE_MASTER); + if (!conn) + return ERR_PTR(-ENOMEM); + +@@ -1639,7 +1646,7 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst, + + acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); + if (!acl) { +- acl = hci_conn_add(hdev, ACL_LINK, dst, HCI_ROLE_MASTER); ++ acl = hci_conn_add_unset(hdev, ACL_LINK, dst, HCI_ROLE_MASTER); + if (!acl) + return ERR_PTR(-ENOMEM); + } +@@ -1699,7 +1706,7 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst, + + sco = hci_conn_hash_lookup_ba(hdev, type, dst); + if (!sco) { +- sco = hci_conn_add(hdev, type, dst, HCI_ROLE_MASTER); ++ sco = hci_conn_add_unset(hdev, type, dst, HCI_ROLE_MASTER); + if (!sco) { + hci_conn_drop(acl); + return ERR_PTR(-ENOMEM); +@@ -1891,7 +1898,7 @@ struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst, + cis = hci_conn_hash_lookup_cis(hdev, dst, dst_type, qos->ucast.cig, + qos->ucast.cis); + if (!cis) { +- cis = hci_conn_add(hdev, ISO_LINK, dst, HCI_ROLE_MASTER); ++ cis = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_MASTER); + if (!cis) + return ERR_PTR(-ENOMEM); + cis->cleanup = cis_cleanup; +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index 195aea2198a96..65601aa52e0d8 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -2535,6 +2535,8 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv) + mutex_init(&hdev->lock); + mutex_init(&hdev->req_lock); + ++ ida_init(&hdev->unset_handle_ida); ++ + INIT_LIST_HEAD(&hdev->mesh_pending); + INIT_LIST_HEAD(&hdev->mgmt_pending); + INIT_LIST_HEAD(&hdev->reject_list); +@@ -2789,6 +2791,7 @@ void hci_release_dev(struct hci_dev *hdev) + hci_codec_list_clear(&hdev->local_codecs); + hci_dev_unlock(hdev); + ++ ida_destroy(&hdev->unset_handle_ida); + ida_simple_remove(&hci_index_ida, hdev->id); + kfree_skb(hdev->sent_cmd); + kfree_skb(hdev->recv_event); +diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c +index 9b34c9f8ee02c..f6d3150bcbb03 100644 +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -2335,8 +2335,8 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) + } + } else { + if (!conn) { +- conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr, +- HCI_ROLE_MASTER); ++ conn = hci_conn_add_unset(hdev, ACL_LINK, &cp->bdaddr, ++ HCI_ROLE_MASTER); + if (!conn) + bt_dev_err(hdev, "no memory for new connection"); + } +@@ -3151,8 +3151,8 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, + hci_bdaddr_list_lookup_with_flags(&hdev->accept_list, + &ev->bdaddr, + BDADDR_BREDR)) { +- conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr, +- HCI_ROLE_SLAVE); ++ conn = hci_conn_add_unset(hdev, ev->link_type, ++ &ev->bdaddr, HCI_ROLE_SLAVE); + if (!conn) { + bt_dev_err(hdev, "no memory for new conn"); + goto unlock; +@@ -3317,8 +3317,8 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data, + conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, + &ev->bdaddr); + if (!conn) { +- conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr, +- HCI_ROLE_SLAVE); ++ conn = hci_conn_add_unset(hdev, ev->link_type, &ev->bdaddr, ++ HCI_ROLE_SLAVE); + if (!conn) { + bt_dev_err(hdev, "no memory for new connection"); + goto unlock; +@@ -5890,7 +5890,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, + if (status) + goto unlock; + +- conn = hci_conn_add(hdev, LE_LINK, bdaddr, role); ++ conn = hci_conn_add_unset(hdev, LE_LINK, bdaddr, role); + if (!conn) { + bt_dev_err(hdev, "no memory for new connection"); + goto unlock; +@@ -5952,17 +5952,11 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, + + conn->dst_type = ev_bdaddr_type(hdev, conn->dst_type, NULL); + +- if (handle > HCI_CONN_HANDLE_MAX) { +- bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x", handle, +- HCI_CONN_HANDLE_MAX); +- status = HCI_ERROR_INVALID_PARAMETERS; +- } +- + /* All connection failure handling is taken care of by the + * hci_conn_failed function which is triggered by the HCI + * request completion callbacks used for connecting. + */ +- if (status) ++ if (status || hci_conn_set_handle(conn, handle)) + goto unlock; + + /* Drop the connection if it has been aborted */ +@@ -5986,7 +5980,6 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, + mgmt_device_connected(hdev, conn, NULL, 0); + + conn->sec_level = BT_SECURITY_LOW; +- conn->handle = handle; + conn->state = BT_CONFIG; + + /* Store current advertising instance as connection advertising instance +@@ -6622,8 +6615,8 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data, + + if (ev->status) { + /* Add connection to indicate the failed PA sync event */ +- pa_sync = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY, +- HCI_ROLE_SLAVE); ++ pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY, ++ HCI_ROLE_SLAVE); + + if (!pa_sync) + goto unlock; +@@ -7019,12 +7012,12 @@ static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data, + + cis = hci_conn_hash_lookup_handle(hdev, cis_handle); + if (!cis) { +- cis = hci_conn_add(hdev, ISO_LINK, &acl->dst, HCI_ROLE_SLAVE); ++ cis = hci_conn_add(hdev, ISO_LINK, &acl->dst, HCI_ROLE_SLAVE, ++ cis_handle); + if (!cis) { + hci_le_reject_cis(hdev, ev->cis_handle); + goto unlock; + } +- cis->handle = cis_handle; + } + + cis->iso_qos.ucast.cig = ev->cig_id; +@@ -7139,10 +7132,9 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, + bis = hci_conn_hash_lookup_handle(hdev, handle); + if (!bis) { + bis = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY, +- HCI_ROLE_SLAVE); ++ HCI_ROLE_SLAVE, handle); + if (!bis) + continue; +- bis->handle = handle; + } + + if (ev->status != 0x42) +@@ -7208,8 +7200,8 @@ static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data, + goto unlock; + + /* Add connection to indicate the PA sync event */ +- pa_sync = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY, +- HCI_ROLE_SLAVE); ++ pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY, ++ HCI_ROLE_SLAVE); + + if (!pa_sync) + goto unlock; +-- +2.42.0 + diff --git a/queue-6.6/bpf-fix-kfunc-callback-register-type-handling.patch b/queue-6.6/bpf-fix-kfunc-callback-register-type-handling.patch new file mode 100644 index 00000000000..da0b66d575a --- /dev/null +++ b/queue-6.6/bpf-fix-kfunc-callback-register-type-handling.patch @@ -0,0 +1,44 @@ +From 721eac1d82245da2733675f434629f920af9f542 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 01:32:10 +0200 +Subject: bpf: Fix kfunc callback register type handling + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit 06d686f771ddc27a8554cd8f5b22e071040dc90e ] + +The kfunc code to handle KF_ARG_PTR_TO_CALLBACK does not check the reg +type before using reg->subprogno. This can accidently permit invalid +pointers from being passed into callback helpers (e.g. silently from +different paths). Likewise, reg->subprogno from the per-register type +union may not be meaningful either. We need to reject any other type +except PTR_TO_FUNC. + +Acked-by: Dave Marchevsky +Fixes: 5d92ddc3de1b ("bpf: Add callback validation to kfunc verifier logic") +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20230912233214.1518551-14-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 9f180ae74e492..82c9e5c470319 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -11202,6 +11202,10 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_ + break; + } + case KF_ARG_PTR_TO_CALLBACK: ++ if (reg->type != PTR_TO_FUNC) { ++ verbose(env, "arg%d expected pointer to func\n", i); ++ return -EINVAL; ++ } + meta->subprogno = reg->subprogno; + break; + case KF_ARG_PTR_TO_REFCOUNTED_KPTR: +-- +2.42.0 + diff --git a/queue-6.6/bpf-fix-missed-rcu-read-lock-in-bpf_task_under_cgrou.patch b/queue-6.6/bpf-fix-missed-rcu-read-lock-in-bpf_task_under_cgrou.patch new file mode 100644 index 00000000000..10cd1941c56 --- /dev/null +++ b/queue-6.6/bpf-fix-missed-rcu-read-lock-in-bpf_task_under_cgrou.patch @@ -0,0 +1,113 @@ +From 8bc90e61285b7eb7f30cb4e18d5a4b56948ef2bb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Oct 2023 13:59:44 +0000 +Subject: bpf: Fix missed rcu read lock in bpf_task_under_cgroup() + +From: Yafang Shao + +[ Upstream commit 29a7e00ffadddd8d68eff311de1bf12ae10687bb ] + +When employed within a sleepable program not under RCU protection, the +use of 'bpf_task_under_cgroup()' may trigger a warning in the kernel log, +particularly when CONFIG_PROVE_RCU is enabled: + + [ 1259.662357] WARNING: suspicious RCU usage + [ 1259.662358] 6.5.0+ #33 Not tainted + [ 1259.662360] ----------------------------- + [ 1259.662361] include/linux/cgroup.h:423 suspicious rcu_dereference_check() usage! + +Other info that might help to debug this: + + [ 1259.662366] rcu_scheduler_active = 2, debug_locks = 1 + [ 1259.662368] 1 lock held by trace/72954: + [ 1259.662369] #0: ffffffffb5e3eda0 (rcu_read_lock_trace){....}-{0:0}, at: __bpf_prog_enter_sleepable+0x0/0xb0 + +Stack backtrace: + + [ 1259.662385] CPU: 50 PID: 72954 Comm: trace Kdump: loaded Not tainted 6.5.0+ #33 + [ 1259.662391] Call Trace: + [ 1259.662393] + [ 1259.662395] dump_stack_lvl+0x6e/0x90 + [ 1259.662401] dump_stack+0x10/0x20 + [ 1259.662404] lockdep_rcu_suspicious+0x163/0x1b0 + [ 1259.662412] task_css_set.part.0+0x23/0x30 + [ 1259.662417] bpf_task_under_cgroup+0xe7/0xf0 + [ 1259.662422] bpf_prog_7fffba481a3bcf88_lsm_run+0x5c/0x93 + [ 1259.662431] bpf_trampoline_6442505574+0x60/0x1000 + [ 1259.662439] bpf_lsm_bpf+0x5/0x20 + [ 1259.662443] ? security_bpf+0x32/0x50 + [ 1259.662452] __sys_bpf+0xe6/0xdd0 + [ 1259.662463] __x64_sys_bpf+0x1a/0x30 + [ 1259.662467] do_syscall_64+0x38/0x90 + [ 1259.662472] entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + [ 1259.662479] RIP: 0033:0x7f487baf8e29 + [...] + [ 1259.662504] + +This issue can be reproduced by executing a straightforward program, as +demonstrated below: + +SEC("lsm.s/bpf") +int BPF_PROG(lsm_run, int cmd, union bpf_attr *attr, unsigned int size) +{ + struct cgroup *cgrp = NULL; + struct task_struct *task; + int ret = 0; + + if (cmd != BPF_LINK_CREATE) + return 0; + + // The cgroup2 should be mounted first + cgrp = bpf_cgroup_from_id(1); + if (!cgrp) + goto out; + task = bpf_get_current_task_btf(); + if (bpf_task_under_cgroup(task, cgrp)) + ret = -1; + bpf_cgroup_release(cgrp); + +out: + return ret; +} + +After running the program, if you subsequently execute another BPF program, +you will encounter the warning. + +It's worth noting that task_under_cgroup_hierarchy() is also utilized by +bpf_current_task_under_cgroup(). However, bpf_current_task_under_cgroup() +doesn't exhibit this issue because it cannot be used in sleepable BPF +programs. + +Fixes: b5ad4cdc46c7 ("bpf: Add bpf_task_under_cgroup() kfunc") +Signed-off-by: Yafang Shao +Signed-off-by: Daniel Borkmann +Acked-by: Stanislav Fomichev +Cc: Feng Zhou +Cc: KP Singh +Link: https://lore.kernel.org/bpf/20231007135945.4306-1-laoar.shao@gmail.com +Signed-off-by: Sasha Levin +--- + kernel/bpf/helpers.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c +index 8bd3812fb8df4..68f54e16c7be0 100644 +--- a/kernel/bpf/helpers.c ++++ b/kernel/bpf/helpers.c +@@ -2197,7 +2197,12 @@ __bpf_kfunc struct cgroup *bpf_cgroup_from_id(u64 cgid) + __bpf_kfunc long bpf_task_under_cgroup(struct task_struct *task, + struct cgroup *ancestor) + { +- return task_under_cgroup_hierarchy(task, ancestor); ++ long ret; ++ ++ rcu_read_lock(); ++ ret = task_under_cgroup_hierarchy(task, ancestor); ++ rcu_read_unlock(); ++ return ret; + } + #endif /* CONFIG_CGROUPS */ + +-- +2.42.0 + diff --git a/queue-6.6/bpf-fix-unnecessary-ebusy-from-htab_lock_bucket.patch b/queue-6.6/bpf-fix-unnecessary-ebusy-from-htab_lock_bucket.patch new file mode 100644 index 00000000000..ac0772bf006 --- /dev/null +++ b/queue-6.6/bpf-fix-unnecessary-ebusy-from-htab_lock_bucket.patch @@ -0,0 +1,78 @@ +From 1eeb6c00615d3c63fa3ab1915c3259f6f218164f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 22:57:41 -0700 +Subject: bpf: Fix unnecessary -EBUSY from htab_lock_bucket + +From: Song Liu + +[ Upstream commit d35381aa73f7e1e8b25f3ed5283287a64d9ddff5 ] + +htab_lock_bucket uses the following logic to avoid recursion: + +1. preempt_disable(); +2. check percpu counter htab->map_locked[hash] for recursion; + 2.1. if map_lock[hash] is already taken, return -BUSY; +3. raw_spin_lock_irqsave(); + +However, if an IRQ hits between 2 and 3, BPF programs attached to the IRQ +logic will not able to access the same hash of the hashtab and get -EBUSY. + +This -EBUSY is not really necessary. Fix it by disabling IRQ before +checking map_locked: + +1. preempt_disable(); +2. local_irq_save(); +3. check percpu counter htab->map_locked[hash] for recursion; + 3.1. if map_lock[hash] is already taken, return -BUSY; +4. raw_spin_lock(). + +Similarly, use raw_spin_unlock() and local_irq_restore() in +htab_unlock_bucket(). + +Fixes: 20b6cc34ea74 ("bpf: Avoid hashtab deadlock with map_locked") +Suggested-by: Tejun Heo +Signed-off-by: Song Liu +Signed-off-by: Andrii Nakryiko +Signed-off-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/7a9576222aa40b1c84ad3a9ba3e64011d1a04d41.camel@linux.ibm.com +Link: https://lore.kernel.org/bpf/20231012055741.3375999-1-song@kernel.org +Signed-off-by: Sasha Levin +--- + kernel/bpf/hashtab.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c +index a8c7e1c5abfac..fd8d4b0addfca 100644 +--- a/kernel/bpf/hashtab.c ++++ b/kernel/bpf/hashtab.c +@@ -155,13 +155,15 @@ static inline int htab_lock_bucket(const struct bpf_htab *htab, + hash = hash & min_t(u32, HASHTAB_MAP_LOCK_MASK, htab->n_buckets - 1); + + preempt_disable(); ++ local_irq_save(flags); + if (unlikely(__this_cpu_inc_return(*(htab->map_locked[hash])) != 1)) { + __this_cpu_dec(*(htab->map_locked[hash])); ++ local_irq_restore(flags); + preempt_enable(); + return -EBUSY; + } + +- raw_spin_lock_irqsave(&b->raw_lock, flags); ++ raw_spin_lock(&b->raw_lock); + *pflags = flags; + + return 0; +@@ -172,8 +174,9 @@ static inline void htab_unlock_bucket(const struct bpf_htab *htab, + unsigned long flags) + { + hash = hash & min_t(u32, HASHTAB_MAP_LOCK_MASK, htab->n_buckets - 1); +- raw_spin_unlock_irqrestore(&b->raw_lock, flags); ++ raw_spin_unlock(&b->raw_lock); + __this_cpu_dec(*(htab->map_locked[hash])); ++ local_irq_restore(flags); + preempt_enable(); + } + +-- +2.42.0 + diff --git a/queue-6.6/bpf-x64-fix-tailcall-infinite-loop.patch b/queue-6.6/bpf-x64-fix-tailcall-infinite-loop.patch new file mode 100644 index 00000000000..f395613777a --- /dev/null +++ b/queue-6.6/bpf-x64-fix-tailcall-infinite-loop.patch @@ -0,0 +1,167 @@ +From 0d0d47ad9c10c242d145547ae320780c54b242c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 23:04:41 +0800 +Subject: bpf, x64: Fix tailcall infinite loop + +From: Leon Hwang + +[ Upstream commit 2b5dcb31a19a2e0acd869b12c9db9b2d696ef544 ] + +From commit ebf7d1f508a73871 ("bpf, x64: rework pro/epilogue and tailcall +handling in JIT"), the tailcall on x64 works better than before. + +From commit e411901c0b775a3a ("bpf: allow for tailcalls in BPF subprograms +for x64 JIT"), tailcall is able to run in BPF subprograms on x64. + +From commit 5b92a28aae4dd0f8 ("bpf: Support attaching tracing BPF program +to other BPF programs"), BPF program is able to trace other BPF programs. + +How about combining them all together? + +1. FENTRY/FEXIT on a BPF subprogram. +2. A tailcall runs in the BPF subprogram. +3. The tailcall calls the subprogram's caller. + +As a result, a tailcall infinite loop comes up. And the loop would halt +the machine. + +As we know, in tail call context, the tail_call_cnt propagates by stack +and rax register between BPF subprograms. So do in trampolines. + +Fixes: ebf7d1f508a7 ("bpf, x64: rework pro/epilogue and tailcall handling in JIT") +Fixes: e411901c0b77 ("bpf: allow for tailcalls in BPF subprograms for x64 JIT") +Reviewed-by: Maciej Fijalkowski +Signed-off-by: Leon Hwang +Link: https://lore.kernel.org/r/20230912150442.2009-3-hffilwlqm@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + arch/x86/net/bpf_jit_comp.c | 28 ++++++++++++++++++++++------ + include/linux/bpf.h | 5 +++++ + kernel/bpf/trampoline.c | 4 ++-- + kernel/bpf/verifier.c | 3 +++ + 4 files changed, 32 insertions(+), 8 deletions(-) + +diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c +index a5930042139d3..52f36c48c1b9e 100644 +--- a/arch/x86/net/bpf_jit_comp.c ++++ b/arch/x86/net/bpf_jit_comp.c +@@ -1018,6 +1018,10 @@ static void emit_shiftx(u8 **pprog, u32 dst_reg, u8 src_reg, bool is64, u8 op) + + #define INSN_SZ_DIFF (((addrs[i] - addrs[i - 1]) - (prog - temp))) + ++/* mov rax, qword ptr [rbp - rounded_stack_depth - 8] */ ++#define RESTORE_TAIL_CALL_CNT(stack) \ ++ EMIT3_off32(0x48, 0x8B, 0x85, -round_up(stack, 8) - 8) ++ + static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image, + int oldproglen, struct jit_context *ctx, bool jmp_padding) + { +@@ -1623,9 +1627,7 @@ st: if (is_imm8(insn->off)) + + func = (u8 *) __bpf_call_base + imm32; + if (tail_call_reachable) { +- /* mov rax, qword ptr [rbp - rounded_stack_depth - 8] */ +- EMIT3_off32(0x48, 0x8B, 0x85, +- -round_up(bpf_prog->aux->stack_depth, 8) - 8); ++ RESTORE_TAIL_CALL_CNT(bpf_prog->aux->stack_depth); + if (!imm32) + return -EINVAL; + offs = 7 + x86_call_depth_emit_accounting(&prog, func); +@@ -2400,6 +2402,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i + * [ ... ] + * [ stack_arg2 ] + * RBP - arg_stack_off [ stack_arg1 ] ++ * RSP [ tail_call_cnt ] BPF_TRAMP_F_TAIL_CALL_CTX + */ + + /* room for return value of orig_call or fentry prog */ +@@ -2464,6 +2467,8 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i + else + /* sub rsp, stack_size */ + EMIT4(0x48, 0x83, 0xEC, stack_size); ++ if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) ++ EMIT1(0x50); /* push rax */ + /* mov QWORD PTR [rbp - rbx_off], rbx */ + emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_6, -rbx_off); + +@@ -2516,9 +2521,15 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i + restore_regs(m, &prog, regs_off); + save_args(m, &prog, arg_stack_off, true); + ++ if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) ++ /* Before calling the original function, restore the ++ * tail_call_cnt from stack to rax. ++ */ ++ RESTORE_TAIL_CALL_CNT(stack_size); ++ + if (flags & BPF_TRAMP_F_ORIG_STACK) { +- emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, 8); +- EMIT2(0xff, 0xd0); /* call *rax */ ++ emit_ldx(&prog, BPF_DW, BPF_REG_6, BPF_REG_FP, 8); ++ EMIT2(0xff, 0xd3); /* call *rbx */ + } else { + /* call original function */ + if (emit_rsb_call(&prog, orig_call, prog)) { +@@ -2569,7 +2580,12 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i + ret = -EINVAL; + goto cleanup; + } +- } ++ } else if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) ++ /* Before running the original function, restore the ++ * tail_call_cnt from stack to rax. ++ */ ++ RESTORE_TAIL_CALL_CNT(stack_size); ++ + /* restore return value of orig_call or fentry prog back into RAX */ + if (save_ret) + emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, -8); +diff --git a/include/linux/bpf.h b/include/linux/bpf.h +index 49f8b691496c4..76055186d6248 100644 +--- a/include/linux/bpf.h ++++ b/include/linux/bpf.h +@@ -1029,6 +1029,11 @@ struct btf_func_model { + */ + #define BPF_TRAMP_F_SHARE_IPMODIFY BIT(6) + ++/* Indicate that current trampoline is in a tail call context. Then, it has to ++ * cache and restore tail_call_cnt to avoid infinite tail call loop. ++ */ ++#define BPF_TRAMP_F_TAIL_CALL_CTX BIT(7) ++ + /* Each call __bpf_prog_enter + call bpf_func + call __bpf_prog_exit is ~50 + * bytes on x86. + */ +diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c +index 53ff50cac61ea..e97aeda3a86b5 100644 +--- a/kernel/bpf/trampoline.c ++++ b/kernel/bpf/trampoline.c +@@ -415,8 +415,8 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut + goto out; + } + +- /* clear all bits except SHARE_IPMODIFY */ +- tr->flags &= BPF_TRAMP_F_SHARE_IPMODIFY; ++ /* clear all bits except SHARE_IPMODIFY and TAIL_CALL_CTX */ ++ tr->flags &= (BPF_TRAMP_F_SHARE_IPMODIFY | BPF_TRAMP_F_TAIL_CALL_CTX); + + if (tlinks[BPF_TRAMP_FEXIT].nr_links || + tlinks[BPF_TRAMP_MODIFY_RETURN].nr_links) { +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 873ade146f3de..9f180ae74e492 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -19641,6 +19641,9 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) + if (!tr) + return -ENOMEM; + ++ if (tgt_prog && tgt_prog->aux->tail_call_reachable) ++ tr->flags = BPF_TRAMP_F_TAIL_CALL_CTX; ++ + prog->aux->dst_trampoline = tr; + return 0; + } +-- +2.42.0 + diff --git a/queue-6.6/can-dev-can_put_echo_skb-don-t-crash-kernel-if-can_p.patch b/queue-6.6/can-dev-can_put_echo_skb-don-t-crash-kernel-if-can_p.patch new file mode 100644 index 00000000000..2a192100374 --- /dev/null +++ b/queue-6.6/can-dev-can_put_echo_skb-don-t-crash-kernel-if-can_p.patch @@ -0,0 +1,43 @@ +From 380c98496a4d23437f9ce5a4cdfa72393c96d7ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 10:23:47 +0200 +Subject: can: dev: can_put_echo_skb(): don't crash kernel if + can_priv::echo_skb is accessed out of bounds + +From: Marc Kleine-Budde + +[ Upstream commit 6411959c10fe917288cbb1038886999148560057 ] + +If the "struct can_priv::echoo_skb" is accessed out of bounds, this +would cause a kernel crash. Instead, issue a meaningful warning +message and return with an error. + +Fixes: a6e4bc530403 ("can: make the number of echo skb's configurable") +Link: https://lore.kernel.org/all/20231005-can-dev-fix-can-restart-v2-5-91b5c1fd922c@pengutronix.de +Reviewed-by: Vincent Mailhol +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/dev/skb.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c +index f6d05b3ef59ab..3ebd4f779b9bd 100644 +--- a/drivers/net/can/dev/skb.c ++++ b/drivers/net/can/dev/skb.c +@@ -49,7 +49,11 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, + { + struct can_priv *priv = netdev_priv(dev); + +- BUG_ON(idx >= priv->echo_skb_max); ++ if (idx >= priv->echo_skb_max) { ++ netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n", ++ __func__, idx, priv->echo_skb_max); ++ return -EINVAL; ++ } + + /* check flag whether this packet has to be looped back */ + if (!(dev->flags & IFF_ECHO) || +-- +2.42.0 + diff --git a/queue-6.6/can-dev-can_restart-don-t-crash-kernel-if-carrier-is.patch b/queue-6.6/can-dev-can_restart-don-t-crash-kernel-if-carrier-is.patch new file mode 100644 index 00000000000..7fc19721ba2 --- /dev/null +++ b/queue-6.6/can-dev-can_restart-don-t-crash-kernel-if-carrier-is.patch @@ -0,0 +1,46 @@ +From 756c8c512eb84dae7175373b2a378c9d97ffcf30 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Sep 2023 21:58:23 +0200 +Subject: can: dev: can_restart(): don't crash kernel if carrier is OK + +From: Marc Kleine-Budde + +[ Upstream commit fe5c9940dfd8ba0c73672dddb30acd1b7a11d4c7 ] + +During testing, I triggered a can_restart() with the netif carrier +being OK [1]. The BUG_ON, which checks if the carrier is OK, results +in a fatal kernel crash. This is neither helpful for debugging nor for +a production system. + +[1] The root cause is a race condition in can_restart() which will be +fixed in the next patch. + +Do not crash the kernel, issue an error message instead, and continue +restarting the CAN device anyway. + +Fixes: 39549eef3587 ("can: CAN Network device driver and Netlink interface") +Link: https://lore.kernel.org/all/20231005-can-dev-fix-can-restart-v2-1-91b5c1fd922c@pengutronix.de +Reviewed-by: Vincent Mailhol +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/dev/dev.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c +index 7f9334a8af500..a5bbdfa9a2693 100644 +--- a/drivers/net/can/dev/dev.c ++++ b/drivers/net/can/dev/dev.c +@@ -132,7 +132,8 @@ static void can_restart(struct net_device *dev) + struct can_frame *cf; + int err; + +- BUG_ON(netif_carrier_ok(dev)); ++ if (netif_carrier_ok(dev)) ++ netdev_err(dev, "Attempt to restart for bus-off recovery, but carrier is OK?\n"); + + /* No synchronization needed because the device is bus-off and + * no messages can come in or go out. +-- +2.42.0 + diff --git a/queue-6.6/can-dev-can_restart-fix-race-condition-between-contr.patch b/queue-6.6/can-dev-can_restart-fix-race-condition-between-contr.patch new file mode 100644 index 00000000000..ba9e157bd54 --- /dev/null +++ b/queue-6.6/can-dev-can_restart-fix-race-condition-between-contr.patch @@ -0,0 +1,102 @@ +From e7629da8f9d549fe62a4b0b2e40a843fe18afa19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 10:25:11 +0200 +Subject: can: dev: can_restart(): fix race condition between controller + restart and netif_carrier_on() + +From: Marc Kleine-Budde + +[ Upstream commit 6841cab8c4504835e4011689cbdb3351dec693fd ] + +This race condition was discovered while updating the at91_can driver +to use can_bus_off(). The following scenario describes how the +converted at91_can driver would behave. + +When a CAN device goes into BUS-OFF state, the driver usually +stops/resets the CAN device and calls can_bus_off(). + +This function sets the netif carrier to off, and (if configured by +user space) schedules a delayed work that calls can_restart() to +restart the CAN device. + +The can_restart() function first checks if the carrier is off and +triggers an error message if the carrier is OK. + +Then it calls the driver's do_set_mode() function to restart the +device, then it sets the netif carrier to on. There is a race window +between these two calls. + +The at91 CAN controller (observed on the sama5d3, a single core 32 bit +ARM CPU) has a hardware limitation. If the device goes into bus-off +while sending a CAN frame, there is no way to abort the sending of +this frame. After the controller is enabled again, another attempt is +made to send it. + +If the bus is still faulty, the device immediately goes back to the +bus-off state. The driver calls can_bus_off(), the netif carrier is +switched off and another can_restart is scheduled. This occurs within +the race window before the original can_restart() handler marks the +netif carrier as OK. This would cause the 2nd can_restart() to be +called with an OK netif carrier, resulting in an error message. + +The flow of the 1st can_restart() looks like this: + +can_restart() + // bail out if netif_carrier is OK + + netif_carrier_ok(dev) + priv->do_set_mode(dev, CAN_MODE_START) + // enable CAN controller + // sama5d3 restarts sending old message + + // CAN devices goes into BUS_OFF, triggers IRQ + +// IRQ handler start + at91_irq() + at91_irq_err_line() + can_bus_off() + netif_carrier_off() + schedule_delayed_work() +// IRQ handler end + + netif_carrier_on() + +The 2nd can_restart() will be called with an OK netif carrier and the +error message will be printed. + +To close the race window, first set the netif carrier to on, then +restart the controller. In case the restart fails with an error code, +roll back the netif carrier to off. + +Fixes: 39549eef3587 ("can: CAN Network device driver and Netlink interface") +Link: https://lore.kernel.org/all/20231005-can-dev-fix-can-restart-v2-2-91b5c1fd922c@pengutronix.de +Reviewed-by: Vincent Mailhol +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/dev/dev.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c +index a5bbdfa9a2693..735d5de3caa0e 100644 +--- a/drivers/net/can/dev/dev.c ++++ b/drivers/net/can/dev/dev.c +@@ -154,11 +154,12 @@ static void can_restart(struct net_device *dev) + priv->can_stats.restarts++; + + /* Now restart the device */ +- err = priv->do_set_mode(dev, CAN_MODE_START); +- + netif_carrier_on(dev); +- if (err) ++ err = priv->do_set_mode(dev, CAN_MODE_START); ++ if (err) { + netdev_err(dev, "Error %d during restart", err); ++ netif_carrier_off(dev); ++ } + } + + static void can_restart_work(struct work_struct *work) +-- +2.42.0 + diff --git a/queue-6.6/can-etas_es58x-add-missing-a-blank-line-after-declar.patch b/queue-6.6/can-etas_es58x-add-missing-a-blank-line-after-declar.patch new file mode 100644 index 00000000000..d5dfd465351 --- /dev/null +++ b/queue-6.6/can-etas_es58x-add-missing-a-blank-line-after-declar.patch @@ -0,0 +1,40 @@ +From f7bf5abde0729a75767db674d535a292fe79de5d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Sep 2023 20:06:48 +0900 +Subject: can: etas_es58x: add missing a blank line after declaration + +From: Vincent Mailhol + +[ Upstream commit 4f8005092cafc194ba6a8e5f39626ba0b9f08271 ] + +Fix below checkpatch warning: + + WARNING: Missing a blank line after declarations + #2233: FILE: drivers/net/can/usb/etas_es58x/es58x_core.c:2233: + + int ret = es58x_init_netdev(es58x_dev, ch_idx); + + if (ret) { + +Fixes: d8f26fd689dd ("can: etas_es58x: remove es58x_get_product_info()") +Signed-off-by: Vincent Mailhol +Link: https://lore.kernel.org/all/20230924110914.183898-3-mailhol.vincent@wanadoo.fr +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/usb/etas_es58x/es58x_core.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c +index 0c7f7505632cd..5e3a72b7c4691 100644 +--- a/drivers/net/can/usb/etas_es58x/es58x_core.c ++++ b/drivers/net/can/usb/etas_es58x/es58x_core.c +@@ -2230,6 +2230,7 @@ static int es58x_probe(struct usb_interface *intf, + + for (ch_idx = 0; ch_idx < es58x_dev->num_can_ch; ch_idx++) { + int ret = es58x_init_netdev(es58x_dev, ch_idx); ++ + if (ret) { + es58x_free_netdevs(es58x_dev); + return ret; +-- +2.42.0 + diff --git a/queue-6.6/can-etas_es58x-rework-the-version-check-logic-to-sil.patch b/queue-6.6/can-etas_es58x-rework-the-version-check-logic-to-sil.patch new file mode 100644 index 00000000000..1d52a3e6e05 --- /dev/null +++ b/queue-6.6/can-etas_es58x-rework-the-version-check-logic-to-sil.patch @@ -0,0 +1,247 @@ +From ddc45735d1fcb974ed95167f01975382f46093ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Sep 2023 20:06:47 +0900 +Subject: can: etas_es58x: rework the version check logic to silence + -Wformat-truncation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Vincent Mailhol + +[ Upstream commit 107e6f6fe6f38577baecf0e01f517c8607a3a625 ] + +Following [1], es58x_devlink.c now triggers the following +format-truncation GCC warnings: + + drivers/net/can/usb/etas_es58x/es58x_devlink.c: In function ‘es58x_devlink_info_get’: + drivers/net/can/usb/etas_es58x/es58x_devlink.c:201:41: warning: ‘%02u’ directive output may be truncated writing between 2 and 3 bytes into a region of size between 1 and 3 [-Wformat-truncation=] + 201 | snprintf(buf, sizeof(buf), "%02u.%02u.%02u", + | ^~~~ + drivers/net/can/usb/etas_es58x/es58x_devlink.c:201:30: note: directive argument in the range [0, 255] + 201 | snprintf(buf, sizeof(buf), "%02u.%02u.%02u", + | ^~~~~~~~~~~~~~~~ + drivers/net/can/usb/etas_es58x/es58x_devlink.c:201:3: note: ‘snprintf’ output between 9 and 12 bytes into a destination of size 9 + 201 | snprintf(buf, sizeof(buf), "%02u.%02u.%02u", + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 202 | fw_ver->major, fw_ver->minor, fw_ver->revision); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + drivers/net/can/usb/etas_es58x/es58x_devlink.c:211:41: warning: ‘%02u’ directive output may be truncated writing between 2 and 3 bytes into a region of size between 1 and 3 [-Wformat-truncation=] + 211 | snprintf(buf, sizeof(buf), "%02u.%02u.%02u", + | ^~~~ + drivers/net/can/usb/etas_es58x/es58x_devlink.c:211:30: note: directive argument in the range [0, 255] + 211 | snprintf(buf, sizeof(buf), "%02u.%02u.%02u", + | ^~~~~~~~~~~~~~~~ + drivers/net/can/usb/etas_es58x/es58x_devlink.c:211:3: note: ‘snprintf’ output between 9 and 12 bytes into a destination of size 9 + 211 | snprintf(buf, sizeof(buf), "%02u.%02u.%02u", + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 212 | bl_ver->major, bl_ver->minor, bl_ver->revision); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + drivers/net/can/usb/etas_es58x/es58x_devlink.c:221:38: warning: ‘%03u’ directive output may be truncated writing between 3 and 5 bytes into a region of size between 2 and 4 [-Wformat-truncation=] + 221 | snprintf(buf, sizeof(buf), "%c%03u/%03u", + | ^~~~ + drivers/net/can/usb/etas_es58x/es58x_devlink.c:221:30: note: directive argument in the range [0, 65535] + 221 | snprintf(buf, sizeof(buf), "%c%03u/%03u", + | ^~~~~~~~~~~~~ + drivers/net/can/usb/etas_es58x/es58x_devlink.c:221:3: note: ‘snprintf’ output between 9 and 13 bytes into a destination of size 9 + 221 | snprintf(buf, sizeof(buf), "%c%03u/%03u", + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 222 | hw_rev->letter, hw_rev->major, hw_rev->minor); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is not an actual bug because the sscanf() parsing makes sure that +the u8 are only two digits long and the u16 only three digits long. +Thus below declaration: + + char buf[max(sizeof("xx.xx.xx"), sizeof("axxx/xxx"))]; + +allocates just what is needed to represent either of the versions. + +This warning was known but ignored because, at the time of writing, +-Wformat-truncation was not present in the kernel, not even at W=3 [2]. + +One way to silence this warning is to check the range of all sub +version numbers are valid: [0, 99] for u8 and range [0, 999] for u16. + +The module already has a logic which considers that when all the sub +version numbers are zero, the version number is not set. Note that not +having access to the device specification, this was an arbitrary +decision. This logic can thus be removed in favor of global check that +would cover both cases: + + - the version number is not set (parsing failed) + - the version number is not valid (paranoiac check to please gcc) + +Before starting to parse the product info string, set the version +sub-numbers to the maximum unsigned integer thus violating the +definitions of struct es58x_sw_version or struct es58x_hw_revision. + +Then, rework the es58x_sw_version_is_set() and +es58x_hw_revision_is_set() functions: remove the check that the +sub-numbers are non zero and replace it by a check that they fit in +the expected number of digits. This done, rename the functions to +reflect the change and rewrite the documentation. While doing so, also +add a description of the return value. + +Finally, the previous version only checked that +&es58x_hw_revision.letter was not the null character. Replace this +check by an alphanumeric character check to make sure that we never +return a special character or a non-printable one and update the +documentation of struct es58x_hw_revision accordingly. + +All those extra checks are paranoid but have the merit to silence the +newly introduced W=1 format-truncation warning [1]. + +[1] commit 6d4ab2e97dcf ("extrawarn: enable format and stringop overflow warnings in W=1") +Link: https://git.kernel.org/torvalds/c/6d4ab2e97dcf + +[2] https://lore.kernel.org/all/CAMZ6Rq+K+6gbaZ35SOJcR9qQaTJ7KR0jW=XoDKFkobjhj8CHhw@mail.gmail.com/ + +Reported-by: Marc Kleine-Budde +Closes: https://lore.kernel.org/linux-can/20230914-carrousel-wrecker-720a08e173e9-mkl@pengutronix.de/ +Fixes: 9f06631c3f1f ("can: etas_es58x: export product information through devlink_ops::info_get()") +Signed-off-by: Vincent Mailhol +Link: https://lore.kernel.org/all/20230924110914.183898-2-mailhol.vincent@wanadoo.fr +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/usb/etas_es58x/es58x_core.h | 6 +- + .../net/can/usb/etas_es58x/es58x_devlink.c | 57 +++++++++++++------ + 2 files changed, 42 insertions(+), 21 deletions(-) + +diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.h b/drivers/net/can/usb/etas_es58x/es58x_core.h +index c1ba1a4e8857b..2e183bdeedd72 100644 +--- a/drivers/net/can/usb/etas_es58x/es58x_core.h ++++ b/drivers/net/can/usb/etas_es58x/es58x_core.h +@@ -378,13 +378,13 @@ struct es58x_sw_version { + + /** + * struct es58x_hw_revision - Hardware revision number. +- * @letter: Revision letter. ++ * @letter: Revision letter, an alphanumeric character. + * @major: Version major number, represented on three digits. + * @minor: Version minor number, represented on three digits. + * + * The hardware revision uses its own format: "axxx/xxx" where 'a' is +- * a letter and 'x' a digit. It can be retrieved from the product +- * information string. ++ * an alphanumeric character and 'x' a digit. It can be retrieved from ++ * the product information string. + */ + struct es58x_hw_revision { + char letter; +diff --git a/drivers/net/can/usb/etas_es58x/es58x_devlink.c b/drivers/net/can/usb/etas_es58x/es58x_devlink.c +index 9fba29e2f57c6..635edeb8f68cd 100644 +--- a/drivers/net/can/usb/etas_es58x/es58x_devlink.c ++++ b/drivers/net/can/usb/etas_es58x/es58x_devlink.c +@@ -125,14 +125,28 @@ static int es58x_parse_hw_rev(struct es58x_device *es58x_dev, + * firmware version, the bootloader version and the hardware + * revision. + * +- * If the function fails, simply emit a log message and continue +- * because product information is not critical for the driver to +- * operate. ++ * If the function fails, set the version or revision to an invalid ++ * value and emit an informal message. Continue probing because the ++ * product information is not critical for the driver to operate. + */ + void es58x_parse_product_info(struct es58x_device *es58x_dev) + { ++ static const struct es58x_sw_version sw_version_not_set = { ++ .major = -1, ++ .minor = -1, ++ .revision = -1, ++ }; ++ static const struct es58x_hw_revision hw_revision_not_set = { ++ .letter = '\0', ++ .major = -1, ++ .minor = -1, ++ }; + char *prod_info; + ++ es58x_dev->firmware_version = sw_version_not_set; ++ es58x_dev->bootloader_version = sw_version_not_set; ++ es58x_dev->hardware_revision = hw_revision_not_set; ++ + prod_info = usb_cache_string(es58x_dev->udev, ES58X_PROD_INFO_IDX); + if (!prod_info) { + dev_warn(es58x_dev->dev, +@@ -150,29 +164,36 @@ void es58x_parse_product_info(struct es58x_device *es58x_dev) + } + + /** +- * es58x_sw_version_is_set() - Check if the version is a valid number. ++ * es58x_sw_version_is_valid() - Check if the version is a valid number. + * @sw_ver: Version number of either the firmware or the bootloader. + * +- * If &es58x_sw_version.major, &es58x_sw_version.minor and +- * &es58x_sw_version.revision are all zero, the product string could +- * not be parsed and the version number is invalid. ++ * If any of the software version sub-numbers do not fit on two ++ * digits, the version is invalid, most probably because the product ++ * string could not be parsed. ++ * ++ * Return: @true if the software version is valid, @false otherwise. + */ +-static inline bool es58x_sw_version_is_set(struct es58x_sw_version *sw_ver) ++static inline bool es58x_sw_version_is_valid(struct es58x_sw_version *sw_ver) + { +- return sw_ver->major || sw_ver->minor || sw_ver->revision; ++ return sw_ver->major < 100 && sw_ver->minor < 100 && ++ sw_ver->revision < 100; + } + + /** +- * es58x_hw_revision_is_set() - Check if the revision is a valid number. ++ * es58x_hw_revision_is_valid() - Check if the revision is a valid number. + * @hw_rev: Revision number of the hardware. + * +- * If &es58x_hw_revision.letter is the null character, the product +- * string could not be parsed and the hardware revision number is +- * invalid. ++ * If &es58x_hw_revision.letter is not a alphanumeric character or if ++ * any of the hardware revision sub-numbers do not fit on three ++ * digits, the revision is invalid, most probably because the product ++ * string could not be parsed. ++ * ++ * Return: @true if the hardware revision is valid, @false otherwise. + */ +-static inline bool es58x_hw_revision_is_set(struct es58x_hw_revision *hw_rev) ++static inline bool es58x_hw_revision_is_valid(struct es58x_hw_revision *hw_rev) + { +- return hw_rev->letter != '\0'; ++ return isalnum(hw_rev->letter) && hw_rev->major < 1000 && ++ hw_rev->minor < 1000; + } + + /** +@@ -197,7 +218,7 @@ static int es58x_devlink_info_get(struct devlink *devlink, + char buf[max(sizeof("xx.xx.xx"), sizeof("axxx/xxx"))]; + int ret = 0; + +- if (es58x_sw_version_is_set(fw_ver)) { ++ if (es58x_sw_version_is_valid(fw_ver)) { + snprintf(buf, sizeof(buf), "%02u.%02u.%02u", + fw_ver->major, fw_ver->minor, fw_ver->revision); + ret = devlink_info_version_running_put(req, +@@ -207,7 +228,7 @@ static int es58x_devlink_info_get(struct devlink *devlink, + return ret; + } + +- if (es58x_sw_version_is_set(bl_ver)) { ++ if (es58x_sw_version_is_valid(bl_ver)) { + snprintf(buf, sizeof(buf), "%02u.%02u.%02u", + bl_ver->major, bl_ver->minor, bl_ver->revision); + ret = devlink_info_version_running_put(req, +@@ -217,7 +238,7 @@ static int es58x_devlink_info_get(struct devlink *devlink, + return ret; + } + +- if (es58x_hw_revision_is_set(hw_rev)) { ++ if (es58x_hw_revision_is_valid(hw_rev)) { + snprintf(buf, sizeof(buf), "%c%03u/%03u", + hw_rev->letter, hw_rev->major, hw_rev->minor); + ret = devlink_info_version_fixed_put(req, +-- +2.42.0 + diff --git a/queue-6.6/certs-break-circular-dependency-when-selftest-is-mod.patch b/queue-6.6/certs-break-circular-dependency-when-selftest-is-mod.patch new file mode 100644 index 00000000000..196b2fdec93 --- /dev/null +++ b/queue-6.6/certs-break-circular-dependency-when-selftest-is-mod.patch @@ -0,0 +1,142 @@ +From 9687be0eb77480116dedf2a97893fb6bbcca4deb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Oct 2023 13:21:44 +0800 +Subject: certs: Break circular dependency when selftest is modular + +From: Herbert Xu + +[ Upstream commit 04a93202ed7c3b451bf22d3ff4bcd379df27f299 ] + +The modular build fails because the self-test code depends on pkcs7 +which in turn depends on x509 which contains the self-test. + +Split the self-test out into its own module to break the cycle. + +Fixes: 3cde3174eb91 ("certs: Add FIPS selftests") +Signed-off-by: Herbert Xu +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/asymmetric_keys/Kconfig | 3 ++- + crypto/asymmetric_keys/Makefile | 3 ++- + crypto/asymmetric_keys/selftest.c | 13 ++++++++++--- + crypto/asymmetric_keys/x509_parser.h | 9 --------- + crypto/asymmetric_keys/x509_public_key.c | 8 +------- + 5 files changed, 15 insertions(+), 21 deletions(-) + +diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig +index 1ef3b46d6f6e5..59ec726b7c770 100644 +--- a/crypto/asymmetric_keys/Kconfig ++++ b/crypto/asymmetric_keys/Kconfig +@@ -76,7 +76,7 @@ config SIGNED_PE_FILE_VERIFICATION + signed PE binary. + + config FIPS_SIGNATURE_SELFTEST +- bool "Run FIPS selftests on the X.509+PKCS7 signature verification" ++ tristate "Run FIPS selftests on the X.509+PKCS7 signature verification" + help + This option causes some selftests to be run on the signature + verification code, using some built in data. This is required +@@ -84,5 +84,6 @@ config FIPS_SIGNATURE_SELFTEST + depends on KEYS + depends on ASYMMETRIC_KEY_TYPE + depends on PKCS7_MESSAGE_PARSER=X509_CERTIFICATE_PARSER ++ depends on X509_CERTIFICATE_PARSER + + endif # ASYMMETRIC_KEY_TYPE +diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile +index 0d1fa1b692c6b..1a273d6df3ebf 100644 +--- a/crypto/asymmetric_keys/Makefile ++++ b/crypto/asymmetric_keys/Makefile +@@ -22,7 +22,8 @@ x509_key_parser-y := \ + x509_cert_parser.o \ + x509_loader.o \ + x509_public_key.o +-x509_key_parser-$(CONFIG_FIPS_SIGNATURE_SELFTEST) += selftest.o ++obj-$(CONFIG_FIPS_SIGNATURE_SELFTEST) += x509_selftest.o ++x509_selftest-y += selftest.o + + $(obj)/x509_cert_parser.o: \ + $(obj)/x509.asn1.h \ +diff --git a/crypto/asymmetric_keys/selftest.c b/crypto/asymmetric_keys/selftest.c +index fa0bf7f242849..c50da7ef90ae9 100644 +--- a/crypto/asymmetric_keys/selftest.c ++++ b/crypto/asymmetric_keys/selftest.c +@@ -4,10 +4,11 @@ + * Written by David Howells (dhowells@redhat.com) + */ + +-#include ++#include + #include ++#include + #include +-#include ++#include + #include "x509_parser.h" + + struct certs_test { +@@ -175,7 +176,7 @@ static const struct certs_test certs_tests[] __initconst = { + TEST(certs_selftest_1_data, certs_selftest_1_pkcs7), + }; + +-int __init fips_signature_selftest(void) ++static int __init fips_signature_selftest(void) + { + struct key *keyring; + int ret, i; +@@ -222,3 +223,9 @@ int __init fips_signature_selftest(void) + key_put(keyring); + return 0; + } ++ ++late_initcall(fips_signature_selftest); ++ ++MODULE_DESCRIPTION("X.509 self tests"); ++MODULE_AUTHOR("Red Hat, Inc."); ++MODULE_LICENSE("GPL"); +diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h +index a299c9c56f409..97a886cbe01c3 100644 +--- a/crypto/asymmetric_keys/x509_parser.h ++++ b/crypto/asymmetric_keys/x509_parser.h +@@ -40,15 +40,6 @@ struct x509_certificate { + bool blacklisted; + }; + +-/* +- * selftest.c +- */ +-#ifdef CONFIG_FIPS_SIGNATURE_SELFTEST +-extern int __init fips_signature_selftest(void); +-#else +-static inline int fips_signature_selftest(void) { return 0; } +-#endif +- + /* + * x509_cert_parser.c + */ +diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c +index 7c71db3ac23d4..6a4f00be22fc1 100644 +--- a/crypto/asymmetric_keys/x509_public_key.c ++++ b/crypto/asymmetric_keys/x509_public_key.c +@@ -262,15 +262,9 @@ static struct asymmetric_key_parser x509_key_parser = { + /* + * Module stuff + */ +-extern int __init certs_selftest(void); + static int __init x509_key_init(void) + { +- int ret; +- +- ret = register_asymmetric_key_parser(&x509_key_parser); +- if (ret < 0) +- return ret; +- return fips_signature_selftest(); ++ return register_asymmetric_key_parser(&x509_key_parser); + } + + static void __exit x509_key_exit(void) +-- +2.42.0 + diff --git a/queue-6.6/cgroup-cpuset-fix-load-balance-state-in-update_parti.patch b/queue-6.6/cgroup-cpuset-fix-load-balance-state-in-update_parti.patch new file mode 100644 index 00000000000..5012c88f08f --- /dev/null +++ b/queue-6.6/cgroup-cpuset-fix-load-balance-state-in-update_parti.patch @@ -0,0 +1,60 @@ +From 89d7711fc3d347d9f4715ae72aac502b6eada512 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Sep 2023 09:32:37 -0400 +Subject: cgroup/cpuset: Fix load balance state in update_partition_sd_lb() + +From: Waiman Long + +[ Upstream commit 6fcdb0183bf024a70abccb0439321c25891c708d ] + +Commit a86ce68078b2 ("cgroup/cpuset: Extract out CS_CPU_EXCLUSIVE +& CS_SCHED_LOAD_BALANCE handling") adds a new helper function +update_partition_sd_lb() to update the load balance state of the +cpuset. However the new load balance is determined by just looking at +whether the cpuset is a valid isolated partition root or not. That is +not enough if the cpuset is not a valid partition root but its parent +is in the isolated state (load balance off). Update the function to +set the new state to be the same as its parent in this case like what +has been done in commit c8c926200c55 ("cgroup/cpuset: Inherit parent's +load balance state in v2"). + +Fixes: a86ce68078b2 ("cgroup/cpuset: Extract out CS_CPU_EXCLUSIVE & CS_SCHED_LOAD_BALANCE handling") +Signed-off-by: Waiman Long +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/cgroup/cpuset.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c +index 58ec88efa4f82..4749e0c86c62c 100644 +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -1304,13 +1304,23 @@ static int update_partition_exclusive(struct cpuset *cs, int new_prs) + * + * Changing load balance flag will automatically call + * rebuild_sched_domains_locked(). ++ * This function is for cgroup v2 only. + */ + static void update_partition_sd_lb(struct cpuset *cs, int old_prs) + { + int new_prs = cs->partition_root_state; +- bool new_lb = (new_prs != PRS_ISOLATED); + bool rebuild_domains = (new_prs > 0) || (old_prs > 0); ++ bool new_lb; + ++ /* ++ * If cs is not a valid partition root, the load balance state ++ * will follow its parent. ++ */ ++ if (new_prs > 0) { ++ new_lb = (new_prs != PRS_ISOLATED); ++ } else { ++ new_lb = is_sched_load_balance(parent_cs(cs)); ++ } + if (new_lb != !!is_sched_load_balance(cs)) { + rebuild_domains = true; + if (new_lb) +-- +2.42.0 + diff --git a/queue-6.6/chtls-fix-tp-rcv_tstamp-initialization.patch b/queue-6.6/chtls-fix-tp-rcv_tstamp-initialization.patch new file mode 100644 index 00000000000..63770ba13e1 --- /dev/null +++ b/queue-6.6/chtls-fix-tp-rcv_tstamp-initialization.patch @@ -0,0 +1,36 @@ +From feac10db43db62384f0e21677246ffb5ad0cf033 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 12:57:36 +0000 +Subject: chtls: fix tp->rcv_tstamp initialization + +From: Eric Dumazet + +[ Upstream commit 225d9ddbacb102621af6d28ff7bf5a0b4ce249d8 ] + +tp->rcv_tstamp should be set to tcp_jiffies, not tcp_time_stamp(). + +Fixes: cc35c88ae4db ("crypto : chtls - CPL handler definition") +Signed-off-by: Eric Dumazet +Cc: Ayush Sawal +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c +index 7750702900fa6..6f6525983130e 100644 +--- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c ++++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c +@@ -2259,7 +2259,7 @@ static void chtls_rx_ack(struct sock *sk, struct sk_buff *skb) + + if (tp->snd_una != snd_una) { + tp->snd_una = snd_una; +- tp->rcv_tstamp = tcp_time_stamp(tp); ++ tp->rcv_tstamp = tcp_jiffies32; + if (tp->snd_una == tp->snd_nxt && + !csk_flag_nochk(csk, CSK_TX_FAILOVER)) + csk_reset_flag(csk, CSK_TX_WAIT_IDLE); +-- +2.42.0 + diff --git a/queue-6.6/clk-imx-imx8-fix-an-error-handling-path-if-devm_clk_.patch b/queue-6.6/clk-imx-imx8-fix-an-error-handling-path-if-devm_clk_.patch new file mode 100644 index 00000000000..47f0ee37337 --- /dev/null +++ b/queue-6.6/clk-imx-imx8-fix-an-error-handling-path-if-devm_clk_.patch @@ -0,0 +1,39 @@ +From c23f03fecd840a5ff60274dc8f72e0cfa3fbe02a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 22:31:03 +0200 +Subject: clk: imx: imx8: Fix an error handling path if + devm_clk_hw_register_mux_parent_data_table() fails + +From: Christophe JAILLET + +[ Upstream commit 9a0108acdb1b6189dcc8f9318edfc6b7e0281df4 ] + +If a devm_clk_hw_register_mux_parent_data_table() call fails, it is likely +that the probe should fail with an error code. + +Set 'ret' before leaving the function. + +Fixes: d3a0946d7ac9 ("clk: imx: imx8: add audio clock mux driver") +Reviewed-by: Peng Fan +Signed-off-by: Christophe JAILLET +Signed-off-by: Abel Vesa +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imx8-acm.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/imx/clk-imx8-acm.c b/drivers/clk/imx/clk-imx8-acm.c +index 87025a6772d0e..73b3b53549517 100644 +--- a/drivers/clk/imx/clk-imx8-acm.c ++++ b/drivers/clk/imx/clk-imx8-acm.c +@@ -373,6 +373,7 @@ static int imx8_acm_clk_probe(struct platform_device *pdev) + sels[i].shift, sels[i].width, + 0, NULL, NULL); + if (IS_ERR(hws[sels[i].clkid])) { ++ ret = PTR_ERR(hws[sels[i].clkid]); + pm_runtime_disable(&pdev->dev); + goto err_clk_register; + } +-- +2.42.0 + diff --git a/queue-6.6/clk-imx-imx8-fix-an-error-handling-path-in-clk_imx_a.patch b/queue-6.6/clk-imx-imx8-fix-an-error-handling-path-in-clk_imx_a.patch new file mode 100644 index 00000000000..05230dbc779 --- /dev/null +++ b/queue-6.6/clk-imx-imx8-fix-an-error-handling-path-in-clk_imx_a.patch @@ -0,0 +1,42 @@ +From 0041bc1849e505a964b494930b6deb24ec3819f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 22:31:02 +0200 +Subject: clk: imx: imx8: Fix an error handling path in + clk_imx_acm_attach_pm_domains() + +From: Christophe JAILLET + +[ Upstream commit 156624e2cf815ce98fad5a24f04370f4459ae6f4 ] + +If a dev_pm_domain_attach_by_id() call fails, previously allocated +resources need to be released. + +Fixes: d3a0946d7ac9 ("clk: imx: imx8: add audio clock mux driver") +Reviewed-by: Peng Fan +Signed-off-by: Christophe JAILLET +Signed-off-by: Abel Vesa +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imx8-acm.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/imx/clk-imx8-acm.c b/drivers/clk/imx/clk-imx8-acm.c +index 1e82f72b75c67..87025a6772d0e 100644 +--- a/drivers/clk/imx/clk-imx8-acm.c ++++ b/drivers/clk/imx/clk-imx8-acm.c +@@ -279,8 +279,10 @@ static int clk_imx_acm_attach_pm_domains(struct device *dev, + + for (i = 0; i < dev_pm->num_domains; i++) { + dev_pm->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i); +- if (IS_ERR(dev_pm->pd_dev[i])) +- return PTR_ERR(dev_pm->pd_dev[i]); ++ if (IS_ERR(dev_pm->pd_dev[i])) { ++ ret = PTR_ERR(dev_pm->pd_dev[i]); ++ goto detach_pm; ++ } + + dev_pm->pd_dev_link[i] = device_link_add(dev, + dev_pm->pd_dev[i], +-- +2.42.0 + diff --git a/queue-6.6/clk-imx-imx8-fix-an-error-handling-path-in-imx8_acm_.patch b/queue-6.6/clk-imx-imx8-fix-an-error-handling-path-in-imx8_acm_.patch new file mode 100644 index 00000000000..83069863b97 --- /dev/null +++ b/queue-6.6/clk-imx-imx8-fix-an-error-handling-path-in-imx8_acm_.patch @@ -0,0 +1,58 @@ +From 9a9323e764e05a6bc83defdb12e56eb0d2d68793 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 22:31:04 +0200 +Subject: clk: imx: imx8: Fix an error handling path in imx8_acm_clk_probe() + +From: Christophe JAILLET + +[ Upstream commit e9a164e367f039629fd5466a79b9f495646e1261 ] + +If an error occurs after a successful clk_imx_acm_attach_pm_domains() call, +it must be undone. + +Add an explicit error handling path, re-order the code and add the missing +clk_imx_acm_detach_pm_domains() call. + +Fixes: d3a0946d7ac9 ("clk: imx: imx8: add audio clock mux driver") +Reviewed-by: Peng Fan +Signed-off-by: Christophe JAILLET +Signed-off-by: Abel Vesa +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imx8-acm.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/imx/clk-imx8-acm.c b/drivers/clk/imx/clk-imx8-acm.c +index 73b3b53549517..1c95ae905eec8 100644 +--- a/drivers/clk/imx/clk-imx8-acm.c ++++ b/drivers/clk/imx/clk-imx8-acm.c +@@ -374,7 +374,6 @@ static int imx8_acm_clk_probe(struct platform_device *pdev) + 0, NULL, NULL); + if (IS_ERR(hws[sels[i].clkid])) { + ret = PTR_ERR(hws[sels[i].clkid]); +- pm_runtime_disable(&pdev->dev); + goto err_clk_register; + } + } +@@ -384,12 +383,16 @@ static int imx8_acm_clk_probe(struct platform_device *pdev) + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_hw_data); + if (ret < 0) { + dev_err(dev, "failed to register hws for ACM\n"); +- pm_runtime_disable(&pdev->dev); ++ goto err_clk_register; + } + +-err_clk_register: ++ pm_runtime_put_sync(&pdev->dev); ++ return 0; + ++err_clk_register: + pm_runtime_put_sync(&pdev->dev); ++ pm_runtime_disable(&pdev->dev); ++ clk_imx_acm_detach_pm_domains(&pdev->dev, &priv->dev_pm); + + return ret; + } +-- +2.42.0 + diff --git a/queue-6.6/clk-imx-imx8mq-correct-error-handling-path.patch b/queue-6.6/clk-imx-imx8mq-correct-error-handling-path.patch new file mode 100644 index 00000000000..fa051a732b1 --- /dev/null +++ b/queue-6.6/clk-imx-imx8mq-correct-error-handling-path.patch @@ -0,0 +1,71 @@ +From a7fce4b422b4472d4ba20824b3ce35af0da85bde Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 1 Oct 2023 20:26:18 +0800 +Subject: clk: imx: imx8mq: correct error handling path + +From: Peng Fan + +[ Upstream commit 577ad169966e6e75b10e004389a3f79813e84b5d ] + +Avoid memory leak in error handling path. It does not make +much sense for the SoC without clk driver, to make program behavior +correct, let's fix it. + +Fixes: b80522040cd3 ("clk: imx: Add clock driver for i.MX8MQ CCM") +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Closes: https://lore.kernel.org/r/202309240551.e46NllPa-lkp@intel.com/ +Signed-off-by: Peng Fan +Link: https://lore.kernel.org/r/20231001122618.194498-1-peng.fan@oss.nxp.com +Signed-off-by: Abel Vesa +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imx8mq.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c +index 4bd65879fcd34..f70ed231b92d6 100644 +--- a/drivers/clk/imx/clk-imx8mq.c ++++ b/drivers/clk/imx/clk-imx8mq.c +@@ -288,8 +288,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) + void __iomem *base; + int err; + +- clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, +- IMX8MQ_CLK_END), GFP_KERNEL); ++ clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MQ_CLK_END), GFP_KERNEL); + if (WARN_ON(!clk_hw_data)) + return -ENOMEM; + +@@ -306,10 +305,12 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) + hws[IMX8MQ_CLK_EXT4] = imx_get_clk_hw_by_name(np, "clk_ext4"); + + np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-anatop"); +- base = of_iomap(np, 0); ++ base = devm_of_iomap(dev, np, 0, NULL); + of_node_put(np); +- if (WARN_ON(!base)) +- return -ENOMEM; ++ if (WARN_ON(IS_ERR(base))) { ++ err = PTR_ERR(base); ++ goto unregister_hws; ++ } + + hws[IMX8MQ_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x28, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MQ_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x18, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +@@ -395,8 +396,10 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) + + np = dev->of_node; + base = devm_platform_ioremap_resource(pdev, 0); +- if (WARN_ON(IS_ERR(base))) +- return PTR_ERR(base); ++ if (WARN_ON(IS_ERR(base))) { ++ err = PTR_ERR(base); ++ goto unregister_hws; ++ } + + /* CORE */ + hws[IMX8MQ_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mq_a53_sels, base + 0x8000); +-- +2.42.0 + diff --git a/queue-6.6/clk-imx-imx8qxp-fix-elcdif_pll-clock.patch b/queue-6.6/clk-imx-imx8qxp-fix-elcdif_pll-clock.patch new file mode 100644 index 00000000000..1a7767c422b --- /dev/null +++ b/queue-6.6/clk-imx-imx8qxp-fix-elcdif_pll-clock.patch @@ -0,0 +1,45 @@ +From a6a4efe23611dcb290eb68e7eaef6149f6199e92 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 17:19:00 +0800 +Subject: clk: imx: imx8qxp: Fix elcdif_pll clock + +From: Robert Chiras + +[ Upstream commit 15cee75dacb82ade710d61bfd536011933ef9bf2 ] + +Move the elcdif_pll clock initialization before the lcd_clk, since the +elcdif_clk needs to be initialized ahead of lcd_clk, being its parent. +This change fixes issues with the LCD clocks during suspend/resume. + +Fixes: babfaa9556d7 ("clk: imx: scu: add more scu clocks") +Suggested-by: Ranjani Vaidyanathan +Acked-by: Laurentiu Palcu +Signed-off-by: Robert Chiras +Signed-off-by: Peng Fan +Reviewed-by: Abel Vesa +Link: https://lore.kernel.org/r/20230912-imx8-clk-v1-v1-2-69a34bcfcae1@nxp.com +Signed-off-by: Abel Vesa +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imx8qxp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c +index cadcbb318f5cf..4020aa4b79bf2 100644 +--- a/drivers/clk/imx/clk-imx8qxp.c ++++ b/drivers/clk/imx/clk-imx8qxp.c +@@ -147,10 +147,10 @@ static int imx8qxp_clk_probe(struct platform_device *pdev) + imx_clk_scu("adc0_clk", IMX_SC_R_ADC_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("adc1_clk", IMX_SC_R_ADC_1, IMX_SC_PM_CLK_PER); + imx_clk_scu("pwm_clk", IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER); ++ imx_clk_scu("elcdif_pll", IMX_SC_R_ELCDIF_PLL, IMX_SC_PM_CLK_PLL); + imx_clk_scu2("lcd_clk", lcd_sels, ARRAY_SIZE(lcd_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER); + imx_clk_scu2("lcd_pxl_clk", lcd_pxl_sels, ARRAY_SIZE(lcd_pxl_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_MISC0); + imx_clk_scu("lcd_pxl_bypass_div_clk", IMX_SC_R_LCD_0, IMX_SC_PM_CLK_BYPASS); +- imx_clk_scu("elcdif_pll", IMX_SC_R_ELCDIF_PLL, IMX_SC_PM_CLK_PLL); + + /* Audio SS */ + imx_clk_scu("audio_pll0_clk", IMX_SC_R_AUDIO_PLL_0, IMX_SC_PM_CLK_PLL); +-- +2.42.0 + diff --git a/queue-6.6/clk-imx-select-mxc_clk-for-clk_imx8qxp.patch b/queue-6.6/clk-imx-select-mxc_clk-for-clk_imx8qxp.patch new file mode 100644 index 00000000000..5d69082b12b --- /dev/null +++ b/queue-6.6/clk-imx-select-mxc_clk-for-clk_imx8qxp.patch @@ -0,0 +1,44 @@ +From bb032ed5d23de38c12febeb1f81c0086d46cc8f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 12:23:54 +0300 +Subject: clk: imx: Select MXC_CLK for CLK_IMX8QXP + +From: Abel Vesa + +[ Upstream commit 317e69c49b4ceef8aebb47d771498ccb3571bdf9 ] + +If the i.MX8QXP clock provider is built-in but the MXC_CLK is +built as module, build fails: + +aarch64-linux-ld: drivers/clk/imx/clk-imx8-acm.o: in function `imx8_acm_clk_probe': +clk-imx8-acm.c:(.text+0x3d0): undefined reference to `imx_check_clk_hws' + +Fix that by selecting MXC_CLK in case of CLK_IMX8QXP. + +Fixes: c2cccb6d0b33 ("clk: imx: add imx8qxp clk driver") +Closes: https://lore.kernel.org/all/8b77219e-b59e-40f1-96f1-980a0b2debcf@infradead.org/ +Reported-by: Randy Dunlap +Reviewed-by: Peng Fan +Acked-by: Randy Dunlap +Tested-by: Randy Dunlap +Signed-off-by: Abel Vesa +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig +index f6b82e0b9703a..db3bca5f4ec9c 100644 +--- a/drivers/clk/imx/Kconfig ++++ b/drivers/clk/imx/Kconfig +@@ -96,6 +96,7 @@ config CLK_IMX8QXP + depends on (ARCH_MXC && ARM64) || COMPILE_TEST + depends on IMX_SCU && HAVE_ARM_SMCCC + select MXC_CLK_SCU ++ select MXC_CLK + help + Build the driver for IMX8QXP SCU based clocks. + +-- +2.42.0 + diff --git a/queue-6.6/clk-keystone-pll-fix-a-couple-null-vs-is_err-checks.patch b/queue-6.6/clk-keystone-pll-fix-a-couple-null-vs-is_err-checks.patch new file mode 100644 index 00000000000..703e5dca62d --- /dev/null +++ b/queue-6.6/clk-keystone-pll-fix-a-couple-null-vs-is_err-checks.patch @@ -0,0 +1,61 @@ +From 569a9f2d78666dcde91786acb32d5e9ee95b771c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Oct 2023 17:01:57 +0300 +Subject: clk: keystone: pll: fix a couple NULL vs IS_ERR() checks + +From: Dan Carpenter + +[ Upstream commit a5d14f8b551eb1551c10053653ee8e27f19672fa ] + +The clk_register_divider() and clk_register_mux() functions returns +error pointers on error but this code checks for NULL. Fix that. + +Fixes: b9e0d40c0d83 ("clk: keystone: add Keystone PLL clock driver") +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/d9da4c97-0da9-499f-9a21-1f8e3f148dc1@moroto.mountain +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/keystone/pll.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/drivers/clk/keystone/pll.c b/drivers/clk/keystone/pll.c +index ee5c72369334f..6bbdd4705d71f 100644 +--- a/drivers/clk/keystone/pll.c ++++ b/drivers/clk/keystone/pll.c +@@ -281,12 +281,13 @@ static void __init of_pll_div_clk_init(struct device_node *node) + + clk = clk_register_divider(NULL, clk_name, parent_name, 0, reg, shift, + mask, 0, NULL); +- if (clk) { +- of_clk_add_provider(node, of_clk_src_simple_get, clk); +- } else { ++ if (IS_ERR(clk)) { + pr_err("%s: error registering divider %s\n", __func__, clk_name); + iounmap(reg); ++ return; + } ++ ++ of_clk_add_provider(node, of_clk_src_simple_get, clk); + } + CLK_OF_DECLARE(pll_divider_clock, "ti,keystone,pll-divider-clock", of_pll_div_clk_init); + +@@ -328,10 +329,12 @@ static void __init of_pll_mux_clk_init(struct device_node *node) + clk = clk_register_mux(NULL, clk_name, (const char **)&parents, + ARRAY_SIZE(parents) , 0, reg, shift, mask, + 0, NULL); +- if (clk) +- of_clk_add_provider(node, of_clk_src_simple_get, clk); +- else ++ if (IS_ERR(clk)) { + pr_err("%s: error registering mux %s\n", __func__, clk_name); ++ return; ++ } ++ ++ of_clk_add_provider(node, of_clk_src_simple_get, clk); + } + CLK_OF_DECLARE(pll_mux_clock, "ti,keystone,pll-mux-clock", of_pll_mux_clk_init); + +-- +2.42.0 + diff --git a/queue-6.6/clk-linux-clk-provider.h-fix-kernel-doc-warnings-and.patch b/queue-6.6/clk-linux-clk-provider.h-fix-kernel-doc-warnings-and.patch new file mode 100644 index 00000000000..94ff9979dcb --- /dev/null +++ b/queue-6.6/clk-linux-clk-provider.h-fix-kernel-doc-warnings-and.patch @@ -0,0 +1,117 @@ +From 76cc32d838e5f455b7ec46cf9841ae4a34a256e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 30 Sep 2023 15:14:26 -0700 +Subject: clk: linux/clk-provider.h: fix kernel-doc warnings and typos + +From: Randy Dunlap + +[ Upstream commit 84aefafe6b294041b7fa0757414c4a29c1bdeea2 ] + +Fix spelling of "Structure". + +Fix multiple kernel-doc warnings: + +clk-provider.h:269: warning: Function parameter or member 'recalc_rate' not described in 'clk_ops' +clk-provider.h:468: warning: Function parameter or member 'parent_data' not described in 'clk_hw_register_fixed_rate_with_accuracy_parent_data' +clk-provider.h:468: warning: Excess function parameter 'parent_name' description in 'clk_hw_register_fixed_rate_with_accuracy_parent_data' +clk-provider.h:482: warning: Function parameter or member 'parent_data' not described in 'clk_hw_register_fixed_rate_parent_accuracy' +clk-provider.h:482: warning: Excess function parameter 'parent_name' description in 'clk_hw_register_fixed_rate_parent_accuracy' +clk-provider.h:687: warning: Function parameter or member 'flags' not described in 'clk_divider' +clk-provider.h:1164: warning: Function parameter or member 'flags' not described in 'clk_fractional_divider' +clk-provider.h:1164: warning: Function parameter or member 'approximation' not described in 'clk_fractional_divider' +clk-provider.h:1213: warning: Function parameter or member 'flags' not described in 'clk_multiplier' + +Fixes: 9fba738a53dd ("clk: add duty cycle support") +Fixes: b2476490ef11 ("clk: introduce the common clock framework") +Fixes: 2d34f09e79c9 ("clk: fixed-rate: Add support for specifying parents via DT/pointers") +Fixes: f5290d8e4f0c ("clk: asm9260: use parent index to link the reference clock") +Fixes: 9d9f78ed9af0 ("clk: basic clock hardware types") +Fixes: e2d0e90fae82 ("clk: new basic clk type for fractional divider") +Fixes: f2e0a53271a4 ("clk: Add a basic multiplier clock") + +Signed-off-by: Randy Dunlap +Cc: Michael Turquette +Cc: Stephen Boyd +Cc: linux-clk@vger.kernel.org +Link: https://lore.kernel.org/r/20230930221428.18463-1-rdunlap@infradead.org +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + include/linux/clk-provider.h | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h +index ec32ec58c59f7..ace3a4ce2fc98 100644 +--- a/include/linux/clk-provider.h ++++ b/include/linux/clk-provider.h +@@ -74,7 +74,7 @@ void clk_hw_forward_rate_request(const struct clk_hw *core, + unsigned long parent_rate); + + /** +- * struct clk_duty - Struture encoding the duty cycle ratio of a clock ++ * struct clk_duty - Structure encoding the duty cycle ratio of a clock + * + * @num: Numerator of the duty cycle ratio + * @den: Denominator of the duty cycle ratio +@@ -129,7 +129,7 @@ struct clk_duty { + * @restore_context: Restore the context of the clock after a restoration + * of power. + * +- * @recalc_rate Recalculate the rate of this clock, by querying hardware. The ++ * @recalc_rate: Recalculate the rate of this clock, by querying hardware. The + * parent rate is an input parameter. It is up to the caller to + * ensure that the prepare_mutex is held across this call. If the + * driver cannot figure out a rate for this clock, it must return +@@ -456,7 +456,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name, + * clock with the clock framework + * @dev: device that is registering this clock + * @name: name of this clock +- * @parent_name: name of clock's parent ++ * @parent_data: name of clock's parent + * @flags: framework-specific flags + * @fixed_rate: non-adjustable clock rate + * @fixed_accuracy: non-adjustable clock accuracy +@@ -471,7 +471,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name, + * the clock framework + * @dev: device that is registering this clock + * @name: name of this clock +- * @parent_name: name of clock's parent ++ * @parent_data: name of clock's parent + * @flags: framework-specific flags + * @fixed_rate: non-adjustable clock rate + */ +@@ -649,7 +649,7 @@ struct clk_div_table { + * Clock with an adjustable divider affecting its output frequency. Implements + * .recalc_rate, .set_rate and .round_rate + * +- * Flags: ++ * @flags: + * CLK_DIVIDER_ONE_BASED - by default the divisor is the value read from the + * register plus one. If CLK_DIVIDER_ONE_BASED is set then the divider is + * the raw value read from the register, with the value of zero considered +@@ -1130,11 +1130,12 @@ struct clk_hw *clk_hw_register_fixed_factor_parent_hw(struct device *dev, + * @mwidth: width of the numerator bit field + * @nshift: shift to the denominator bit field + * @nwidth: width of the denominator bit field ++ * @approximation: clk driver's callback for calculating the divider clock + * @lock: register lock + * + * Clock with adjustable fractional divider affecting its output frequency. + * +- * Flags: ++ * @flags: + * CLK_FRAC_DIVIDER_ZERO_BASED - by default the numerator and denominator + * is the value read from the register. If CLK_FRAC_DIVIDER_ZERO_BASED + * is set then the numerator and denominator are both the value read +@@ -1191,7 +1192,7 @@ void clk_hw_unregister_fractional_divider(struct clk_hw *hw); + * Clock with an adjustable multiplier affecting its output frequency. + * Implements .recalc_rate, .set_rate and .round_rate + * +- * Flags: ++ * @flags: + * CLK_MULTIPLIER_ZERO_BYPASS - By default, the multiplier is the value read + * from the register, with 0 being a valid value effectively + * zeroing the output clock rate. If CLK_MULTIPLIER_ZERO_BYPASS is +-- +2.42.0 + diff --git a/queue-6.6/clk-mediatek-clk-mt2701-add-check-for-mtk_alloc_clk_.patch b/queue-6.6/clk-mediatek-clk-mt2701-add-check-for-mtk_alloc_clk_.patch new file mode 100644 index 00000000000..768c78e535e --- /dev/null +++ b/queue-6.6/clk-mediatek-clk-mt2701-add-check-for-mtk_alloc_clk_.patch @@ -0,0 +1,66 @@ +From 7fa5ca0d0008cee882ea5787d343a6598d2c3e25 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Sep 2023 10:46:58 +0800 +Subject: clk: mediatek: clk-mt2701: Add check for mtk_alloc_clk_data + +From: Jiasheng Jiang + +[ Upstream commit 0d6e24b422a2166a9297a8286ff2e6ab9a5e8cd3 ] + +Add the check for the return value of mtk_alloc_clk_data() in order to +avoid NULL pointer dereference. + +Fixes: e9862118272a ("clk: mediatek: Add MT2701 clock support") +Signed-off-by: Jiasheng Jiang +Link: https://lore.kernel.org/r/20230901024658.23405-1-jiasheng@iscas.ac.cn +Reviewed-by: Markus Schneider-Pargmann +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/mediatek/clk-mt2701.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c +index c81f3e33ce568..12d9560eb4ba2 100644 +--- a/drivers/clk/mediatek/clk-mt2701.c ++++ b/drivers/clk/mediatek/clk-mt2701.c +@@ -667,6 +667,8 @@ static int mtk_topckgen_init(struct platform_device *pdev) + return PTR_ERR(base); + + clk_data = mtk_alloc_clk_data(CLK_TOP_NR); ++ if (!clk_data) ++ return -ENOMEM; + + mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), + clk_data); +@@ -747,6 +749,8 @@ static void __init mtk_infrasys_init_early(struct device_node *node) + + if (!infra_clk_data) { + infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR); ++ if (!infra_clk_data) ++ return; + + for (i = 0; i < CLK_INFRA_NR; i++) + infra_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER); +@@ -774,6 +778,8 @@ static int mtk_infrasys_init(struct platform_device *pdev) + + if (!infra_clk_data) { + infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR); ++ if (!infra_clk_data) ++ return -ENOMEM; + } else { + for (i = 0; i < CLK_INFRA_NR; i++) { + if (infra_clk_data->hws[i] == ERR_PTR(-EPROBE_DEFER)) +@@ -890,6 +896,8 @@ static int mtk_pericfg_init(struct platform_device *pdev) + return PTR_ERR(base); + + clk_data = mtk_alloc_clk_data(CLK_PERI_NR); ++ if (!clk_data) ++ return -ENOMEM; + + mtk_clk_register_gates(&pdev->dev, node, peri_clks, + ARRAY_SIZE(peri_clks), clk_data); +-- +2.42.0 + diff --git a/queue-6.6/clk-mediatek-clk-mt6765-add-check-for-mtk_alloc_clk_.patch b/queue-6.6/clk-mediatek-clk-mt6765-add-check-for-mtk_alloc_clk_.patch new file mode 100644 index 00000000000..2e843f4eb2a --- /dev/null +++ b/queue-6.6/clk-mediatek-clk-mt6765-add-check-for-mtk_alloc_clk_.patch @@ -0,0 +1,56 @@ +From cf7be00e844c3e76dc6ff455c8c91f2441a13587 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 17:34:03 +0800 +Subject: clk: mediatek: clk-mt6765: Add check for mtk_alloc_clk_data + +From: Jiasheng Jiang + +[ Upstream commit b82681042724924ae3ba0f2f2eeec217fa31e830 ] + +Add the check for the return value of mtk_alloc_clk_data() in order to +avoid NULL pointer dereference. + +Fixes: 1aca9939bf72 ("clk: mediatek: Add MT6765 clock support") +Signed-off-by: Jiasheng Jiang +Link: https://lore.kernel.org/r/20230912093407.21505-1-jiasheng@iscas.ac.cn +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/mediatek/clk-mt6765.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/clk/mediatek/clk-mt6765.c b/drivers/clk/mediatek/clk-mt6765.c +index 1f4c8d0c041ab..9c7f7407d7980 100644 +--- a/drivers/clk/mediatek/clk-mt6765.c ++++ b/drivers/clk/mediatek/clk-mt6765.c +@@ -737,6 +737,8 @@ static int clk_mt6765_apmixed_probe(struct platform_device *pdev) + return PTR_ERR(base); + + clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); ++ if (!clk_data) ++ return -ENOMEM; + + mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + +@@ -769,6 +771,8 @@ static int clk_mt6765_top_probe(struct platform_device *pdev) + return PTR_ERR(base); + + clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); ++ if (!clk_data) ++ return -ENOMEM; + + mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks), + clk_data); +@@ -807,6 +811,8 @@ static int clk_mt6765_ifr_probe(struct platform_device *pdev) + return PTR_ERR(base); + + clk_data = mtk_alloc_clk_data(CLK_IFR_NR_CLK); ++ if (!clk_data) ++ return -ENOMEM; + + mtk_clk_register_gates(&pdev->dev, node, ifr_clks, + ARRAY_SIZE(ifr_clks), clk_data); +-- +2.42.0 + diff --git a/queue-6.6/clk-mediatek-clk-mt6779-add-check-for-mtk_alloc_clk_.patch b/queue-6.6/clk-mediatek-clk-mt6779-add-check-for-mtk_alloc_clk_.patch new file mode 100644 index 00000000000..9a014fb479d --- /dev/null +++ b/queue-6.6/clk-mediatek-clk-mt6779-add-check-for-mtk_alloc_clk_.patch @@ -0,0 +1,47 @@ +From 448ed6e5ae8d7adf999c7ae805769e54b06fdaa9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 17:34:04 +0800 +Subject: clk: mediatek: clk-mt6779: Add check for mtk_alloc_clk_data + +From: Jiasheng Jiang + +[ Upstream commit 1f57f78fbacf630430bf954e5a84caafdfea30c0 ] + +Add the check for the return value of mtk_alloc_clk_data() in order to +avoid NULL pointer dereference. + +Fixes: 710774e04861 ("clk: mediatek: Add MT6779 clock support") +Signed-off-by: Jiasheng Jiang +Link: https://lore.kernel.org/r/20230912093407.21505-2-jiasheng@iscas.ac.cn +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/mediatek/clk-mt6779.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/clk/mediatek/clk-mt6779.c b/drivers/clk/mediatek/clk-mt6779.c +index 3ee2f5a2319a0..ffedb1fe3c672 100644 +--- a/drivers/clk/mediatek/clk-mt6779.c ++++ b/drivers/clk/mediatek/clk-mt6779.c +@@ -1217,6 +1217,8 @@ static int clk_mt6779_apmixed_probe(struct platform_device *pdev) + struct device_node *node = pdev->dev.of_node; + + clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); ++ if (!clk_data) ++ return -ENOMEM; + + mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + +@@ -1237,6 +1239,8 @@ static int clk_mt6779_top_probe(struct platform_device *pdev) + return PTR_ERR(base); + + clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); ++ if (!clk_data) ++ return -ENOMEM; + + mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), + clk_data); +-- +2.42.0 + diff --git a/queue-6.6/clk-mediatek-clk-mt6797-add-check-for-mtk_alloc_clk_.patch b/queue-6.6/clk-mediatek-clk-mt6797-add-check-for-mtk_alloc_clk_.patch new file mode 100644 index 00000000000..39641ad3b24 --- /dev/null +++ b/queue-6.6/clk-mediatek-clk-mt6797-add-check-for-mtk_alloc_clk_.patch @@ -0,0 +1,56 @@ +From 4776c41ff9cf3118fd1cc65e4c1200895c7d5a9c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 17:34:05 +0800 +Subject: clk: mediatek: clk-mt6797: Add check for mtk_alloc_clk_data + +From: Jiasheng Jiang + +[ Upstream commit 606f6366a35a3329545e38129804d65ef26ed7d2 ] + +Add the check for the return value of mtk_alloc_clk_data() in order to +avoid NULL pointer dereference. + +Fixes: 96596aa06628 ("clk: mediatek: add clk support for MT6797") +Signed-off-by: Jiasheng Jiang +Link: https://lore.kernel.org/r/20230912093407.21505-3-jiasheng@iscas.ac.cn +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/mediatek/clk-mt6797.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/clk/mediatek/clk-mt6797.c b/drivers/clk/mediatek/clk-mt6797.c +index 2ebd25f0ce71d..f12d4e9ff0bba 100644 +--- a/drivers/clk/mediatek/clk-mt6797.c ++++ b/drivers/clk/mediatek/clk-mt6797.c +@@ -390,6 +390,8 @@ static int mtk_topckgen_init(struct platform_device *pdev) + return PTR_ERR(base); + + clk_data = mtk_alloc_clk_data(CLK_TOP_NR); ++ if (!clk_data) ++ return -ENOMEM; + + mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs), + clk_data); +@@ -545,6 +547,8 @@ static void mtk_infrasys_init_early(struct device_node *node) + + if (!infra_clk_data) { + infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR); ++ if (!infra_clk_data) ++ return; + + for (i = 0; i < CLK_INFRA_NR; i++) + infra_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER); +@@ -570,6 +574,8 @@ static int mtk_infrasys_init(struct platform_device *pdev) + + if (!infra_clk_data) { + infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR); ++ if (!infra_clk_data) ++ return -ENOMEM; + } else { + for (i = 0; i < CLK_INFRA_NR; i++) { + if (infra_clk_data->hws[i] == ERR_PTR(-EPROBE_DEFER)) +-- +2.42.0 + diff --git a/queue-6.6/clk-mediatek-clk-mt7629-add-check-for-mtk_alloc_clk_.patch b/queue-6.6/clk-mediatek-clk-mt7629-add-check-for-mtk_alloc_clk_.patch new file mode 100644 index 00000000000..f67640c71e9 --- /dev/null +++ b/queue-6.6/clk-mediatek-clk-mt7629-add-check-for-mtk_alloc_clk_.patch @@ -0,0 +1,56 @@ +From 718b3f853043f582f71fe84bb09e7b4cddd121e6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 17:34:07 +0800 +Subject: clk: mediatek: clk-mt7629: Add check for mtk_alloc_clk_data + +From: Jiasheng Jiang + +[ Upstream commit 2befa515c1bb6cdd33c262b909d93d1973a219aa ] + +Add the check for the return value of mtk_alloc_clk_data() in order to +avoid NULL pointer dereference. + +Fixes: 3b5e748615e7 ("clk: mediatek: add clock support for MT7629 SoC") +Signed-off-by: Jiasheng Jiang +Link: https://lore.kernel.org/r/20230912093407.21505-5-jiasheng@iscas.ac.cn +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/mediatek/clk-mt7629.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c +index 2882107d0f240..b8a1f01bc974d 100644 +--- a/drivers/clk/mediatek/clk-mt7629.c ++++ b/drivers/clk/mediatek/clk-mt7629.c +@@ -555,6 +555,8 @@ static int mtk_topckgen_init(struct platform_device *pdev) + return PTR_ERR(base); + + clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); ++ if (!clk_data) ++ return -ENOMEM; + + mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), + clk_data); +@@ -579,6 +581,8 @@ static int mtk_infrasys_init(struct platform_device *pdev) + struct clk_hw_onecell_data *clk_data; + + clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK); ++ if (!clk_data) ++ return -ENOMEM; + + mtk_clk_register_gates(&pdev->dev, node, infra_clks, + ARRAY_SIZE(infra_clks), clk_data); +@@ -602,6 +606,8 @@ static int mtk_pericfg_init(struct platform_device *pdev) + return PTR_ERR(base); + + clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK); ++ if (!clk_data) ++ return -ENOMEM; + + mtk_clk_register_gates(&pdev->dev, node, peri_clks, + ARRAY_SIZE(peri_clks), clk_data); +-- +2.42.0 + diff --git a/queue-6.6/clk-mediatek-clk-mt7629-eth-add-check-for-mtk_alloc_.patch b/queue-6.6/clk-mediatek-clk-mt7629-eth-add-check-for-mtk_alloc_.patch new file mode 100644 index 00000000000..eaadebbe33a --- /dev/null +++ b/queue-6.6/clk-mediatek-clk-mt7629-eth-add-check-for-mtk_alloc_.patch @@ -0,0 +1,47 @@ +From f593fb8781c1d685c46e741e5b3451506f4cb4f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 17:34:06 +0800 +Subject: clk: mediatek: clk-mt7629-eth: Add check for mtk_alloc_clk_data + +From: Jiasheng Jiang + +[ Upstream commit 0884393c63cc9a1772f7121a6645ba7bd76feeb9 ] + +Add the check for the return value of mtk_alloc_clk_data() in order to +avoid NULL pointer dereference. + +Fixes: 3b5e748615e7 ("clk: mediatek: add clock support for MT7629 SoC") +Signed-off-by: Jiasheng Jiang +Link: https://lore.kernel.org/r/20230912093407.21505-4-jiasheng@iscas.ac.cn +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/mediatek/clk-mt7629-eth.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/clk/mediatek/clk-mt7629-eth.c b/drivers/clk/mediatek/clk-mt7629-eth.c +index fe714debdc9ec..1bfedc988cfe8 100644 +--- a/drivers/clk/mediatek/clk-mt7629-eth.c ++++ b/drivers/clk/mediatek/clk-mt7629-eth.c +@@ -77,6 +77,8 @@ static int clk_mt7629_ethsys_init(struct platform_device *pdev) + int r; + + clk_data = mtk_alloc_clk_data(CLK_ETH_NR_CLK); ++ if (!clk_data) ++ return -ENOMEM; + + mtk_clk_register_gates(&pdev->dev, node, eth_clks, + CLK_ETH_NR_CLK, clk_data); +@@ -100,6 +102,8 @@ static int clk_mt7629_sgmiisys_init(struct platform_device *pdev) + int r; + + clk_data = mtk_alloc_clk_data(CLK_SGMII_NR_CLK); ++ if (!clk_data) ++ return -ENOMEM; + + mtk_clk_register_gates(&pdev->dev, node, sgmii_clks[id++], + CLK_SGMII_NR_CLK, clk_data); +-- +2.42.0 + diff --git a/queue-6.6/clk-mediatek-fix-double-free-in-mtk_clk_register_pll.patch b/queue-6.6/clk-mediatek-fix-double-free-in-mtk_clk_register_pll.patch new file mode 100644 index 00000000000..cc4b81f0820 --- /dev/null +++ b/queue-6.6/clk-mediatek-fix-double-free-in-mtk_clk_register_pll.patch @@ -0,0 +1,56 @@ +From deff89507345abb19da2c893fa078de0c0cbb723 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Oct 2023 08:00:53 +0300 +Subject: clk: mediatek: fix double free in mtk_clk_register_pllfh() + +From: Dan Carpenter + +[ Upstream commit bd54ccc0f147019dac38e7841876a7415459b875 ] + +The mtk_clk_register_pll_ops() currently frees the "pll" parameter. +The function has two callers, mtk_clk_register_pll() and +mtk_clk_register_pllfh(). The first one, the _pll() function relies on +the free, but for the second _pllfh() function it causes a double free +bug. + +Really the frees should be done in the caller because that's where +the allocation is. + +Fixes: d7964de8a8ea ("clk: mediatek: Add new clock driver to handle FHCTL hardware") +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/cd7fa365-28cc-4c34-ac64-6da57c98baa6@moroto.mountain +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/mediatek/clk-pll.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c +index a4eca5fd539c8..513ab6b1b3229 100644 +--- a/drivers/clk/mediatek/clk-pll.c ++++ b/drivers/clk/mediatek/clk-pll.c +@@ -321,10 +321,8 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll, + + ret = clk_hw_register(NULL, &pll->hw); + +- if (ret) { +- kfree(pll); ++ if (ret) + return ERR_PTR(ret); +- } + + return &pll->hw; + } +@@ -340,6 +338,8 @@ struct clk_hw *mtk_clk_register_pll(const struct mtk_pll_data *data, + return ERR_PTR(-ENOMEM); + + hw = mtk_clk_register_pll_ops(pll, data, base, &mtk_pll_ops); ++ if (IS_ERR(hw)) ++ kfree(pll); + + return hw; + } +-- +2.42.0 + diff --git a/queue-6.6/clk-npcm7xx-fix-incorrect-kfree.patch b/queue-6.6/clk-npcm7xx-fix-incorrect-kfree.patch new file mode 100644 index 00000000000..40434272be7 --- /dev/null +++ b/queue-6.6/clk-npcm7xx-fix-incorrect-kfree.patch @@ -0,0 +1,45 @@ +From a517618b9b21a34a3162020d1e47b7927fb77919 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 23 Sep 2023 15:31:27 +0200 +Subject: clk: npcm7xx: Fix incorrect kfree +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jonathan Neuschäfer + +[ Upstream commit bbc5080bef4a245106aa8e8d424ba8847ca7c0ca ] + +The corresponding allocation is: + +> npcm7xx_clk_data = kzalloc(struct_size(npcm7xx_clk_data, hws, +> NPCM7XX_NUM_CLOCKS), GFP_KERNEL); + +... so, kfree should be applied to npcm7xx_clk_data, not +npcm7xx_clk_data->hws. + +Fixes: fcfd14369856 ("clk: npcm7xx: add clock controller") +Signed-off-by: Jonathan Neuschäfer +Link: https://lore.kernel.org/r/20230923133127.1815621-1-j.neuschaefer@gmx.net +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/clk-npcm7xx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/clk-npcm7xx.c b/drivers/clk/clk-npcm7xx.c +index e319cfa51a8a3..030186def9c69 100644 +--- a/drivers/clk/clk-npcm7xx.c ++++ b/drivers/clk/clk-npcm7xx.c +@@ -510,7 +510,7 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np) + return; + + npcm7xx_init_fail: +- kfree(npcm7xx_clk_data->hws); ++ kfree(npcm7xx_clk_data); + npcm7xx_init_np_err: + iounmap(clk_base); + npcm7xx_init_error: +-- +2.42.0 + diff --git a/queue-6.6/clk-qcom-apss-ipq-pll-fix-l-value-for-ipq5332_pll_co.patch b/queue-6.6/clk-qcom-apss-ipq-pll-fix-l-value-for-ipq5332_pll_co.patch new file mode 100644 index 00000000000..30ba5d3ba5b --- /dev/null +++ b/queue-6.6/clk-qcom-apss-ipq-pll-fix-l-value-for-ipq5332_pll_co.patch @@ -0,0 +1,44 @@ +From a72629f4862fabfc0440e985693f17674b32559e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 11:49:34 +0530 +Subject: clk: qcom: apss-ipq-pll: Fix 'l' value for ipq5332_pll_config + +From: Varadarajan Narayanan + +[ Upstream commit 5b7a4d3d2b33398330aef69e0ff5656273483587 ] + +The earlier 'l' value of 0x3e is for 1.5GHz. Not all SKUs support +this frequency. Hence set it to 0x2d to get 1.1GHz which is +supported in all SKUs. + +The frequency can still increase above this initial configuration +made here when the cpufreq driver picks a different OPP. + +Reviewed-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Fixes: c7ef7fbb1ccf ("clk: qcom: apss-ipq-pll: add support for IPQ5332") +Signed-off-by: Kathiravan T +Signed-off-by: Varadarajan Narayanan +Link: https://lore.kernel.org/r/00e6be6cb9cee56628123a64ade118d0a752018b.1697781921.git.quic_varada@quicinc.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/apss-ipq-pll.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/qcom/apss-ipq-pll.c b/drivers/clk/qcom/apss-ipq-pll.c +index 18c4ffe153d6c..41279e5437a62 100644 +--- a/drivers/clk/qcom/apss-ipq-pll.c ++++ b/drivers/clk/qcom/apss-ipq-pll.c +@@ -74,7 +74,7 @@ static struct clk_alpha_pll ipq_pll_stromer_plus = { + }; + + static const struct alpha_pll_config ipq5332_pll_config = { +- .l = 0x3e, ++ .l = 0x2d, + .config_ctl_val = 0x4001075b, + .config_ctl_hi_val = 0x304, + .main_output_mask = BIT(0), +-- +2.42.0 + diff --git a/queue-6.6/clk-qcom-apss-ipq-pll-use-stromer-plus-ops-for-strom.patch b/queue-6.6/clk-qcom-apss-ipq-pll-use-stromer-plus-ops-for-strom.patch new file mode 100644 index 00000000000..c6f5c2b5578 --- /dev/null +++ b/queue-6.6/clk-qcom-apss-ipq-pll-use-stromer-plus-ops-for-strom.patch @@ -0,0 +1,43 @@ +From 877c744c6aca0a824fdeb0bb1274f601862ccaeb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 11:49:33 +0530 +Subject: clk: qcom: apss-ipq-pll: Use stromer plus ops for stromer plus pll + +From: Varadarajan Narayanan + +[ Upstream commit 267e29198436a8cb6770213471f72502c895096a ] + +The set rate and determine rate operations are different between +Stromer and Stromer Plus PLLs. Since the programming sequence is +different, the PLLs dont get configured properly and random, +inexplicable crash/freeze is seen. Hence, use stromer plus ops +for ipq_pll_stromer_plus. + +Reviewed-by: Dmitry Baryshkov +Acked-by: Stephen Boyd +Fixes: c7ef7fbb1ccf ("clk: qcom: apss-ipq-pll: add support for IPQ5332") +Signed-off-by: Kathiravan T +Signed-off-by: Varadarajan Narayanan +Link: https://lore.kernel.org/r/c86ecaa23dc4f39650bcf4a3bd54a617a932e4fd.1697781921.git.quic_varada@quicinc.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/apss-ipq-pll.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/qcom/apss-ipq-pll.c b/drivers/clk/qcom/apss-ipq-pll.c +index e170331858cc1..18c4ffe153d6c 100644 +--- a/drivers/clk/qcom/apss-ipq-pll.c ++++ b/drivers/clk/qcom/apss-ipq-pll.c +@@ -68,7 +68,7 @@ static struct clk_alpha_pll ipq_pll_stromer_plus = { + .fw_name = "xo", + }, + .num_parents = 1, +- .ops = &clk_alpha_pll_stromer_ops, ++ .ops = &clk_alpha_pll_stromer_plus_ops, + }, + }, + }; +-- +2.42.0 + diff --git a/queue-6.6/clk-qcom-clk-alpha-pll-introduce-stromer-plus-ops.patch b/queue-6.6/clk-qcom-clk-alpha-pll-introduce-stromer-plus-ops.patch new file mode 100644 index 00000000000..25330358872 --- /dev/null +++ b/queue-6.6/clk-qcom-clk-alpha-pll-introduce-stromer-plus-ops.patch @@ -0,0 +1,112 @@ +From e7c031d792703c8a650bcba44fa97b5eef1c0297 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 11:49:32 +0530 +Subject: clk: qcom: clk-alpha-pll: introduce stromer plus ops + +From: Varadarajan Narayanan + +[ Upstream commit 84da48921a97cee3dd1391659e93ee01d122b78b ] + +Stromer plus APSS PLL does not support dynamic frequency scaling. +To switch between frequencies, we have to shut down the PLL, +configure the L and ALPHA values and turn on again. So introduce the +separate set of ops for Stromer Plus PLL. + +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Kathiravan T +Signed-off-by: Varadarajan Narayanan +Link: https://lore.kernel.org/r/2affa6c63ff0c4342230623a7d4eef02ec7c02d4.1697781921.git.quic_varada@quicinc.com +Signed-off-by: Bjorn Andersson +Stable-dep-of: 267e29198436 ("clk: qcom: apss-ipq-pll: Use stromer plus ops for stromer plus pll") +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/clk-alpha-pll.c | 63 ++++++++++++++++++++++++++++++++ + drivers/clk/qcom/clk-alpha-pll.h | 1 + + 2 files changed, 64 insertions(+) + +diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c +index e4ef645f65d1f..892f2efc1c32c 100644 +--- a/drivers/clk/qcom/clk-alpha-pll.c ++++ b/drivers/clk/qcom/clk-alpha-pll.c +@@ -2479,3 +2479,66 @@ const struct clk_ops clk_alpha_pll_stromer_ops = { + .set_rate = clk_alpha_pll_stromer_set_rate, + }; + EXPORT_SYMBOL_GPL(clk_alpha_pll_stromer_ops); ++ ++static int clk_alpha_pll_stromer_plus_set_rate(struct clk_hw *hw, ++ unsigned long rate, ++ unsigned long prate) ++{ ++ struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); ++ u32 l, alpha_width = pll_alpha_width(pll); ++ int ret, pll_mode; ++ u64 a; ++ ++ rate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); ++ ++ ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &pll_mode); ++ if (ret) ++ return ret; ++ ++ regmap_write(pll->clkr.regmap, PLL_MODE(pll), 0); ++ ++ /* Delay of 2 output clock ticks required until output is disabled */ ++ udelay(1); ++ ++ regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); ++ ++ if (alpha_width > ALPHA_BITWIDTH) ++ a <<= alpha_width - ALPHA_BITWIDTH; ++ ++ regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a); ++ regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), ++ a >> ALPHA_BITWIDTH); ++ ++ regmap_write(pll->clkr.regmap, PLL_MODE(pll), PLL_BYPASSNL); ++ ++ /* Wait five micro seconds or more */ ++ udelay(5); ++ regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_RESET_N, ++ PLL_RESET_N); ++ ++ /* The lock time should be less than 50 micro seconds worst case */ ++ usleep_range(50, 60); ++ ++ ret = wait_for_pll_enable_lock(pll); ++ if (ret) { ++ pr_err("Wait for PLL enable lock failed [%s] %d\n", ++ clk_hw_get_name(hw), ret); ++ return ret; ++ } ++ ++ if (pll_mode & PLL_OUTCTRL) ++ regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_OUTCTRL, ++ PLL_OUTCTRL); ++ ++ return 0; ++} ++ ++const struct clk_ops clk_alpha_pll_stromer_plus_ops = { ++ .prepare = clk_alpha_pll_enable, ++ .unprepare = clk_alpha_pll_disable, ++ .is_enabled = clk_alpha_pll_is_enabled, ++ .recalc_rate = clk_alpha_pll_recalc_rate, ++ .determine_rate = clk_alpha_pll_stromer_determine_rate, ++ .set_rate = clk_alpha_pll_stromer_plus_set_rate, ++}; ++EXPORT_SYMBOL_GPL(clk_alpha_pll_stromer_plus_ops); +diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h +index e4bd863027ab6..903fbab9b58e9 100644 +--- a/drivers/clk/qcom/clk-alpha-pll.h ++++ b/drivers/clk/qcom/clk-alpha-pll.h +@@ -152,6 +152,7 @@ extern const struct clk_ops clk_alpha_pll_postdiv_ops; + extern const struct clk_ops clk_alpha_pll_huayra_ops; + extern const struct clk_ops clk_alpha_pll_postdiv_ro_ops; + extern const struct clk_ops clk_alpha_pll_stromer_ops; ++extern const struct clk_ops clk_alpha_pll_stromer_plus_ops; + + extern const struct clk_ops clk_alpha_pll_fabia_ops; + extern const struct clk_ops clk_alpha_pll_fixed_fabia_ops; +-- +2.42.0 + diff --git a/queue-6.6/clk-qcom-clk-rcg2-fix-clock-rate-overflow-for-high-p.patch b/queue-6.6/clk-qcom-clk-rcg2-fix-clock-rate-overflow-for-high-p.patch new file mode 100644 index 00000000000..335f6b415d5 --- /dev/null +++ b/queue-6.6/clk-qcom-clk-rcg2-fix-clock-rate-overflow-for-high-p.patch @@ -0,0 +1,57 @@ +From 4d7ce833c1ff8a548a7e767ea096781dd6b8dbc7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Sep 2023 13:06:40 +0530 +Subject: clk: qcom: clk-rcg2: Fix clock rate overflow for high parent + frequencies + +From: Devi Priya + +[ Upstream commit f7b7d30158cff246667273bd2a62fc93ee0725d2 ] + +If the parent clock rate is greater than unsigned long max/2 then +integer overflow happens when calculating the clock rate on 32-bit systems. +As RCG2 uses half integer dividers, the clock rate is first being +multiplied by 2 which will overflow the unsigned long max value. +Hence, replace the common pattern of doing 64-bit multiplication +and then a do_div() call with simpler mult_frac call. + +Fixes: bcd61c0f535a ("clk: qcom: Add support for root clock generators (RCGs)") +Signed-off-by: Devi Priya +Reviewed-by: Marijn Suijten +Link: https://lore.kernel.org/r/20230901073640.4973-1-quic_devipriy@quicinc.com +[bjorn: Also drop unnecessary {} around single statements] +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/clk-rcg2.c | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c +index e22baf3a7112a..5183c74b074f8 100644 +--- a/drivers/clk/qcom/clk-rcg2.c ++++ b/drivers/clk/qcom/clk-rcg2.c +@@ -158,17 +158,11 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index) + static unsigned long + calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 hid_div) + { +- if (hid_div) { +- rate *= 2; +- rate /= hid_div + 1; +- } ++ if (hid_div) ++ rate = mult_frac(rate, 2, hid_div + 1); + +- if (mode) { +- u64 tmp = rate; +- tmp *= m; +- do_div(tmp, n); +- rate = tmp; +- } ++ if (mode) ++ rate = mult_frac(rate, m, n); + + return rate; + } +-- +2.42.0 + diff --git a/queue-6.6/clk-qcom-config-ipq_apss_6018-should-depend-on-qcom_.patch b/queue-6.6/clk-qcom-config-ipq_apss_6018-should-depend-on-qcom_.patch new file mode 100644 index 00000000000..5a99bce928a --- /dev/null +++ b/queue-6.6/clk-qcom-config-ipq_apss_6018-should-depend-on-qcom_.patch @@ -0,0 +1,41 @@ +From a2bdb38e0a0f1eca26df88e9163fbe8b1137da33 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 11:49:31 +0530 +Subject: clk: qcom: config IPQ_APSS_6018 should depend on QCOM_SMEM + +From: Varadarajan Narayanan + +[ Upstream commit 6a15647d0adc686226045e8046369f34d6ab03ed ] + +The config IPQ_APSS_6018 should depend on QCOM_SMEM, to +avoid the following error reported by 'kernel test robot' + + loongarch64-linux-ld: drivers/clk/qcom/apss-ipq6018.o: in function `apss_ipq6018_probe': + >> apss-ipq6018.c:(.text+0xd0): undefined reference to `qcom_smem_get_soc_id' + +Fixes: 5e77b4ef1b19 ("clk: qcom: Add ipq6018 apss clock controller") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/r/202310181650.g8THtfsm-lkp@intel.com/ +Signed-off-by: Varadarajan Narayanan +Link: https://lore.kernel.org/r/f4c4d65a7cb71e807d6d472c63c7718408c8f5f0.1697781921.git.quic_varada@quicinc.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig +index 865db5202e4cf..a79b837583894 100644 +--- a/drivers/clk/qcom/Kconfig ++++ b/drivers/clk/qcom/Kconfig +@@ -131,6 +131,7 @@ config IPQ_APSS_6018 + tristate "IPQ APSS Clock Controller" + select IPQ_APSS_PLL + depends on QCOM_APCS_IPC || COMPILE_TEST ++ depends on QCOM_SMEM + help + Support for APSS clock controller on IPQ platforms. The + APSS clock controller manages the Mux and enable block that feeds the +-- +2.42.0 + diff --git a/queue-6.6/clk-qcom-gcc-msm8996-remove-rpm-bus-clocks.patch b/queue-6.6/clk-qcom-gcc-msm8996-remove-rpm-bus-clocks.patch new file mode 100644 index 00000000000..d4c9f5b5ddd --- /dev/null +++ b/queue-6.6/clk-qcom-gcc-msm8996-remove-rpm-bus-clocks.patch @@ -0,0 +1,521 @@ +From c614a6bed40e4666af48c6735592242524e0d415 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 31 Aug 2023 11:39:14 +0200 +Subject: clk: qcom: gcc-msm8996: Remove RPM bus clocks + +From: Konrad Dybcio + +[ Upstream commit 4afda5f6bcdf673ef2556fcfa458daf3a5a648d8 ] + +The GCC driver contains clocks that are owned (meaning configured and +scaled) by the RPM core. + +Remove them from Linux to stop interjecting the RPM's logic. + +Fixes: b1e010c0730a ("clk: qcom: Add MSM8996 Global Clock Control (GCC) driver") +Signed-off-by: Konrad Dybcio +Reviewed-by: Dmitry Baryshkov +Tested-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20230830-topic-rpmbusclocks8996gcc-v1-1-9e99bedcdc3b@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-msm8996.c | 237 +-------------------------------- + 1 file changed, 5 insertions(+), 232 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c +index 14dcc3f036683..e7b03a17514a5 100644 +--- a/drivers/clk/qcom/gcc-msm8996.c ++++ b/drivers/clk/qcom/gcc-msm8996.c +@@ -244,71 +244,6 @@ static const struct clk_parent_data gcc_xo_gpll0_gpll4_gpll0_early_div[] = { + { .hw = &gpll0_early_div.hw } + }; + +-static const struct freq_tbl ftbl_system_noc_clk_src[] = { +- F(19200000, P_XO, 1, 0, 0), +- F(50000000, P_GPLL0_EARLY_DIV, 6, 0, 0), +- F(100000000, P_GPLL0, 6, 0, 0), +- F(150000000, P_GPLL0, 4, 0, 0), +- F(200000000, P_GPLL0, 3, 0, 0), +- F(240000000, P_GPLL0, 2.5, 0, 0), +- { } +-}; +- +-static struct clk_rcg2 system_noc_clk_src = { +- .cmd_rcgr = 0x0401c, +- .hid_width = 5, +- .parent_map = gcc_xo_gpll0_gpll0_early_div_map, +- .freq_tbl = ftbl_system_noc_clk_src, +- .clkr.hw.init = &(struct clk_init_data){ +- .name = "system_noc_clk_src", +- .parent_data = gcc_xo_gpll0_gpll0_early_div, +- .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_early_div), +- .ops = &clk_rcg2_ops, +- }, +-}; +- +-static const struct freq_tbl ftbl_config_noc_clk_src[] = { +- F(19200000, P_XO, 1, 0, 0), +- F(37500000, P_GPLL0, 16, 0, 0), +- F(75000000, P_GPLL0, 8, 0, 0), +- { } +-}; +- +-static struct clk_rcg2 config_noc_clk_src = { +- .cmd_rcgr = 0x0500c, +- .hid_width = 5, +- .parent_map = gcc_xo_gpll0_map, +- .freq_tbl = ftbl_config_noc_clk_src, +- .clkr.hw.init = &(struct clk_init_data){ +- .name = "config_noc_clk_src", +- .parent_data = gcc_xo_gpll0, +- .num_parents = ARRAY_SIZE(gcc_xo_gpll0), +- .ops = &clk_rcg2_ops, +- }, +-}; +- +-static const struct freq_tbl ftbl_periph_noc_clk_src[] = { +- F(19200000, P_XO, 1, 0, 0), +- F(37500000, P_GPLL0, 16, 0, 0), +- F(50000000, P_GPLL0, 12, 0, 0), +- F(75000000, P_GPLL0, 8, 0, 0), +- F(100000000, P_GPLL0, 6, 0, 0), +- { } +-}; +- +-static struct clk_rcg2 periph_noc_clk_src = { +- .cmd_rcgr = 0x06014, +- .hid_width = 5, +- .parent_map = gcc_xo_gpll0_map, +- .freq_tbl = ftbl_periph_noc_clk_src, +- .clkr.hw.init = &(struct clk_init_data){ +- .name = "periph_noc_clk_src", +- .parent_data = gcc_xo_gpll0, +- .num_parents = ARRAY_SIZE(gcc_xo_gpll0), +- .ops = &clk_rcg2_ops, +- }, +-}; +- + static const struct freq_tbl ftbl_usb30_master_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(120000000, P_GPLL0, 5, 0, 0), +@@ -1297,11 +1232,7 @@ static struct clk_branch gcc_mmss_noc_cfg_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mmss_noc_cfg_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &config_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .flags = CLK_IGNORE_UNUSED, + .ops = &clk_branch2_ops, + }, + }, +@@ -1464,11 +1395,6 @@ static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_phy_cfg_ahb2phy_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &periph_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -1498,11 +1424,6 @@ static struct clk_branch gcc_sdcc1_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &periph_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -1549,11 +1470,6 @@ static struct clk_branch gcc_sdcc2_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &periph_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -1583,11 +1499,6 @@ static struct clk_branch gcc_sdcc3_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc3_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &periph_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -1617,11 +1528,6 @@ static struct clk_branch gcc_sdcc4_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc4_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &periph_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -1635,11 +1541,6 @@ static struct clk_branch gcc_blsp1_ahb_clk = { + .enable_mask = BIT(17), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &periph_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -1977,11 +1878,6 @@ static struct clk_branch gcc_blsp2_ahb_clk = { + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &periph_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2318,11 +2214,6 @@ static struct clk_branch gcc_pdm_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &periph_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2353,11 +2244,6 @@ static struct clk_branch gcc_prng_ahb_clk = { + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &config_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2370,11 +2256,6 @@ static struct clk_branch gcc_tsif_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_tsif_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &periph_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2422,11 +2303,6 @@ static struct clk_branch gcc_boot_rom_ahb_clk = { + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &config_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2520,11 +2396,6 @@ static struct clk_branch gcc_pcie_0_slv_axi_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_slv_axi_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &system_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2537,11 +2408,6 @@ static struct clk_branch gcc_pcie_0_mstr_axi_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_mstr_axi_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &system_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2554,11 +2420,6 @@ static struct clk_branch gcc_pcie_0_cfg_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_cfg_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &config_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2606,11 +2467,6 @@ static struct clk_branch gcc_pcie_1_slv_axi_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_slv_axi_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &system_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2623,11 +2479,6 @@ static struct clk_branch gcc_pcie_1_mstr_axi_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_mstr_axi_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &system_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2640,11 +2491,6 @@ static struct clk_branch gcc_pcie_1_cfg_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_cfg_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &config_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2692,11 +2538,6 @@ static struct clk_branch gcc_pcie_2_slv_axi_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_2_slv_axi_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &system_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2709,11 +2550,6 @@ static struct clk_branch gcc_pcie_2_mstr_axi_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_2_mstr_axi_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &system_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2726,11 +2562,6 @@ static struct clk_branch gcc_pcie_2_cfg_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_2_cfg_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &config_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2778,11 +2609,6 @@ static struct clk_branch gcc_pcie_phy_cfg_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_phy_cfg_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &config_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2829,11 +2655,6 @@ static struct clk_branch gcc_ufs_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &config_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -3060,11 +2881,7 @@ static struct clk_branch gcc_aggre0_snoc_axi_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre0_snoc_axi_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &system_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +@@ -3077,11 +2894,7 @@ static struct clk_branch gcc_aggre0_cnoc_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre0_cnoc_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &config_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +@@ -3094,11 +2907,7 @@ static struct clk_branch gcc_smmu_aggre0_axi_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_smmu_aggre0_axi_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &system_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +@@ -3111,11 +2920,7 @@ static struct clk_branch gcc_smmu_aggre0_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_smmu_aggre0_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &config_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, ++ .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +@@ -3162,10 +2967,6 @@ static struct clk_branch gcc_dcc_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_dcc_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &config_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +@@ -3178,10 +2979,6 @@ static struct clk_branch gcc_aggre0_noc_mpu_cfg_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre0_noc_mpu_cfg_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &config_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +@@ -3194,11 +2991,6 @@ static struct clk_branch gcc_qspi_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &periph_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -3347,10 +3139,6 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_cfg_ahb_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &config_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +@@ -3363,10 +3151,6 @@ static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_mnoc_bimc_axi_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &system_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +@@ -3379,10 +3163,6 @@ static struct clk_branch gcc_mss_snoc_axi_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_snoc_axi_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &system_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +@@ -3395,10 +3175,6 @@ static struct clk_branch gcc_mss_q6_bimc_axi_clk = { + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_q6_bimc_axi_clk", +- .parent_hws = (const struct clk_hw*[]){ +- &system_noc_clk_src.clkr.hw, +- }, +- .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +@@ -3495,9 +3271,6 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { + [GPLL0] = &gpll0.clkr, + [GPLL4_EARLY] = &gpll4_early.clkr, + [GPLL4] = &gpll4.clkr, +- [SYSTEM_NOC_CLK_SRC] = &system_noc_clk_src.clkr, +- [CONFIG_NOC_CLK_SRC] = &config_noc_clk_src.clkr, +- [PERIPH_NOC_CLK_SRC] = &periph_noc_clk_src.clkr, + [USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr, + [USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr, + [USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr, +-- +2.42.0 + diff --git a/queue-6.6/clk-qcom-gcc-sm8150-fix-gcc_sdcc2_apps_clk_src.patch b/queue-6.6/clk-qcom-gcc-sm8150-fix-gcc_sdcc2_apps_clk_src.patch new file mode 100644 index 00000000000..077370061cf --- /dev/null +++ b/queue-6.6/clk-qcom-gcc-sm8150-fix-gcc_sdcc2_apps_clk_src.patch @@ -0,0 +1,39 @@ +From 0d4313c9d987b85ce222f95b77dd64ec0ce1c530 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 20:56:11 +0300 +Subject: clk: qcom: gcc-sm8150: Fix gcc_sdcc2_apps_clk_src + +From: Danila Tikhonov + +[ Upstream commit 7138c244fb293f24ce8ab782961022eff00a10c4 ] + +Set .flags = CLK_OPS_PARENT_ENABLE to fix "gcc_sdcc2_apps_clk_src: rcg +didn't update its configuration" error. + +Fixes: 2a1d7eb854bb ("clk: qcom: gcc: Add global clock controller driver for SM8150") +Tested-by: Arseniy Velikanov +Signed-off-by: Danila Tikhonov +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230913175612.8685-1-danila@jiaxyga.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-sm8150.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/qcom/gcc-sm8150.c b/drivers/clk/qcom/gcc-sm8150.c +index 41ab210875fb2..05d115c52dfeb 100644 +--- a/drivers/clk/qcom/gcc-sm8150.c ++++ b/drivers/clk/qcom/gcc-sm8150.c +@@ -774,7 +774,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .name = "gcc_sdcc2_apps_clk_src", + .parent_data = gcc_parents_6, + .num_parents = ARRAY_SIZE(gcc_parents_6), +- .flags = CLK_SET_RATE_PARENT, ++ .flags = CLK_OPS_PARENT_ENABLE, + .ops = &clk_rcg2_floor_ops, + }, + }; +-- +2.42.0 + diff --git a/queue-6.6/clk-qcom-ipq5018-drop-the-clk_set_rate_parent-flag-f.patch b/queue-6.6/clk-qcom-ipq5018-drop-the-clk_set_rate_parent-flag-f.patch new file mode 100644 index 00000000000..18dfc65f1c3 --- /dev/null +++ b/queue-6.6/clk-qcom-ipq5018-drop-the-clk_set_rate_parent-flag-f.patch @@ -0,0 +1,59 @@ +From cec338ed3fc6386393ed6ff4254e8454e0f5a041 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 12:29:53 +0530 +Subject: clk: qcom: ipq5018: drop the CLK_SET_RATE_PARENT flag from GPLL + clocks + +From: Kathiravan Thirumoorthy + +[ Upstream commit 01a5e4c6731ab6b4b74822661d296f8893fc1230 ] + +GPLL clock rates are fixed and shouldn't be scaled based on the +request from dependent clocks. Doing so will result in the unexpected +behaviour. So drop the CLK_SET_RATE_PARENT flag from the GPLL clocks. + +---- +Changes in V2: + - New patch + +Fixes: e3fdbef1bab8 ("clk: qcom: Add Global Clock controller (GCC) driver for IPQ5018") +Signed-off-by: Kathiravan Thirumoorthy +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230913-gpll_cleanup-v2-3-c8ceb1a37680@quicinc.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-ipq5018.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-ipq5018.c b/drivers/clk/qcom/gcc-ipq5018.c +index 19dc2b71cacf0..2a3c0659b7008 100644 +--- a/drivers/clk/qcom/gcc-ipq5018.c ++++ b/drivers/clk/qcom/gcc-ipq5018.c +@@ -128,7 +128,6 @@ static struct clk_alpha_pll_postdiv gpll0 = { + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, +- .flags = CLK_SET_RATE_PARENT, + }, + }; + +@@ -143,7 +142,6 @@ static struct clk_alpha_pll_postdiv gpll2 = { + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, +- .flags = CLK_SET_RATE_PARENT, + }, + }; + +@@ -158,7 +156,6 @@ static struct clk_alpha_pll_postdiv gpll4 = { + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, +- .flags = CLK_SET_RATE_PARENT, + }, + }; + +-- +2.42.0 + diff --git a/queue-6.6/clk-qcom-ipq5332-drop-set-rate-parent-from-gpll0-dep.patch b/queue-6.6/clk-qcom-ipq5332-drop-set-rate-parent-from-gpll0-dep.patch new file mode 100644 index 00000000000..3732f72f55c --- /dev/null +++ b/queue-6.6/clk-qcom-ipq5332-drop-set-rate-parent-from-gpll0-dep.patch @@ -0,0 +1,47 @@ +From 3148d30cd065010f81f71f51aab086bdbfa675b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 31 Aug 2023 14:58:53 +0530 +Subject: clk: qcom: ipq5332: Drop set rate parent from gpll0 dependent clocks + +From: Varadarajan Narayanan + +[ Upstream commit ccd8ab030643040600a663edde56b434b6f4fb6c ] + +IPQ5332's GPLL0's nominal/turbo frequency is 800MHz. +This must not be scaled based on the requirement of +dependent clocks. Hence remove the CLK_SET_RATE_PARENT +flag. + +Fixes: 3d89d52970fd ("clk: qcom: add Global Clock controller (GCC) driver for IPQ5332 SoC") +Signed-off-by: Varadarajan Narayanan +Reviewed-by: Kathiravan T +Link: https://lore.kernel.org/r/1693474133-10467-1-git-send-email-quic_varada@quicinc.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-ipq5332.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-ipq5332.c b/drivers/clk/qcom/gcc-ipq5332.c +index b02026f8549b2..b836159fbdefa 100644 +--- a/drivers/clk/qcom/gcc-ipq5332.c ++++ b/drivers/clk/qcom/gcc-ipq5332.c +@@ -71,7 +71,6 @@ static struct clk_fixed_factor gpll0_div2 = { + &gpll0_main.clkr.hw }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, +- .flags = CLK_SET_RATE_PARENT, + }, + }; + +@@ -85,7 +84,6 @@ static struct clk_alpha_pll_postdiv gpll0 = { + &gpll0_main.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, +- .flags = CLK_SET_RATE_PARENT, + }, + }; + +-- +2.42.0 + diff --git a/queue-6.6/clk-qcom-ipq5332-drop-the-clk_set_rate_parent-flag-f.patch b/queue-6.6/clk-qcom-ipq5332-drop-the-clk_set_rate_parent-flag-f.patch new file mode 100644 index 00000000000..8ea91ad9f41 --- /dev/null +++ b/queue-6.6/clk-qcom-ipq5332-drop-the-clk_set_rate_parent-flag-f.patch @@ -0,0 +1,47 @@ +From 72d8dfc4f92b73487c9682edd26983a051507134 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 12:29:55 +0530 +Subject: clk: qcom: ipq5332: drop the CLK_SET_RATE_PARENT flag from GPLL + clocks + +From: Kathiravan Thirumoorthy + +[ Upstream commit 5635ef0bd1052420bc659a00be6fd0c60cec5cb9 ] + +GPLL clock rates are fixed and shouldn't be scaled based on the +request from dependent clocks. Doing so will result in the unexpected +behaviour. So drop the CLK_SET_RATE_PARENT flag from the GPLL clocks. + +Fixes: 3d89d52970fd ("clk: qcom: add Global Clock controller (GCC) driver for IPQ5332 SoC") +Signed-off-by: Kathiravan Thirumoorthy +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230913-gpll_cleanup-v2-5-c8ceb1a37680@quicinc.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-ipq5332.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-ipq5332.c b/drivers/clk/qcom/gcc-ipq5332.c +index b836159fbdefa..f98591148a976 100644 +--- a/drivers/clk/qcom/gcc-ipq5332.c ++++ b/drivers/clk/qcom/gcc-ipq5332.c +@@ -112,7 +112,6 @@ static struct clk_alpha_pll_postdiv gpll2 = { + &gpll2_main.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, +- .flags = CLK_SET_RATE_PARENT, + }, + }; + +@@ -152,7 +151,6 @@ static struct clk_alpha_pll_postdiv gpll4 = { + &gpll4_main.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, +- .flags = CLK_SET_RATE_PARENT, + }, + }; + +-- +2.42.0 + diff --git a/queue-6.6/clk-qcom-ipq9574-drop-the-clk_set_rate_parent-flag-f.patch b/queue-6.6/clk-qcom-ipq9574-drop-the-clk_set_rate_parent-flag-f.patch new file mode 100644 index 00000000000..e4082804fb2 --- /dev/null +++ b/queue-6.6/clk-qcom-ipq9574-drop-the-clk_set_rate_parent-flag-f.patch @@ -0,0 +1,67 @@ +From c5e99402b928a31039036dfb742ac69c816f7ee0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 12:29:54 +0530 +Subject: clk: qcom: ipq9574: drop the CLK_SET_RATE_PARENT flag from GPLL + clocks + +From: Kathiravan Thirumoorthy + +[ Upstream commit 99a8f8764b70158a712992640a6be46a8fd79d15 ] + +GPLL clock rates are fixed and shouldn't be scaled based on the request +from dependent clocks. Doing so will result in the unexpected behaviour. +So drop the CLK_SET_RATE_PARENT flag from the GPLL clocks. + +---- +Changes in V2: + - No changes + +Fixes: d75b82cff488 ("clk: qcom: Add Global Clock Controller driver for IPQ9574") +Signed-off-by: Kathiravan Thirumoorthy +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230913-gpll_cleanup-v2-4-c8ceb1a37680@quicinc.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-ipq9574.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-ipq9574.c b/drivers/clk/qcom/gcc-ipq9574.c +index 8f430367299e6..e8190108e1aef 100644 +--- a/drivers/clk/qcom/gcc-ipq9574.c ++++ b/drivers/clk/qcom/gcc-ipq9574.c +@@ -87,7 +87,6 @@ static struct clk_fixed_factor gpll0_out_main_div2 = { + &gpll0_main.clkr.hw + }, + .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_fixed_factor_ops, + }, + }; +@@ -102,7 +101,6 @@ static struct clk_alpha_pll_postdiv gpll0 = { + &gpll0_main.clkr.hw + }, + .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, + }; +@@ -132,7 +130,6 @@ static struct clk_alpha_pll_postdiv gpll4 = { + &gpll4_main.clkr.hw + }, + .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, + }; +@@ -162,7 +159,6 @@ static struct clk_alpha_pll_postdiv gpll2 = { + &gpll2_main.clkr.hw + }, + .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, + }; +-- +2.42.0 + diff --git a/queue-6.6/clk-qcom-mmcc-msm8998-don-t-check-halt-bit-on-some-b.patch b/queue-6.6/clk-qcom-mmcc-msm8998-don-t-check-halt-bit-on-some-b.patch new file mode 100644 index 00000000000..9f3d9307ae9 --- /dev/null +++ b/queue-6.6/clk-qcom-mmcc-msm8998-don-t-check-halt-bit-on-some-b.patch @@ -0,0 +1,55 @@ +From 7306128ef4932b80b8fd35428220436c3e71afce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Aug 2023 21:20:27 +0200 +Subject: clk: qcom: mmcc-msm8998: Don't check halt bit on some branch clks + +From: Konrad Dybcio + +[ Upstream commit 9906c4140897bbdbff7bb71c6ae67903cb9954ce ] + +Some branch clocks are governed externally and we're only supposed to +send a request concerning their shutdown, not actually ensure it happens. + +Use the BRANCH_HALT_SKIP define to skip checking the halt bit. + +Fixes: d14b15b5931c ("clk: qcom: Add MSM8998 Multimedia Clock Controller (MMCC) driver") +Reviewed-by: Jeffrey Hugo +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230531-topic-8998_mmssclk-v3-4-ba1b1fd9ee75@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/mmcc-msm8998.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/clk/qcom/mmcc-msm8998.c b/drivers/clk/qcom/mmcc-msm8998.c +index a023c4374be96..b0b51adb73a54 100644 +--- a/drivers/clk/qcom/mmcc-msm8998.c ++++ b/drivers/clk/qcom/mmcc-msm8998.c +@@ -2439,6 +2439,7 @@ static struct clk_branch fd_ahb_clk = { + + static struct clk_branch mnoc_ahb_clk = { + .halt_reg = 0x5024, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x5024, + .enable_mask = BIT(0), +@@ -2454,6 +2455,7 @@ static struct clk_branch mnoc_ahb_clk = { + + static struct clk_branch bimc_smmu_ahb_clk = { + .halt_reg = 0xe004, ++ .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0xe004, + .hwcg_bit = 1, + .clkr = { +@@ -2471,6 +2473,7 @@ static struct clk_branch bimc_smmu_ahb_clk = { + + static struct clk_branch bimc_smmu_axi_clk = { + .halt_reg = 0xe008, ++ .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0xe008, + .hwcg_bit = 1, + .clkr = { +-- +2.42.0 + diff --git a/queue-6.6/clk-qcom-mmcc-msm8998-fix-the-smmu-gdsc.patch b/queue-6.6/clk-qcom-mmcc-msm8998-fix-the-smmu-gdsc.patch new file mode 100644 index 00000000000..0f82a8e151c --- /dev/null +++ b/queue-6.6/clk-qcom-mmcc-msm8998-fix-the-smmu-gdsc.patch @@ -0,0 +1,48 @@ +From 667c42d92d3e9958527038f7aa487f49e18cd9d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Aug 2023 21:20:28 +0200 +Subject: clk: qcom: mmcc-msm8998: Fix the SMMU GDSC + +From: Konrad Dybcio + +[ Upstream commit 1fc62c8347397faf4e18249e88ecd4470c0a5357 ] + +The SMMU GDSC doesn't have to be ALWAYS-ON and shouldn't feature the +HW_CTRL flag (it's separate from hw_ctrl_addr). In addition to that, +it should feature a cxc entry for bimc_smmu_axi_clk and be marked as +votable. + +Fix all of these issues. + +Fixes: d14b15b5931c ("clk: qcom: Add MSM8998 Multimedia Clock Controller (MMCC) driver") +Signed-off-by: Konrad Dybcio +Reviewed-by: Jeffrey Hugo +Link: https://lore.kernel.org/r/20230531-topic-8998_mmssclk-v3-5-ba1b1fd9ee75@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/mmcc-msm8998.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/qcom/mmcc-msm8998.c b/drivers/clk/qcom/mmcc-msm8998.c +index b0b51adb73a54..1180e48c687ac 100644 +--- a/drivers/clk/qcom/mmcc-msm8998.c ++++ b/drivers/clk/qcom/mmcc-msm8998.c +@@ -2610,11 +2610,13 @@ static struct gdsc camss_cpp_gdsc = { + static struct gdsc bimc_smmu_gdsc = { + .gdscr = 0xe020, + .gds_hw_ctrl = 0xe024, ++ .cxcs = (unsigned int []){ 0xe008 }, ++ .cxc_count = 1, + .pd = { + .name = "bimc_smmu", + }, + .pwrsts = PWRSTS_OFF_ON, +- .flags = HW_CTRL | ALWAYS_ON, ++ .flags = VOTABLE, + }; + + static struct clk_regmap *mmcc_msm8998_clocks[] = { +-- +2.42.0 + diff --git a/queue-6.6/clk-ralink-mtmips-quiet-unused-variable-warning.patch b/queue-6.6/clk-ralink-mtmips-quiet-unused-variable-warning.patch new file mode 100644 index 00000000000..e8ed5fe6e01 --- /dev/null +++ b/queue-6.6/clk-ralink-mtmips-quiet-unused-variable-warning.patch @@ -0,0 +1,85 @@ +From 0dd8949fb1697a88faa7dcd4658dc3fbcb806010 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 27 Aug 2023 04:39:32 +0200 +Subject: clk: ralink: mtmips: quiet unused variable warning + +From: Sergio Paracuellos + +[ Upstream commit 619102313466eaf8a6ac188e711f5df749dac6d4 ] + +When CONFIG_OF is disabled then the matching table is not referenced and +the following warning appears: + +drivers/clk/ralink/clk-mtmips.c:821:34: warning: unused variable 'mtmips_of_match' [-Wunused-const-variable] +821 | static const struct of_device_id mtmips_of_match[] = { + | ^ + +There are two match tables in the driver: one for the clock driver and the +other for the reset driver. The only difference between them is that the +clock driver uses 'data' and does not have 'ralink,rt2880-reset' compatible. +Both just can be merged into a single one just by adding the compatible +'ralink,rt2880-reset' entry to 'mtmips_of_match[]', which will allow it to +be used for 'mtmips_clk_driver' (which doesn't use the data) as well as for +'mtmips_clk_init()' (which doesn't need get called for 'ralink,rt2880-reset'). + +Doing in this way ensures that 'CONFIG_OF' is not disabled anymore so the +above warning disapears. + +Fixes: 6f3b15586eef ("clk: ralink: add clock and reset driver for MTMIPS SoCs") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202307242310.CdOnd2py-lkp@intel.com/ +Suggested-by: Arnd Bergmann +Signed-off-by: Sergio Paracuellos +Link: https://lore.kernel.org/r/20230827023932.501102-1-sergio.paracuellos@gmail.com +Reviewed-by: Nathan Chancellor +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/ralink/clk-mtmips.c | 20 +++++--------------- + 1 file changed, 5 insertions(+), 15 deletions(-) + +diff --git a/drivers/clk/ralink/clk-mtmips.c b/drivers/clk/ralink/clk-mtmips.c +index 1e7991439527a..50a443bf79ecd 100644 +--- a/drivers/clk/ralink/clk-mtmips.c ++++ b/drivers/clk/ralink/clk-mtmips.c +@@ -821,6 +821,10 @@ static const struct mtmips_clk_data mt76x8_clk_data = { + }; + + static const struct of_device_id mtmips_of_match[] = { ++ { ++ .compatible = "ralink,rt2880-reset", ++ .data = NULL, ++ }, + { + .compatible = "ralink,rt2880-sysc", + .data = &rt2880_clk_data, +@@ -1088,25 +1092,11 @@ static int mtmips_clk_probe(struct platform_device *pdev) + return 0; + } + +-static const struct of_device_id mtmips_clk_of_match[] = { +- { .compatible = "ralink,rt2880-reset" }, +- { .compatible = "ralink,rt2880-sysc" }, +- { .compatible = "ralink,rt3050-sysc" }, +- { .compatible = "ralink,rt3052-sysc" }, +- { .compatible = "ralink,rt3352-sysc" }, +- { .compatible = "ralink,rt3883-sysc" }, +- { .compatible = "ralink,rt5350-sysc" }, +- { .compatible = "ralink,mt7620-sysc" }, +- { .compatible = "ralink,mt7628-sysc" }, +- { .compatible = "ralink,mt7688-sysc" }, +- {} +-}; +- + static struct platform_driver mtmips_clk_driver = { + .probe = mtmips_clk_probe, + .driver = { + .name = "mtmips-clk", +- .of_match_table = mtmips_clk_of_match, ++ .of_match_table = mtmips_of_match, + }, + }; + +-- +2.42.0 + diff --git a/queue-6.6/clk-renesas-rcar-gen3-extend-sdnh-divider-table.patch b/queue-6.6/clk-renesas-rcar-gen3-extend-sdnh-divider-table.patch new file mode 100644 index 00000000000..151d027634b --- /dev/null +++ b/queue-6.6/clk-renesas-rcar-gen3-extend-sdnh-divider-table.patch @@ -0,0 +1,74 @@ +From 49820480d15599d06d414377d4bfaa7b9ee85ff1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Sep 2023 10:03:17 +0200 +Subject: clk: renesas: rcar-gen3: Extend SDnH divider table + +From: Dirk Behme + +[ Upstream commit d5252d9697a3e7007c741e9c103073868955a304 ] + +The clock dividers might be used with clock stop bit enabled or not. +Current tables only support recommended values from the datasheet. This +might result in warnings like below because no valid clock divider is +found. Resulting in a 0 divider. + +There are Renesas ARM Trusted Firmware version out there which e.g. +configure 0x201 (shifted logical right by 2: 0x80) and with this match +the added { STPnHCK | 0, 1 }: + +https://github.com/renesas-rcar/arm-trusted-firmware/blob/rcar_gen3_v2.3/drivers/renesas/rcar/emmc/emmc_init.c#L108 + +------------[ cut here ]------------ +sd1h: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set +WARNING: CPU: 1 PID: 1 at drivers/clk/clk-divider.c:141 divider_recalc_rate+0x48/0x70 +Modules linked in: +CPU: 1 PID: 1 Comm: swapper/0 Not tainted 6.1.52 #1 +Hardware name: Custom board based on r8a7796 (DT) +pstate: 40000005 (nZcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) +pc : divider_recalc_rate+0x48/0x70 +... +------------[ cut here ]------------ + +Fixes: bb6d3fa98a41 ("clk: renesas: rcar-gen3: Switch to new SD clock handling") +Signed-off-by: Dirk Behme +[wsa: extended the table to 5 entries, added comments, reword commit message a little] +Signed-off-by: Wolfram Sang +Tested-by: Dirk Behme +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20230928080317.28224-1-wsa+renesas@sang-engineering.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/rcar-cpg-lib.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/renesas/rcar-cpg-lib.c b/drivers/clk/renesas/rcar-cpg-lib.c +index e2e0447de1901..5a15f8788b922 100644 +--- a/drivers/clk/renesas/rcar-cpg-lib.c ++++ b/drivers/clk/renesas/rcar-cpg-lib.c +@@ -70,8 +70,21 @@ void cpg_simple_notifier_register(struct raw_notifier_head *notifiers, + #define STPnHCK BIT(9 - SDnSRCFC_SHIFT) + + static const struct clk_div_table cpg_sdh_div_table[] = { ++ /* ++ * These values are recommended by the datasheet. Because they come ++ * first, Linux will only use these. ++ */ + { 0, 1 }, { 1, 2 }, { STPnHCK | 2, 4 }, { STPnHCK | 3, 8 }, +- { STPnHCK | 4, 16 }, { 0, 0 }, ++ { STPnHCK | 4, 16 }, ++ /* ++ * These values are not recommended because STPnHCK is wrong. But they ++ * have been seen because of broken firmware. So, we support reading ++ * them but Linux will sanitize them when initializing through ++ * recalc_rate. ++ */ ++ { STPnHCK | 0, 1 }, { STPnHCK | 1, 2 }, { 2, 4 }, { 3, 8 }, { 4, 16 }, ++ /* Sentinel */ ++ { 0, 0 } + }; + + struct clk * __init cpg_sdh_clk_register(const char *name, +-- +2.42.0 + diff --git a/queue-6.6/clk-renesas-rzg2l-fix-computation-formula.patch b/queue-6.6/clk-renesas-rzg2l-fix-computation-formula.patch new file mode 100644 index 00000000000..d433dc9adcc --- /dev/null +++ b/queue-6.6/clk-renesas-rzg2l-fix-computation-formula.patch @@ -0,0 +1,70 @@ +From e30d8a68d61a63c015eab49b95c6abd6a7059e6b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 08:38:52 +0300 +Subject: clk: renesas: rzg2l: Fix computation formula + +From: Claudiu Beznea + +[ Upstream commit a2b23159499efd36b2d63b3c4534075d12ddc97a ] + +According to the hardware manual for RZ/G2L +(r01uh0914ej0130-rzg2l-rzg2lc.pdf), the computation formula for PLL rate +is as follows: + + Fout = ((m + k/65536) * Fin) / (p * 2^s) + +and k has values in the range [-32768, 32767]. Dividing k by 65536 with +integer arithmetic gives zero all the time, causing slight differences +b/w what has been set vs. what is displayed. Thus, get rid of this and +decompose the formula before dividing k by 65536. + +Fixes: ef3c613ccd68a ("clk: renesas: Add CPG core wrapper for RZ/G2L SoC") +Signed-off-by: Claudiu Beznea +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20230929053915.1530607-6-claudiu.beznea@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/rzg2l-cpg.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c +index 53f17f3587472..3f01620e292b6 100644 +--- a/drivers/clk/renesas/rzg2l-cpg.c ++++ b/drivers/clk/renesas/rzg2l-cpg.c +@@ -42,7 +42,7 @@ + #define GET_SHIFT(val) ((val >> 12) & 0xff) + #define GET_WIDTH(val) ((val >> 8) & 0xf) + +-#define KDIV(val) FIELD_GET(GENMASK(31, 16), val) ++#define KDIV(val) ((s16)FIELD_GET(GENMASK(31, 16), val)) + #define MDIV(val) FIELD_GET(GENMASK(15, 6), val) + #define PDIV(val) FIELD_GET(GENMASK(5, 0), val) + #define SDIV(val) FIELD_GET(GENMASK(2, 0), val) +@@ -695,18 +695,18 @@ static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw, + struct pll_clk *pll_clk = to_pll(hw); + struct rzg2l_cpg_priv *priv = pll_clk->priv; + unsigned int val1, val2; +- unsigned int mult = 1; +- unsigned int div = 1; ++ u64 rate; + + if (pll_clk->type != CLK_TYPE_SAM_PLL) + return parent_rate; + + val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf)); + val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf)); +- mult = MDIV(val1) + KDIV(val1) / 65536; +- div = PDIV(val1) << SDIV(val2); + +- return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, div); ++ rate = mul_u64_u32_shr(parent_rate, (MDIV(val1) << 16) + KDIV(val1), ++ 16 + SDIV(val2)); ++ ++ return DIV_ROUND_CLOSEST_ULL(rate, PDIV(val1)); + } + + static const struct clk_ops rzg2l_cpg_pll_ops = { +-- +2.42.0 + diff --git a/queue-6.6/clk-renesas-rzg2l-lock-around-writes-to-mux-register.patch b/queue-6.6/clk-renesas-rzg2l-lock-around-writes-to-mux-register.patch new file mode 100644 index 00000000000..47eb3b6c016 --- /dev/null +++ b/queue-6.6/clk-renesas-rzg2l-lock-around-writes-to-mux-register.patch @@ -0,0 +1,92 @@ +From 9775269143b894b5ed03e25490951bda8f8ca29c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 08:38:50 +0300 +Subject: clk: renesas: rzg2l: Lock around writes to mux register + +From: Claudiu Beznea + +[ Upstream commit d2692ed490e680a41401cef879adebcfafb4298f ] + +The SD MUX output (SD0) is further divided by 4 in G2{L,UL}. The +divided clock is SD0_DIV4. SD0_DIV4 is registered with +CLK_SET_RATE_PARENT which means a rate request for it is propagated to +the MUX and could reach rzg2l_cpg_sd_clk_mux_set_parent() concurrently +with the users of SD0. +Add proper locking to avoid concurrent accesses on SD MUX set rate +registers. + +Fixes: eaff33646f4cb ("clk: renesas: rzg2l: Add SDHI clk mux support") +Signed-off-by: Claudiu Beznea +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20230929053915.1530607-4-claudiu.beznea@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/rzg2l-cpg.c | 23 +++++++++++++---------- + drivers/clk/renesas/rzg2l-cpg.h | 2 +- + 2 files changed, 14 insertions(+), 11 deletions(-) + +diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c +index 9d25f7d0494e6..4c1f388ded6b2 100644 +--- a/drivers/clk/renesas/rzg2l-cpg.c ++++ b/drivers/clk/renesas/rzg2l-cpg.c +@@ -189,6 +189,7 @@ static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index) + u32 shift = GET_SHIFT(hwdata->conf); + const u32 clk_src_266 = 2; + u32 msk, val, bitmask; ++ unsigned long flags; + int ret; + + /* +@@ -204,23 +205,25 @@ static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index) + */ + bitmask = (GENMASK(GET_WIDTH(hwdata->conf) - 1, 0) << shift) << 16; + msk = off ? CPG_CLKSTATUS_SELSDHI1_STS : CPG_CLKSTATUS_SELSDHI0_STS; ++ spin_lock_irqsave(&priv->rmw_lock, flags); + if (index != clk_src_266) { + writel(bitmask | ((clk_src_266 + 1) << shift), priv->base + off); + +- ret = readl_poll_timeout(priv->base + CPG_CLKSTATUS, val, +- !(val & msk), 100, +- CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US); +- if (ret) { +- dev_err(priv->dev, "failed to switch clk source\n"); +- return ret; +- } ++ ret = readl_poll_timeout_atomic(priv->base + CPG_CLKSTATUS, val, ++ !(val & msk), 10, ++ CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US); ++ if (ret) ++ goto unlock; + } + + writel(bitmask | ((index + 1) << shift), priv->base + off); + +- ret = readl_poll_timeout(priv->base + CPG_CLKSTATUS, val, +- !(val & msk), 100, +- CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US); ++ ret = readl_poll_timeout_atomic(priv->base + CPG_CLKSTATUS, val, ++ !(val & msk), 10, ++ CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US); ++unlock: ++ spin_unlock_irqrestore(&priv->rmw_lock, flags); ++ + if (ret) + dev_err(priv->dev, "failed to switch clk source\n"); + +diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h +index 6cee9e56acc72..91e9c2569f801 100644 +--- a/drivers/clk/renesas/rzg2l-cpg.h ++++ b/drivers/clk/renesas/rzg2l-cpg.h +@@ -43,7 +43,7 @@ + #define CPG_CLKSTATUS_SELSDHI0_STS BIT(28) + #define CPG_CLKSTATUS_SELSDHI1_STS BIT(29) + +-#define CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US 20000 ++#define CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US 200 + + /* n = 0/1/2 for PLL1/4/6 */ + #define CPG_SAMPLL_CLK1(n) (0x04 + (16 * n)) +-- +2.42.0 + diff --git a/queue-6.6/clk-renesas-rzg2l-trust-value-returned-by-hardware.patch b/queue-6.6/clk-renesas-rzg2l-trust-value-returned-by-hardware.patch new file mode 100644 index 00000000000..c6353f4c2cc --- /dev/null +++ b/queue-6.6/clk-renesas-rzg2l-trust-value-returned-by-hardware.patch @@ -0,0 +1,48 @@ +From c4b054255f5c21fa069dfb689f44a87240529241 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 08:38:51 +0300 +Subject: clk: renesas: rzg2l: Trust value returned by hardware + +From: Claudiu Beznea + +[ Upstream commit bf51d3b2d048c312764a55d91d67a85ee5535e31 ] + +The onitial value of the CPG_PL2SDHI_DSEL bits 0..1 or 4..6 is 01b. The +hardware user's manual (r01uh0914ej0130-rzg2l-rzg2lc.pdf) specifies that +setting 0 is prohibited. Hence rzg2l_cpg_sd_clk_mux_get_parent() should +just read CPG_PL2SDHI_DSEL, trust the value, and return the proper clock +parent index based on the value read. + +Fixes: eaff33646f4cb ("clk: renesas: rzg2l: Add SDHI clk mux support") +Signed-off-by: Claudiu Beznea +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20230929053915.1530607-5-claudiu.beznea@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/rzg2l-cpg.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c +index 4c1f388ded6b2..2058a7e3a6aad 100644 +--- a/drivers/clk/renesas/rzg2l-cpg.c ++++ b/drivers/clk/renesas/rzg2l-cpg.c +@@ -238,14 +238,8 @@ static u8 rzg2l_cpg_sd_clk_mux_get_parent(struct clk_hw *hw) + + val >>= GET_SHIFT(hwdata->conf); + val &= GENMASK(GET_WIDTH(hwdata->conf) - 1, 0); +- if (val) { +- val--; +- } else { +- /* Prohibited clk source, change it to 533 MHz(reset value) */ +- rzg2l_cpg_sd_clk_mux_set_parent(hw, 0); +- } + +- return val; ++ return val ? val - 1 : 0; + } + + static const struct clk_ops rzg2l_cpg_sd_clk_mux_ops = { +-- +2.42.0 + diff --git a/queue-6.6/clk-renesas-rzg2l-use-field_get-for-pll-register-fie.patch b/queue-6.6/clk-renesas-rzg2l-use-field_get-for-pll-register-fie.patch new file mode 100644 index 00000000000..0ca58d8a7d3 --- /dev/null +++ b/queue-6.6/clk-renesas-rzg2l-use-field_get-for-pll-register-fie.patch @@ -0,0 +1,55 @@ +From ef41ce2ed103cccdef30ddc1eb8bdef4c2d8c2c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 07:51:33 +0300 +Subject: clk: renesas: rzg2l: Use FIELD_GET() for PLL register fields + +From: Claudiu Beznea + +[ Upstream commit 72977f07b035e488c3f1928832a1616c6cae7278 ] + +Use FIELD_GET() for PLL register fields. This is its purpose. + +Signed-off-by: Claudiu Beznea +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20230912045157.177966-14-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Stable-dep-of: a2b23159499e ("clk: renesas: rzg2l: Fix computation formula") +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/rzg2l-cpg.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c +index 2058a7e3a6aad..53f17f3587472 100644 +--- a/drivers/clk/renesas/rzg2l-cpg.c ++++ b/drivers/clk/renesas/rzg2l-cpg.c +@@ -11,6 +11,7 @@ + * Copyright (C) 2015 Renesas Electronics Corp. + */ + ++#include + #include + #include + #include +@@ -38,14 +39,13 @@ + #define WARN_DEBUG(x) do { } while (0) + #endif + +-#define DIV_RSMASK(v, s, m) ((v >> s) & m) + #define GET_SHIFT(val) ((val >> 12) & 0xff) + #define GET_WIDTH(val) ((val >> 8) & 0xf) + +-#define KDIV(val) DIV_RSMASK(val, 16, 0xffff) +-#define MDIV(val) DIV_RSMASK(val, 6, 0x3ff) +-#define PDIV(val) DIV_RSMASK(val, 0, 0x3f) +-#define SDIV(val) DIV_RSMASK(val, 0, 0x7) ++#define KDIV(val) FIELD_GET(GENMASK(31, 16), val) ++#define MDIV(val) FIELD_GET(GENMASK(15, 6), val) ++#define PDIV(val) FIELD_GET(GENMASK(5, 0), val) ++#define SDIV(val) FIELD_GET(GENMASK(2, 0), val) + + #define CLK_ON_R(reg) (reg) + #define CLK_MON_R(reg) (0x180 + (reg)) +-- +2.42.0 + diff --git a/queue-6.6/clk-renesas-rzg2l-wait-for-status-bit-of-sd-mux-befo.patch b/queue-6.6/clk-renesas-rzg2l-wait-for-status-bit-of-sd-mux-befo.patch new file mode 100644 index 00000000000..416dcc798d5 --- /dev/null +++ b/queue-6.6/clk-renesas-rzg2l-wait-for-status-bit-of-sd-mux-befo.patch @@ -0,0 +1,72 @@ +From 1b39b1e5ad2fa1cf21bd3bd6ae6a7c96b6eab834 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 08:38:49 +0300 +Subject: clk: renesas: rzg2l: Wait for status bit of SD mux before continuing + +From: Claudiu Beznea + +[ Upstream commit 549f4ae2601f968e2474c6031fb4799468882f64 ] + +The hardware user manual for RZ/G2L (r01uh0914ej0130-rzg2l-rzg2lc.pdf, +chapter 7.4.7 Procedure for Switching Clocks by the Dynamic Switching +Frequency Selectors) specifies that we need to check CPG_PL2SDHI_DSEL +for SD clock switching status. + +Fixes: eaff33646f4cb ("clk: renesas: rzg2l: Add SDHI clk mux support") +Signed-off-by: Claudiu Beznea +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20230929053915.1530607-3-claudiu.beznea@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/rzg2l-cpg.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c +index 47f488387f33a..9d25f7d0494e6 100644 +--- a/drivers/clk/renesas/rzg2l-cpg.c ++++ b/drivers/clk/renesas/rzg2l-cpg.c +@@ -188,7 +188,8 @@ static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index) + u32 off = GET_REG_OFFSET(hwdata->conf); + u32 shift = GET_SHIFT(hwdata->conf); + const u32 clk_src_266 = 2; +- u32 bitmask; ++ u32 msk, val, bitmask; ++ int ret; + + /* + * As per the HW manual, we should not directly switch from 533 MHz to +@@ -202,14 +203,10 @@ static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index) + * the index to value mapping is done by adding 1 to the index. + */ + bitmask = (GENMASK(GET_WIDTH(hwdata->conf) - 1, 0) << shift) << 16; ++ msk = off ? CPG_CLKSTATUS_SELSDHI1_STS : CPG_CLKSTATUS_SELSDHI0_STS; + if (index != clk_src_266) { +- u32 msk, val; +- int ret; +- + writel(bitmask | ((clk_src_266 + 1) << shift), priv->base + off); + +- msk = off ? CPG_CLKSTATUS_SELSDHI1_STS : CPG_CLKSTATUS_SELSDHI0_STS; +- + ret = readl_poll_timeout(priv->base + CPG_CLKSTATUS, val, + !(val & msk), 100, + CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US); +@@ -221,7 +218,13 @@ static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index) + + writel(bitmask | ((index + 1) << shift), priv->base + off); + +- return 0; ++ ret = readl_poll_timeout(priv->base + CPG_CLKSTATUS, val, ++ !(val & msk), 100, ++ CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US); ++ if (ret) ++ dev_err(priv->dev, "failed to switch clk source\n"); ++ ++ return ret; + } + + static u8 rzg2l_cpg_sd_clk_mux_get_parent(struct clk_hw *hw) +-- +2.42.0 + diff --git a/queue-6.6/clk-scmi-free-scmi_clk-allocated-when-the-clocks-wit.patch b/queue-6.6/clk-scmi-free-scmi_clk-allocated-when-the-clocks-wit.patch new file mode 100644 index 00000000000..2cfff2e0ba6 --- /dev/null +++ b/queue-6.6/clk-scmi-free-scmi_clk-allocated-when-the-clocks-wit.patch @@ -0,0 +1,40 @@ +From 8615c9f62effc42d98286a3b97943acf4e59e6de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 20:36:00 +0100 +Subject: clk: scmi: Free scmi_clk allocated when the clocks with invalid info + are skipped + +From: Sudeep Holla + +[ Upstream commit 3537a75e73f3420614a358d0c8b390ea483cc87d ] + +Add the missing devm_kfree() when we skip the clocks with invalid or +missing information from the firmware. + +Cc: Cristian Marussi +Cc: Michael Turquette +Cc: Stephen Boyd +Cc: linux-clk@vger.kernel.org +Fixes: 6d6a1d82eaef ("clk: add support for clocks provided by SCMI") +Link: https://lore.kernel.org/r/20231004193600.66232-1-sudeep.holla@arm.com +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + drivers/clk/clk-scmi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c +index 2c7a830ce3080..fdec715c9ba9b 100644 +--- a/drivers/clk/clk-scmi.c ++++ b/drivers/clk/clk-scmi.c +@@ -213,6 +213,7 @@ static int scmi_clocks_probe(struct scmi_device *sdev) + sclk->info = scmi_proto_clk_ops->info_get(ph, idx); + if (!sclk->info) { + dev_dbg(dev, "invalid clock info for idx %d\n", idx); ++ devm_kfree(dev, sclk); + continue; + } + +-- +2.42.0 + diff --git a/queue-6.6/clk-ti-fix-double-free-in-of_ti_divider_clk_setup.patch b/queue-6.6/clk-ti-fix-double-free-in-of_ti_divider_clk_setup.patch new file mode 100644 index 00000000000..ae7138b9ad6 --- /dev/null +++ b/queue-6.6/clk-ti-fix-double-free-in-of_ti_divider_clk_setup.patch @@ -0,0 +1,51 @@ +From 0c838d321754ebdd7d29bc26eb3b6304532ce45c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Oct 2023 10:04:36 +0300 +Subject: clk: ti: fix double free in of_ti_divider_clk_setup() + +From: Dan Carpenter + +[ Upstream commit 7af5b9eadd64c9e02a71f97c45bcdf3b64841f6b ] + +The "div" pointer is freed in _register_divider() and again in +of_ti_divider_clk_setup(). Delete the free in _register_divider() + +Fixes: fbbc18591585 ("clk: ti: divider: cleanup _register_divider and ti_clk_get_div_table") +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/6d36eeec-6c8a-4f11-a579-aa3cd7c38749@moroto.mountain +Reviewed-by: Tony Lindgren +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/ti/divider.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c +index 768a1f3398b47..5d5bb123ba949 100644 +--- a/drivers/clk/ti/divider.c ++++ b/drivers/clk/ti/divider.c +@@ -309,7 +309,6 @@ static struct clk *_register_divider(struct device_node *node, + u32 flags, + struct clk_omap_divider *div) + { +- struct clk *clk; + struct clk_init_data init; + const char *parent_name; + const char *name; +@@ -326,12 +325,7 @@ static struct clk *_register_divider(struct device_node *node, + div->hw.init = &init; + + /* register the clock */ +- clk = of_ti_clk_register(node, &div->hw, name); +- +- if (IS_ERR(clk)) +- kfree(div); +- +- return clk; ++ return of_ti_clk_register(node, &div->hw, name); + } + + int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, +-- +2.42.0 + diff --git a/queue-6.6/clocksource-drivers-arm_arch_timer-limit-xgene-1-wor.patch b/queue-6.6/clocksource-drivers-arm_arch_timer-limit-xgene-1-wor.patch new file mode 100644 index 00000000000..c94df476c2e --- /dev/null +++ b/queue-6.6/clocksource-drivers-arm_arch_timer-limit-xgene-1-wor.patch @@ -0,0 +1,81 @@ +From 8a5a38f4d9a2031ef432a15c947999039df25c57 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Oct 2023 16:31:27 +0100 +Subject: clocksource/drivers/arm_arch_timer: limit XGene-1 workaround + +From: Andre Przywara + +[ Upstream commit 851354cbd12bb9500909733c3d4054306f61df87 ] + +The AppliedMicro XGene-1 CPU has an erratum where the timer condition +would only consider TVAL, not CVAL. We currently apply a workaround when +seeing the PartNum field of MIDR_EL1 being 0x000, under the assumption +that this would match only the XGene-1 CPU model. +However even the Ampere eMAG (aka XGene-3) uses that same part number, and +only differs in the "Variant" and "Revision" fields: XGene-1's MIDR is +0x500f0000, our eMAG reports 0x503f0002. Experiments show the latter +doesn't show the faulty behaviour. + +Increase the specificity of the check to only consider partnum 0x000 and +variant 0x00, to exclude the Ampere eMAG. + +Fixes: 012f18850452 ("clocksource/drivers/arm_arch_timer: Work around broken CVAL implementations") +Reported-by: Ross Burton +Signed-off-by: Andre Przywara +Acked-by: Marc Zyngier +Reviewed-by: Oliver Upton +Link: https://lore.kernel.org/r/20231016153127.116101-1-andre.przywara@arm.com +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + arch/arm64/include/asm/cputype.h | 3 ++- + arch/arm64/kvm/guest.c | 2 +- + drivers/clocksource/arm_arch_timer.c | 5 +++-- + 3 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h +index 74d00feb62f03..7c7493cb571f9 100644 +--- a/arch/arm64/include/asm/cputype.h ++++ b/arch/arm64/include/asm/cputype.h +@@ -86,7 +86,8 @@ + #define ARM_CPU_PART_NEOVERSE_N2 0xD49 + #define ARM_CPU_PART_CORTEX_A78C 0xD4B + +-#define APM_CPU_PART_POTENZA 0x000 ++#define APM_CPU_PART_XGENE 0x000 ++#define APM_CPU_VAR_POTENZA 0x00 + + #define CAVIUM_CPU_PART_THUNDERX 0x0A1 + #define CAVIUM_CPU_PART_THUNDERX_81XX 0x0A2 +diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c +index 95f6945c44325..a1710e5fa72b6 100644 +--- a/arch/arm64/kvm/guest.c ++++ b/arch/arm64/kvm/guest.c +@@ -874,7 +874,7 @@ u32 __attribute_const__ kvm_target_cpu(void) + break; + case ARM_CPU_IMP_APM: + switch (part_number) { +- case APM_CPU_PART_POTENZA: ++ case APM_CPU_PART_XGENE: + return KVM_ARM_TARGET_XGENE_POTENZA; + } + break; +diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c +index 7dd2c615bce23..071b04f1ee730 100644 +--- a/drivers/clocksource/arm_arch_timer.c ++++ b/drivers/clocksource/arm_arch_timer.c +@@ -836,8 +836,9 @@ static u64 __arch_timer_check_delta(void) + * Note that TVAL is signed, thus has only 31 of its + * 32 bits to express magnitude. + */ +- MIDR_ALL_VERSIONS(MIDR_CPU_MODEL(ARM_CPU_IMP_APM, +- APM_CPU_PART_POTENZA)), ++ MIDR_REV_RANGE(MIDR_CPU_MODEL(ARM_CPU_IMP_APM, ++ APM_CPU_PART_XGENE), ++ APM_CPU_VAR_POTENZA, 0x0, 0xf), + {}, + }; + +-- +2.42.0 + diff --git a/queue-6.6/cpu-smt-make-smt-control-more-robust-against-enumera.patch b/queue-6.6/cpu-smt-make-smt-control-more-robust-against-enumera.patch new file mode 100644 index 00000000000..6b6fadb27e5 --- /dev/null +++ b/queue-6.6/cpu-smt-make-smt-control-more-robust-against-enumera.patch @@ -0,0 +1,113 @@ +From 8d793e42de9821755192236eee336a83a5a48a20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Aug 2023 10:18:27 +0200 +Subject: cpu/SMT: Make SMT control more robust against enumeration failures + +From: Thomas Gleixner + +[ Upstream commit d91bdd96b55cc3ce98d883a60f133713821b80a6 ] + +The SMT control mechanism got added as speculation attack vector +mitigation. The implemented logic relies on the primary thread mask to +be set up properly. + +This turns out to be an issue with XEN/PV guests because their CPU hotplug +mechanics do not enumerate APICs and therefore the mask is never correctly +populated. + +This went unnoticed so far because by chance XEN/PV ends up with +smp_num_siblings == 2. So smt_hotplug_control stays at its default value +CPU_SMT_ENABLED and the primary thread mask is never evaluated in the +context of CPU hotplug. + +This stopped "working" with the upcoming overhaul of the topology +evaluation which legitimately provides a fake topology for XEN/PV. That +sets smp_num_siblings to 1, which causes the core CPU hot-plug core to +refuse to bring up the APs. + +This happens because smt_hotplug_control is set to CPU_SMT_NOT_SUPPORTED +which causes cpu_smt_allowed() to evaluate the unpopulated primary thread +mask with the conclusion that all non-boot CPUs are not valid to be +plugged. + +Make cpu_smt_allowed() more robust and take CPU_SMT_NOT_SUPPORTED and +CPU_SMT_NOT_IMPLEMENTED into account. Rename it to cpu_bootable() while at +it as that makes it more clear what the function is about. + +The primary mask issue on x86 XEN/PV needs to be addressed separately as +there are users outside of the CPU hotplug code too. + +Fixes: 05736e4ac13c ("cpu/hotplug: Provide knobs to control SMT") +Reported-by: Juergen Gross +Signed-off-by: Thomas Gleixner +Tested-by: Juergen Gross +Tested-by: Sohil Mehta +Tested-by: Michael Kelley +Tested-by: Peter Zijlstra (Intel) +Tested-by: Zhang Rui +Acked-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/r/20230814085112.149440843@linutronix.de +Signed-off-by: Sasha Levin +--- + kernel/cpu.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/kernel/cpu.c b/kernel/cpu.c +index 6de7c6bb74eee..1a189da3bdac5 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -659,11 +659,19 @@ static inline bool cpu_smt_thread_allowed(unsigned int cpu) + #endif + } + +-static inline bool cpu_smt_allowed(unsigned int cpu) ++static inline bool cpu_bootable(unsigned int cpu) + { + if (cpu_smt_control == CPU_SMT_ENABLED && cpu_smt_thread_allowed(cpu)) + return true; + ++ /* All CPUs are bootable if controls are not configured */ ++ if (cpu_smt_control == CPU_SMT_NOT_IMPLEMENTED) ++ return true; ++ ++ /* All CPUs are bootable if CPU is not SMT capable */ ++ if (cpu_smt_control == CPU_SMT_NOT_SUPPORTED) ++ return true; ++ + if (topology_is_primary_thread(cpu)) + return true; + +@@ -685,7 +693,7 @@ bool cpu_smt_possible(void) + EXPORT_SYMBOL_GPL(cpu_smt_possible); + + #else +-static inline bool cpu_smt_allowed(unsigned int cpu) { return true; } ++static inline bool cpu_bootable(unsigned int cpu) { return true; } + #endif + + static inline enum cpuhp_state +@@ -788,10 +796,10 @@ static int bringup_wait_for_ap_online(unsigned int cpu) + * SMT soft disabling on X86 requires to bring the CPU out of the + * BIOS 'wait for SIPI' state in order to set the CR4.MCE bit. The + * CPU marked itself as booted_once in notify_cpu_starting() so the +- * cpu_smt_allowed() check will now return false if this is not the ++ * cpu_bootable() check will now return false if this is not the + * primary sibling. + */ +- if (!cpu_smt_allowed(cpu)) ++ if (!cpu_bootable(cpu)) + return -ECANCELED; + return 0; + } +@@ -1741,7 +1749,7 @@ static int cpu_up(unsigned int cpu, enum cpuhp_state target) + err = -EBUSY; + goto out; + } +- if (!cpu_smt_allowed(cpu)) { ++ if (!cpu_bootable(cpu)) { + err = -EPERM; + goto out; + } +-- +2.42.0 + diff --git a/queue-6.6/cpufreq-tegra194-fix-warning-due-to-missing-opp_put.patch b/queue-6.6/cpufreq-tegra194-fix-warning-due-to-missing-opp_put.patch new file mode 100644 index 00000000000..c2178aa2334 --- /dev/null +++ b/queue-6.6/cpufreq-tegra194-fix-warning-due-to-missing-opp_put.patch @@ -0,0 +1,58 @@ +From 02c28cc01a136bd167290579cdf5e52bc6c19421 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Aug 2023 14:13:22 +0530 +Subject: cpufreq: tegra194: fix warning due to missing opp_put + +From: Sumit Gupta + +[ Upstream commit bae8222a6c291dbe58c908dab5c2abd3a75d0d63 ] + +Fix the warning due to missing dev_pm_opp_put() call and hence +wrong refcount value. This causes below warning message when +trying to remove the module. + + Call trace: + dev_pm_opp_put_opp_table+0x154/0x15c + dev_pm_opp_remove_table+0x34/0xa0 + _dev_pm_opp_cpumask_remove_table+0x7c/0xbc + dev_pm_opp_of_cpumask_remove_table+0x10/0x18 + tegra194_cpufreq_exit+0x24/0x34 [tegra194_cpufreq] + cpufreq_remove_dev+0xa8/0xf8 + subsys_interface_unregister+0x90/0xe8 + cpufreq_unregister_driver+0x54/0x9c + tegra194_cpufreq_remove+0x18/0x2c [tegra194_cpufreq] + platform_remove+0x24/0x74 + device_remove+0x48/0x78 + device_release_driver_internal+0xc8/0x160 + driver_detach+0x4c/0x90 + bus_remove_driver+0x68/0xb8 + driver_unregister+0x2c/0x58 + platform_driver_unregister+0x10/0x18 + tegra194_ccplex_driver_exit+0x14/0x1e0 [tegra194_cpufreq] + __arm64_sys_delete_module+0x184/0x270 + +Fixes: f41e1442ac5b ("cpufreq: tegra194: add OPP support and set bandwidth") +Signed-off-by: Sumit Gupta +[ Viresh: Add a blank line ] +Signed-off-by: Viresh Kumar +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/tegra194-cpufreq.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/cpufreq/tegra194-cpufreq.c b/drivers/cpufreq/tegra194-cpufreq.c +index 88ef5e57ccd05..386aed3637b4e 100644 +--- a/drivers/cpufreq/tegra194-cpufreq.c ++++ b/drivers/cpufreq/tegra194-cpufreq.c +@@ -450,6 +450,8 @@ static int tegra_cpufreq_init_cpufreq_table(struct cpufreq_policy *policy, + if (IS_ERR(opp)) + continue; + ++ dev_pm_opp_put(opp); ++ + ret = dev_pm_opp_enable(cpu_dev, pos->frequency * KHZ); + if (ret < 0) + return ret; +-- +2.42.0 + diff --git a/queue-6.6/cpupower-fix-reference-to-nonexistent-document.patch b/queue-6.6/cpupower-fix-reference-to-nonexistent-document.patch new file mode 100644 index 00000000000..eeba5061daa --- /dev/null +++ b/queue-6.6/cpupower-fix-reference-to-nonexistent-document.patch @@ -0,0 +1,45 @@ +From 6e8796f72b9a54d5f7fcfa6ca2cec65e739fb67c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 22 Oct 2023 20:54:46 +0200 +Subject: cpupower: fix reference to nonexistent document + +From: Vegard Nossum + +[ Upstream commit 6feb1a9641197ee630bf43b5c34ea1d9f8b4a0aa ] + +This file was renamed from .txt to .rst and left a dangling reference. +Fix it. + +Fixes: 151f4e2bdc7a ("docs: power: convert docs to ReST and rename to *.rst") +Cc: Mauro Carvalho Chehab +Cc: Bjorn Helgaas +Cc: Mark Brown +Cc: Srivatsa S. Bhat (VMware) +Cc: Srinivas Pandruvada +Cc: Jacob Pan +Cc: Arjan van de Ven +Cc: Rafael J. Wysocki +Cc: Len Brown +Signed-off-by: Vegard Nossum +Signed-off-by: Shuah Khan +Signed-off-by: Sasha Levin +--- + tools/power/cpupower/man/cpupower-powercap-info.1 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/power/cpupower/man/cpupower-powercap-info.1 b/tools/power/cpupower/man/cpupower-powercap-info.1 +index df3087000efb8..145d6f06fa72d 100644 +--- a/tools/power/cpupower/man/cpupower-powercap-info.1 ++++ b/tools/power/cpupower/man/cpupower-powercap-info.1 +@@ -17,7 +17,7 @@ settings of all cores, see cpupower(1) how to choose specific cores. + .SH "DOCUMENTATION" + + kernel sources: +-Documentation/power/powercap/powercap.txt ++Documentation/power/powercap/powercap.rst + + + .SH "SEE ALSO" +-- +2.42.0 + diff --git a/queue-6.6/crypto-caam-jr-fix-chacha20-poly1305-self-test-failu.patch b/queue-6.6/crypto-caam-jr-fix-chacha20-poly1305-self-test-failu.patch new file mode 100644 index 00000000000..7787792796f --- /dev/null +++ b/queue-6.6/crypto-caam-jr-fix-chacha20-poly1305-self-test-failu.patch @@ -0,0 +1,39 @@ +From 35490d34c8253a99208574341083d767c9517725 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 18:12:37 +0530 +Subject: crypto: caam/jr - fix Chacha20 + Poly1305 self test failure + +From: Gaurav Jain + +[ Upstream commit a8d3cdcc092fb2f2882acb6c20473a1be0ef4484 ] + +key buffer is not copied in chachapoly_setkey function, +results in wrong output for encryption/decryption operation. + +fix this by memcpy the key in caam_ctx key arrary + +Fixes: d6bbd4eea243 ("crypto: caam/jr - add support for Chacha20 + Poly1305") +Signed-off-by: Gaurav Jain +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/caam/caamalg.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c +index eba2d750c3b07..066f08a3a040d 100644 +--- a/drivers/crypto/caam/caamalg.c ++++ b/drivers/crypto/caam/caamalg.c +@@ -575,7 +575,8 @@ static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key, + if (keylen != CHACHA_KEY_SIZE + saltlen) + return -EINVAL; + +- ctx->cdata.key_virt = key; ++ memcpy(ctx->key, key, keylen); ++ ctx->cdata.key_virt = ctx->key; + ctx->cdata.keylen = keylen - saltlen; + + return chachapoly_set_sh_desc(aead); +-- +2.42.0 + diff --git a/queue-6.6/crypto-caam-qi2-fix-chacha20-poly1305-self-test-fail.patch b/queue-6.6/crypto-caam-qi2-fix-chacha20-poly1305-self-test-fail.patch new file mode 100644 index 00000000000..bb7652576c2 --- /dev/null +++ b/queue-6.6/crypto-caam-qi2-fix-chacha20-poly1305-self-test-fail.patch @@ -0,0 +1,39 @@ +From e618fa225c6e7325e4e6789b0b5873e7583b9527 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 15:14:44 +0530 +Subject: crypto: caam/qi2 - fix Chacha20 + Poly1305 self test failure + +From: Gaurav Jain + +[ Upstream commit 7b8c6aee0d5b864e70c0da82583f9862e374eaf3 ] + +key buffer is not copied in chachapoly_setkey function, +results in wrong output for encryption/decryption operation. + +fix this by memcpy the key in caam_ctx key arrary + +Fixes: c10a53367901 ("crypto: caam/qi2 - add support for Chacha20 + Poly1305") +Signed-off-by: Gaurav Jain +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/caam/caamalg_qi2.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/caam/caamalg_qi2.c b/drivers/crypto/caam/caamalg_qi2.c +index 9156bbe038b7b..a148ff1f0872c 100644 +--- a/drivers/crypto/caam/caamalg_qi2.c ++++ b/drivers/crypto/caam/caamalg_qi2.c +@@ -641,7 +641,8 @@ static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key, + if (keylen != CHACHA_KEY_SIZE + saltlen) + return -EINVAL; + +- ctx->cdata.key_virt = key; ++ memcpy(ctx->key, key, keylen); ++ ctx->cdata.key_virt = ctx->key; + ctx->cdata.keylen = keylen - saltlen; + + return chachapoly_set_sh_desc(aead); +-- +2.42.0 + diff --git a/queue-6.6/crypto-ccp-fix-dbc-sample-application-error-handling.patch b/queue-6.6/crypto-ccp-fix-dbc-sample-application-error-handling.patch new file mode 100644 index 00000000000..3f40263bb90 --- /dev/null +++ b/queue-6.6/crypto-ccp-fix-dbc-sample-application-error-handling.patch @@ -0,0 +1,96 @@ +From 3c20cda944741212b237b91e67bf9e12e0614aa0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Aug 2023 10:07:57 -0500 +Subject: crypto: ccp - Fix DBC sample application error handling + +From: Mario Limonciello + +[ Upstream commit 70f242c1933e9e881c13c31640bb6d56e8b7e738 ] + +The sample application was taking values from ioctl() and treating +those as the error codes to present to a user. + +This is incorrect when ret is non-zero, the error is stored to `errno`. +Use this value instead. + +Fixes: f40d42f116cf ("crypto: ccp - Add a sample python script for Dynamic Boost Control") +Fixes: febe3ed3222f ("crypto: ccp - Add a sample library for ioctl use") +Signed-off-by: Mario Limonciello +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + tools/crypto/ccp/dbc.c | 16 ++++++++-------- + tools/crypto/ccp/dbc.py | 3 +-- + 2 files changed, 9 insertions(+), 10 deletions(-) + +diff --git a/tools/crypto/ccp/dbc.c b/tools/crypto/ccp/dbc.c +index 37e813175642f..7774e981849fa 100644 +--- a/tools/crypto/ccp/dbc.c ++++ b/tools/crypto/ccp/dbc.c +@@ -8,6 +8,7 @@ + */ + + #include ++#include + #include + #include + +@@ -22,16 +23,14 @@ int get_nonce(int fd, void *nonce_out, void *signature) + struct dbc_user_nonce tmp = { + .auth_needed = !!signature, + }; +- int ret; + + assert(nonce_out); + + if (signature) + memcpy(tmp.signature, signature, sizeof(tmp.signature)); + +- ret = ioctl(fd, DBCIOCNONCE, &tmp); +- if (ret) +- return ret; ++ if (ioctl(fd, DBCIOCNONCE, &tmp)) ++ return errno; + memcpy(nonce_out, tmp.nonce, sizeof(tmp.nonce)); + + return 0; +@@ -47,7 +46,9 @@ int set_uid(int fd, __u8 *uid, __u8 *signature) + memcpy(tmp.uid, uid, sizeof(tmp.uid)); + memcpy(tmp.signature, signature, sizeof(tmp.signature)); + +- return ioctl(fd, DBCIOCUID, &tmp); ++ if (ioctl(fd, DBCIOCUID, &tmp)) ++ return errno; ++ return 0; + } + + int process_param(int fd, int msg_index, __u8 *signature, int *data) +@@ -63,9 +64,8 @@ int process_param(int fd, int msg_index, __u8 *signature, int *data) + + memcpy(tmp.signature, signature, sizeof(tmp.signature)); + +- ret = ioctl(fd, DBCIOCPARAM, &tmp); +- if (ret) +- return ret; ++ if (ioctl(fd, DBCIOCPARAM, &tmp)) ++ return errno; + + *data = tmp.param; + return 0; +diff --git a/tools/crypto/ccp/dbc.py b/tools/crypto/ccp/dbc.py +index 3f6a825ffc9e4..3956efe7537ac 100644 +--- a/tools/crypto/ccp/dbc.py ++++ b/tools/crypto/ccp/dbc.py +@@ -27,8 +27,7 @@ lib = ctypes.CDLL("./dbc_library.so", mode=ctypes.RTLD_GLOBAL) + + + def handle_error(code): +- val = code * -1 +- raise OSError(val, os.strerror(val)) ++ raise OSError(code, os.strerror(code)) + + + def get_nonce(device, signature): +-- +2.42.0 + diff --git a/queue-6.6/crypto-ccp-fix-ioctl-unit-tests.patch b/queue-6.6/crypto-ccp-fix-ioctl-unit-tests.patch new file mode 100644 index 00000000000..c539bc04c84 --- /dev/null +++ b/queue-6.6/crypto-ccp-fix-ioctl-unit-tests.patch @@ -0,0 +1,94 @@ +From d2c3fe584ad6d8ea0f57479e51ec8f37cae7f6dd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Aug 2023 10:07:56 -0500 +Subject: crypto: ccp - Fix ioctl unit tests + +From: Mario Limonciello + +[ Upstream commit 7f71c3e033824e1da237916a1885e3c0699f86b2 ] + +A local environment change was importing ioctl_opt which is required +for ioctl tests to pass. Add the missing import for it. + +Fixes: 15f8aa7bb3e5 ("crypto: ccp - Add unit tests for dynamic boost control") +Signed-off-by: Mario Limonciello +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + tools/crypto/ccp/test_dbc.py | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +diff --git a/tools/crypto/ccp/test_dbc.py b/tools/crypto/ccp/test_dbc.py +index 998bb3e3cd040..a28a1f94c1d2f 100755 +--- a/tools/crypto/ccp/test_dbc.py ++++ b/tools/crypto/ccp/test_dbc.py +@@ -4,6 +4,12 @@ import unittest + import os + import time + import glob ++import fcntl ++try: ++ import ioctl_opt as ioctl ++except ImportError: ++ ioctl = None ++ pass + from dbc import * + + # Artificial delay between set commands +@@ -64,13 +70,16 @@ class TestInvalidIoctls(DynamicBoostControlTest): + def setUp(self) -> None: + if not os.path.exists(DEVICE_NODE): + self.skipTest("system is unsupported") ++ if not ioctl: ++ self.skipTest("unable to test IOCTLs without ioctl_opt") ++ + return super().setUp() + + def test_invalid_nonce_ioctl(self) -> None: + """tries to call get_nonce ioctl with invalid data structures""" + + # 0x1 (get nonce), and invalid data +- INVALID1 = IOWR(ord("D"), 0x01, invalid_param) ++ INVALID1 = ioctl.IOWR(ord("D"), 0x01, invalid_param) + with self.assertRaises(OSError) as error: + fcntl.ioctl(self.d, INVALID1, self.data, True) + self.assertEqual(error.exception.errno, 22) +@@ -79,7 +88,7 @@ class TestInvalidIoctls(DynamicBoostControlTest): + """tries to call set_uid ioctl with invalid data structures""" + + # 0x2 (set uid), and invalid data +- INVALID2 = IOW(ord("D"), 0x02, invalid_param) ++ INVALID2 = ioctl.IOW(ord("D"), 0x02, invalid_param) + with self.assertRaises(OSError) as error: + fcntl.ioctl(self.d, INVALID2, self.data, True) + self.assertEqual(error.exception.errno, 22) +@@ -88,7 +97,7 @@ class TestInvalidIoctls(DynamicBoostControlTest): + """tries to call set_uid ioctl with invalid data structures""" + + # 0x2 as RW (set uid), and invalid data +- INVALID3 = IOWR(ord("D"), 0x02, invalid_param) ++ INVALID3 = ioctl.IOWR(ord("D"), 0x02, invalid_param) + with self.assertRaises(OSError) as error: + fcntl.ioctl(self.d, INVALID3, self.data, True) + self.assertEqual(error.exception.errno, 22) +@@ -96,7 +105,7 @@ class TestInvalidIoctls(DynamicBoostControlTest): + def test_invalid_param_ioctl(self) -> None: + """tries to call param ioctl with invalid data structures""" + # 0x3 (param), and invalid data +- INVALID4 = IOWR(ord("D"), 0x03, invalid_param) ++ INVALID4 = ioctl.IOWR(ord("D"), 0x03, invalid_param) + with self.assertRaises(OSError) as error: + fcntl.ioctl(self.d, INVALID4, self.data, True) + self.assertEqual(error.exception.errno, 22) +@@ -104,7 +113,7 @@ class TestInvalidIoctls(DynamicBoostControlTest): + def test_invalid_call_ioctl(self) -> None: + """tries to call the DBC ioctl with invalid data structures""" + # 0x4, and invalid data +- INVALID5 = IOWR(ord("D"), 0x04, invalid_param) ++ INVALID5 = ioctl.IOWR(ord("D"), 0x04, invalid_param) + with self.assertRaises(OSError) as error: + fcntl.ioctl(self.d, INVALID5, self.data, True) + self.assertEqual(error.exception.errno, 22) +-- +2.42.0 + diff --git a/queue-6.6/crypto-ccp-fix-sample-application-signature-passing.patch b/queue-6.6/crypto-ccp-fix-sample-application-signature-passing.patch new file mode 100644 index 00000000000..dbc249a2ec2 --- /dev/null +++ b/queue-6.6/crypto-ccp-fix-sample-application-signature-passing.patch @@ -0,0 +1,54 @@ +From 5d9535771da282c2e9641112633213a022577ac5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Aug 2023 10:07:58 -0500 +Subject: crypto: ccp - Fix sample application signature passing + +From: Mario Limonciello + +[ Upstream commit 2ad01eb5fad24627ab4e196dc54a220753b2238b ] + +When parameters are sent the PSP returns back it's own signature +for the application to verify the authenticity of the result. + +Display this signature to the caller instead of the one the caller +sent. + +Fixes: f40d42f116cf ("crypto: ccp - Add a sample python script for Dynamic Boost Control") +Fixes: febe3ed3222f ("crypto: ccp - Add a sample library for ioctl use") +Signed-off-by: Mario Limonciello +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + tools/crypto/ccp/dbc.c | 1 + + tools/crypto/ccp/dbc.py | 5 +++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/tools/crypto/ccp/dbc.c b/tools/crypto/ccp/dbc.c +index 7774e981849fa..a807df0f05974 100644 +--- a/tools/crypto/ccp/dbc.c ++++ b/tools/crypto/ccp/dbc.c +@@ -68,5 +68,6 @@ int process_param(int fd, int msg_index, __u8 *signature, int *data) + return errno; + + *data = tmp.param; ++ memcpy(signature, tmp.signature, sizeof(tmp.signature)); + return 0; + } +diff --git a/tools/crypto/ccp/dbc.py b/tools/crypto/ccp/dbc.py +index 3956efe7537ac..2b91415b19407 100644 +--- a/tools/crypto/ccp/dbc.py ++++ b/tools/crypto/ccp/dbc.py +@@ -57,7 +57,8 @@ def process_param(device, message, signature, data=None): + if type(message) != tuple: + raise ValueError("Expected message tuple") + arg = ctypes.c_int(data if data else 0) +- ret = lib.process_param(device.fileno(), message[0], signature, ctypes.pointer(arg)) ++ sig = ctypes.create_string_buffer(signature, len(signature)) ++ ret = lib.process_param(device.fileno(), message[0], ctypes.pointer(sig), ctypes.pointer(arg)) + if ret: + handle_error(ret) +- return arg, signature ++ return arg.value, sig.value +-- +2.42.0 + diff --git a/queue-6.6/crypto-ccp-fix-some-unfused-tests.patch b/queue-6.6/crypto-ccp-fix-some-unfused-tests.patch new file mode 100644 index 00000000000..31218d53a22 --- /dev/null +++ b/queue-6.6/crypto-ccp-fix-some-unfused-tests.patch @@ -0,0 +1,108 @@ +From b8533a86a63260bde7013551bcbf6a4804cb8a6e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Aug 2023 10:07:59 -0500 +Subject: crypto: ccp - Fix some unfused tests + +From: Mario Limonciello + +[ Upstream commit 7b3c2348d314a18f6ed84bab67023ae5d1ec6b1e ] + +Some of the tests for unfused parts referenced a named member parameter, +but when the test suite was switched to call a python ctypes library they +weren't updated. Adjust them to refer to the first argument of the +process_param() call and set the data type of the signature appropriately. + +Fixes: 15f8aa7bb3e5 ("crypto: ccp - Add unit tests for dynamic boost control") +Signed-off-by: Mario Limonciello +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + tools/crypto/ccp/test_dbc.py | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/tools/crypto/ccp/test_dbc.py b/tools/crypto/ccp/test_dbc.py +index a28a1f94c1d2f..79de3638a01ab 100755 +--- a/tools/crypto/ccp/test_dbc.py ++++ b/tools/crypto/ccp/test_dbc.py +@@ -33,8 +33,8 @@ def system_is_secured() -> bool: + class DynamicBoostControlTest(unittest.TestCase): + def __init__(self, data) -> None: + self.d = None +- self.signature = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" +- self.uid = "1111111111111111" ++ self.signature = b"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" ++ self.uid = b"1111111111111111" + super().__init__(data) + + def setUp(self) -> None: +@@ -192,12 +192,12 @@ class TestUnFusedSystem(DynamicBoostControlTest): + # SOC power + soc_power_max = process_param(self.d, PARAM_GET_SOC_PWR_MAX, self.signature) + soc_power_min = process_param(self.d, PARAM_GET_SOC_PWR_MIN, self.signature) +- self.assertGreater(soc_power_max.parameter, soc_power_min.parameter) ++ self.assertGreater(soc_power_max[0], soc_power_min[0]) + + # fmax + fmax_max = process_param(self.d, PARAM_GET_FMAX_MAX, self.signature) + fmax_min = process_param(self.d, PARAM_GET_FMAX_MIN, self.signature) +- self.assertGreater(fmax_max.parameter, fmax_min.parameter) ++ self.assertGreater(fmax_max[0], fmax_min[0]) + + # cap values + keys = { +@@ -208,7 +208,7 @@ class TestUnFusedSystem(DynamicBoostControlTest): + } + for k in keys: + result = process_param(self.d, keys[k], self.signature) +- self.assertGreater(result.parameter, 0) ++ self.assertGreater(result[0], 0) + + def test_get_invalid_param(self) -> None: + """fetch an invalid parameter""" +@@ -226,17 +226,17 @@ class TestUnFusedSystem(DynamicBoostControlTest): + original = process_param(self.d, PARAM_GET_FMAX_CAP, self.signature) + + # set the fmax +- target = original.parameter - 100 ++ target = original[0] - 100 + process_param(self.d, PARAM_SET_FMAX_CAP, self.signature, target) + time.sleep(SET_DELAY) + new = process_param(self.d, PARAM_GET_FMAX_CAP, self.signature) +- self.assertEqual(new.parameter, target) ++ self.assertEqual(new[0], target) + + # revert back to current +- process_param(self.d, PARAM_SET_FMAX_CAP, self.signature, original.parameter) ++ process_param(self.d, PARAM_SET_FMAX_CAP, self.signature, original[0]) + time.sleep(SET_DELAY) + cur = process_param(self.d, PARAM_GET_FMAX_CAP, self.signature) +- self.assertEqual(cur.parameter, original.parameter) ++ self.assertEqual(cur[0], original[0]) + + def test_set_power_cap(self) -> None: + """get/set power cap limit""" +@@ -244,17 +244,17 @@ class TestUnFusedSystem(DynamicBoostControlTest): + original = process_param(self.d, PARAM_GET_PWR_CAP, self.signature) + + # set the fmax +- target = original.parameter - 10 ++ target = original[0] - 10 + process_param(self.d, PARAM_SET_PWR_CAP, self.signature, target) + time.sleep(SET_DELAY) + new = process_param(self.d, PARAM_GET_PWR_CAP, self.signature) +- self.assertEqual(new.parameter, target) ++ self.assertEqual(new[0], target) + + # revert back to current +- process_param(self.d, PARAM_SET_PWR_CAP, self.signature, original.parameter) ++ process_param(self.d, PARAM_SET_PWR_CAP, self.signature, original[0]) + time.sleep(SET_DELAY) + cur = process_param(self.d, PARAM_GET_PWR_CAP, self.signature) +- self.assertEqual(cur.parameter, original.parameter) ++ self.assertEqual(cur[0], original[0]) + + def test_set_3d_graphics_mode(self) -> None: + """set/get 3d graphics mode""" +-- +2.42.0 + diff --git a/queue-6.6/crypto-ccp-get-a-free-page-to-use-while-fetching-ini.patch b/queue-6.6/crypto-ccp-get-a-free-page-to-use-while-fetching-ini.patch new file mode 100644 index 00000000000..afc805620ad --- /dev/null +++ b/queue-6.6/crypto-ccp-get-a-free-page-to-use-while-fetching-ini.patch @@ -0,0 +1,38 @@ +From a06b894e4597ddc0ddf686a946e0497d9894491a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Aug 2023 10:07:55 -0500 +Subject: crypto: ccp - Get a free page to use while fetching initial nonce + +From: Mario Limonciello + +[ Upstream commit 53f7f779f45cbe1771bc4ae05f0320e204a18611 ] + +dbc_dev_init() gets a free page from `GFP_KERNEL`, but if that page has +any data in it the first nonce request will fail. +This prevents dynamic boost control from probing. To fix this, explicitly +request a zeroed page with `__GFP_ZERO` to ensure first nonce fetch works. + +Fixes: c04cf9e14f10 ("crypto: ccp - Add support for fetching a nonce for dynamic boost control") +Signed-off-by: Mario Limonciello +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/ccp/dbc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/crypto/ccp/dbc.c b/drivers/crypto/ccp/dbc.c +index 839ea14b9a853..6f33149ef80df 100644 +--- a/drivers/crypto/ccp/dbc.c ++++ b/drivers/crypto/ccp/dbc.c +@@ -205,7 +205,7 @@ int dbc_dev_init(struct psp_device *psp) + return -ENOMEM; + + BUILD_BUG_ON(sizeof(union dbc_buffer) > PAGE_SIZE); +- dbc_dev->mbox = (void *)devm_get_free_pages(dev, GFP_KERNEL, 0); ++ dbc_dev->mbox = (void *)devm_get_free_pages(dev, GFP_KERNEL | __GFP_ZERO, 0); + if (!dbc_dev->mbox) { + ret = -ENOMEM; + goto cleanup_dev; +-- +2.42.0 + diff --git a/queue-6.6/crypto-hisilicon-hpre-fix-a-erroneous-check-after-sn.patch b/queue-6.6/crypto-hisilicon-hpre-fix-a-erroneous-check-after-sn.patch new file mode 100644 index 00000000000..d4fc647203b --- /dev/null +++ b/queue-6.6/crypto-hisilicon-hpre-fix-a-erroneous-check-after-sn.patch @@ -0,0 +1,36 @@ +From 47d535cb8ee6a3a99620bfd9ee5d870ea92616d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 22:17:29 +0200 +Subject: crypto: hisilicon/hpre - Fix a erroneous check after snprintf() + +From: Christophe JAILLET + +[ Upstream commit c977950146720abff14e46d8c53f5638b06a9182 ] + +This error handling looks really strange. +Check if the string has been truncated instead. + +Fixes: 02ab994635eb ("crypto: hisilicon - Fixed some tiny bugs of HPRE") +Signed-off-by: Christophe JAILLET +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/hisilicon/hpre/hpre_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c +index 39297ce70f441..db44d889438a6 100644 +--- a/drivers/crypto/hisilicon/hpre/hpre_main.c ++++ b/drivers/crypto/hisilicon/hpre/hpre_main.c +@@ -1033,7 +1033,7 @@ static int hpre_cluster_debugfs_init(struct hisi_qm *qm) + + for (i = 0; i < clusters_num; i++) { + ret = snprintf(buf, HPRE_DBGFS_VAL_MAX_LEN, "cluster%d", i); +- if (ret < 0) ++ if (ret >= HPRE_DBGFS_VAL_MAX_LEN) + return -EINVAL; + tmp_d = debugfs_create_dir(buf, qm->debug.debug_root); + +-- +2.42.0 + diff --git a/queue-6.6/crypto-hisilicon-qm-fix-pf-queue-parameter-issue.patch b/queue-6.6/crypto-hisilicon-qm-fix-pf-queue-parameter-issue.patch new file mode 100644 index 00000000000..6c1612ad13c --- /dev/null +++ b/queue-6.6/crypto-hisilicon-qm-fix-pf-queue-parameter-issue.patch @@ -0,0 +1,196 @@ +From 791bce3976c78d93a8e05452b743e3f71c8920fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Sep 2023 16:57:22 +0800 +Subject: crypto: hisilicon/qm - fix PF queue parameter issue + +From: Longfang Liu + +[ Upstream commit 5831fc1fd4a578232fea708b82de0c666ed17153 ] + +If the queue isolation feature is enabled, the number of queues +supported by the device changes. When PF is enabled using the +current default number of queues, the default number of queues may +be greater than the number supported by the device. As a result, +the PF fails to be bound to the driver. + +After modification, if queue isolation feature is enabled, when +the default queue parameter is greater than the number supported +by the device, the number of enabled queues will be changed to +the number supported by the device, so that the PF and driver +can be properly bound. + +Fixes: 8bbecfb402f7 ("crypto: hisilicon/qm - add queue isolation support for Kunpeng930") +Signed-off-by: Longfang Liu +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/hisilicon/hpre/hpre_main.c | 5 +++++ + drivers/crypto/hisilicon/qm.c | 18 ++++++++++++------ + drivers/crypto/hisilicon/qm_common.h | 1 - + drivers/crypto/hisilicon/sec2/sec_main.c | 5 +++++ + drivers/crypto/hisilicon/zip/zip_main.c | 5 +++++ + include/linux/hisi_acc_qm.h | 7 +++++++ + 6 files changed, 34 insertions(+), 7 deletions(-) + +diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c +index db44d889438a6..3dce35debf637 100644 +--- a/drivers/crypto/hisilicon/hpre/hpre_main.c ++++ b/drivers/crypto/hisilicon/hpre/hpre_main.c +@@ -433,8 +433,11 @@ static u32 uacce_mode = UACCE_MODE_NOUACCE; + module_param_cb(uacce_mode, &hpre_uacce_mode_ops, &uacce_mode, 0444); + MODULE_PARM_DESC(uacce_mode, UACCE_MODE_DESC); + ++static bool pf_q_num_flag; + static int pf_q_num_set(const char *val, const struct kernel_param *kp) + { ++ pf_q_num_flag = true; ++ + return q_num_set(val, kp, PCI_DEVICE_ID_HUAWEI_HPRE_PF); + } + +@@ -1157,6 +1160,8 @@ static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) + qm->qp_num = pf_q_num; + qm->debug.curr_qm_qp_num = pf_q_num; + qm->qm_list = &hpre_devices; ++ if (pf_q_num_flag) ++ set_bit(QM_MODULE_PARAM, &qm->misc_ctl); + } + + ret = hisi_qm_init(qm); +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index a99fd589445ce..1638c0a7df310 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -206,8 +206,6 @@ + #define WAIT_PERIOD 20 + #define REMOVE_WAIT_DELAY 10 + +-#define QM_DRIVER_REMOVING 0 +-#define QM_RST_SCHED 1 + #define QM_QOS_PARAM_NUM 2 + #define QM_QOS_MAX_VAL 1000 + #define QM_QOS_RATE 100 +@@ -2824,7 +2822,6 @@ static void hisi_qm_pre_init(struct hisi_qm *qm) + mutex_init(&qm->mailbox_lock); + init_rwsem(&qm->qps_lock); + qm->qp_in_used = 0; +- qm->misc_ctl = false; + if (test_bit(QM_SUPPORT_RPM, &qm->caps)) { + if (!acpi_device_power_manageable(ACPI_COMPANION(&pdev->dev))) + dev_info(&pdev->dev, "_PS0 and _PR0 are not defined"); +@@ -5093,6 +5090,7 @@ static int qm_irqs_register(struct hisi_qm *qm) + + static int qm_get_qp_num(struct hisi_qm *qm) + { ++ struct device *dev = &qm->pdev->dev; + bool is_db_isolation; + + /* VF's qp_num assigned by PF in v2, and VF can get qp_num by vft. */ +@@ -5109,13 +5107,21 @@ static int qm_get_qp_num(struct hisi_qm *qm) + qm->max_qp_num = hisi_qm_get_hw_info(qm, qm_basic_info, + QM_FUNC_MAX_QP_CAP, is_db_isolation); + +- /* check if qp number is valid */ +- if (qm->qp_num > qm->max_qp_num) { +- dev_err(&qm->pdev->dev, "qp num(%u) is more than max qp num(%u)!\n", ++ if (qm->qp_num <= qm->max_qp_num) ++ return 0; ++ ++ if (test_bit(QM_MODULE_PARAM, &qm->misc_ctl)) { ++ /* Check whether the set qp number is valid */ ++ dev_err(dev, "qp num(%u) is more than max qp num(%u)!\n", + qm->qp_num, qm->max_qp_num); + return -EINVAL; + } + ++ dev_info(dev, "Default qp num(%u) is too big, reset it to Function's max qp num(%u)!\n", ++ qm->qp_num, qm->max_qp_num); ++ qm->qp_num = qm->max_qp_num; ++ qm->debug.curr_qm_qp_num = qm->qp_num; ++ + return 0; + } + +diff --git a/drivers/crypto/hisilicon/qm_common.h b/drivers/crypto/hisilicon/qm_common.h +index 1406a422d4551..8e36aa9c681be 100644 +--- a/drivers/crypto/hisilicon/qm_common.h ++++ b/drivers/crypto/hisilicon/qm_common.h +@@ -4,7 +4,6 @@ + #define QM_COMMON_H + + #define QM_DBG_READ_LEN 256 +-#define QM_RESETTING 2 + + struct qm_cqe { + __le32 rsvd0; +diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c +index 77f9f131b8503..62bd8936a9154 100644 +--- a/drivers/crypto/hisilicon/sec2/sec_main.c ++++ b/drivers/crypto/hisilicon/sec2/sec_main.c +@@ -311,8 +311,11 @@ static int sec_diff_regs_show(struct seq_file *s, void *unused) + } + DEFINE_SHOW_ATTRIBUTE(sec_diff_regs); + ++static bool pf_q_num_flag; + static int sec_pf_q_num_set(const char *val, const struct kernel_param *kp) + { ++ pf_q_num_flag = true; ++ + return q_num_set(val, kp, PCI_DEVICE_ID_HUAWEI_SEC_PF); + } + +@@ -1120,6 +1123,8 @@ static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) + qm->qp_num = pf_q_num; + qm->debug.curr_qm_qp_num = pf_q_num; + qm->qm_list = &sec_devices; ++ if (pf_q_num_flag) ++ set_bit(QM_MODULE_PARAM, &qm->misc_ctl); + } else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) { + /* + * have no way to get qm configure in VM in v1 hardware, +diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c +index f3ce34198775d..84dbaeb07ea83 100644 +--- a/drivers/crypto/hisilicon/zip/zip_main.c ++++ b/drivers/crypto/hisilicon/zip/zip_main.c +@@ -364,8 +364,11 @@ static u32 uacce_mode = UACCE_MODE_NOUACCE; + module_param_cb(uacce_mode, &zip_uacce_mode_ops, &uacce_mode, 0444); + MODULE_PARM_DESC(uacce_mode, UACCE_MODE_DESC); + ++static bool pf_q_num_flag; + static int pf_q_num_set(const char *val, const struct kernel_param *kp) + { ++ pf_q_num_flag = true; ++ + return q_num_set(val, kp, PCI_DEVICE_ID_HUAWEI_ZIP_PF); + } + +@@ -1139,6 +1142,8 @@ static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) + qm->qp_num = pf_q_num; + qm->debug.curr_qm_qp_num = pf_q_num; + qm->qm_list = &zip_devices; ++ if (pf_q_num_flag) ++ set_bit(QM_MODULE_PARAM, &qm->misc_ctl); + } else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) { + /* + * have no way to get qm configure in VM in v1 hardware, +diff --git a/include/linux/hisi_acc_qm.h b/include/linux/hisi_acc_qm.h +index 39fbfb4be944b..9da4f3f1e6d61 100644 +--- a/include/linux/hisi_acc_qm.h ++++ b/include/linux/hisi_acc_qm.h +@@ -144,6 +144,13 @@ enum qm_vf_state { + QM_NOT_READY, + }; + ++enum qm_misc_ctl_bits { ++ QM_DRIVER_REMOVING = 0x0, ++ QM_RST_SCHED, ++ QM_RESETTING, ++ QM_MODULE_PARAM, ++}; ++ + enum qm_cap_bits { + QM_SUPPORT_DB_ISOLATION = 0x0, + QM_SUPPORT_FUNC_QOS, +-- +2.42.0 + diff --git a/queue-6.6/crypto-qat-consolidate-services-structure.patch b/queue-6.6/crypto-qat-consolidate-services-structure.patch new file mode 100644 index 00000000000..6cc477a2cd7 --- /dev/null +++ b/queue-6.6/crypto-qat-consolidate-services-structure.patch @@ -0,0 +1,236 @@ +From 4c14770b89b6afaaae5cc89d52be1ff005af2221 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 15:14:12 +0100 +Subject: crypto: qat - consolidate services structure + +From: Giovanni Cabiddu + +[ Upstream commit 71713766380712c8ab2d604605e7b0b20f977801 ] + +The data structure that associates a service id with its name is +replicated across the driver. +Remove duplication by moving this data structure to a new include file, +adf_cfg_services.h in order to have consistency across the drivers. + +Note that the data structure is re-instantiated every time the new +include is added to a compilation unit. + +Signed-off-by: Giovanni Cabiddu +Reviewed-by: Andy Shevchenko +Signed-off-by: Herbert Xu +Stable-dep-of: a238487f7965 ("crypto: qat - fix ring to service map for QAT GEN4") +Signed-off-by: Sasha Levin +--- + .../intel/qat/qat_4xxx/adf_4xxx_hw_data.c | 27 ++------------- + drivers/crypto/intel/qat/qat_4xxx/adf_drv.c | 33 +++---------------- + .../intel/qat/qat_common/adf_cfg_services.h | 32 ++++++++++++++++++ + .../crypto/intel/qat/qat_common/adf_sysfs.c | 17 ++-------- + 4 files changed, 42 insertions(+), 67 deletions(-) + create mode 100644 drivers/crypto/intel/qat/qat_common/adf_cfg_services.h + +diff --git a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c +index dd4464b7e00b1..cc2285b9f17b4 100644 +--- a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c ++++ b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c +@@ -11,6 +11,7 @@ + #include + #include + #include "adf_4xxx_hw_data.h" ++#include "adf_cfg_services.h" + #include "icp_qat_hw.h" + + enum adf_fw_objs { +@@ -100,30 +101,6 @@ static struct adf_hw_device_class adf_4xxx_class = { + .instances = 0, + }; + +-enum dev_services { +- SVC_CY = 0, +- SVC_CY2, +- SVC_DC, +- SVC_SYM, +- SVC_ASYM, +- SVC_DC_ASYM, +- SVC_ASYM_DC, +- SVC_DC_SYM, +- SVC_SYM_DC, +-}; +- +-static const char *const dev_cfg_services[] = { +- [SVC_CY] = ADF_CFG_CY, +- [SVC_CY2] = ADF_CFG_ASYM_SYM, +- [SVC_DC] = ADF_CFG_DC, +- [SVC_SYM] = ADF_CFG_SYM, +- [SVC_ASYM] = ADF_CFG_ASYM, +- [SVC_DC_ASYM] = ADF_CFG_DC_ASYM, +- [SVC_ASYM_DC] = ADF_CFG_ASYM_DC, +- [SVC_DC_SYM] = ADF_CFG_DC_SYM, +- [SVC_SYM_DC] = ADF_CFG_SYM_DC, +-}; +- + static int get_service_enabled(struct adf_accel_dev *accel_dev) + { + char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0}; +@@ -137,7 +114,7 @@ static int get_service_enabled(struct adf_accel_dev *accel_dev) + return ret; + } + +- ret = match_string(dev_cfg_services, ARRAY_SIZE(dev_cfg_services), ++ ret = match_string(adf_cfg_services, ARRAY_SIZE(adf_cfg_services), + services); + if (ret < 0) + dev_err(&GET_DEV(accel_dev), +diff --git a/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c +index 6d4e2e139ffa2..204a00a204f2d 100644 +--- a/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c ++++ b/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c +@@ -11,6 +11,7 @@ + #include + + #include "adf_4xxx_hw_data.h" ++#include "adf_cfg_services.h" + #include "qat_compression.h" + #include "qat_crypto.h" + #include "adf_transport_access_macros.h" +@@ -23,30 +24,6 @@ static const struct pci_device_id adf_pci_tbl[] = { + }; + MODULE_DEVICE_TABLE(pci, adf_pci_tbl); + +-enum configs { +- DEV_CFG_CY = 0, +- DEV_CFG_DC, +- DEV_CFG_SYM, +- DEV_CFG_ASYM, +- DEV_CFG_ASYM_SYM, +- DEV_CFG_ASYM_DC, +- DEV_CFG_DC_ASYM, +- DEV_CFG_SYM_DC, +- DEV_CFG_DC_SYM, +-}; +- +-static const char * const services_operations[] = { +- ADF_CFG_CY, +- ADF_CFG_DC, +- ADF_CFG_SYM, +- ADF_CFG_ASYM, +- ADF_CFG_ASYM_SYM, +- ADF_CFG_ASYM_DC, +- ADF_CFG_DC_ASYM, +- ADF_CFG_SYM_DC, +- ADF_CFG_DC_SYM, +-}; +- + static void adf_cleanup_accel(struct adf_accel_dev *accel_dev) + { + if (accel_dev->hw_device) { +@@ -292,16 +269,16 @@ int adf_gen4_dev_config(struct adf_accel_dev *accel_dev) + if (ret) + goto err; + +- ret = sysfs_match_string(services_operations, services); ++ ret = sysfs_match_string(adf_cfg_services, services); + if (ret < 0) + goto err; + + switch (ret) { +- case DEV_CFG_CY: +- case DEV_CFG_ASYM_SYM: ++ case SVC_CY: ++ case SVC_CY2: + ret = adf_crypto_dev_config(accel_dev); + break; +- case DEV_CFG_DC: ++ case SVC_DC: + ret = adf_comp_dev_config(accel_dev); + break; + default: +diff --git a/drivers/crypto/intel/qat/qat_common/adf_cfg_services.h b/drivers/crypto/intel/qat/qat_common/adf_cfg_services.h +new file mode 100644 +index 0000000000000..7fcb3b8f148a6 +--- /dev/null ++++ b/drivers/crypto/intel/qat/qat_common/adf_cfg_services.h +@@ -0,0 +1,32 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* Copyright(c) 2023 Intel Corporation */ ++#ifndef _ADF_CFG_SERVICES_H_ ++#define _ADF_CFG_SERVICES_H_ ++ ++#include "adf_cfg_strings.h" ++ ++enum adf_services { ++ SVC_CY = 0, ++ SVC_CY2, ++ SVC_DC, ++ SVC_SYM, ++ SVC_ASYM, ++ SVC_DC_ASYM, ++ SVC_ASYM_DC, ++ SVC_DC_SYM, ++ SVC_SYM_DC, ++}; ++ ++static const char *const adf_cfg_services[] = { ++ [SVC_CY] = ADF_CFG_CY, ++ [SVC_CY2] = ADF_CFG_ASYM_SYM, ++ [SVC_DC] = ADF_CFG_DC, ++ [SVC_SYM] = ADF_CFG_SYM, ++ [SVC_ASYM] = ADF_CFG_ASYM, ++ [SVC_DC_ASYM] = ADF_CFG_DC_ASYM, ++ [SVC_ASYM_DC] = ADF_CFG_ASYM_DC, ++ [SVC_DC_SYM] = ADF_CFG_DC_SYM, ++ [SVC_SYM_DC] = ADF_CFG_SYM_DC, ++}; ++ ++#endif +diff --git a/drivers/crypto/intel/qat/qat_common/adf_sysfs.c b/drivers/crypto/intel/qat/qat_common/adf_sysfs.c +index 8880af1aa1b5b..8f04b0d3c5ac8 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_sysfs.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_sysfs.c +@@ -5,6 +5,7 @@ + #include + #include "adf_accel_devices.h" + #include "adf_cfg.h" ++#include "adf_cfg_services.h" + #include "adf_common_drv.h" + + static const char * const state_operations[] = { +@@ -84,18 +85,6 @@ static ssize_t state_store(struct device *dev, struct device_attribute *attr, + return count; + } + +-static const char * const services_operations[] = { +- ADF_CFG_CY, +- ADF_CFG_DC, +- ADF_CFG_SYM, +- ADF_CFG_ASYM, +- ADF_CFG_ASYM_SYM, +- ADF_CFG_ASYM_DC, +- ADF_CFG_DC_ASYM, +- ADF_CFG_SYM_DC, +- ADF_CFG_DC_SYM, +-}; +- + static ssize_t cfg_services_show(struct device *dev, struct device_attribute *attr, + char *buf) + { +@@ -130,7 +119,7 @@ static ssize_t cfg_services_store(struct device *dev, struct device_attribute *a + struct adf_accel_dev *accel_dev; + int ret; + +- ret = sysfs_match_string(services_operations, buf); ++ ret = sysfs_match_string(adf_cfg_services, buf); + if (ret < 0) + return ret; + +@@ -144,7 +133,7 @@ static ssize_t cfg_services_store(struct device *dev, struct device_attribute *a + return -EINVAL; + } + +- ret = adf_sysfs_update_dev_config(accel_dev, services_operations[ret]); ++ ret = adf_sysfs_update_dev_config(accel_dev, adf_cfg_services[ret]); + if (ret < 0) + return ret; + +-- +2.42.0 + diff --git a/queue-6.6/crypto-qat-enable-dc-chaining-service.patch b/queue-6.6/crypto-qat-enable-dc-chaining-service.patch new file mode 100644 index 00000000000..c68495be385 --- /dev/null +++ b/queue-6.6/crypto-qat-enable-dc-chaining-service.patch @@ -0,0 +1,283 @@ +From 751b9c0bc59388486c961a993e9bfa936c27e81c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 15:14:13 +0100 +Subject: crypto: qat - enable dc chaining service + +From: Adam Guerin + +[ Upstream commit 37b14f2dfa791fd485dbc536f8d1ffe8c6990290 ] + +QAT GEN4 devices support chained compression operations. These +allow, with a single request to firmware, to hash then compress +data. + +Extend the configuration to enable such mode. The cfg_services +operations in sysfs are extended to allow the string "dcc". When +selected, the driver downloads to the device both the symmetric +crypto and the compression firmware images and sends an admin message +to firmware which enables `chained` operations. +In addition, it sets the device's capabilities as the combination +of compression and symmetric crypto capabilities, while excluding +the ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC bit to indicate +that in this mode, symmetric crypto instances are not supported. + +When "dcc" is enabled, the device will handle compression requests +as if the "dc" configuration is loaded ("dcc" is a variation of "dc") +and the driver will register the acomp algorithms. + +As for the other extended configurations, "dcc" is only available for +qat_4xxx devices and the chaining service will be only accessible from +user space. + +Signed-off-by: Adam Guerin +Reviewed-by: Giovanni Cabiddu +Signed-off-by: Herbert Xu +Stable-dep-of: a238487f7965 ("crypto: qat - fix ring to service map for QAT GEN4") +Signed-off-by: Sasha Levin +--- + Documentation/ABI/testing/sysfs-driver-qat | 2 + + .../intel/qat/qat_4xxx/adf_4xxx_hw_data.c | 29 ++++++++++++++ + drivers/crypto/intel/qat/qat_4xxx/adf_drv.c | 1 + + .../crypto/intel/qat/qat_common/adf_admin.c | 39 +++++++++++++++++-- + .../intel/qat/qat_common/adf_cfg_services.h | 2 + + .../intel/qat/qat_common/adf_cfg_strings.h | 1 + + .../qat/qat_common/icp_qat_fw_init_admin.h | 1 + + 7 files changed, 71 insertions(+), 4 deletions(-) + +diff --git a/Documentation/ABI/testing/sysfs-driver-qat b/Documentation/ABI/testing/sysfs-driver-qat +index ef6d6c57105ef..96834d103a09e 100644 +--- a/Documentation/ABI/testing/sysfs-driver-qat ++++ b/Documentation/ABI/testing/sysfs-driver-qat +@@ -29,6 +29,8 @@ Description: (RW) Reports the current configuration of the QAT device. + services + * asym;sym: identical to sym;asym + * dc: the device is configured for running compression services ++ * dcc: identical to dc but enables the dc chaining feature, ++ hash then compression. If this is not required chose dc + * sym: the device is configured for running symmetric crypto + services + * asym: the device is configured for running asymmetric crypto +diff --git a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c +index cc2285b9f17b4..12b5d18191119 100644 +--- a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c ++++ b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c +@@ -76,11 +76,18 @@ static const struct adf_fw_config adf_fw_sym_dc_config[] = { + {0x100, ADF_FW_ADMIN_OBJ}, + }; + ++static const struct adf_fw_config adf_fw_dcc_config[] = { ++ {0xF0, ADF_FW_DC_OBJ}, ++ {0xF, ADF_FW_SYM_OBJ}, ++ {0x100, ADF_FW_ADMIN_OBJ}, ++}; ++ + static_assert(ARRAY_SIZE(adf_fw_cy_config) == ARRAY_SIZE(adf_fw_dc_config)); + static_assert(ARRAY_SIZE(adf_fw_cy_config) == ARRAY_SIZE(adf_fw_sym_config)); + static_assert(ARRAY_SIZE(adf_fw_cy_config) == ARRAY_SIZE(adf_fw_asym_config)); + static_assert(ARRAY_SIZE(adf_fw_cy_config) == ARRAY_SIZE(adf_fw_asym_dc_config)); + static_assert(ARRAY_SIZE(adf_fw_cy_config) == ARRAY_SIZE(adf_fw_sym_dc_config)); ++static_assert(ARRAY_SIZE(adf_fw_cy_config) == ARRAY_SIZE(adf_fw_dcc_config)); + + /* Worker thread to service arbiter mappings */ + static const u32 default_thrd_to_arb_map[ADF_4XXX_MAX_ACCELENGINES] = { +@@ -95,6 +102,12 @@ static const u32 thrd_to_arb_map_dc[ADF_4XXX_MAX_ACCELENGINES] = { + 0x0 + }; + ++static const u32 thrd_to_arb_map_dcc[ADF_4XXX_MAX_ACCELENGINES] = { ++ 0x00000000, 0x00000000, 0x00000000, 0x00000000, ++ 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, ++ 0x0 ++}; ++ + static struct adf_hw_device_class adf_4xxx_class = { + .name = ADF_4XXX_DEVICE_NAME, + .type = DEV_4XXX, +@@ -189,6 +202,7 @@ static u32 get_accel_cap(struct adf_accel_dev *accel_dev) + { + struct pci_dev *pdev = accel_dev->accel_pci_dev.pci_dev; + u32 capabilities_sym, capabilities_asym, capabilities_dc; ++ u32 capabilities_dcc; + u32 fusectl1; + + /* Read accelerator capabilities mask */ +@@ -261,6 +275,14 @@ static u32 get_accel_cap(struct adf_accel_dev *accel_dev) + return capabilities_sym | capabilities_asym; + case SVC_DC: + return capabilities_dc; ++ case SVC_DCC: ++ /* ++ * Sym capabilities are available for chaining operations, ++ * but sym crypto instances cannot be supported ++ */ ++ capabilities_dcc = capabilities_dc | capabilities_sym; ++ capabilities_dcc &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC; ++ return capabilities_dcc; + case SVC_SYM: + return capabilities_sym; + case SVC_ASYM: +@@ -286,6 +308,8 @@ static const u32 *adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev) + switch (get_service_enabled(accel_dev)) { + case SVC_DC: + return thrd_to_arb_map_dc; ++ case SVC_DCC: ++ return thrd_to_arb_map_dcc; + default: + return default_thrd_to_arb_map; + } +@@ -383,6 +407,9 @@ static const char *uof_get_name(struct adf_accel_dev *accel_dev, u32 obj_num, + case SVC_DC: + id = adf_fw_dc_config[obj_num].obj; + break; ++ case SVC_DCC: ++ id = adf_fw_dcc_config[obj_num].obj; ++ break; + case SVC_SYM: + id = adf_fw_sym_config[obj_num].obj; + break; +@@ -429,6 +456,8 @@ static u32 uof_get_ae_mask(struct adf_accel_dev *accel_dev, u32 obj_num) + return adf_fw_cy_config[obj_num].ae_mask; + case SVC_DC: + return adf_fw_dc_config[obj_num].ae_mask; ++ case SVC_DCC: ++ return adf_fw_dcc_config[obj_num].ae_mask; + case SVC_CY2: + return adf_fw_cy_config[obj_num].ae_mask; + case SVC_SYM: +diff --git a/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c +index 204a00a204f2d..90f5c1ca7b8d8 100644 +--- a/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c ++++ b/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c +@@ -279,6 +279,7 @@ int adf_gen4_dev_config(struct adf_accel_dev *accel_dev) + ret = adf_crypto_dev_config(accel_dev); + break; + case SVC_DC: ++ case SVC_DCC: + ret = adf_comp_dev_config(accel_dev); + break; + default: +diff --git a/drivers/crypto/intel/qat/qat_common/adf_admin.c b/drivers/crypto/intel/qat/qat_common/adf_admin.c +index ff790823b8686..194d64d4b99a1 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_admin.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_admin.c +@@ -8,6 +8,7 @@ + #include + #include "adf_accel_devices.h" + #include "adf_common_drv.h" ++#include "adf_cfg.h" + #include "adf_heartbeat.h" + #include "icp_qat_fw_init_admin.h" + +@@ -212,6 +213,17 @@ int adf_get_fw_timestamp(struct adf_accel_dev *accel_dev, u64 *timestamp) + return 0; + } + ++static int adf_set_chaining(struct adf_accel_dev *accel_dev) ++{ ++ u32 ae_mask = GET_HW_DATA(accel_dev)->ae_mask; ++ struct icp_qat_fw_init_admin_resp resp = { }; ++ struct icp_qat_fw_init_admin_req req = { }; ++ ++ req.cmd_id = ICP_QAT_FW_DC_CHAIN_INIT; ++ ++ return adf_send_admin(accel_dev, &req, &resp, ae_mask); ++} ++ + static int adf_get_dc_capabilities(struct adf_accel_dev *accel_dev, + u32 *capabilities) + { +@@ -284,6 +296,19 @@ int adf_send_admin_hb_timer(struct adf_accel_dev *accel_dev, uint32_t ticks) + return adf_send_admin(accel_dev, &req, &resp, ae_mask); + } + ++static bool is_dcc_enabled(struct adf_accel_dev *accel_dev) ++{ ++ char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0}; ++ int ret; ++ ++ ret = adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, ++ ADF_SERVICES_ENABLED, services); ++ if (ret) ++ return false; ++ ++ return !strcmp(services, "dcc"); ++} ++ + /** + * adf_send_admin_init() - Function sends init message to FW + * @accel_dev: Pointer to acceleration device. +@@ -297,6 +322,16 @@ int adf_send_admin_init(struct adf_accel_dev *accel_dev) + u32 dc_capabilities = 0; + int ret; + ++ ret = adf_set_fw_constants(accel_dev); ++ if (ret) ++ return ret; ++ ++ if (is_dcc_enabled(accel_dev)) { ++ ret = adf_set_chaining(accel_dev); ++ if (ret) ++ return ret; ++ } ++ + ret = adf_get_dc_capabilities(accel_dev, &dc_capabilities); + if (ret) { + dev_err(&GET_DEV(accel_dev), "Cannot get dc capabilities\n"); +@@ -304,10 +339,6 @@ int adf_send_admin_init(struct adf_accel_dev *accel_dev) + } + accel_dev->hw_device->extended_dc_capabilities = dc_capabilities; + +- ret = adf_set_fw_constants(accel_dev); +- if (ret) +- return ret; +- + return adf_init_ae(accel_dev); + } + EXPORT_SYMBOL_GPL(adf_send_admin_init); +diff --git a/drivers/crypto/intel/qat/qat_common/adf_cfg_services.h b/drivers/crypto/intel/qat/qat_common/adf_cfg_services.h +index 7fcb3b8f148a6..b353d40c5c6d0 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_cfg_services.h ++++ b/drivers/crypto/intel/qat/qat_common/adf_cfg_services.h +@@ -9,6 +9,7 @@ enum adf_services { + SVC_CY = 0, + SVC_CY2, + SVC_DC, ++ SVC_DCC, + SVC_SYM, + SVC_ASYM, + SVC_DC_ASYM, +@@ -21,6 +22,7 @@ static const char *const adf_cfg_services[] = { + [SVC_CY] = ADF_CFG_CY, + [SVC_CY2] = ADF_CFG_ASYM_SYM, + [SVC_DC] = ADF_CFG_DC, ++ [SVC_DCC] = ADF_CFG_DCC, + [SVC_SYM] = ADF_CFG_SYM, + [SVC_ASYM] = ADF_CFG_ASYM, + [SVC_DC_ASYM] = ADF_CFG_DC_ASYM, +diff --git a/drivers/crypto/intel/qat/qat_common/adf_cfg_strings.h b/drivers/crypto/intel/qat/qat_common/adf_cfg_strings.h +index 6066dc637352c..322b76903a737 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_cfg_strings.h ++++ b/drivers/crypto/intel/qat/qat_common/adf_cfg_strings.h +@@ -32,6 +32,7 @@ + #define ADF_CFG_DC_ASYM "dc;asym" + #define ADF_CFG_SYM_DC "sym;dc" + #define ADF_CFG_DC_SYM "dc;sym" ++#define ADF_CFG_DCC "dcc" + #define ADF_SERVICES_ENABLED "ServicesEnabled" + #define ADF_PM_IDLE_SUPPORT "PmIdleSupport" + #define ADF_ETRMGR_COALESCING_ENABLED "InterruptCoalescingEnabled" +diff --git a/drivers/crypto/intel/qat/qat_common/icp_qat_fw_init_admin.h b/drivers/crypto/intel/qat/qat_common/icp_qat_fw_init_admin.h +index 3e968a4bcc9cd..019a6443834e0 100644 +--- a/drivers/crypto/intel/qat/qat_common/icp_qat_fw_init_admin.h ++++ b/drivers/crypto/intel/qat/qat_common/icp_qat_fw_init_admin.h +@@ -16,6 +16,7 @@ enum icp_qat_fw_init_admin_cmd_id { + ICP_QAT_FW_HEARTBEAT_SYNC = 7, + ICP_QAT_FW_HEARTBEAT_GET = 8, + ICP_QAT_FW_COMP_CAPABILITY_GET = 9, ++ ICP_QAT_FW_DC_CHAIN_INIT = 11, + ICP_QAT_FW_HEARTBEAT_TIMER_SET = 13, + ICP_QAT_FW_TIMER_GET = 19, + ICP_QAT_FW_PM_STATE_CONFIG = 128, +-- +2.42.0 + diff --git a/queue-6.6/crypto-qat-fix-deadlock-in-backlog-processing.patch b/queue-6.6/crypto-qat-fix-deadlock-in-backlog-processing.patch new file mode 100644 index 00000000000..7fd05d30cb9 --- /dev/null +++ b/queue-6.6/crypto-qat-fix-deadlock-in-backlog-processing.patch @@ -0,0 +1,110 @@ +From 3366d0f1b16e16cbd1c9033f7a5aa8cd2a505249 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 16:33:21 +0100 +Subject: crypto: qat - fix deadlock in backlog processing + +From: Giovanni Cabiddu + +[ Upstream commit 203b01001c4d741205b9c329acddc5193ed56fbd ] + +If a request has the flag CRYPTO_TFM_REQ_MAY_BACKLOG set, the function +qat_alg_send_message_maybacklog(), enqueues it in a backlog list if +either (1) there is already at least one request in the backlog list, or +(2) the HW ring is nearly full or (3) the enqueue to the HW ring fails. +If an interrupt occurs right before the lock in qat_alg_backlog_req() is +taken and the backlog queue is being emptied, then there is no request +in the HW queues that can trigger a subsequent interrupt that can clear +the backlog queue. In addition subsequent requests are enqueued to the +backlog list and not sent to the hardware. + +Fix it by holding the lock while taking the decision if the request +needs to be included in the backlog queue or not. This synchronizes the +flow with the interrupt handler that drains the backlog queue. + +For performance reasons, the logic has been changed to try to enqueue +first without holding the lock. + +Fixes: 386823839732 ("crypto: qat - add backlog mechanism") +Reported-by: Mikulas Patocka +Closes: https://lore.kernel.org/all/af9581e2-58f9-cc19-428f-6f18f1f83d54@redhat.com/T/ +Signed-off-by: Giovanni Cabiddu +Reviewed-by: Mikulas Patocka +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + .../intel/qat/qat_common/qat_algs_send.c | 46 ++++++++++--------- + 1 file changed, 25 insertions(+), 21 deletions(-) + +diff --git a/drivers/crypto/intel/qat/qat_common/qat_algs_send.c b/drivers/crypto/intel/qat/qat_common/qat_algs_send.c +index bb80455b3e81e..b97b678823a97 100644 +--- a/drivers/crypto/intel/qat/qat_common/qat_algs_send.c ++++ b/drivers/crypto/intel/qat/qat_common/qat_algs_send.c +@@ -40,40 +40,44 @@ void qat_alg_send_backlog(struct qat_instance_backlog *backlog) + spin_unlock_bh(&backlog->lock); + } + +-static void qat_alg_backlog_req(struct qat_alg_req *req, +- struct qat_instance_backlog *backlog) +-{ +- INIT_LIST_HEAD(&req->list); +- +- spin_lock_bh(&backlog->lock); +- list_add_tail(&req->list, &backlog->list); +- spin_unlock_bh(&backlog->lock); +-} +- +-static int qat_alg_send_message_maybacklog(struct qat_alg_req *req) ++static bool qat_alg_try_enqueue(struct qat_alg_req *req) + { + struct qat_instance_backlog *backlog = req->backlog; + struct adf_etr_ring_data *tx_ring = req->tx_ring; + u32 *fw_req = req->fw_req; + +- /* If any request is already backlogged, then add to backlog list */ ++ /* Check if any request is already backlogged */ + if (!list_empty(&backlog->list)) +- goto enqueue; ++ return false; + +- /* If ring is nearly full, then add to backlog list */ ++ /* Check if ring is nearly full */ + if (adf_ring_nearly_full(tx_ring)) +- goto enqueue; ++ return false; + +- /* If adding request to HW ring fails, then add to backlog list */ ++ /* Try to enqueue to HW ring */ + if (adf_send_message(tx_ring, fw_req)) +- goto enqueue; ++ return false; + +- return -EINPROGRESS; ++ return true; ++} + +-enqueue: +- qat_alg_backlog_req(req, backlog); + +- return -EBUSY; ++static int qat_alg_send_message_maybacklog(struct qat_alg_req *req) ++{ ++ struct qat_instance_backlog *backlog = req->backlog; ++ int ret = -EINPROGRESS; ++ ++ if (qat_alg_try_enqueue(req)) ++ return ret; ++ ++ spin_lock_bh(&backlog->lock); ++ if (!qat_alg_try_enqueue(req)) { ++ list_add_tail(&req->list, &backlog->list); ++ ret = -EBUSY; ++ } ++ spin_unlock_bh(&backlog->lock); ++ ++ return ret; + } + + int qat_alg_send_message(struct qat_alg_req *req) +-- +2.42.0 + diff --git a/queue-6.6/crypto-qat-fix-ring-to-service-map-for-qat-gen4.patch b/queue-6.6/crypto-qat-fix-ring-to-service-map-for-qat-gen4.patch new file mode 100644 index 00000000000..3d33ec90f40 --- /dev/null +++ b/queue-6.6/crypto-qat-fix-ring-to-service-map-for-qat-gen4.patch @@ -0,0 +1,130 @@ +From 5aa198259ac256f0a16608ef09017fc8001d93b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 15:49:23 +0200 +Subject: crypto: qat - fix ring to service map for QAT GEN4 + +From: Giovanni Cabiddu + +[ Upstream commit a238487f7965d102794ed9f8aff0b667cd2ae886 ] + +The 4xxx drivers hardcode the ring to service mapping. However, when +additional configurations where added to the driver, the mappings were +not updated. This implies that an incorrect mapping might be reported +through pfvf for certain configurations. + +Add an algorithm that computes the correct ring to service mapping based +on the firmware loaded on the device. + +Fixes: 0cec19c761e5 ("crypto: qat - add support for compression for 4xxx") +Signed-off-by: Giovanni Cabiddu +Reviewed-by: Damian Muszynski +Reviewed-by: Tero Kristo +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + .../intel/qat/qat_4xxx/adf_4xxx_hw_data.c | 54 +++++++++++++++++++ + .../intel/qat/qat_common/adf_accel_devices.h | 1 + + .../crypto/intel/qat/qat_common/adf_init.c | 3 ++ + 3 files changed, 58 insertions(+) + +diff --git a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c +index 44b732fb80bca..a5691ba0b7244 100644 +--- a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c ++++ b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c +@@ -423,6 +423,59 @@ static const struct adf_fw_config *get_fw_config(struct adf_accel_dev *accel_dev + } + } + ++enum adf_rp_groups { ++ RP_GROUP_0 = 0, ++ RP_GROUP_1, ++ RP_GROUP_COUNT ++}; ++ ++static u16 get_ring_to_svc_map(struct adf_accel_dev *accel_dev) ++{ ++ enum adf_cfg_service_type rps[RP_GROUP_COUNT]; ++ const struct adf_fw_config *fw_config; ++ u16 ring_to_svc_map; ++ int i, j; ++ ++ fw_config = get_fw_config(accel_dev); ++ if (!fw_config) ++ return 0; ++ ++ for (i = 0; i < RP_GROUP_COUNT; i++) { ++ switch (fw_config[i].ae_mask) { ++ case ADF_AE_GROUP_0: ++ j = RP_GROUP_0; ++ break; ++ case ADF_AE_GROUP_1: ++ j = RP_GROUP_1; ++ break; ++ default: ++ return 0; ++ } ++ ++ switch (fw_config[i].obj) { ++ case ADF_FW_SYM_OBJ: ++ rps[j] = SYM; ++ break; ++ case ADF_FW_ASYM_OBJ: ++ rps[j] = ASYM; ++ break; ++ case ADF_FW_DC_OBJ: ++ rps[j] = COMP; ++ break; ++ default: ++ rps[j] = 0; ++ break; ++ } ++ } ++ ++ ring_to_svc_map = rps[RP_GROUP_0] << ADF_CFG_SERV_RING_PAIR_0_SHIFT | ++ rps[RP_GROUP_1] << ADF_CFG_SERV_RING_PAIR_1_SHIFT | ++ rps[RP_GROUP_0] << ADF_CFG_SERV_RING_PAIR_2_SHIFT | ++ rps[RP_GROUP_1] << ADF_CFG_SERV_RING_PAIR_3_SHIFT; ++ ++ return ring_to_svc_map; ++} ++ + static const char *uof_get_name(struct adf_accel_dev *accel_dev, u32 obj_num, + const char * const fw_objs[], int num_objs) + { +@@ -519,6 +572,7 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data, u32 dev_id) + hw_data->uof_get_ae_mask = uof_get_ae_mask; + hw_data->set_msix_rttable = set_msix_default_rttable; + hw_data->set_ssm_wdtimer = adf_gen4_set_ssm_wdtimer; ++ hw_data->get_ring_to_svc_map = get_ring_to_svc_map; + hw_data->disable_iov = adf_disable_sriov; + hw_data->ring_pair_reset = adf_gen4_ring_pair_reset; + hw_data->enable_pm = adf_gen4_enable_pm; +diff --git a/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h b/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h +index 1e84ff309ed3b..79d5a1535eda3 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h ++++ b/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h +@@ -182,6 +182,7 @@ struct adf_hw_device_data { + void (*get_arb_info)(struct arb_info *arb_csrs_info); + void (*get_admin_info)(struct admin_info *admin_csrs_info); + enum dev_sku_info (*get_sku)(struct adf_hw_device_data *self); ++ u16 (*get_ring_to_svc_map)(struct adf_accel_dev *accel_dev); + int (*alloc_irq)(struct adf_accel_dev *accel_dev); + void (*free_irq)(struct adf_accel_dev *accel_dev); + void (*enable_error_correction)(struct adf_accel_dev *accel_dev); +diff --git a/drivers/crypto/intel/qat/qat_common/adf_init.c b/drivers/crypto/intel/qat/qat_common/adf_init.c +index 7323a9f1f11c8..0f9e2d59ce385 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_init.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_init.c +@@ -97,6 +97,9 @@ static int adf_dev_init(struct adf_accel_dev *accel_dev) + return -EFAULT; + } + ++ if (hw_data->get_ring_to_svc_map) ++ hw_data->ring_to_svc_map = hw_data->get_ring_to_svc_map(accel_dev); ++ + if (adf_ae_init(accel_dev)) { + dev_err(&GET_DEV(accel_dev), + "Failed to initialise Acceleration Engine\n"); +-- +2.42.0 + diff --git a/queue-6.6/crypto-qat-fix-state-machines-cleanup-paths.patch b/queue-6.6/crypto-qat-fix-state-machines-cleanup-paths.patch new file mode 100644 index 00000000000..fdd277e5315 --- /dev/null +++ b/queue-6.6/crypto-qat-fix-state-machines-cleanup-paths.patch @@ -0,0 +1,79 @@ +From c5d3a1f302de2cf5a1ee09727a57c32f076b0b83 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 10:55:45 +0100 +Subject: crypto: qat - fix state machines cleanup paths + +From: Giovanni Cabiddu + +[ Upstream commit c9ca9756f376f51f985130a0e599d956065d4c44 ] + +Commit 1bdc85550a2b ("crypto: qat - fix concurrency issue when device +state changes") introduced the function adf_dev_down() which wraps the +functions adf_dev_stop() and adf_dev_shutdown(). +In a subsequent change, the sequence adf_dev_stop() followed by +adf_dev_shutdown() was then replaced across the driver with just a call +to the function adf_dev_down(). + +The functions adf_dev_stop() and adf_dev_shutdown() are called in error +paths to stop the accelerator and free up resources and can be called +even if the counterparts adf_dev_init() and adf_dev_start() did not +complete successfully. +However, the implementation of adf_dev_down() prevents the stop/shutdown +sequence if the device is found already down. +For example, if adf_dev_init() fails, the device status is not set as +started and therefore a call to adf_dev_down() won't be calling +adf_dev_shutdown() to undo what adf_dev_init() did. + +Do not check if a device is started in adf_dev_down() but do the +equivalent check in adf_sysfs.c when handling a DEV_DOWN command from +the user. + +Fixes: 2b60f79c7b81 ("crypto: qat - replace state machine calls") +Signed-off-by: Giovanni Cabiddu +Reviewed-by: Adam Guerin +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/intel/qat/qat_common/adf_init.c | 7 ------- + drivers/crypto/intel/qat/qat_common/adf_sysfs.c | 7 +++++++ + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/crypto/intel/qat/qat_common/adf_init.c b/drivers/crypto/intel/qat/qat_common/adf_init.c +index 89001fe92e762..35aef5e8fc386 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_init.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_init.c +@@ -440,13 +440,6 @@ int adf_dev_down(struct adf_accel_dev *accel_dev, bool reconfig) + + mutex_lock(&accel_dev->state_lock); + +- if (!adf_dev_started(accel_dev)) { +- dev_info(&GET_DEV(accel_dev), "Device qat_dev%d already down\n", +- accel_dev->accel_id); +- ret = -EINVAL; +- goto out; +- } +- + if (reconfig) { + ret = adf_dev_shutdown_cache_cfg(accel_dev); + goto out; +diff --git a/drivers/crypto/intel/qat/qat_common/adf_sysfs.c b/drivers/crypto/intel/qat/qat_common/adf_sysfs.c +index a74d2f9303670..a8f33558d7cb8 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_sysfs.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_sysfs.c +@@ -52,6 +52,13 @@ static ssize_t state_store(struct device *dev, struct device_attribute *attr, + case DEV_DOWN: + dev_info(dev, "Stopping device qat_dev%d\n", accel_id); + ++ if (!adf_dev_started(accel_dev)) { ++ dev_info(&GET_DEV(accel_dev), "Device qat_dev%d already down\n", ++ accel_id); ++ ++ break; ++ } ++ + ret = adf_dev_down(accel_dev, true); + if (ret < 0) + return -EINVAL; +-- +2.42.0 + diff --git a/queue-6.6/crypto-qat-fix-unregistration-of-compression-algorit.patch b/queue-6.6/crypto-qat-fix-unregistration-of-compression-algorit.patch new file mode 100644 index 00000000000..47192b23089 --- /dev/null +++ b/queue-6.6/crypto-qat-fix-unregistration-of-compression-algorit.patch @@ -0,0 +1,79 @@ +From 56c3413f3111b3baeec8efce038c007a3efa7d7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 10:55:49 +0100 +Subject: crypto: qat - fix unregistration of compression algorithms + +From: Giovanni Cabiddu + +[ Upstream commit 11af152f784d9eca54e193140891ac52de36e9a9 ] + +The function adf_dev_init(), through the subsystem qat_compression, +populates the list of list of compression instances +accel_dev->compression_list. If the list of instances is not empty, +the function adf_dev_start() will then call qat_compression_registers() +register the compression algorithms into the crypto framework. + +If any of the functions in adf_dev_start() fail, the caller of such +function, in the error path calls adf_dev_down() which in turn call +adf_dev_stop() and adf_dev_shutdown(), see for example the function +state_store in adf_sriov.c. +However, if the registration of compression algorithms is not done, +adf_dev_stop() will try to unregister the algorithms regardless. +This might cause the counter active_devs in qat_compression.c to get +to a negative value. + +Add a new state, ADF_STATUS_COMPRESSION_ALGS_REGISTERED, which tracks +if the compression algorithms are registered into the crypto framework. +Then use this to unregister the algorithms if such flag is set. This +ensures that the compression algorithms are only unregistered if +previously registered. + +Fixes: 1198ae56c9a5 ("crypto: qat - expose deflate through acomp api for QAT GEN2") +Signed-off-by: Giovanni Cabiddu +Reviewed-by: Adam Guerin +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/intel/qat/qat_common/adf_common_drv.h | 1 + + drivers/crypto/intel/qat/qat_common/adf_init.c | 5 ++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/intel/qat/qat_common/adf_common_drv.h b/drivers/crypto/intel/qat/qat_common/adf_common_drv.h +index ed640cb37616b..79ff7982378d9 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_common_drv.h ++++ b/drivers/crypto/intel/qat/qat_common/adf_common_drv.h +@@ -26,6 +26,7 @@ + #define ADF_STATUS_PF_RUNNING 7 + #define ADF_STATUS_IRQ_ALLOCATED 8 + #define ADF_STATUS_CRYPTO_ALGS_REGISTERED 9 ++#define ADF_STATUS_COMP_ALGS_REGISTERED 10 + + enum adf_dev_reset_mode { + ADF_DEV_RESET_ASYNC = 0, +diff --git a/drivers/crypto/intel/qat/qat_common/adf_init.c b/drivers/crypto/intel/qat/qat_common/adf_init.c +index ef8623f81fa33..7323a9f1f11c8 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_init.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_init.c +@@ -240,6 +240,7 @@ static int adf_dev_start(struct adf_accel_dev *accel_dev) + clear_bit(ADF_STATUS_STARTED, &accel_dev->status); + return -EFAULT; + } ++ set_bit(ADF_STATUS_COMP_ALGS_REGISTERED, &accel_dev->status); + + adf_dbgfs_add(accel_dev); + +@@ -280,8 +281,10 @@ static void adf_dev_stop(struct adf_accel_dev *accel_dev) + } + clear_bit(ADF_STATUS_CRYPTO_ALGS_REGISTERED, &accel_dev->status); + +- if (!list_empty(&accel_dev->compression_list)) ++ if (!list_empty(&accel_dev->compression_list) && ++ test_bit(ADF_STATUS_COMP_ALGS_REGISTERED, &accel_dev->status)) + qat_comp_algs_unregister(); ++ clear_bit(ADF_STATUS_COMP_ALGS_REGISTERED, &accel_dev->status); + + list_for_each(list_itr, &service_table) { + service = list_entry(list_itr, struct service_hndl, list); +-- +2.42.0 + diff --git a/queue-6.6/crypto-qat-fix-unregistration-of-crypto-algorithms.patch b/queue-6.6/crypto-qat-fix-unregistration-of-crypto-algorithms.patch new file mode 100644 index 00000000000..d45bb40dda4 --- /dev/null +++ b/queue-6.6/crypto-qat-fix-unregistration-of-crypto-algorithms.patch @@ -0,0 +1,80 @@ +From f3a2d259c86112935045b0cc271db5d80d686955 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 10:55:48 +0100 +Subject: crypto: qat - fix unregistration of crypto algorithms + +From: Giovanni Cabiddu + +[ Upstream commit 9b2f33a1bfcda90b857431a764c9c8f9a412bbe5 ] + +The function adf_dev_init(), through the subsystem qat_crypto, populates +the list of list of crypto instances accel_dev->crypto_list. +If the list of instances is not empty, the function adf_dev_start() will +then call qat_algs_registers() and qat_asym_algs_register() to register +the crypto algorithms into the crypto framework. + +If any of the functions in adf_dev_start() fail, the caller of such +function, in the error path calls adf_dev_down() which in turn call +adf_dev_stop() and adf_dev_shutdown(), see for example the function +state_store in adf_sriov.c. +However, if the registration of crypto algorithms is not done, +adf_dev_stop() will try to unregister the algorithms regardless. +This might cause the counter active_devs in qat_algs.c and +qat_asym_algs.c to get to a negative value. + +Add a new state, ADF_STATUS_CRYPTO_ALGS_REGISTERED, which tracks if the +crypto algorithms are registered into the crypto framework. Then use +this to unregister the algorithms if such flag is set. This ensures that +the crypto algorithms are only unregistered if previously registered. + +Fixes: d8cba25d2c68 ("crypto: qat - Intel(R) QAT driver framework") +Signed-off-by: Giovanni Cabiddu +Reviewed-by: Adam Guerin +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/intel/qat/qat_common/adf_common_drv.h | 1 + + drivers/crypto/intel/qat/qat_common/adf_init.c | 5 ++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/intel/qat/qat_common/adf_common_drv.h b/drivers/crypto/intel/qat/qat_common/adf_common_drv.h +index 673b5044c62a5..ed640cb37616b 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_common_drv.h ++++ b/drivers/crypto/intel/qat/qat_common/adf_common_drv.h +@@ -25,6 +25,7 @@ + #define ADF_STATUS_AE_STARTED 6 + #define ADF_STATUS_PF_RUNNING 7 + #define ADF_STATUS_IRQ_ALLOCATED 8 ++#define ADF_STATUS_CRYPTO_ALGS_REGISTERED 9 + + enum adf_dev_reset_mode { + ADF_DEV_RESET_ASYNC = 0, +diff --git a/drivers/crypto/intel/qat/qat_common/adf_init.c b/drivers/crypto/intel/qat/qat_common/adf_init.c +index 35aef5e8fc386..ef8623f81fa33 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_init.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_init.c +@@ -231,6 +231,7 @@ static int adf_dev_start(struct adf_accel_dev *accel_dev) + clear_bit(ADF_STATUS_STARTED, &accel_dev->status); + return -EFAULT; + } ++ set_bit(ADF_STATUS_CRYPTO_ALGS_REGISTERED, &accel_dev->status); + + if (!list_empty(&accel_dev->compression_list) && qat_comp_algs_register()) { + dev_err(&GET_DEV(accel_dev), +@@ -272,10 +273,12 @@ static void adf_dev_stop(struct adf_accel_dev *accel_dev) + clear_bit(ADF_STATUS_STARTING, &accel_dev->status); + clear_bit(ADF_STATUS_STARTED, &accel_dev->status); + +- if (!list_empty(&accel_dev->crypto_list)) { ++ if (!list_empty(&accel_dev->crypto_list) && ++ test_bit(ADF_STATUS_CRYPTO_ALGS_REGISTERED, &accel_dev->status)) { + qat_algs_unregister(); + qat_asym_algs_unregister(); + } ++ clear_bit(ADF_STATUS_CRYPTO_ALGS_REGISTERED, &accel_dev->status); + + if (!list_empty(&accel_dev->compression_list)) + qat_comp_algs_unregister(); +-- +2.42.0 + diff --git a/queue-6.6/crypto-qat-ignore-subsequent-state-up-commands.patch b/queue-6.6/crypto-qat-ignore-subsequent-state-up-commands.patch new file mode 100644 index 00000000000..08c10cc7695 --- /dev/null +++ b/queue-6.6/crypto-qat-ignore-subsequent-state-up-commands.patch @@ -0,0 +1,42 @@ +From b92ffcb6fb8e158de2a5e226d7358c425882f8dd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 10:55:47 +0100 +Subject: crypto: qat - ignore subsequent state up commands + +From: Giovanni Cabiddu + +[ Upstream commit 9c20cb8b1847dedddec3d5163079290542bf00bf ] + +If the device is already in the up state, a subsequent write of `up` to +the sysfs attribute /sys/bus/pci/devices//qat/state brings the +device down. +Fix this behaviour by ignoring subsequent `up` commands if the device is +already in the up state. + +Fixes: 1bdc85550a2b ("crypto: qat - fix concurrency issue when device state changes") +Signed-off-by: Giovanni Cabiddu +Reviewed-by: Adam Guerin +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/intel/qat/qat_common/adf_sysfs.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/intel/qat/qat_common/adf_sysfs.c b/drivers/crypto/intel/qat/qat_common/adf_sysfs.c +index a8f33558d7cb8..8880af1aa1b5b 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_sysfs.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_sysfs.c +@@ -68,7 +68,9 @@ static ssize_t state_store(struct device *dev, struct device_attribute *attr, + dev_info(dev, "Starting device qat_dev%d\n", accel_id); + + ret = adf_dev_up(accel_dev, true); +- if (ret < 0) { ++ if (ret == -EALREADY) { ++ break; ++ } else if (ret) { + dev_err(dev, "Failed to start device qat_dev%d\n", + accel_id); + adf_dev_down(accel_dev, true); +-- +2.42.0 + diff --git a/queue-6.6/crypto-qat-increase-size-of-buffers.patch b/queue-6.6/crypto-qat-increase-size-of-buffers.patch new file mode 100644 index 00000000000..1a5bbe203bb --- /dev/null +++ b/queue-6.6/crypto-qat-increase-size-of-buffers.patch @@ -0,0 +1,72 @@ +From 40b081101924f4ba8c5964d20879fd85cd2dbe70 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 10:03:47 +0100 +Subject: crypto: qat - increase size of buffers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Giovanni Cabiddu + +[ Upstream commit 4e4e2ed22d505c5bacf65c6a39bfb6d120d24785 ] + +Increase the size of the buffers used for composing the names used for +the transport debugfs entries and the vector name to avoid a potential +truncation. + +This resolves the following errors when compiling the driver with W=1 +and KCFLAGS=-Werror on GCC 12.3.1: + + drivers/crypto/intel/qat/qat_common/adf_transport_debug.c: In function ‘adf_ring_debugfs_add’: + drivers/crypto/intel/qat/qat_common/adf_transport_debug.c:100:60: error: ‘snprintf’ output may be truncated before the last format character [-Werror=format-truncation=] + drivers/crypto/intel/qat/qat_common/adf_isr.c: In function ‘adf_isr_resource_alloc’: + drivers/crypto/intel/qat/qat_common/adf_isr.c:197:47: error: ‘%d’ directive output may be truncated writing between 1 and 11 bytes into a region of size between 0 and 5 [-Werror=format-truncation=] + +Fixes: a672a9dc872e ("crypto: qat - Intel(R) QAT transport code") +Signed-off-by: Giovanni Cabiddu +Reviewed-by: Damian Muszynski +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/intel/qat/qat_common/adf_accel_devices.h | 2 +- + drivers/crypto/intel/qat/qat_common/adf_transport_debug.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h b/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h +index e57abde66f4fb..1e84ff309ed3b 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h ++++ b/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h +@@ -29,7 +29,7 @@ + #define ADF_PCI_MAX_BARS 3 + #define ADF_DEVICE_NAME_LENGTH 32 + #define ADF_ETR_MAX_RINGS_PER_BANK 16 +-#define ADF_MAX_MSIX_VECTOR_NAME 16 ++#define ADF_MAX_MSIX_VECTOR_NAME 48 + #define ADF_DEVICE_NAME_PREFIX "qat_" + + enum adf_accel_capabilities { +diff --git a/drivers/crypto/intel/qat/qat_common/adf_transport_debug.c b/drivers/crypto/intel/qat/qat_common/adf_transport_debug.c +index 08bca1c506c0e..e2dd568b87b51 100644 +--- a/drivers/crypto/intel/qat/qat_common/adf_transport_debug.c ++++ b/drivers/crypto/intel/qat/qat_common/adf_transport_debug.c +@@ -90,7 +90,7 @@ DEFINE_SEQ_ATTRIBUTE(adf_ring_debug); + int adf_ring_debugfs_add(struct adf_etr_ring_data *ring, const char *name) + { + struct adf_etr_ring_debug_entry *ring_debug; +- char entry_name[8]; ++ char entry_name[16]; + + ring_debug = kzalloc(sizeof(*ring_debug), GFP_KERNEL); + if (!ring_debug) +@@ -192,7 +192,7 @@ int adf_bank_debugfs_add(struct adf_etr_bank_data *bank) + { + struct adf_accel_dev *accel_dev = bank->accel_dev; + struct dentry *parent = accel_dev->transport->debug; +- char name[8]; ++ char name[16]; + + snprintf(name, sizeof(name), "bank_%02d", bank->bank_number); + bank->bank_debug_dir = debugfs_create_dir(name, parent); +-- +2.42.0 + diff --git a/queue-6.6/crypto-qat-refactor-fw-config-related-functions.patch b/queue-6.6/crypto-qat-refactor-fw-config-related-functions.patch new file mode 100644 index 00000000000..c52d99ad2bd --- /dev/null +++ b/queue-6.6/crypto-qat-refactor-fw-config-related-functions.patch @@ -0,0 +1,131 @@ +From 2a684590bb3e07d3a0438a5087077bd1122b3477 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 15:49:21 +0200 +Subject: crypto: qat - refactor fw config related functions + +From: Giovanni Cabiddu + +[ Upstream commit 2990d2edac6061c6f0f646a46e40957244be2268 ] + +The logic that selects the correct adf_fw_config structure based on the +configured service is replicated twice in the uof_get_name() and +uof_get_ae_mask() functions. Refactor the code so that there is no +replication. + +This does not introduce any functional change. + +Signed-off-by: Giovanni Cabiddu +Reviewed-by: Damian Muszynski +Reviewed-by: Tero Kristo +Signed-off-by: Herbert Xu +Stable-dep-of: a238487f7965 ("crypto: qat - fix ring to service map for QAT GEN4") +Signed-off-by: Sasha Levin +--- + .../intel/qat/qat_4xxx/adf_4xxx_hw_data.c | 69 ++++++++----------- + 1 file changed, 28 insertions(+), 41 deletions(-) + +diff --git a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c +index 12b5d18191119..10839269c4d32 100644 +--- a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c ++++ b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c +@@ -394,40 +394,42 @@ static u32 uof_get_num_objs(void) + return ARRAY_SIZE(adf_fw_cy_config); + } + +-static const char *uof_get_name(struct adf_accel_dev *accel_dev, u32 obj_num, +- const char * const fw_objs[], int num_objs) ++static const struct adf_fw_config *get_fw_config(struct adf_accel_dev *accel_dev) + { +- int id; +- + switch (get_service_enabled(accel_dev)) { + case SVC_CY: + case SVC_CY2: +- id = adf_fw_cy_config[obj_num].obj; +- break; ++ return adf_fw_cy_config; + case SVC_DC: +- id = adf_fw_dc_config[obj_num].obj; +- break; ++ return adf_fw_dc_config; + case SVC_DCC: +- id = adf_fw_dcc_config[obj_num].obj; +- break; ++ return adf_fw_dcc_config; + case SVC_SYM: +- id = adf_fw_sym_config[obj_num].obj; +- break; ++ return adf_fw_sym_config; + case SVC_ASYM: +- id = adf_fw_asym_config[obj_num].obj; +- break; ++ return adf_fw_asym_config; + case SVC_ASYM_DC: + case SVC_DC_ASYM: +- id = adf_fw_asym_dc_config[obj_num].obj; +- break; ++ return adf_fw_asym_dc_config; + case SVC_SYM_DC: + case SVC_DC_SYM: +- id = adf_fw_sym_dc_config[obj_num].obj; +- break; ++ return adf_fw_sym_dc_config; + default: +- id = -EINVAL; +- break; ++ return NULL; + } ++} ++ ++static const char *uof_get_name(struct adf_accel_dev *accel_dev, u32 obj_num, ++ const char * const fw_objs[], int num_objs) ++{ ++ const struct adf_fw_config *fw_config; ++ int id; ++ ++ fw_config = get_fw_config(accel_dev); ++ if (fw_config) ++ id = fw_config[obj_num].obj; ++ else ++ id = -EINVAL; + + if (id < 0 || id > num_objs) + return NULL; +@@ -451,28 +453,13 @@ static const char *uof_get_name_402xx(struct adf_accel_dev *accel_dev, u32 obj_n + + static u32 uof_get_ae_mask(struct adf_accel_dev *accel_dev, u32 obj_num) + { +- switch (get_service_enabled(accel_dev)) { +- case SVC_CY: +- return adf_fw_cy_config[obj_num].ae_mask; +- case SVC_DC: +- return adf_fw_dc_config[obj_num].ae_mask; +- case SVC_DCC: +- return adf_fw_dcc_config[obj_num].ae_mask; +- case SVC_CY2: +- return adf_fw_cy_config[obj_num].ae_mask; +- case SVC_SYM: +- return adf_fw_sym_config[obj_num].ae_mask; +- case SVC_ASYM: +- return adf_fw_asym_config[obj_num].ae_mask; +- case SVC_ASYM_DC: +- case SVC_DC_ASYM: +- return adf_fw_asym_dc_config[obj_num].ae_mask; +- case SVC_SYM_DC: +- case SVC_DC_SYM: +- return adf_fw_sym_dc_config[obj_num].ae_mask; +- default: ++ const struct adf_fw_config *fw_config; ++ ++ fw_config = get_fw_config(accel_dev); ++ if (!fw_config) + return 0; +- } ++ ++ return fw_config[obj_num].ae_mask; + } + + void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data, u32 dev_id) +-- +2.42.0 + diff --git a/queue-6.6/crypto-qat-use-masks-for-ae-groups.patch b/queue-6.6/crypto-qat-use-masks-for-ae-groups.patch new file mode 100644 index 00000000000..1f9b3e233cf --- /dev/null +++ b/queue-6.6/crypto-qat-use-masks-for-ae-groups.patch @@ -0,0 +1,110 @@ +From 18b93dc6892b635e0c775c567396511ebcd85660 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 15:49:22 +0200 +Subject: crypto: qat - use masks for AE groups + +From: Giovanni Cabiddu + +[ Upstream commit f7df2329eec1729a606bba8ed1566a1b3c248bad ] + +The adf_fw_config structures hardcode a bit mask that represents the +acceleration engines (AEs) where a certain firmware image will have to +be loaded to. Remove the hardcoded masks and replace them with defines. + +This does not introduce any functional change. + +Signed-off-by: Giovanni Cabiddu +Reviewed-by: Damian Muszynski +Reviewed-by: Tero Kristo +Signed-off-by: Herbert Xu +Stable-dep-of: a238487f7965 ("crypto: qat - fix ring to service map for QAT GEN4") +Signed-off-by: Sasha Levin +--- + .../intel/qat/qat_4xxx/adf_4xxx_hw_data.c | 46 ++++++++++--------- + 1 file changed, 25 insertions(+), 21 deletions(-) + +diff --git a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c +index 10839269c4d32..44b732fb80bca 100644 +--- a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c ++++ b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c +@@ -14,6 +14,10 @@ + #include "adf_cfg_services.h" + #include "icp_qat_hw.h" + ++#define ADF_AE_GROUP_0 GENMASK(3, 0) ++#define ADF_AE_GROUP_1 GENMASK(7, 4) ++#define ADF_AE_GROUP_2 BIT(8) ++ + enum adf_fw_objs { + ADF_FW_SYM_OBJ, + ADF_FW_ASYM_OBJ, +@@ -41,45 +45,45 @@ struct adf_fw_config { + }; + + static const struct adf_fw_config adf_fw_cy_config[] = { +- {0xF0, ADF_FW_SYM_OBJ}, +- {0xF, ADF_FW_ASYM_OBJ}, +- {0x100, ADF_FW_ADMIN_OBJ}, ++ {ADF_AE_GROUP_1, ADF_FW_SYM_OBJ}, ++ {ADF_AE_GROUP_0, ADF_FW_ASYM_OBJ}, ++ {ADF_AE_GROUP_2, ADF_FW_ADMIN_OBJ}, + }; + + static const struct adf_fw_config adf_fw_dc_config[] = { +- {0xF0, ADF_FW_DC_OBJ}, +- {0xF, ADF_FW_DC_OBJ}, +- {0x100, ADF_FW_ADMIN_OBJ}, ++ {ADF_AE_GROUP_1, ADF_FW_DC_OBJ}, ++ {ADF_AE_GROUP_0, ADF_FW_DC_OBJ}, ++ {ADF_AE_GROUP_2, ADF_FW_ADMIN_OBJ}, + }; + + static const struct adf_fw_config adf_fw_sym_config[] = { +- {0xF0, ADF_FW_SYM_OBJ}, +- {0xF, ADF_FW_SYM_OBJ}, +- {0x100, ADF_FW_ADMIN_OBJ}, ++ {ADF_AE_GROUP_1, ADF_FW_SYM_OBJ}, ++ {ADF_AE_GROUP_0, ADF_FW_SYM_OBJ}, ++ {ADF_AE_GROUP_2, ADF_FW_ADMIN_OBJ}, + }; + + static const struct adf_fw_config adf_fw_asym_config[] = { +- {0xF0, ADF_FW_ASYM_OBJ}, +- {0xF, ADF_FW_ASYM_OBJ}, +- {0x100, ADF_FW_ADMIN_OBJ}, ++ {ADF_AE_GROUP_1, ADF_FW_ASYM_OBJ}, ++ {ADF_AE_GROUP_0, ADF_FW_ASYM_OBJ}, ++ {ADF_AE_GROUP_2, ADF_FW_ADMIN_OBJ}, + }; + + static const struct adf_fw_config adf_fw_asym_dc_config[] = { +- {0xF0, ADF_FW_ASYM_OBJ}, +- {0xF, ADF_FW_DC_OBJ}, +- {0x100, ADF_FW_ADMIN_OBJ}, ++ {ADF_AE_GROUP_1, ADF_FW_ASYM_OBJ}, ++ {ADF_AE_GROUP_0, ADF_FW_DC_OBJ}, ++ {ADF_AE_GROUP_2, ADF_FW_ADMIN_OBJ}, + }; + + static const struct adf_fw_config adf_fw_sym_dc_config[] = { +- {0xF0, ADF_FW_SYM_OBJ}, +- {0xF, ADF_FW_DC_OBJ}, +- {0x100, ADF_FW_ADMIN_OBJ}, ++ {ADF_AE_GROUP_1, ADF_FW_SYM_OBJ}, ++ {ADF_AE_GROUP_0, ADF_FW_DC_OBJ}, ++ {ADF_AE_GROUP_2, ADF_FW_ADMIN_OBJ}, + }; + + static const struct adf_fw_config adf_fw_dcc_config[] = { +- {0xF0, ADF_FW_DC_OBJ}, +- {0xF, ADF_FW_SYM_OBJ}, +- {0x100, ADF_FW_ADMIN_OBJ}, ++ {ADF_AE_GROUP_1, ADF_FW_DC_OBJ}, ++ {ADF_AE_GROUP_0, ADF_FW_SYM_OBJ}, ++ {ADF_AE_GROUP_2, ADF_FW_ADMIN_OBJ}, + }; + + static_assert(ARRAY_SIZE(adf_fw_cy_config) == ARRAY_SIZE(adf_fw_dc_config)); +-- +2.42.0 + diff --git a/queue-6.6/cxl-core-regs-rename-dev-to-host-in-struct-cxl_regis.patch b/queue-6.6/cxl-core-regs-rename-dev-to-host-in-struct-cxl_regis.patch new file mode 100644 index 00000000000..ddf70c00adc --- /dev/null +++ b/queue-6.6/cxl-core-regs-rename-dev-to-host-in-struct-cxl_regis.patch @@ -0,0 +1,208 @@ +From 1958468cd3496b86f76a56194e602de8fbc86a99 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Oct 2023 19:16:55 +0200 +Subject: cxl/core/regs: Rename @dev to @host in struct cxl_register_map + +From: Robert Richter + +[ Upstream commit dd22581f89537163f065e8ef7c125ce0fddf62cc ] + +The primary role of @dev is to host the mappings for devm operations. +@dev is too ambiguous as a name. I.e. when does @dev refer to the +'struct device *' instance that the registers belong, and when does +@dev refer to the 'struct device *' instance hosting the mapping for +devm operations? + +Clarify the role of @dev in cxl_register_map by renaming it to @host. +Also, rename local variables to 'host' where map->host is used. + +Signed-off-by: Terry Bowman +Signed-off-by: Robert Richter +Reviewed-by: Jonathan Cameron +Link: https://lore.kernel.org/r/20231018171713.1883517-3-rrichter@amd.com +Signed-off-by: Dan Williams +Stable-dep-of: 33d9c987bf8f ("cxl/port: Fix @host confusion in cxl_dport_setup_regs()") +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/hdm.c | 2 +- + drivers/cxl/core/port.c | 4 ++-- + drivers/cxl/core/regs.c | 28 ++++++++++++++-------------- + drivers/cxl/cxl.h | 4 ++-- + drivers/cxl/pci.c | 2 +- + 5 files changed, 20 insertions(+), 20 deletions(-) + +diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c +index 506c9e14cdf98..3ad0d39d3d3fa 100644 +--- a/drivers/cxl/core/hdm.c ++++ b/drivers/cxl/core/hdm.c +@@ -85,7 +85,7 @@ static int map_hdm_decoder_regs(struct cxl_port *port, void __iomem *crb, + struct cxl_component_regs *regs) + { + struct cxl_register_map map = { +- .dev = &port->dev, ++ .host = &port->dev, + .resource = port->component_reg_phys, + .base = crb, + .max_size = CXL_COMPONENT_REG_BLOCK_SIZE, +diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c +index 5ba606c6e03ff..c24cfe2271948 100644 +--- a/drivers/cxl/core/port.c ++++ b/drivers/cxl/core/port.c +@@ -697,14 +697,14 @@ static struct cxl_port *cxl_port_alloc(struct device *uport_dev, + return ERR_PTR(rc); + } + +-static int cxl_setup_comp_regs(struct device *dev, struct cxl_register_map *map, ++static int cxl_setup_comp_regs(struct device *host, struct cxl_register_map *map, + resource_size_t component_reg_phys) + { + if (component_reg_phys == CXL_RESOURCE_NONE) + return 0; + + *map = (struct cxl_register_map) { +- .dev = dev, ++ .host = host, + .reg_type = CXL_REGLOC_RBI_COMPONENT, + .resource = component_reg_phys, + .max_size = CXL_COMPONENT_REG_BLOCK_SIZE, +diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c +index 6281127b3e9d9..e0fbe964f6f0a 100644 +--- a/drivers/cxl/core/regs.c ++++ b/drivers/cxl/core/regs.c +@@ -204,7 +204,7 @@ int cxl_map_component_regs(const struct cxl_register_map *map, + struct cxl_component_regs *regs, + unsigned long map_mask) + { +- struct device *dev = map->dev; ++ struct device *host = map->host; + struct mapinfo { + const struct cxl_reg_map *rmap; + void __iomem **addr; +@@ -225,7 +225,7 @@ int cxl_map_component_regs(const struct cxl_register_map *map, + continue; + phys_addr = map->resource + mi->rmap->offset; + length = mi->rmap->size; +- *(mi->addr) = devm_cxl_iomap_block(dev, phys_addr, length); ++ *(mi->addr) = devm_cxl_iomap_block(host, phys_addr, length); + if (!*(mi->addr)) + return -ENOMEM; + } +@@ -237,7 +237,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_map_component_regs, CXL); + int cxl_map_device_regs(const struct cxl_register_map *map, + struct cxl_device_regs *regs) + { +- struct device *dev = map->dev; ++ struct device *host = map->host; + resource_size_t phys_addr = map->resource; + struct mapinfo { + const struct cxl_reg_map *rmap; +@@ -259,7 +259,7 @@ int cxl_map_device_regs(const struct cxl_register_map *map, + + addr = phys_addr + mi->rmap->offset; + length = mi->rmap->size; +- *(mi->addr) = devm_cxl_iomap_block(dev, addr, length); ++ *(mi->addr) = devm_cxl_iomap_block(host, addr, length); + if (!*(mi->addr)) + return -ENOMEM; + } +@@ -309,7 +309,7 @@ int cxl_find_regblock_instance(struct pci_dev *pdev, enum cxl_regloc_type type, + int regloc, i; + + *map = (struct cxl_register_map) { +- .dev = &pdev->dev, ++ .host = &pdev->dev, + .resource = CXL_RESOURCE_NONE, + }; + +@@ -403,15 +403,15 @@ EXPORT_SYMBOL_NS_GPL(cxl_map_pmu_regs, CXL); + + static int cxl_map_regblock(struct cxl_register_map *map) + { +- struct device *dev = map->dev; ++ struct device *host = map->host; + + map->base = ioremap(map->resource, map->max_size); + if (!map->base) { +- dev_err(dev, "failed to map registers\n"); ++ dev_err(host, "failed to map registers\n"); + return -ENOMEM; + } + +- dev_dbg(dev, "Mapped CXL Memory Device resource %pa\n", &map->resource); ++ dev_dbg(host, "Mapped CXL Memory Device resource %pa\n", &map->resource); + return 0; + } + +@@ -425,28 +425,28 @@ static int cxl_probe_regs(struct cxl_register_map *map) + { + struct cxl_component_reg_map *comp_map; + struct cxl_device_reg_map *dev_map; +- struct device *dev = map->dev; ++ struct device *host = map->host; + void __iomem *base = map->base; + + switch (map->reg_type) { + case CXL_REGLOC_RBI_COMPONENT: + comp_map = &map->component_map; +- cxl_probe_component_regs(dev, base, comp_map); +- dev_dbg(dev, "Set up component registers\n"); ++ cxl_probe_component_regs(host, base, comp_map); ++ dev_dbg(host, "Set up component registers\n"); + break; + case CXL_REGLOC_RBI_MEMDEV: + dev_map = &map->device_map; +- cxl_probe_device_regs(dev, base, dev_map); ++ cxl_probe_device_regs(host, base, dev_map); + if (!dev_map->status.valid || !dev_map->mbox.valid || + !dev_map->memdev.valid) { +- dev_err(dev, "registers not found: %s%s%s\n", ++ dev_err(host, "registers not found: %s%s%s\n", + !dev_map->status.valid ? "status " : "", + !dev_map->mbox.valid ? "mbox " : "", + !dev_map->memdev.valid ? "memdev " : ""); + return -ENXIO; + } + +- dev_dbg(dev, "Probing device registers...\n"); ++ dev_dbg(host, "Probing device registers...\n"); + break; + default: + break; +diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h +index 76d92561af294..b5b015b661eae 100644 +--- a/drivers/cxl/cxl.h ++++ b/drivers/cxl/cxl.h +@@ -247,7 +247,7 @@ struct cxl_pmu_reg_map { + + /** + * struct cxl_register_map - DVSEC harvested register block mapping parameters +- * @dev: device for devm operations and logging ++ * @host: device for devm operations and logging + * @base: virtual base of the register-block-BAR + @block_offset + * @resource: physical resource base of the register block + * @max_size: maximum mapping size to perform register search +@@ -257,7 +257,7 @@ struct cxl_pmu_reg_map { + * @pmu_map: cxl_reg_maps for CXL Performance Monitoring Units + */ + struct cxl_register_map { +- struct device *dev; ++ struct device *host; + void __iomem *base; + resource_size_t resource; + resource_size_t max_size; +diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c +index 33c48370a830c..8bece1e2e2491 100644 +--- a/drivers/cxl/pci.c ++++ b/drivers/cxl/pci.c +@@ -474,7 +474,7 @@ static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev, + resource_size_t component_reg_phys; + + *map = (struct cxl_register_map) { +- .dev = &pdev->dev, ++ .host = &pdev->dev, + .resource = CXL_RESOURCE_NONE, + }; + +-- +2.42.0 + diff --git a/queue-6.6/cxl-hdm-remove-broken-error-path.patch b/queue-6.6/cxl-hdm-remove-broken-error-path.patch new file mode 100644 index 00000000000..7c3fd6d5a80 --- /dev/null +++ b/queue-6.6/cxl-hdm-remove-broken-error-path.patch @@ -0,0 +1,103 @@ +From a2a4766cb3a4b250190217bcaf0a467cd069363d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Oct 2023 14:09:19 -0700 +Subject: cxl/hdm: Remove broken error path + +From: Dan Williams + +[ Upstream commit 5d09c63f11f083707b60c8ea0bb420651c47740f ] + +Dan reports that cxl_decoder_commit() potentially leaks a hold of +cxl_dpa_rwsem. The potential error case is a "should not" happen +scenario, turn it into a "can not" happen scenario by adding the error +check to cxl_port_setup_targets() where other setting validation occurs. + +Reported-by: Dan Carpenter +Closes: http://lore.kernel.org/r/63295673-5d63-4919-b851-3b06d48734c0@moroto.mountain +Reviewed-by: Dave Jiang +Reviewed-by: Ira Weiny +Fixes: 176baefb2eb5 ("cxl/hdm: Commit decoder state to hardware") +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/hdm.c | 19 ++----------------- + drivers/cxl/core/region.c | 8 ++++++++ + 2 files changed, 10 insertions(+), 17 deletions(-) + +diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c +index 3ad0d39d3d3fa..64e86b786db52 100644 +--- a/drivers/cxl/core/hdm.c ++++ b/drivers/cxl/core/hdm.c +@@ -575,17 +575,11 @@ static void cxld_set_type(struct cxl_decoder *cxld, u32 *ctrl) + CXL_HDM_DECODER0_CTRL_HOSTONLY); + } + +-static int cxlsd_set_targets(struct cxl_switch_decoder *cxlsd, u64 *tgt) ++static void cxlsd_set_targets(struct cxl_switch_decoder *cxlsd, u64 *tgt) + { + struct cxl_dport **t = &cxlsd->target[0]; + int ways = cxlsd->cxld.interleave_ways; + +- if (dev_WARN_ONCE(&cxlsd->cxld.dev, +- ways > 8 || ways > cxlsd->nr_targets, +- "ways: %d overflows targets: %d\n", ways, +- cxlsd->nr_targets)) +- return -ENXIO; +- + *tgt = FIELD_PREP(GENMASK(7, 0), t[0]->port_id); + if (ways > 1) + *tgt |= FIELD_PREP(GENMASK(15, 8), t[1]->port_id); +@@ -601,8 +595,6 @@ static int cxlsd_set_targets(struct cxl_switch_decoder *cxlsd, u64 *tgt) + *tgt |= FIELD_PREP(GENMASK_ULL(55, 48), t[6]->port_id); + if (ways > 7) + *tgt |= FIELD_PREP(GENMASK_ULL(63, 56), t[7]->port_id); +- +- return 0; + } + + /* +@@ -689,13 +681,7 @@ static int cxl_decoder_commit(struct cxl_decoder *cxld) + void __iomem *tl_lo = hdm + CXL_HDM_DECODER0_TL_LOW(id); + u64 targets; + +- rc = cxlsd_set_targets(cxlsd, &targets); +- if (rc) { +- dev_dbg(&port->dev, "%s: target configuration error\n", +- dev_name(&cxld->dev)); +- goto err; +- } +- ++ cxlsd_set_targets(cxlsd, &targets); + writel(upper_32_bits(targets), tl_hi); + writel(lower_32_bits(targets), tl_lo); + } else { +@@ -713,7 +699,6 @@ static int cxl_decoder_commit(struct cxl_decoder *cxld) + + port->commit_end++; + rc = cxld_await_commit(hdm, cxld->id); +-err: + if (rc) { + dev_dbg(&port->dev, "%s: error %d committing decoder\n", + dev_name(&cxld->dev), rc); +diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c +index d1f513800c10d..85c0881fba442 100644 +--- a/drivers/cxl/core/region.c ++++ b/drivers/cxl/core/region.c +@@ -1189,6 +1189,14 @@ static int cxl_port_setup_targets(struct cxl_port *port, + return rc; + } + ++ if (iw > 8 || iw > cxlsd->nr_targets) { ++ dev_dbg(&cxlr->dev, ++ "%s:%s:%s: ways: %d overflows targets: %d\n", ++ dev_name(port->uport_dev), dev_name(&port->dev), ++ dev_name(&cxld->dev), iw, cxlsd->nr_targets); ++ return -ENXIO; ++ } ++ + if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) { + if (cxld->interleave_ways != iw || + cxld->interleave_granularity != ig || +-- +2.42.0 + diff --git a/queue-6.6/cxl-mem-fix-shutdown-order.patch b/queue-6.6/cxl-mem-fix-shutdown-order.patch new file mode 100644 index 00000000000..8e41e28d41a --- /dev/null +++ b/queue-6.6/cxl-mem-fix-shutdown-order.patch @@ -0,0 +1,84 @@ +From a13d9bd2ee3ad27c601468614c42d3867015acce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Sep 2023 18:02:07 -0700 +Subject: cxl/mem: Fix shutdown order + +From: Dan Williams + +[ Upstream commit 88d3917f82ed4215a2154432c26de1480a61b209 ] + +Ira reports that removing cxl_mock_mem causes a crash with the following +trace: + + BUG: kernel NULL pointer dereference, address: 0000000000000044 + [..] + RIP: 0010:cxl_region_decode_reset+0x7f/0x180 [cxl_core] + [..] + Call Trace: + + cxl_region_detach+0xe8/0x210 [cxl_core] + cxl_decoder_kill_region+0x27/0x40 [cxl_core] + cxld_unregister+0x29/0x40 [cxl_core] + devres_release_all+0xb8/0x110 + device_unbind_cleanup+0xe/0x70 + device_release_driver_internal+0x1d2/0x210 + bus_remove_device+0xd7/0x150 + device_del+0x155/0x3e0 + device_unregister+0x13/0x60 + devm_release_action+0x4d/0x90 + ? __pfx_unregister_port+0x10/0x10 [cxl_core] + delete_endpoint+0x121/0x130 [cxl_core] + devres_release_all+0xb8/0x110 + device_unbind_cleanup+0xe/0x70 + device_release_driver_internal+0x1d2/0x210 + bus_remove_device+0xd7/0x150 + device_del+0x155/0x3e0 + ? lock_release+0x142/0x290 + cdev_device_del+0x15/0x50 + cxl_memdev_unregister+0x54/0x70 [cxl_core] + +This crash is due to the clearing out the cxl_memdev's driver context +(@cxlds) before the subsystem is done with it. This is ultimately due to +the region(s), that this memdev is a member, being torn down and expecting +to be able to de-reference @cxlds, like here: + +static int cxl_region_decode_reset(struct cxl_region *cxlr, int count) +... + if (cxlds->rcd) + goto endpoint_reset; +... + +Fix it by keeping the driver context valid until memdev-device +unregistration, and subsequently the entire stack of related +dependencies, unwinds. + +Fixes: 9cc238c7a526 ("cxl/pci: Introduce cdevm_file_operations") +Reported-by: Ira Weiny +Reviewed-by: Davidlohr Bueso +Reviewed-by: Dave Jiang +Reviewed-by: Jonathan Cameron +Reviewed-by: Ira Weiny +Tested-by: Ira Weiny +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/memdev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c +index a02061028b710..fed9573cf355e 100644 +--- a/drivers/cxl/core/memdev.c ++++ b/drivers/cxl/core/memdev.c +@@ -559,8 +559,8 @@ static void cxl_memdev_unregister(void *_cxlmd) + struct cxl_memdev *cxlmd = _cxlmd; + struct device *dev = &cxlmd->dev; + +- cxl_memdev_shutdown(dev); + cdev_device_del(&cxlmd->cdev, dev); ++ cxl_memdev_shutdown(dev); + put_device(dev); + } + +-- +2.42.0 + diff --git a/queue-6.6/cxl-memdev-fix-sanitize-vs-decoder-setup-locking.patch b/queue-6.6/cxl-memdev-fix-sanitize-vs-decoder-setup-locking.patch new file mode 100644 index 00000000000..07a4fcb7969 --- /dev/null +++ b/queue-6.6/cxl-memdev-fix-sanitize-vs-decoder-setup-locking.patch @@ -0,0 +1,332 @@ +From 9fc79c96e028568ef26771a8fe60424c444207c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 18:35:01 -0700 +Subject: cxl/memdev: Fix sanitize vs decoder setup locking + +From: Dan Williams + +[ Upstream commit 339818380868e34ff2c482db05031bf47a67d609 ] + +The sanitize operation is destructive and the expectation is that the +device is unmapped while in progress. The current implementation does a +lockless check for decoders being active, but then does nothing to +prevent decoders from racing to be committed. Introduce state tracking +to resolve this race. + +This incidentally cleans up unpriveleged userspace from triggering mmio +read cycles by spinning on reading the 'security/state' attribute. Which +at a minimum is a waste since the kernel state machine can cache the +completion result. + +Lastly cxl_mem_sanitize() was mistakenly marked EXPORT_SYMBOL() in the +original implementation, but an export was never required. + +Fixes: 0c36b6ad436a ("cxl/mbox: Add sanitization handling machinery") +Cc: Davidlohr Bueso +Reviewed-by: Jonathan Cameron +Reviewed-by: Davidlohr Bueso +Reviewed-by: Dave Jiang +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/core.h | 1 + + drivers/cxl/core/hdm.c | 19 ++++++++++++++ + drivers/cxl/core/mbox.c | 55 ++++++++++++++++++++++++++++----------- + drivers/cxl/core/memdev.c | 43 ++++++++++++------------------ + drivers/cxl/core/port.c | 6 +++++ + drivers/cxl/core/region.c | 6 ----- + drivers/cxl/cxlmem.h | 4 ++- + drivers/cxl/pci.c | 5 ++++ + 8 files changed, 90 insertions(+), 49 deletions(-) + +diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h +index 45e7e044cf4a0..8e5f3d84311e5 100644 +--- a/drivers/cxl/core/core.h ++++ b/drivers/cxl/core/core.h +@@ -75,6 +75,7 @@ resource_size_t __rcrb_to_component(struct device *dev, + enum cxl_rcrb which); + + extern struct rw_semaphore cxl_dpa_rwsem; ++extern struct rw_semaphore cxl_region_rwsem; + + int cxl_memdev_init(void); + void cxl_memdev_exit(void); +diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c +index 4449b34a80cc9..506c9e14cdf98 100644 +--- a/drivers/cxl/core/hdm.c ++++ b/drivers/cxl/core/hdm.c +@@ -650,6 +650,25 @@ static int cxl_decoder_commit(struct cxl_decoder *cxld) + return -EBUSY; + } + ++ /* ++ * For endpoint decoders hosted on CXL memory devices that ++ * support the sanitize operation, make sure sanitize is not in-flight. ++ */ ++ if (is_endpoint_decoder(&cxld->dev)) { ++ struct cxl_endpoint_decoder *cxled = ++ to_cxl_endpoint_decoder(&cxld->dev); ++ struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); ++ struct cxl_memdev_state *mds = ++ to_cxl_memdev_state(cxlmd->cxlds); ++ ++ if (mds && mds->security.sanitize_active) { ++ dev_dbg(&cxlmd->dev, ++ "attempted to commit %s during sanitize\n", ++ dev_name(&cxld->dev)); ++ return -EBUSY; ++ } ++ } ++ + down_read(&cxl_dpa_rwsem); + /* common decoder settings */ + ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(cxld->id)); +diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c +index 4df4f614f490e..b91bb98869917 100644 +--- a/drivers/cxl/core/mbox.c ++++ b/drivers/cxl/core/mbox.c +@@ -1125,20 +1125,7 @@ int cxl_dev_state_identify(struct cxl_memdev_state *mds) + } + EXPORT_SYMBOL_NS_GPL(cxl_dev_state_identify, CXL); + +-/** +- * cxl_mem_sanitize() - Send a sanitization command to the device. +- * @mds: The device data for the operation +- * @cmd: The specific sanitization command opcode +- * +- * Return: 0 if the command was executed successfully, regardless of +- * whether or not the actual security operation is done in the background, +- * such as for the Sanitize case. +- * Error return values can be the result of the mailbox command, -EINVAL +- * when security requirements are not met or invalid contexts. +- * +- * See CXL 3.0 @8.2.9.8.5.1 Sanitize and @8.2.9.8.5.2 Secure Erase. +- */ +-int cxl_mem_sanitize(struct cxl_memdev_state *mds, u16 cmd) ++static int __cxl_mem_sanitize(struct cxl_memdev_state *mds, u16 cmd) + { + int rc; + u32 sec_out = 0; +@@ -1183,7 +1170,45 @@ int cxl_mem_sanitize(struct cxl_memdev_state *mds, u16 cmd) + + return 0; + } +-EXPORT_SYMBOL_NS_GPL(cxl_mem_sanitize, CXL); ++ ++ ++/** ++ * cxl_mem_sanitize() - Send a sanitization command to the device. ++ * @cxlmd: The device for the operation ++ * @cmd: The specific sanitization command opcode ++ * ++ * Return: 0 if the command was executed successfully, regardless of ++ * whether or not the actual security operation is done in the background, ++ * such as for the Sanitize case. ++ * Error return values can be the result of the mailbox command, -EINVAL ++ * when security requirements are not met or invalid contexts, or -EBUSY ++ * if the sanitize operation is already in flight. ++ * ++ * See CXL 3.0 @8.2.9.8.5.1 Sanitize and @8.2.9.8.5.2 Secure Erase. ++ */ ++int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd) ++{ ++ struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); ++ struct cxl_port *endpoint; ++ int rc; ++ ++ /* synchronize with cxl_mem_probe() and decoder write operations */ ++ device_lock(&cxlmd->dev); ++ endpoint = cxlmd->endpoint; ++ down_read(&cxl_region_rwsem); ++ /* ++ * Require an endpoint to be safe otherwise the driver can not ++ * be sure that the device is unmapped. ++ */ ++ if (endpoint && endpoint->commit_end == -1) ++ rc = __cxl_mem_sanitize(mds, cmd); ++ else ++ rc = -EBUSY; ++ up_read(&cxl_region_rwsem); ++ device_unlock(&cxlmd->dev); ++ ++ return rc; ++} + + static int add_dpa_res(struct device *dev, struct resource *parent, + struct resource *res, resource_size_t start, +diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c +index 4c2e24a1a89c2..a02061028b710 100644 +--- a/drivers/cxl/core/memdev.c ++++ b/drivers/cxl/core/memdev.c +@@ -125,13 +125,16 @@ static ssize_t security_state_show(struct device *dev, + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); + struct cxl_dev_state *cxlds = cxlmd->cxlds; + struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds); +- u64 reg = readq(cxlds->regs.mbox + CXLDEV_MBOX_BG_CMD_STATUS_OFFSET); +- u32 pct = FIELD_GET(CXLDEV_MBOX_BG_CMD_COMMAND_PCT_MASK, reg); +- u16 cmd = FIELD_GET(CXLDEV_MBOX_BG_CMD_COMMAND_OPCODE_MASK, reg); + unsigned long state = mds->security.state; ++ int rc = 0; + +- if (cmd == CXL_MBOX_OP_SANITIZE && pct != 100) +- return sysfs_emit(buf, "sanitize\n"); ++ /* sync with latest submission state */ ++ mutex_lock(&mds->mbox_mutex); ++ if (mds->security.sanitize_active) ++ rc = sysfs_emit(buf, "sanitize\n"); ++ mutex_unlock(&mds->mbox_mutex); ++ if (rc) ++ return rc; + + if (!(state & CXL_PMEM_SEC_STATE_USER_PASS_SET)) + return sysfs_emit(buf, "disabled\n"); +@@ -152,24 +155,17 @@ static ssize_t security_sanitize_store(struct device *dev, + const char *buf, size_t len) + { + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); +- struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); +- struct cxl_port *port = cxlmd->endpoint; + bool sanitize; + ssize_t rc; + + if (kstrtobool(buf, &sanitize) || !sanitize) + return -EINVAL; + +- if (!port || !is_cxl_endpoint(port)) +- return -EINVAL; +- +- /* ensure no regions are mapped to this memdev */ +- if (port->commit_end != -1) +- return -EBUSY; +- +- rc = cxl_mem_sanitize(mds, CXL_MBOX_OP_SANITIZE); ++ rc = cxl_mem_sanitize(cxlmd, CXL_MBOX_OP_SANITIZE); ++ if (rc) ++ return rc; + +- return rc ? rc : len; ++ return len; + } + static struct device_attribute dev_attr_security_sanitize = + __ATTR(sanitize, 0200, NULL, security_sanitize_store); +@@ -179,24 +175,17 @@ static ssize_t security_erase_store(struct device *dev, + const char *buf, size_t len) + { + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); +- struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); +- struct cxl_port *port = cxlmd->endpoint; + ssize_t rc; + bool erase; + + if (kstrtobool(buf, &erase) || !erase) + return -EINVAL; + +- if (!port || !is_cxl_endpoint(port)) +- return -EINVAL; +- +- /* ensure no regions are mapped to this memdev */ +- if (port->commit_end != -1) +- return -EBUSY; +- +- rc = cxl_mem_sanitize(mds, CXL_MBOX_OP_SECURE_ERASE); ++ rc = cxl_mem_sanitize(cxlmd, CXL_MBOX_OP_SECURE_ERASE); ++ if (rc) ++ return rc; + +- return rc ? rc : len; ++ return len; + } + static struct device_attribute dev_attr_security_erase = + __ATTR(erase, 0200, NULL, security_erase_store); +diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c +index 7ca01a834e188..5ba606c6e03ff 100644 +--- a/drivers/cxl/core/port.c ++++ b/drivers/cxl/core/port.c +@@ -28,6 +28,12 @@ + * instantiated by the core. + */ + ++/* ++ * All changes to the interleave configuration occur with this lock held ++ * for write. ++ */ ++DECLARE_RWSEM(cxl_region_rwsem); ++ + static DEFINE_IDA(cxl_port_ida); + static DEFINE_XARRAY(cxl_root_buses); + +diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c +index 6d63b8798c299..d74bf1b664b6c 100644 +--- a/drivers/cxl/core/region.c ++++ b/drivers/cxl/core/region.c +@@ -28,12 +28,6 @@ + * 3. Decoder targets + */ + +-/* +- * All changes to the interleave configuration occur with this lock held +- * for write. +- */ +-static DECLARE_RWSEM(cxl_region_rwsem); +- + static struct cxl_region *to_cxl_region(struct device *dev); + + static ssize_t uuid_show(struct device *dev, struct device_attribute *attr, +diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h +index fbdee1d637175..6933bc20e76b6 100644 +--- a/drivers/cxl/cxlmem.h ++++ b/drivers/cxl/cxlmem.h +@@ -364,6 +364,7 @@ struct cxl_fw_state { + * @state: state of last security operation + * @enabled_cmds: All security commands enabled in the CEL + * @poll_tmo_secs: polling timeout ++ * @sanitize_active: sanitize completion pending + * @poll_dwork: polling work item + * @sanitize_node: sanitation sysfs file to notify + */ +@@ -371,6 +372,7 @@ struct cxl_security_state { + unsigned long state; + DECLARE_BITMAP(enabled_cmds, CXL_SEC_ENABLED_MAX); + int poll_tmo_secs; ++ bool sanitize_active; + struct delayed_work poll_dwork; + struct kernfs_node *sanitize_node; + }; +@@ -884,7 +886,7 @@ static inline void cxl_mem_active_dec(void) + } + #endif + +-int cxl_mem_sanitize(struct cxl_memdev_state *mds, u16 cmd); ++int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd); + + struct cxl_hdm { + struct cxl_component_regs regs; +diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c +index 05f3d14921e6a..33c48370a830c 100644 +--- a/drivers/cxl/pci.c ++++ b/drivers/cxl/pci.c +@@ -154,6 +154,7 @@ static void cxl_mbox_sanitize_work(struct work_struct *work) + mds->security.poll_tmo_secs = 0; + if (mds->security.sanitize_node) + sysfs_notify_dirent(mds->security.sanitize_node); ++ mds->security.sanitize_active = false; + + dev_dbg(cxlds->dev, "Sanitization operation ended\n"); + } else { +@@ -292,9 +293,13 @@ static int __cxl_pci_mbox_send_cmd(struct cxl_memdev_state *mds, + * and allow userspace to poll(2) for completion. + */ + if (mbox_cmd->opcode == CXL_MBOX_OP_SANITIZE) { ++ if (mds->security.sanitize_active) ++ return -EBUSY; ++ + /* give first timeout a second */ + timeout = 1; + mds->security.poll_tmo_secs = timeout; ++ mds->security.sanitize_active = true; + schedule_delayed_work(&mds->security.poll_dwork, + timeout * HZ); + dev_dbg(dev, "Sanitization operation started\n"); +-- +2.42.0 + diff --git a/queue-6.6/cxl-pci-clarify-devm-host-for-memdev-relative-setup.patch b/queue-6.6/cxl-pci-clarify-devm-host-for-memdev-relative-setup.patch new file mode 100644 index 00000000000..df40d9c1a6c --- /dev/null +++ b/queue-6.6/cxl-pci-clarify-devm-host-for-memdev-relative-setup.patch @@ -0,0 +1,146 @@ +From bf72c2996ed4da61659e35cfd541626219a7a3e6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 16:04:49 -0700 +Subject: cxl/pci: Clarify devm host for memdev relative setup + +From: Dan Williams + +[ Upstream commit f29a824b0b6710328a78b018de3c2cfa9db65876 ] + +It is all too easy to get confused about @dev usage in the CXL driver +stack. Before adding a new cxl_pci_probe() setup operation that has a +devm lifetime dependent on @cxlds->dev binding, but also references +@cxlmd->dev, and prints messages, rework the devm_cxl_add_memdev() and +cxl_memdev_setup_fw_upload() function signatures to make this +distinction explicit. I.e. pass in the devm context as an @host argument +rather than infer it from other objects. + +This is in preparation for adding a devm_cxl_sanitize_setup_notifier(). + +Note the whitespace fixup near the change of the devm_cxl_add_memdev() +signature. That uncaught typo originated in the patch that added +cxl_memdev_security_init(). + +Reviewed-by: Jonathan Cameron +Reviewed-by: Ira Weiny +Reviewed-by: Dave Jiang +Signed-off-by: Dan Williams +Stable-dep-of: 5f2da1971446 ("cxl/pci: Fix sanitize notifier setup") +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/memdev.c | 16 ++++++++-------- + drivers/cxl/cxlmem.h | 5 +++-- + drivers/cxl/pci.c | 4 ++-- + tools/testing/cxl/test/mem.c | 4 ++-- + 4 files changed, 15 insertions(+), 14 deletions(-) + +diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c +index 6efe4e2a2cf53..63353d9903745 100644 +--- a/drivers/cxl/core/memdev.c ++++ b/drivers/cxl/core/memdev.c +@@ -960,12 +960,12 @@ static const struct fw_upload_ops cxl_memdev_fw_ops = { + .cleanup = cxl_fw_cleanup, + }; + +-static void devm_cxl_remove_fw_upload(void *fwl) ++static void cxl_remove_fw_upload(void *fwl) + { + firmware_upload_unregister(fwl); + } + +-int cxl_memdev_setup_fw_upload(struct cxl_memdev_state *mds) ++int devm_cxl_setup_fw_upload(struct device *host, struct cxl_memdev_state *mds) + { + struct cxl_dev_state *cxlds = &mds->cxlds; + struct device *dev = &cxlds->cxlmd->dev; +@@ -978,10 +978,9 @@ int cxl_memdev_setup_fw_upload(struct cxl_memdev_state *mds) + &cxl_memdev_fw_ops, mds); + if (IS_ERR(fwl)) + return PTR_ERR(fwl); +- +- return devm_add_action_or_reset(cxlds->dev, devm_cxl_remove_fw_upload, fwl); ++ return devm_add_action_or_reset(host, cxl_remove_fw_upload, fwl); + } +-EXPORT_SYMBOL_NS_GPL(cxl_memdev_setup_fw_upload, CXL); ++EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_fw_upload, CXL); + + static const struct file_operations cxl_memdev_fops = { + .owner = THIS_MODULE, +@@ -1019,9 +1018,10 @@ static int cxl_memdev_security_init(struct cxl_memdev *cxlmd) + } + + return devm_add_action_or_reset(cxlds->dev, put_sanitize, mds); +- } ++} + +-struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds) ++struct cxl_memdev *devm_cxl_add_memdev(struct device *host, ++ struct cxl_dev_state *cxlds) + { + struct cxl_memdev *cxlmd; + struct device *dev; +@@ -1053,7 +1053,7 @@ struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds) + if (rc) + goto err; + +- rc = devm_add_action_or_reset(cxlds->dev, cxl_memdev_unregister, cxlmd); ++ rc = devm_add_action_or_reset(host, cxl_memdev_unregister, cxlmd); + if (rc) + return ERR_PTR(rc); + return cxlmd; +diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h +index 55f00ad17a772..fdb2c8dd98d0f 100644 +--- a/drivers/cxl/cxlmem.h ++++ b/drivers/cxl/cxlmem.h +@@ -84,9 +84,10 @@ static inline bool is_cxl_endpoint(struct cxl_port *port) + return is_cxl_memdev(port->uport_dev); + } + +-struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds); ++struct cxl_memdev *devm_cxl_add_memdev(struct device *host, ++ struct cxl_dev_state *cxlds); + struct cxl_memdev_state; +-int cxl_memdev_setup_fw_upload(struct cxl_memdev_state *mds); ++int devm_cxl_setup_fw_upload(struct device *host, struct cxl_memdev_state *mds); + int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled, + resource_size_t base, resource_size_t len, + resource_size_t skipped); +diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c +index 49d9b2ef5c5c0..58894b8b59dac 100644 +--- a/drivers/cxl/pci.c ++++ b/drivers/cxl/pci.c +@@ -867,11 +867,11 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + if (rc) + return rc; + +- cxlmd = devm_cxl_add_memdev(cxlds); ++ cxlmd = devm_cxl_add_memdev(&pdev->dev, cxlds); + if (IS_ERR(cxlmd)) + return PTR_ERR(cxlmd); + +- rc = cxl_memdev_setup_fw_upload(mds); ++ rc = devm_cxl_setup_fw_upload(&pdev->dev, mds); + if (rc) + return rc; + +diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c +index 464fc39ed2776..68118c37f0b56 100644 +--- a/tools/testing/cxl/test/mem.c ++++ b/tools/testing/cxl/test/mem.c +@@ -1450,11 +1450,11 @@ static int cxl_mock_mem_probe(struct platform_device *pdev) + mdata->mes.mds = mds; + cxl_mock_add_event_logs(&mdata->mes); + +- cxlmd = devm_cxl_add_memdev(cxlds); ++ cxlmd = devm_cxl_add_memdev(&pdev->dev, cxlds); + if (IS_ERR(cxlmd)) + return PTR_ERR(cxlmd); + +- rc = cxl_memdev_setup_fw_upload(mds); ++ rc = devm_cxl_setup_fw_upload(&pdev->dev, mds); + if (rc) + return rc; + +-- +2.42.0 + diff --git a/queue-6.6/cxl-pci-cleanup-sanitize-to-always-poll.patch b/queue-6.6/cxl-pci-cleanup-sanitize-to-always-poll.patch new file mode 100644 index 00000000000..6dac09859e4 --- /dev/null +++ b/queue-6.6/cxl-pci-cleanup-sanitize-to-always-poll.patch @@ -0,0 +1,185 @@ +From a86ffc4e26ef43b45b26b0af02c750a8ab509fa6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 12:44:20 -0700 +Subject: cxl/pci: Cleanup 'sanitize' to always poll + +From: Dan Williams + +[ Upstream commit e30a106558e7d1e06d1fcfd12466dc646673d03d ] + +In preparation for fixing the init/teardown of the 'sanitize' workqueue +and sysfs notification mechanism, arrange for cxl_mbox_sanitize_work() +to be the single location where the sysfs attribute is notified. With +that change there is no distinction between polled mode and interrupt +mode. All the interrupt does is accelerate the polling interval. + +The change to check for "mds->security.sanitize_node" under the lock is +there to ensure that the interrupt, the work routine and the +setup/teardown code can all have a consistent view of the registered +notifier and the workqueue state. I.e. the expectation is that the +interrupt is live past the point that the sanitize sysfs attribute is +published, and it may race teardown, so it must be consulted under a +lock. Given that new locking requirement, cxl_pci_mbox_irq() is moved +from hard to thread irq context. + +Lastly, some opportunistic replacements of +"queue_delayed_work(system_wq, ...)", which is just open coded +schedule_delayed_work(), are included. + +Reviewed-by: Dave Jiang +Reviewed-by: Jonathan Cameron +Reviewed-by: Ira Weiny +Reviewed-by: Davidlohr Bueso +Signed-off-by: Dan Williams +Stable-dep-of: 5f2da1971446 ("cxl/pci: Fix sanitize notifier setup") +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/memdev.c | 3 +- + drivers/cxl/cxlmem.h | 2 -- + drivers/cxl/pci.c | 60 ++++++++++++++++----------------------- + 3 files changed, 26 insertions(+), 39 deletions(-) + +diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c +index 14b547c07f547..2a7a07f6d1652 100644 +--- a/drivers/cxl/core/memdev.c ++++ b/drivers/cxl/core/memdev.c +@@ -561,8 +561,7 @@ static void cxl_memdev_security_shutdown(struct device *dev) + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); + struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); + +- if (mds->security.poll) +- cancel_delayed_work_sync(&mds->security.poll_dwork); ++ cancel_delayed_work_sync(&mds->security.poll_dwork); + } + + static void cxl_memdev_shutdown(struct device *dev) +diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h +index 706f8a6d1ef43..55f00ad17a772 100644 +--- a/drivers/cxl/cxlmem.h ++++ b/drivers/cxl/cxlmem.h +@@ -360,7 +360,6 @@ struct cxl_fw_state { + * + * @state: state of last security operation + * @enabled_cmds: All security commands enabled in the CEL +- * @poll: polling for sanitization is enabled, device has no mbox irq support + * @poll_tmo_secs: polling timeout + * @poll_dwork: polling work item + * @sanitize_node: sanitation sysfs file to notify +@@ -368,7 +367,6 @@ struct cxl_fw_state { + struct cxl_security_state { + unsigned long state; + DECLARE_BITMAP(enabled_cmds, CXL_SEC_ENABLED_MAX); +- bool poll; + int poll_tmo_secs; + struct delayed_work poll_dwork; + struct kernfs_node *sanitize_node; +diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c +index aa1b3dd9e64c4..49d9b2ef5c5c0 100644 +--- a/drivers/cxl/pci.c ++++ b/drivers/cxl/pci.c +@@ -128,10 +128,10 @@ static irqreturn_t cxl_pci_mbox_irq(int irq, void *id) + reg = readq(cxlds->regs.mbox + CXLDEV_MBOX_BG_CMD_STATUS_OFFSET); + opcode = FIELD_GET(CXLDEV_MBOX_BG_CMD_COMMAND_OPCODE_MASK, reg); + if (opcode == CXL_MBOX_OP_SANITIZE) { ++ mutex_lock(&mds->mbox_mutex); + if (mds->security.sanitize_node) +- sysfs_notify_dirent(mds->security.sanitize_node); +- +- dev_dbg(cxlds->dev, "Sanitization operation ended\n"); ++ mod_delayed_work(system_wq, &mds->security.poll_dwork, 0); ++ mutex_unlock(&mds->mbox_mutex); + } else { + /* short-circuit the wait in __cxl_pci_mbox_send_cmd() */ + rcuwait_wake_up(&mds->mbox_wait); +@@ -160,8 +160,7 @@ static void cxl_mbox_sanitize_work(struct work_struct *work) + int timeout = mds->security.poll_tmo_secs + 10; + + mds->security.poll_tmo_secs = min(15 * 60, timeout); +- queue_delayed_work(system_wq, &mds->security.poll_dwork, +- timeout * HZ); ++ schedule_delayed_work(&mds->security.poll_dwork, timeout * HZ); + } + mutex_unlock(&mds->mbox_mutex); + } +@@ -293,15 +292,11 @@ static int __cxl_pci_mbox_send_cmd(struct cxl_memdev_state *mds, + * and allow userspace to poll(2) for completion. + */ + if (mbox_cmd->opcode == CXL_MBOX_OP_SANITIZE) { +- if (mds->security.poll) { +- /* give first timeout a second */ +- timeout = 1; +- mds->security.poll_tmo_secs = timeout; +- queue_delayed_work(system_wq, +- &mds->security.poll_dwork, +- timeout * HZ); +- } +- ++ /* give first timeout a second */ ++ timeout = 1; ++ mds->security.poll_tmo_secs = timeout; ++ schedule_delayed_work(&mds->security.poll_dwork, ++ timeout * HZ); + dev_dbg(dev, "Sanitization operation started\n"); + goto success; + } +@@ -384,7 +379,9 @@ static int cxl_pci_setup_mailbox(struct cxl_memdev_state *mds) + const int cap = readl(cxlds->regs.mbox + CXLDEV_MBOX_CAPS_OFFSET); + struct device *dev = cxlds->dev; + unsigned long timeout; ++ int irq, msgnum; + u64 md_status; ++ u32 ctrl; + + timeout = jiffies + mbox_ready_timeout * HZ; + do { +@@ -432,33 +429,26 @@ static int cxl_pci_setup_mailbox(struct cxl_memdev_state *mds) + dev_dbg(dev, "Mailbox payload sized %zu", mds->payload_size); + + rcuwait_init(&mds->mbox_wait); ++ INIT_DELAYED_WORK(&mds->security.poll_dwork, cxl_mbox_sanitize_work); + +- if (cap & CXLDEV_MBOX_CAP_BG_CMD_IRQ) { +- u32 ctrl; +- int irq, msgnum; +- struct pci_dev *pdev = to_pci_dev(cxlds->dev); +- +- msgnum = FIELD_GET(CXLDEV_MBOX_CAP_IRQ_MSGNUM_MASK, cap); +- irq = pci_irq_vector(pdev, msgnum); +- if (irq < 0) +- goto mbox_poll; +- +- if (cxl_request_irq(cxlds, irq, cxl_pci_mbox_irq, NULL)) +- goto mbox_poll; ++ /* background command interrupts are optional */ ++ if (!(cap & CXLDEV_MBOX_CAP_BG_CMD_IRQ)) ++ return 0; + +- /* enable background command mbox irq support */ +- ctrl = readl(cxlds->regs.mbox + CXLDEV_MBOX_CTRL_OFFSET); +- ctrl |= CXLDEV_MBOX_CTRL_BG_CMD_IRQ; +- writel(ctrl, cxlds->regs.mbox + CXLDEV_MBOX_CTRL_OFFSET); ++ msgnum = FIELD_GET(CXLDEV_MBOX_CAP_IRQ_MSGNUM_MASK, cap); ++ irq = pci_irq_vector(to_pci_dev(cxlds->dev), msgnum); ++ if (irq < 0) ++ return 0; + ++ if (cxl_request_irq(cxlds, irq, NULL, cxl_pci_mbox_irq)) + return 0; +- } + +-mbox_poll: +- mds->security.poll = true; +- INIT_DELAYED_WORK(&mds->security.poll_dwork, cxl_mbox_sanitize_work); ++ dev_dbg(cxlds->dev, "Mailbox interrupts enabled\n"); ++ /* enable background command mbox irq support */ ++ ctrl = readl(cxlds->regs.mbox + CXLDEV_MBOX_CTRL_OFFSET); ++ ctrl |= CXLDEV_MBOX_CTRL_BG_CMD_IRQ; ++ writel(ctrl, cxlds->regs.mbox + CXLDEV_MBOX_CTRL_OFFSET); + +- dev_dbg(cxlds->dev, "Mailbox interrupts are unsupported"); + return 0; + } + +-- +2.42.0 + diff --git a/queue-6.6/cxl-pci-fix-sanitize-notifier-setup.patch b/queue-6.6/cxl-pci-fix-sanitize-notifier-setup.patch new file mode 100644 index 00000000000..d34508e1fda --- /dev/null +++ b/queue-6.6/cxl-pci-fix-sanitize-notifier-setup.patch @@ -0,0 +1,199 @@ +From 86812ebbc31ea6948777e68aed80ebca125fc923 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 16:49:36 -0700 +Subject: cxl/pci: Fix sanitize notifier setup + +From: Dan Williams + +[ Upstream commit 5f2da19714465739da2449253b13ac06cb353a26 ] + +Fix a race condition between the mailbox-background command interrupt +firing and the security-state sysfs attribute being removed. + +The race is difficult to see due to the awkward placement of the +sanitize-notifier setup code and the multiple places the teardown calls +are made, cxl_memdev_security_init() and cxl_memdev_security_shutdown(). + +Unify setup in one place, cxl_sanitize_setup_notifier(). Arrange for +the paired cxl_sanitize_teardown_notifier() to safely quiet the notifier +and let the cxl_memdev + irq be unregistered later in the flow. + +Note: The special wrinkle of the sanitize notifier is that it interacts +with interrupts, which are enabled early in the flow, and it interacts +with memdev sysfs which is not initialized until late in the flow. Hence +why this setup routine takes an @cxlmd argument, and not just @mds. + +This fix is also needed as a preparation fix for a memdev unregistration +crash. + +Reported-by: Jonathan Cameron +Closes: http://lore.kernel.org/r/20230929100316.00004546@Huawei.com +Cc: Dave Jiang +Cc: Davidlohr Bueso +Fixes: 0c36b6ad436a ("cxl/mbox: Add sanitization handling machinery") +Reviewed-by: Dave Jiang +Reviewed-by: Ira Weiny +Reviewed-by: Davidlohr Bueso +Reviewed-by: Jonathan Cameron +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/memdev.c | 86 ++++++++++++++++++++------------------- + drivers/cxl/cxlmem.h | 2 + + drivers/cxl/pci.c | 4 ++ + 3 files changed, 50 insertions(+), 42 deletions(-) + +diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c +index 63353d9903745..4c2e24a1a89c2 100644 +--- a/drivers/cxl/core/memdev.c ++++ b/drivers/cxl/core/memdev.c +@@ -556,20 +556,11 @@ void clear_exclusive_cxl_commands(struct cxl_memdev_state *mds, + } + EXPORT_SYMBOL_NS_GPL(clear_exclusive_cxl_commands, CXL); + +-static void cxl_memdev_security_shutdown(struct device *dev) +-{ +- struct cxl_memdev *cxlmd = to_cxl_memdev(dev); +- struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); +- +- cancel_delayed_work_sync(&mds->security.poll_dwork); +-} +- + static void cxl_memdev_shutdown(struct device *dev) + { + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); + + down_write(&cxl_memdev_rwsem); +- cxl_memdev_security_shutdown(dev); + cxlmd->cxlds = NULL; + up_write(&cxl_memdev_rwsem); + } +@@ -991,35 +982,6 @@ static const struct file_operations cxl_memdev_fops = { + .llseek = noop_llseek, + }; + +-static void put_sanitize(void *data) +-{ +- struct cxl_memdev_state *mds = data; +- +- sysfs_put(mds->security.sanitize_node); +-} +- +-static int cxl_memdev_security_init(struct cxl_memdev *cxlmd) +-{ +- struct cxl_dev_state *cxlds = cxlmd->cxlds; +- struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds); +- struct device *dev = &cxlmd->dev; +- struct kernfs_node *sec; +- +- sec = sysfs_get_dirent(dev->kobj.sd, "security"); +- if (!sec) { +- dev_err(dev, "sysfs_get_dirent 'security' failed\n"); +- return -ENODEV; +- } +- mds->security.sanitize_node = sysfs_get_dirent(sec, "state"); +- sysfs_put(sec); +- if (!mds->security.sanitize_node) { +- dev_err(dev, "sysfs_get_dirent 'state' failed\n"); +- return -ENODEV; +- } +- +- return devm_add_action_or_reset(cxlds->dev, put_sanitize, mds); +-} +- + struct cxl_memdev *devm_cxl_add_memdev(struct device *host, + struct cxl_dev_state *cxlds) + { +@@ -1049,10 +1011,6 @@ struct cxl_memdev *devm_cxl_add_memdev(struct device *host, + if (rc) + goto err; + +- rc = cxl_memdev_security_init(cxlmd); +- if (rc) +- goto err; +- + rc = devm_add_action_or_reset(host, cxl_memdev_unregister, cxlmd); + if (rc) + return ERR_PTR(rc); +@@ -1069,6 +1027,50 @@ struct cxl_memdev *devm_cxl_add_memdev(struct device *host, + } + EXPORT_SYMBOL_NS_GPL(devm_cxl_add_memdev, CXL); + ++static void sanitize_teardown_notifier(void *data) ++{ ++ struct cxl_memdev_state *mds = data; ++ struct kernfs_node *state; ++ ++ /* ++ * Prevent new irq triggered invocations of the workqueue and ++ * flush inflight invocations. ++ */ ++ mutex_lock(&mds->mbox_mutex); ++ state = mds->security.sanitize_node; ++ mds->security.sanitize_node = NULL; ++ mutex_unlock(&mds->mbox_mutex); ++ ++ cancel_delayed_work_sync(&mds->security.poll_dwork); ++ sysfs_put(state); ++} ++ ++int devm_cxl_sanitize_setup_notifier(struct device *host, ++ struct cxl_memdev *cxlmd) ++{ ++ struct cxl_dev_state *cxlds = cxlmd->cxlds; ++ struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds); ++ struct kernfs_node *sec; ++ ++ if (!test_bit(CXL_SEC_ENABLED_SANITIZE, mds->security.enabled_cmds)) ++ return 0; ++ ++ /* ++ * Note, the expectation is that @cxlmd would have failed to be ++ * created if these sysfs_get_dirent calls fail. ++ */ ++ sec = sysfs_get_dirent(cxlmd->dev.kobj.sd, "security"); ++ if (!sec) ++ return -ENOENT; ++ mds->security.sanitize_node = sysfs_get_dirent(sec, "state"); ++ sysfs_put(sec); ++ if (!mds->security.sanitize_node) ++ return -ENOENT; ++ ++ return devm_add_action_or_reset(host, sanitize_teardown_notifier, mds); ++} ++EXPORT_SYMBOL_NS_GPL(devm_cxl_sanitize_setup_notifier, CXL); ++ + __init int cxl_memdev_init(void) + { + dev_t devt; +diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h +index fdb2c8dd98d0f..fbdee1d637175 100644 +--- a/drivers/cxl/cxlmem.h ++++ b/drivers/cxl/cxlmem.h +@@ -86,6 +86,8 @@ static inline bool is_cxl_endpoint(struct cxl_port *port) + + struct cxl_memdev *devm_cxl_add_memdev(struct device *host, + struct cxl_dev_state *cxlds); ++int devm_cxl_sanitize_setup_notifier(struct device *host, ++ struct cxl_memdev *cxlmd); + struct cxl_memdev_state; + int devm_cxl_setup_fw_upload(struct device *host, struct cxl_memdev_state *mds); + int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled, +diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c +index 58894b8b59dac..05f3d14921e6a 100644 +--- a/drivers/cxl/pci.c ++++ b/drivers/cxl/pci.c +@@ -875,6 +875,10 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + if (rc) + return rc; + ++ rc = devm_cxl_sanitize_setup_notifier(&pdev->dev, cxlmd); ++ if (rc) ++ return rc; ++ + pmu_count = cxl_count_regblock(pdev, CXL_REGLOC_RBI_PMU); + for (i = 0; i < pmu_count; i++) { + struct cxl_pmu_regs pmu_regs; +-- +2.42.0 + diff --git a/queue-6.6/cxl-pci-remove-inconsistent-usage-of-dev_err_probe.patch b/queue-6.6/cxl-pci-remove-inconsistent-usage-of-dev_err_probe.patch new file mode 100644 index 00000000000..f01ddc4eee2 --- /dev/null +++ b/queue-6.6/cxl-pci-remove-inconsistent-usage-of-dev_err_probe.patch @@ -0,0 +1,62 @@ +From 2ca95c4aa9f203c709b236ffba62ce4fe4b25e04 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 16:24:39 -0700 +Subject: cxl/pci: Remove inconsistent usage of dev_err_probe() + +From: Dan Williams + +[ Upstream commit 2627c995c15dc375f4b5a591d782a14b1c0e3e7d ] + +If dev_err_probe() is to be used it should at least be used consistently +within the same function. It is also worth questioning whether +every potential -ENOMEM needs an explicit error message. + +Remove the cxl_setup_fw_upload() error prints for what are rare / +hardware-independent failures. + +Reviewed-by: Jonathan Cameron +Reviewed-by: Ira Weiny +Reviewed-by: Davidlohr Bueso +Reviewed-by: Dave Jiang +Signed-off-by: Dan Williams +Stable-dep-of: 5f2da1971446 ("cxl/pci: Fix sanitize notifier setup") +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/memdev.c | 13 ++----------- + 1 file changed, 2 insertions(+), 11 deletions(-) + +diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c +index 2a7a07f6d1652..6efe4e2a2cf53 100644 +--- a/drivers/cxl/core/memdev.c ++++ b/drivers/cxl/core/memdev.c +@@ -970,7 +970,6 @@ int cxl_memdev_setup_fw_upload(struct cxl_memdev_state *mds) + struct cxl_dev_state *cxlds = &mds->cxlds; + struct device *dev = &cxlds->cxlmd->dev; + struct fw_upload *fwl; +- int rc; + + if (!test_bit(CXL_MEM_COMMAND_ID_GET_FW_INFO, mds->enabled_cmds)) + return 0; +@@ -978,17 +977,9 @@ int cxl_memdev_setup_fw_upload(struct cxl_memdev_state *mds) + fwl = firmware_upload_register(THIS_MODULE, dev, dev_name(dev), + &cxl_memdev_fw_ops, mds); + if (IS_ERR(fwl)) +- return dev_err_probe(dev, PTR_ERR(fwl), +- "Failed to register firmware loader\n"); +- +- rc = devm_add_action_or_reset(cxlds->dev, devm_cxl_remove_fw_upload, +- fwl); +- if (rc) +- dev_err(dev, +- "Failed to add firmware loader remove action: %d\n", +- rc); ++ return PTR_ERR(fwl); + +- return rc; ++ return devm_add_action_or_reset(cxlds->dev, devm_cxl_remove_fw_upload, fwl); + } + EXPORT_SYMBOL_NS_GPL(cxl_memdev_setup_fw_upload, CXL); + +-- +2.42.0 + diff --git a/queue-6.6/cxl-pci-remove-unnecessary-device-reference-manageme.patch b/queue-6.6/cxl-pci-remove-unnecessary-device-reference-manageme.patch new file mode 100644 index 00000000000..84ced46f350 --- /dev/null +++ b/queue-6.6/cxl-pci-remove-unnecessary-device-reference-manageme.patch @@ -0,0 +1,53 @@ +From 81d697cd89a60604270558e681ae8e3acfea210e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 14:44:46 -0700 +Subject: cxl/pci: Remove unnecessary device reference management in sanitize + work + +From: Dan Williams + +[ Upstream commit 76fe8713dd0a1331d84d767e8e5d3f365d959e8a ] + +Given that any particular put_device() could be the final put of the +device, the fact that there are usages of cxlds->dev after +put_device(cxlds->dev) is a red flag. Drop the reference counting since +the device is pinned by being registered and will not be unregistered +without triggering the driver + workqueue to shutdown. + +Reviewed-by: Dave Jiang +Reviewed-by: Davidlohr Bueso +Reviewed-by: Jonathan Cameron +Reviewed-by: Ira Weiny +Signed-off-by: Dan Williams +Stable-dep-of: 5f2da1971446 ("cxl/pci: Fix sanitize notifier setup") +Signed-off-by: Sasha Levin +--- + drivers/cxl/pci.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c +index 44a21ab7add51..aa1b3dd9e64c4 100644 +--- a/drivers/cxl/pci.c ++++ b/drivers/cxl/pci.c +@@ -152,8 +152,6 @@ static void cxl_mbox_sanitize_work(struct work_struct *work) + mutex_lock(&mds->mbox_mutex); + if (cxl_mbox_background_complete(cxlds)) { + mds->security.poll_tmo_secs = 0; +- put_device(cxlds->dev); +- + if (mds->security.sanitize_node) + sysfs_notify_dirent(mds->security.sanitize_node); + +@@ -296,9 +294,6 @@ static int __cxl_pci_mbox_send_cmd(struct cxl_memdev_state *mds, + */ + if (mbox_cmd->opcode == CXL_MBOX_OP_SANITIZE) { + if (mds->security.poll) { +- /* hold the device throughout */ +- get_device(cxlds->dev); +- + /* give first timeout a second */ + timeout = 1; + mds->security.poll_tmo_secs = timeout; +-- +2.42.0 + diff --git a/queue-6.6/cxl-port-fix-host-confusion-in-cxl_dport_setup_regs.patch b/queue-6.6/cxl-port-fix-host-confusion-in-cxl_dport_setup_regs.patch new file mode 100644 index 00000000000..2f78c69fcdf --- /dev/null +++ b/queue-6.6/cxl-port-fix-host-confusion-in-cxl_dport_setup_regs.patch @@ -0,0 +1,131 @@ +From 6509b70f8bb4497e57e5f1caae925ea67348edbc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Oct 2023 19:16:56 +0200 +Subject: cxl/port: Fix @host confusion in cxl_dport_setup_regs() + +From: Dan Williams + +[ Upstream commit 33d9c987bf8fb68a9292aba7cc4b1711fcb1be4d ] + +commit 5d2ffbe4b81a ("cxl/port: Store the downstream port's Component Register mappings in struct cxl_dport") + +...moved the dport component registers from a raw component_reg_phys +passed in at dport instantiation time to a 'struct cxl_register_map' +populated with both the component register data *and* the "host" device +for mapping operations. + +While typical CXL switch dports are mapped by their associated 'struct +cxl_port', an RCH host bridge dport registered by cxl_acpi needs to wait +until the cxl_mem driver makes the attachment to map the registers. This +is because there are no intervening 'struct cxl_port' instances between +the root cxl_port and the endpoint port in an RCH topology. + +For now just mark the host as NULL in the RCH dport case until code that +needs to map the dport registers arrives. + +This patch is not flagged for -stable since nothing in the current +driver uses the dport->comp_map. + +Now, I am slightly uneasy that cxl_setup_comp_regs() sets map->host to a +wrong value and then cxl_dport_setup_regs() fixes it up, but the +alternatives I came up with are more messy. For example, adding an +@logdev to 'struct cxl_register_map' that the dev_printk()s can fall +back to when @host is NULL. I settled on "post-fixup+comment" since it +is only RCH dports that have this special case where register probing is +split between a host-bridge RCRB lookup and when cxl_mem_probe() does +the association of the cxl_memdev and endpoint port. + +[moved rename of @comp_map to @reg_map into next patch] + +Fixes: 5d2ffbe4b81a ("cxl/port: Store the downstream port's Component Register mappings in struct cxl_dport") +Signed-off-by: Robert Richter +Reviewed-by: Jonathan Cameron +Link: https://lore.kernel.org/r/20231018171713.1883517-4-rrichter@amd.com +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/port.c | 43 +++++++++++++++++++++++++++++------------ + 1 file changed, 31 insertions(+), 12 deletions(-) + +diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c +index c24cfe2271948..2c6001592fe20 100644 +--- a/drivers/cxl/core/port.c ++++ b/drivers/cxl/core/port.c +@@ -722,13 +722,23 @@ static int cxl_port_setup_regs(struct cxl_port *port, + component_reg_phys); + } + +-static int cxl_dport_setup_regs(struct cxl_dport *dport, ++static int cxl_dport_setup_regs(struct device *host, struct cxl_dport *dport, + resource_size_t component_reg_phys) + { ++ int rc; ++ + if (dev_is_platform(dport->dport_dev)) + return 0; +- return cxl_setup_comp_regs(dport->dport_dev, &dport->comp_map, +- component_reg_phys); ++ ++ /* ++ * use @dport->dport_dev for the context for error messages during ++ * register probing, and fixup @host after the fact, since @host may be ++ * NULL. ++ */ ++ rc = cxl_setup_comp_regs(dport->dport_dev, &dport->comp_map, ++ component_reg_phys); ++ dport->comp_map.host = host; ++ return rc; + } + + static struct cxl_port *__devm_cxl_add_port(struct device *host, +@@ -989,7 +999,16 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev, + if (!dport) + return ERR_PTR(-ENOMEM); + +- if (rcrb != CXL_RESOURCE_NONE) { ++ dport->dport_dev = dport_dev; ++ dport->port_id = port_id; ++ dport->port = port; ++ ++ if (rcrb == CXL_RESOURCE_NONE) { ++ rc = cxl_dport_setup_regs(&port->dev, dport, ++ component_reg_phys); ++ if (rc) ++ return ERR_PTR(rc); ++ } else { + dport->rcrb.base = rcrb; + component_reg_phys = __rcrb_to_component(dport_dev, &dport->rcrb, + CXL_RCRB_DOWNSTREAM); +@@ -998,6 +1017,14 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev, + return ERR_PTR(-ENXIO); + } + ++ /* ++ * RCH @dport is not ready to map until associated with its ++ * memdev ++ */ ++ rc = cxl_dport_setup_regs(NULL, dport, component_reg_phys); ++ if (rc) ++ return ERR_PTR(rc); ++ + dport->rch = true; + } + +@@ -1005,14 +1032,6 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev, + dev_dbg(dport_dev, "Component Registers found for dport: %pa\n", + &component_reg_phys); + +- dport->dport_dev = dport_dev; +- dport->port_id = port_id; +- dport->port = port; +- +- rc = cxl_dport_setup_regs(dport, component_reg_phys); +- if (rc) +- return ERR_PTR(rc); +- + cond_cxl_root_lock(port); + rc = add_dport(port, dport); + cond_cxl_root_unlock(port); +-- +2.42.0 + diff --git a/queue-6.6/cxl-region-calculate-a-target-position-in-a-region-i.patch b/queue-6.6/cxl-region-calculate-a-target-position-in-a-region-i.patch new file mode 100644 index 00000000000..10fa78f866a --- /dev/null +++ b/queue-6.6/cxl-region-calculate-a-target-position-in-a-region-i.patch @@ -0,0 +1,196 @@ +From 209bce4b9266437fd1fa557d3dd2b61ac6e47e17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Oct 2023 13:04:48 -0700 +Subject: cxl/region: Calculate a target position in a region interleave + +From: Alison Schofield + +[ Upstream commit a3e00c964fb943934af916f48f0dd43b5110c866 ] + +Introduce a calculation to find a target's position in a region +interleave. Perform a self-test of the calculation on user-defined +regions. + +The region driver uses the kernel sort() function to put region +targets in relative order. Positions are assigned based on each +target's index in that sorted list. That relative sort doesn't +consider the offset of a port into its parent port which causes +some auto-discovered regions to fail creation. In one failure case, +a 2 + 2 config (2 host bridges each with 2 endpoints), the sort +puts all the targets of one port ahead of another port when they +were expected to be interleaved. + +In preparation for repairing the autodiscovery region assembly, +introduce a new method for discovering a target position in the +region interleave. + +cxl_calc_interleave_pos() adds a method to find the target position by +ascending from an endpoint to a root decoder. The calculation starts +with the endpoint's local position and position in the parent port. It +traverses towards the root decoder and examines both position and ways +in order to allow the position to be refined all the way to the root +decoder. + +This calculation: position = position * parent_ways + parent_pos; +applied iteratively yields the correct position. + +Include a self-test that exercises this new position calculation against +every successfully configured user-defined region. + +Signed-off-by: Alison Schofield +Link: https://lore.kernel.org/r/0ac32c75cf81dd8b86bf07d70ff139d33c2300bc.1698263080.git.alison.schofield@intel.com +Signed-off-by: Dan Williams +Stable-dep-of: 0cf36a85c140 ("cxl/region: Use cxl_calc_interleave_pos() for auto-discovery") +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/region.c | 127 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 127 insertions(+) + +diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c +index f43b2b051b301..ccde7489edbde 100644 +--- a/drivers/cxl/core/region.c ++++ b/drivers/cxl/core/region.c +@@ -1497,6 +1497,113 @@ static int match_switch_decoder_by_range(struct device *dev, void *data) + return (r1->start == r2->start && r1->end == r2->end); + } + ++static int find_pos_and_ways(struct cxl_port *port, struct range *range, ++ int *pos, int *ways) ++{ ++ struct cxl_switch_decoder *cxlsd; ++ struct cxl_port *parent; ++ struct device *dev; ++ int rc = -ENXIO; ++ ++ parent = next_port(port); ++ if (!parent) ++ return rc; ++ ++ dev = device_find_child(&parent->dev, range, ++ match_switch_decoder_by_range); ++ if (!dev) { ++ dev_err(port->uport_dev, ++ "failed to find decoder mapping %#llx-%#llx\n", ++ range->start, range->end); ++ return rc; ++ } ++ cxlsd = to_cxl_switch_decoder(dev); ++ *ways = cxlsd->cxld.interleave_ways; ++ ++ for (int i = 0; i < *ways; i++) { ++ if (cxlsd->target[i] == port->parent_dport) { ++ *pos = i; ++ rc = 0; ++ break; ++ } ++ } ++ put_device(dev); ++ ++ return rc; ++} ++ ++/** ++ * cxl_calc_interleave_pos() - calculate an endpoint position in a region ++ * @cxled: endpoint decoder member of given region ++ * ++ * The endpoint position is calculated by traversing the topology from ++ * the endpoint to the root decoder and iteratively applying this ++ * calculation: ++ * ++ * position = position * parent_ways + parent_pos; ++ * ++ * ...where @position is inferred from switch and root decoder target lists. ++ * ++ * Return: position >= 0 on success ++ * -ENXIO on failure ++ */ ++static int cxl_calc_interleave_pos(struct cxl_endpoint_decoder *cxled) ++{ ++ struct cxl_port *iter, *port = cxled_to_port(cxled); ++ struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); ++ struct range *range = &cxled->cxld.hpa_range; ++ int parent_ways = 0, parent_pos = 0, pos = 0; ++ int rc; ++ ++ /* ++ * Example: the expected interleave order of the 4-way region shown ++ * below is: mem0, mem2, mem1, mem3 ++ * ++ * root_port ++ * / \ ++ * host_bridge_0 host_bridge_1 ++ * | | | | ++ * mem0 mem1 mem2 mem3 ++ * ++ * In the example the calculator will iterate twice. The first iteration ++ * uses the mem position in the host-bridge and the ways of the host- ++ * bridge to generate the first, or local, position. The second ++ * iteration uses the host-bridge position in the root_port and the ways ++ * of the root_port to refine the position. ++ * ++ * A trace of the calculation per endpoint looks like this: ++ * mem0: pos = 0 * 2 + 0 mem2: pos = 0 * 2 + 0 ++ * pos = 0 * 2 + 0 pos = 0 * 2 + 1 ++ * pos: 0 pos: 1 ++ * ++ * mem1: pos = 0 * 2 + 1 mem3: pos = 0 * 2 + 1 ++ * pos = 1 * 2 + 0 pos = 1 * 2 + 1 ++ * pos: 2 pos = 3 ++ * ++ * Note that while this example is simple, the method applies to more ++ * complex topologies, including those with switches. ++ */ ++ ++ /* Iterate from endpoint to root_port refining the position */ ++ for (iter = port; iter; iter = next_port(iter)) { ++ if (is_cxl_root(iter)) ++ break; ++ ++ rc = find_pos_and_ways(iter, range, &parent_pos, &parent_ways); ++ if (rc) ++ return rc; ++ ++ pos = pos * parent_ways + parent_pos; ++ } ++ ++ dev_dbg(&cxlmd->dev, ++ "decoder:%s parent:%s port:%s range:%#llx-%#llx pos:%d\n", ++ dev_name(&cxled->cxld.dev), dev_name(cxlmd->dev.parent), ++ dev_name(&port->dev), range->start, range->end, pos); ++ ++ return pos; ++} ++ + static void find_positions(const struct cxl_switch_decoder *cxlsd, + const struct cxl_port *iter_a, + const struct cxl_port *iter_b, int *a_pos, +@@ -1760,6 +1867,26 @@ static int cxl_region_attach(struct cxl_region *cxlr, + .end = p->res->end, + }; + ++ if (p->nr_targets != p->interleave_ways) ++ return 0; ++ ++ /* ++ * Test the auto-discovery position calculator function ++ * against this successfully created user-defined region. ++ * A fail message here means that this interleave config ++ * will fail when presented as CXL_REGION_F_AUTO. ++ */ ++ for (int i = 0; i < p->nr_targets; i++) { ++ struct cxl_endpoint_decoder *cxled = p->targets[i]; ++ int test_pos; ++ ++ test_pos = cxl_calc_interleave_pos(cxled); ++ dev_dbg(&cxled->cxld.dev, ++ "Test cxl_calc_interleave_pos(): %s test_pos:%d cxled->pos:%d\n", ++ (test_pos == cxled->pos) ? "success" : "fail", ++ test_pos, cxled->pos); ++ } ++ + return 0; + + err_decrement: +-- +2.42.0 + diff --git a/queue-6.6/cxl-region-fix-cxl_region_rwsem-lock-held-when-retur.patch b/queue-6.6/cxl-region-fix-cxl_region_rwsem-lock-held-when-retur.patch new file mode 100644 index 00000000000..29da9d19c99 --- /dev/null +++ b/queue-6.6/cxl-region-fix-cxl_region_rwsem-lock-held-when-retur.patch @@ -0,0 +1,59 @@ +From fea0766f75335ba1d6f35db24649c69aa398f92e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 16:54:50 +0800 +Subject: cxl/region: Fix cxl_region_rwsem lock held when returning to user + space + +From: Li Zhijian + +[ Upstream commit 3531b27f1f04a6bc9c95cf00d40efe618d57aa93 ] + +Fix a missed "goto out" to unlock on error to cleanup this splat: + + WARNING: lock held when returning to user space! + 6.6.0-rc3-lizhijian+ #213 Not tainted + ------------------------------------------------ + cxl/673 is leaving the kernel with locks still held! + 1 lock held by cxl/673: + #0: ffffffffa013b9d0 (cxl_region_rwsem){++++}-{3:3}, at: commit_store+0x7d/0x3e0 [cxl_core] + +In terms of user visible impact of this bug for backports: + +cxl_region_invalidate_memregion() on x86 invokes wbinvd which is a +problematic instruction for virtualized environments. So, on virtualized +x86, cxl_region_invalidate_memregion() returns an error. This failure +case got missed because CXL memory-expander device passthrough is not a +production use case, and emulation of CXL devices is typically limited +to kernel development builds with CONFIG_CXL_REGION_INVALIDATION_TEST=y, +that makes cxl_region_invalidate_memregion() succeed. + +In other words, the expected exposure of this bug is limited to CXL +subsystem development environments using QEMU that neglected +CONFIG_CXL_REGION_INVALIDATION_TEST=y. + +Fixes: d1257d098a5a ("cxl/region: Move cache invalidation before region teardown, and before setup") +Signed-off-by: Li Zhijian +Reviewed-by: Ira Weiny +Link: https://lore.kernel.org/r/20231025085450.2514906-1-lizhijian@fujitsu.com +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/region.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c +index 644032cd680e4..d1f513800c10d 100644 +--- a/drivers/cxl/core/region.c ++++ b/drivers/cxl/core/region.c +@@ -288,7 +288,7 @@ static ssize_t commit_store(struct device *dev, struct device_attribute *attr, + */ + rc = cxl_region_invalidate_memregion(cxlr); + if (rc) +- return rc; ++ goto out; + + if (commit) { + rc = cxl_region_decode_commit(cxlr); +-- +2.42.0 + diff --git a/queue-6.6/cxl-region-prepare-the-decoder-match-range-helper-fo.patch b/queue-6.6/cxl-region-prepare-the-decoder-match-range-helper-fo.patch new file mode 100644 index 00000000000..ffb6d5587f6 --- /dev/null +++ b/queue-6.6/cxl-region-prepare-the-decoder-match-range-helper-fo.patch @@ -0,0 +1,98 @@ +From a33bedccaef47f6a87862a1eb7739d69891f4325 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Oct 2023 08:46:54 -0700 +Subject: cxl/region: Prepare the decoder match range helper for reuse + +From: Alison Schofield + +[ Upstream commit 1110581412c7a223439bb3ecdcdd9f4432e08231 ] + +match_decoder_by_range() and decoder_match_range() both determine +if an HPA range matches a decoder. The first does it for root +decoders and the second one operates on switch decoders. + +Tidy these up with clear naming and make the switch helper more +like the root decoder helper in style and functionality. Make it +take the actual range, rather than an endpoint decoder from which +it extracts the range. Require an exact match on switch decoders, +because unlike a root decoder that maps an entire region, Linux +only supports 1:1 mapping of switch to endpoint decoders. Note that +root-decoders are a super-set of switch-decoders and the range they +cover is a super-set of a region, hence the use of range_contains() for +that case. + +Aside from aesthetics and maintainability, this is in preparation +for reuse. + +Signed-off-by: Alison Schofield +Reviewed-by: Dave Jiang +Reviewed-by: Jonathan Cameron +Reviewed-by: Jim Harris +Link: https://lore.kernel.org/r/011b1f498e1758bb8df17c5951be00bd8d489e3b.1698263080.git.alison.schofield@intel.com +[djbw: fixup root decoder vs switch decoder range checks] +Signed-off-by: Dan Williams +Stable-dep-of: 0cf36a85c140 ("cxl/region: Use cxl_calc_interleave_pos() for auto-discovery") +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/region.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c +index d74bf1b664b6c..f43b2b051b301 100644 +--- a/drivers/cxl/core/region.c ++++ b/drivers/cxl/core/region.c +@@ -1481,16 +1481,20 @@ static struct cxl_port *next_port(struct cxl_port *port) + return port->parent_dport->port; + } + +-static int decoder_match_range(struct device *dev, void *data) ++static int match_switch_decoder_by_range(struct device *dev, void *data) + { +- struct cxl_endpoint_decoder *cxled = data; + struct cxl_switch_decoder *cxlsd; ++ struct range *r1, *r2 = data; + + if (!is_switch_decoder(dev)) + return 0; + + cxlsd = to_cxl_switch_decoder(dev); +- return range_contains(&cxlsd->cxld.hpa_range, &cxled->cxld.hpa_range); ++ r1 = &cxlsd->cxld.hpa_range; ++ ++ if (is_root_decoder(dev)) ++ return range_contains(r1, r2); ++ return (r1->start == r2->start && r1->end == r2->end); + } + + static void find_positions(const struct cxl_switch_decoder *cxlsd, +@@ -1559,7 +1563,8 @@ static int cmp_decode_pos(const void *a, const void *b) + goto err; + } + +- dev = device_find_child(&port->dev, cxled_a, decoder_match_range); ++ dev = device_find_child(&port->dev, &cxled_a->cxld.hpa_range, ++ match_switch_decoder_by_range); + if (!dev) { + struct range *range = &cxled_a->cxld.hpa_range; + +@@ -2690,7 +2695,7 @@ static int devm_cxl_add_dax_region(struct cxl_region *cxlr) + return rc; + } + +-static int match_decoder_by_range(struct device *dev, void *data) ++static int match_root_decoder_by_range(struct device *dev, void *data) + { + struct range *r1, *r2 = data; + struct cxl_root_decoder *cxlrd; +@@ -2821,7 +2826,7 @@ int cxl_add_to_region(struct cxl_port *root, struct cxl_endpoint_decoder *cxled) + int rc; + + cxlrd_dev = device_find_child(&root->dev, &cxld->hpa_range, +- match_decoder_by_range); ++ match_root_decoder_by_range); + if (!cxlrd_dev) { + dev_err(cxlmd->dev.parent, + "%s:%s no CXL window for range %#llx:%#llx\n", +-- +2.42.0 + diff --git a/queue-6.6/cxl-region-use-cxl_calc_interleave_pos-for-auto-disc.patch b/queue-6.6/cxl-region-use-cxl_calc_interleave_pos-for-auto-disc.patch new file mode 100644 index 00000000000..99b8e39eee3 --- /dev/null +++ b/queue-6.6/cxl-region-use-cxl_calc_interleave_pos-for-auto-disc.patch @@ -0,0 +1,207 @@ +From 4a2dec0c802537a3ea4e653258154ff52dd9a16c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 13:01:34 -0700 +Subject: cxl/region: Use cxl_calc_interleave_pos() for auto-discovery + +From: Alison Schofield + +[ Upstream commit 0cf36a85c1408f86a967fb1db721de1b89b9e675 ] + +For auto-discovered regions the driver must assign each target to +a valid position in the region interleave set based on the decoder +topology. + +The current implementation fails to parse valid decode topologies, +as it does not consider the child offset into a parent port. The sort +put all targets of one port ahead of another port when an interleave +was expected, causing the region assembly to fail. + +Replace the existing relative sort with cxl_calc_interleave_pos() that +finds the exact position in a region interleave for an endpoint based +on a walk up the ancestral tree from endpoint to root decoder. + +cxl_calc_interleave_pos() was introduced in a prior patch, so the work +here is to use it in cxl_region_sort_targets(). + +Remove the obsoleted helper functions from the prior sort. + +Testing passes on pre-production hardware with BIOS defined regions +that natively trigger this autodiscovery path of the region driver. +Testing passes a CXL unit test using the dev_dbg() calculation test +(see cxl_region_attach()) across an expanded set of region configs: +1, 1, 1+1, 1+1+1, 2, 2+2, 2+2+2, 2+2+2+2, 4, 4+4, where each number +represents the count of endpoints per host bridge. + +Fixes: a32320b71f08 ("cxl/region: Add region autodiscovery") +Reported-by: Dmytro Adamenko +Signed-off-by: Alison Schofield +Reviewed-by: Dave Jiang +Reviewed-by: Jim Harris +Link: https://lore.kernel.org/r/3946cc55ddc19678733eddc9de2c317749f43f3b.1698263080.git.alison.schofield@intel.com +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/region.c | 127 +++++--------------------------------- + 1 file changed, 15 insertions(+), 112 deletions(-) + +diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c +index ccde7489edbde..644032cd680e4 100644 +--- a/drivers/cxl/core/region.c ++++ b/drivers/cxl/core/region.c +@@ -1474,6 +1474,14 @@ static int cxl_region_attach_auto(struct cxl_region *cxlr, + return 0; + } + ++static int cmp_interleave_pos(const void *a, const void *b) ++{ ++ struct cxl_endpoint_decoder *cxled_a = *(typeof(cxled_a) *)a; ++ struct cxl_endpoint_decoder *cxled_b = *(typeof(cxled_b) *)b; ++ ++ return cxled_a->pos - cxled_b->pos; ++} ++ + static struct cxl_port *next_port(struct cxl_port *port) + { + if (!port->parent_dport) +@@ -1604,131 +1612,26 @@ static int cxl_calc_interleave_pos(struct cxl_endpoint_decoder *cxled) + return pos; + } + +-static void find_positions(const struct cxl_switch_decoder *cxlsd, +- const struct cxl_port *iter_a, +- const struct cxl_port *iter_b, int *a_pos, +- int *b_pos) +-{ +- int i; +- +- for (i = 0, *a_pos = -1, *b_pos = -1; i < cxlsd->nr_targets; i++) { +- if (cxlsd->target[i] == iter_a->parent_dport) +- *a_pos = i; +- else if (cxlsd->target[i] == iter_b->parent_dport) +- *b_pos = i; +- if (*a_pos >= 0 && *b_pos >= 0) +- break; +- } +-} +- +-static int cmp_decode_pos(const void *a, const void *b) +-{ +- struct cxl_endpoint_decoder *cxled_a = *(typeof(cxled_a) *)a; +- struct cxl_endpoint_decoder *cxled_b = *(typeof(cxled_b) *)b; +- struct cxl_memdev *cxlmd_a = cxled_to_memdev(cxled_a); +- struct cxl_memdev *cxlmd_b = cxled_to_memdev(cxled_b); +- struct cxl_port *port_a = cxled_to_port(cxled_a); +- struct cxl_port *port_b = cxled_to_port(cxled_b); +- struct cxl_port *iter_a, *iter_b, *port = NULL; +- struct cxl_switch_decoder *cxlsd; +- struct device *dev; +- int a_pos, b_pos; +- unsigned int seq; +- +- /* Exit early if any prior sorting failed */ +- if (cxled_a->pos < 0 || cxled_b->pos < 0) +- return 0; +- +- /* +- * Walk up the hierarchy to find a shared port, find the decoder that +- * maps the range, compare the relative position of those dport +- * mappings. +- */ +- for (iter_a = port_a; iter_a; iter_a = next_port(iter_a)) { +- struct cxl_port *next_a, *next_b; +- +- next_a = next_port(iter_a); +- if (!next_a) +- break; +- +- for (iter_b = port_b; iter_b; iter_b = next_port(iter_b)) { +- next_b = next_port(iter_b); +- if (next_a != next_b) +- continue; +- port = next_a; +- break; +- } +- +- if (port) +- break; +- } +- +- if (!port) { +- dev_err(cxlmd_a->dev.parent, +- "failed to find shared port with %s\n", +- dev_name(cxlmd_b->dev.parent)); +- goto err; +- } +- +- dev = device_find_child(&port->dev, &cxled_a->cxld.hpa_range, +- match_switch_decoder_by_range); +- if (!dev) { +- struct range *range = &cxled_a->cxld.hpa_range; +- +- dev_err(port->uport_dev, +- "failed to find decoder that maps %#llx-%#llx\n", +- range->start, range->end); +- goto err; +- } +- +- cxlsd = to_cxl_switch_decoder(dev); +- do { +- seq = read_seqbegin(&cxlsd->target_lock); +- find_positions(cxlsd, iter_a, iter_b, &a_pos, &b_pos); +- } while (read_seqretry(&cxlsd->target_lock, seq)); +- +- put_device(dev); +- +- if (a_pos < 0 || b_pos < 0) { +- dev_err(port->uport_dev, +- "failed to find shared decoder for %s and %s\n", +- dev_name(cxlmd_a->dev.parent), +- dev_name(cxlmd_b->dev.parent)); +- goto err; +- } +- +- dev_dbg(port->uport_dev, "%s comes %s %s\n", +- dev_name(cxlmd_a->dev.parent), +- a_pos - b_pos < 0 ? "before" : "after", +- dev_name(cxlmd_b->dev.parent)); +- +- return a_pos - b_pos; +-err: +- cxled_a->pos = -1; +- return 0; +-} +- + static int cxl_region_sort_targets(struct cxl_region *cxlr) + { + struct cxl_region_params *p = &cxlr->params; + int i, rc = 0; + +- sort(p->targets, p->nr_targets, sizeof(p->targets[0]), cmp_decode_pos, +- NULL); +- + for (i = 0; i < p->nr_targets; i++) { + struct cxl_endpoint_decoder *cxled = p->targets[i]; + ++ cxled->pos = cxl_calc_interleave_pos(cxled); + /* +- * Record that sorting failed, but still continue to restore +- * cxled->pos with its ->targets[] position so that follow-on +- * code paths can reliably do p->targets[cxled->pos] to +- * self-reference their entry. ++ * Record that sorting failed, but still continue to calc ++ * cxled->pos so that follow-on code paths can reliably ++ * do p->targets[cxled->pos] to self-reference their entry. + */ + if (cxled->pos < 0) + rc = -ENXIO; +- cxled->pos = i; + } ++ /* Keep the cxlr target list in interleave position order */ ++ sort(p->targets, p->nr_targets, sizeof(p->targets[0]), ++ cmp_interleave_pos, NULL); + + dev_dbg(&cxlr->dev, "region sort %s\n", rc ? "failed" : "successful"); + return rc; +-- +2.42.0 + diff --git a/queue-6.6/debugfs-fix-__rcu-type-comparison-warning.patch b/queue-6.6/debugfs-fix-__rcu-type-comparison-warning.patch new file mode 100644 index 00000000000..db97e4b70c3 --- /dev/null +++ b/queue-6.6/debugfs-fix-__rcu-type-comparison-warning.patch @@ -0,0 +1,46 @@ +From 16670a6a9002cb015fcdba4ee51aa6c7c37da0e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 06:45:12 -0700 +Subject: debugfs: Fix __rcu type comparison warning + +From: Mike Tipton + +[ Upstream commit 7360a48bd0f5e62b2d00c387d5d3f2821eb290ce ] + +Sparse reports the following: + +fs/debugfs/file.c:942:9: sparse: sparse: incompatible types in comparison expression (different address spaces): +fs/debugfs/file.c:942:9: sparse: char [noderef] __rcu * +fs/debugfs/file.c:942:9: sparse: char * + +rcu_assign_pointer() expects that it's assigning to pointers annotated +with __rcu. We can't annotate the generic struct file::private_data, so +cast it instead. + +Fixes: 86b5488121db ("debugfs: Add write support to debugfs_create_str()") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202309091933.BRWlSnCq-lkp@intel.com/ +Signed-off-by: Mike Tipton +Link: https://lore.kernel.org/r/20230922134512.5126-1-quic_mdtipton@quicinc.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + fs/debugfs/file.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c +index 87b3753aa4b1e..c45e8c2d62e11 100644 +--- a/fs/debugfs/file.c ++++ b/fs/debugfs/file.c +@@ -939,7 +939,7 @@ static ssize_t debugfs_write_file_str(struct file *file, const char __user *user + new[pos + count] = '\0'; + strim(new); + +- rcu_assign_pointer(*(char **)file->private_data, new); ++ rcu_assign_pointer(*(char __rcu **)file->private_data, new); + synchronize_rcu(); + kfree(old); + +-- +2.42.0 + diff --git a/queue-6.6/dlm-be-sure-we-reset-all-nodes-at-forced-shutdown.patch b/queue-6.6/dlm-be-sure-we-reset-all-nodes-at-forced-shutdown.patch new file mode 100644 index 00000000000..474d17d721e --- /dev/null +++ b/queue-6.6/dlm-be-sure-we-reset-all-nodes-at-forced-shutdown.patch @@ -0,0 +1,47 @@ +From 1208111fd6ad01dc5f57e12ebaf64d4625a3641f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 18:04:46 -0400 +Subject: dlm: be sure we reset all nodes at forced shutdown + +From: Alexander Aring + +[ Upstream commit e759eb3e27e5b624930548f1c0eda90da6e26ee9 ] + +In case we running in a force shutdown in either midcomms or lowcomms +implementation we will make sure we reset all per midcomms node +information. + +Fixes: 63e711b08160 ("fs: dlm: create midcomms nodes when configure") +Signed-off-by: Alexander Aring +Signed-off-by: David Teigland +Signed-off-by: Sasha Levin +--- + fs/dlm/midcomms.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/fs/dlm/midcomms.c b/fs/dlm/midcomms.c +index 4ad71e97cec2a..6bc8d7f89b2cc 100644 +--- a/fs/dlm/midcomms.c ++++ b/fs/dlm/midcomms.c +@@ -1405,10 +1405,16 @@ void dlm_midcomms_shutdown(void) + midcomms_shutdown(node); + } + } +- srcu_read_unlock(&nodes_srcu, idx); +- mutex_unlock(&close_lock); + + dlm_lowcomms_shutdown(); ++ ++ for (i = 0; i < CONN_HASH_SIZE; i++) { ++ hlist_for_each_entry_rcu(node, &node_hash[i], hlist) { ++ midcomms_node_reset(node); ++ } ++ } ++ srcu_read_unlock(&nodes_srcu, idx); ++ mutex_unlock(&close_lock); + } + + int dlm_midcomms_close(int nodeid) +-- +2.42.0 + diff --git a/queue-6.6/dlm-fix-creating-multiple-node-structures.patch b/queue-6.6/dlm-fix-creating-multiple-node-structures.patch new file mode 100644 index 00000000000..769d282f639 --- /dev/null +++ b/queue-6.6/dlm-fix-creating-multiple-node-structures.patch @@ -0,0 +1,56 @@ +From 2bd55507b9e863c8d28b9b4b2a9bb6fb9b7e766d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 18:04:44 -0400 +Subject: dlm: fix creating multiple node structures + +From: Alexander Aring + +[ Upstream commit fe9b619e6e94acf0b068fb1a8f658f5a96b8fad7 ] + +This patch will lookup existing nodes instead of always creating them +when dlm_midcomms_addr() is called. The idea is here to create midcomms +nodes when user space getting informed that nodes joins the cluster. This +is the case when dlm_midcomms_addr() is called, however it can be called +multiple times by user space to add several address configurations to one +node e.g. when using SCTP. Those multiple times need to be filtered out +and we doing that by looking up if the node exists before. Due configfs +entry it is safe that this function gets only called once at a time. + +Fixes: 63e711b08160 ("fs: dlm: create midcomms nodes when configure") +Signed-off-by: Alexander Aring +Signed-off-by: David Teigland +Signed-off-by: Sasha Levin +--- + fs/dlm/midcomms.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/fs/dlm/midcomms.c b/fs/dlm/midcomms.c +index f641b36a36db0..455265c6ba53d 100644 +--- a/fs/dlm/midcomms.c ++++ b/fs/dlm/midcomms.c +@@ -337,13 +337,21 @@ static struct midcomms_node *nodeid2node(int nodeid) + + int dlm_midcomms_addr(int nodeid, struct sockaddr_storage *addr, int len) + { +- int ret, r = nodeid_hash(nodeid); ++ int ret, idx, r = nodeid_hash(nodeid); + struct midcomms_node *node; + + ret = dlm_lowcomms_addr(nodeid, addr, len); + if (ret) + return ret; + ++ idx = srcu_read_lock(&nodes_srcu); ++ node = __find_node(nodeid, r); ++ if (node) { ++ srcu_read_unlock(&nodes_srcu, idx); ++ return 0; ++ } ++ srcu_read_unlock(&nodes_srcu, idx); ++ + node = kmalloc(sizeof(*node), GFP_NOFS); + if (!node) + return -ENOMEM; +-- +2.42.0 + diff --git a/queue-6.6/dlm-fix-no-ack-after-final-message.patch b/queue-6.6/dlm-fix-no-ack-after-final-message.patch new file mode 100644 index 00000000000..50ad4aa7106 --- /dev/null +++ b/queue-6.6/dlm-fix-no-ack-after-final-message.patch @@ -0,0 +1,50 @@ +From 0643c9ea61d1ce7211cb55ebe82b89dfbdb507b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 18:04:47 -0400 +Subject: dlm: fix no ack after final message + +From: Alexander Aring + +[ Upstream commit 6212e4528b248a4bc9b4fe68e029a84689c67461 ] + +In case of an final DLM message we can't should not send an ack out +after the final message. This patch moves the ack message before the +messages will be transmitted. If it's the final message and the +receiving node turns into DLM_CLOSED state another ack messages will +being received and turning the receiving node into DLM_ESTABLISHED +again. + +Fixes: 1696c75f1864 ("fs: dlm: add send ack threshold and append acks to msgs") +Signed-off-by: Alexander Aring +Signed-off-by: David Teigland +Signed-off-by: Sasha Levin +--- + fs/dlm/midcomms.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/fs/dlm/midcomms.c b/fs/dlm/midcomms.c +index 6bc8d7f89b2cc..2247ebb61be1e 100644 +--- a/fs/dlm/midcomms.c ++++ b/fs/dlm/midcomms.c +@@ -1038,15 +1038,15 @@ struct dlm_mhandle *dlm_midcomms_get_mhandle(int nodeid, int len, + + break; + case DLM_VERSION_3_2: ++ /* send ack back if necessary */ ++ dlm_send_ack_threshold(node, DLM_SEND_ACK_BACK_MSG_THRESHOLD); ++ + msg = dlm_midcomms_get_msg_3_2(mh, nodeid, len, allocation, + ppc); + if (!msg) { + dlm_free_mhandle(mh); + goto err; + } +- +- /* send ack back if necessary */ +- dlm_send_ack_threshold(node, DLM_SEND_ACK_BACK_MSG_THRESHOLD); + break; + default: + dlm_free_mhandle(mh); +-- +2.42.0 + diff --git a/queue-6.6/dlm-fix-remove-member-after-close-call.patch b/queue-6.6/dlm-fix-remove-member-after-close-call.patch new file mode 100644 index 00000000000..a6f6acae3c3 --- /dev/null +++ b/queue-6.6/dlm-fix-remove-member-after-close-call.patch @@ -0,0 +1,73 @@ +From 2c725725503a7d7e23ae4900165da5bc132b559f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 18:04:45 -0400 +Subject: dlm: fix remove member after close call + +From: Alexander Aring + +[ Upstream commit 2776635edc7fcd62e03cb2efb93c31f685887460 ] + +The idea of commit 63e711b08160 ("fs: dlm: create midcomms nodes when +configure") is to set the midcomms node lifetime when a node joins or +leaves the cluster. Currently we can hit the following warning: + +[10844.611495] ------------[ cut here ]------------ +[10844.615913] WARNING: CPU: 4 PID: 84304 at fs/dlm/midcomms.c:1263 +dlm_midcomms_remove_member+0x13f/0x180 [dlm] + +or running in a state where we hit a midcomms node usage count in a +negative value: + +[ 260.830782] node 2 users dec count -1 + +The first warning happens when the a specific node does not exists and +it was probably removed but dlm_midcomms_close() which is called when a +node leaves the cluster. The second kernel log message is probably in a +case when dlm_midcomms_addr() is called when a joined the cluster but +due fencing a node leaved the cluster without getting removed from the +lockspace. If the node joins the cluster and it was removed from the +cluster due fencing the first call is to remove the node from lockspaces +triggered by the user space. In both cases if the node wasn't found or +the user count is zero, we should ignore any additional midcomms handling +of dlm_midcomms_remove_member(). + +Fixes: 63e711b08160 ("fs: dlm: create midcomms nodes when configure") +Signed-off-by: Alexander Aring +Signed-off-by: David Teigland +Signed-off-by: Sasha Levin +--- + fs/dlm/midcomms.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/fs/dlm/midcomms.c b/fs/dlm/midcomms.c +index 455265c6ba53d..4ad71e97cec2a 100644 +--- a/fs/dlm/midcomms.c ++++ b/fs/dlm/midcomms.c +@@ -1268,12 +1268,23 @@ void dlm_midcomms_remove_member(int nodeid) + + idx = srcu_read_lock(&nodes_srcu); + node = nodeid2node(nodeid); +- if (WARN_ON_ONCE(!node)) { ++ /* in case of dlm_midcomms_close() removes node */ ++ if (!node) { + srcu_read_unlock(&nodes_srcu, idx); + return; + } + + spin_lock(&node->state_lock); ++ /* case of dlm_midcomms_addr() created node but ++ * was not added before because dlm_midcomms_close() ++ * removed the node ++ */ ++ if (!node->users) { ++ spin_unlock(&node->state_lock); ++ srcu_read_unlock(&nodes_srcu, idx); ++ return; ++ } ++ + node->users--; + pr_debug("node %d users dec count %d\n", nodeid, node->users); + +-- +2.42.0 + diff --git a/queue-6.6/dmaengine-idxd-register-dsa_bus_type-before-register.patch b/queue-6.6/dmaengine-idxd-register-dsa_bus_type-before-register.patch new file mode 100644 index 00000000000..12f60ea3397 --- /dev/null +++ b/queue-6.6/dmaengine-idxd-register-dsa_bus_type-before-register.patch @@ -0,0 +1,63 @@ +From b2f9acb9589ac85f0ec0ceebf3070b28ea9607ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Sep 2023 09:22:32 -0700 +Subject: dmaengine: idxd: Register dsa_bus_type before registering idxd + sub-drivers + +From: Fenghua Yu + +[ Upstream commit 88928addeec577386e8c83b48b5bc24d28ba97fd ] + +idxd sub-drivers belong to bus dsa_bus_type. Thus, dsa_bus_type must be +registered in dsa bus init before idxd drivers can be registered. + +But the order is wrong when both idxd and idxd_bus are builtin drivers. +In this case, idxd driver is compiled and linked before idxd_bus driver. +Since the initcall order is determined by the link order, idxd sub-drivers +are registered in idxd initcall before dsa_bus_type is registered +in idxd_bus initcall. idxd initcall fails: + +[ 21.562803] calling idxd_init_module+0x0/0x110 @ 1 +[ 21.570761] Driver 'idxd' was unable to register with bus_type 'dsa' because the bus was not initialized. +[ 21.586475] initcall idxd_init_module+0x0/0x110 returned -22 after 15717 usecs +[ 21.597178] calling dsa_bus_init+0x0/0x20 @ 1 + +To fix the issue, compile and link idxd_bus driver before idxd driver +to ensure the right registration order. + +Fixes: d9e5481fca74 ("dmaengine: dsa: move dsa_bus_type out of idxd driver to standalone") +Reported-by: Michael Prinke +Signed-off-by: Fenghua Yu +Reviewed-by: Dave Jiang +Reviewed-by: Lijun Pan +Tested-by: Lijun Pan +Link: https://lore.kernel.org/r/20230924162232.1409454-1-fenghua.yu@intel.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/dma/idxd/Makefile | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/dma/idxd/Makefile b/drivers/dma/idxd/Makefile +index dc096839ac637..c5e679070e463 100644 +--- a/drivers/dma/idxd/Makefile ++++ b/drivers/dma/idxd/Makefile +@@ -1,12 +1,12 @@ + ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=IDXD + ++obj-$(CONFIG_INTEL_IDXD_BUS) += idxd_bus.o ++idxd_bus-y := bus.o ++ + obj-$(CONFIG_INTEL_IDXD) += idxd.o + idxd-y := init.o irq.o device.o sysfs.o submit.o dma.o cdev.o debugfs.o + + idxd-$(CONFIG_INTEL_IDXD_PERFMON) += perfmon.o + +-obj-$(CONFIG_INTEL_IDXD_BUS) += idxd_bus.o +-idxd_bus-y := bus.o +- + obj-$(CONFIG_INTEL_IDXD_COMPAT) += idxd_compat.o + idxd_compat-y := compat.o +-- +2.42.0 + diff --git a/queue-6.6/dmaengine-pxa_dma-remove-an-erroneous-bug_on-in-pxad.patch b/queue-6.6/dmaengine-pxa_dma-remove-an-erroneous-bug_on-in-pxad.patch new file mode 100644 index 00000000000..89e0815e4b1 --- /dev/null +++ b/queue-6.6/dmaengine-pxa_dma-remove-an-erroneous-bug_on-in-pxad.patch @@ -0,0 +1,43 @@ +From 640f0d4c88848b202359630372c4bfa7d7791121 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Oct 2023 13:13:09 +0200 +Subject: dmaengine: pxa_dma: Remove an erroneous BUG_ON() in pxad_free_desc() + +From: Christophe JAILLET + +[ Upstream commit 83c761f568733277ce1f7eb9dc9e890649c29a8c ] + +If pxad_alloc_desc() fails on the first dma_pool_alloc() call, then +sw_desc->nb_desc is zero. +In such a case pxad_free_desc() is called and it will BUG_ON(). + +Remove this erroneous BUG_ON(). + +It is also useless, because if "sw_desc->nb_desc == 0", then, on the first +iteration of the for loop, i is -1 and the loop will not be executed. +(both i and sw_desc->nb_desc are 'int') + +Fixes: a57e16cf0333 ("dmaengine: pxa: add pxa dmaengine driver") +Signed-off-by: Christophe JAILLET +Link: https://lore.kernel.org/r/c8fc5563c9593c914fde41f0f7d1489a21b45a9a.1696676782.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/dma/pxa_dma.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c +index 1b046d9a3a269..16d342654da2b 100644 +--- a/drivers/dma/pxa_dma.c ++++ b/drivers/dma/pxa_dma.c +@@ -722,7 +722,6 @@ static void pxad_free_desc(struct virt_dma_desc *vd) + dma_addr_t dma; + struct pxad_desc_sw *sw_desc = to_pxad_sw_desc(vd); + +- BUG_ON(sw_desc->nb_desc == 0); + for (i = sw_desc->nb_desc - 1; i >= 0; i--) { + if (i > 0) + dma = sw_desc->hw_desc[i - 1]->ddadr; +-- +2.42.0 + diff --git a/queue-6.6/dmaengine-ti-edma-handle-irq_of_parse_and_map-errors.patch b/queue-6.6/dmaengine-ti-edma-handle-irq_of_parse_and_map-errors.patch new file mode 100644 index 00000000000..113f153fb4c --- /dev/null +++ b/queue-6.6/dmaengine-ti-edma-handle-irq_of_parse_and_map-errors.patch @@ -0,0 +1,48 @@ +From 45a5ce65238c32d1b4fed2dac42f4512a396de07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 15:59:59 +0300 +Subject: dmaengine: ti: edma: handle irq_of_parse_and_map() errors + +From: Dan Carpenter + +[ Upstream commit 14f6d317913f634920a640e9047aa2e66f5bdcb7 ] + +Zero is not a valid IRQ for in-kernel code and the irq_of_parse_and_map() +function returns zero on error. So this check for valid IRQs should only +accept values > 0. + +Fixes: 2b6b3b742019 ("ARM/dmaengine: edma: Merge the two drivers under drivers/dma/") +Signed-off-by: Dan Carpenter +Acked-by: Peter Ujfalusi +Link: https://lore.kernel.org/r/f15cb6a7-8449-4f79-98b6-34072f04edbc@moroto.mountain +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/dma/ti/edma.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/dma/ti/edma.c b/drivers/dma/ti/edma.c +index aa8e2e8ac2609..33d6d931b33bb 100644 +--- a/drivers/dma/ti/edma.c ++++ b/drivers/dma/ti/edma.c +@@ -2401,7 +2401,7 @@ static int edma_probe(struct platform_device *pdev) + if (irq < 0 && node) + irq = irq_of_parse_and_map(node, 0); + +- if (irq >= 0) { ++ if (irq > 0) { + irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccint", + dev_name(dev)); + ret = devm_request_irq(dev, irq, dma_irq_handler, 0, irq_name, +@@ -2417,7 +2417,7 @@ static int edma_probe(struct platform_device *pdev) + if (irq < 0 && node) + irq = irq_of_parse_and_map(node, 2); + +- if (irq >= 0) { ++ if (irq > 0) { + irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccerrint", + dev_name(dev)); + ret = devm_request_irq(dev, irq, dma_ccerr_handler, 0, irq_name, +-- +2.42.0 + diff --git a/queue-6.6/drivers-clocksource-timer-ti-dm-don-t-call-clk_get_r.patch b/queue-6.6/drivers-clocksource-timer-ti-dm-don-t-call-clk_get_r.patch new file mode 100644 index 00000000000..f13d6846335 --- /dev/null +++ b/queue-6.6/drivers-clocksource-timer-ti-dm-don-t-call-clk_get_r.patch @@ -0,0 +1,118 @@ +From d7b0c29c8f17d70c3d5566b92dbdfa848bec8506 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Oct 2023 08:50:20 +0300 +Subject: drivers/clocksource/timer-ti-dm: Don't call clk_get_rate() in stop + function + +From: Ivaylo Dimitrov + +[ Upstream commit 12590d4d0e331d3cb9e6b3494515cd61c8a6624e ] + +clk_get_rate() might sleep, and that prevents dm-timer based PWM from being +used from atomic context. + +Fix that by getting fclk rate in probe() and using a notifier in case rate +changes. + +Fixes: af04aa856e93 ("ARM: OMAP: Move dmtimer driver out of plat-omap to drivers under clocksource") +Signed-off-by: Ivaylo Dimitrov +Reviewed-by: Tony Lindgren +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/1696312220-11550-1-git-send-email-ivo.g.dimitrov.75@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-ti-dm.c | 36 ++++++++++++++++++++++++------- + 1 file changed, 28 insertions(+), 8 deletions(-) + +diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c +index 09ab29cb7f641..5f60f6bd33866 100644 +--- a/drivers/clocksource/timer-ti-dm.c ++++ b/drivers/clocksource/timer-ti-dm.c +@@ -140,6 +140,8 @@ struct dmtimer { + struct platform_device *pdev; + struct list_head node; + struct notifier_block nb; ++ struct notifier_block fclk_nb; ++ unsigned long fclk_rate; + }; + + static u32 omap_reserved_systimers; +@@ -253,8 +255,7 @@ static inline void __omap_dm_timer_enable_posted(struct dmtimer *timer) + timer->posted = OMAP_TIMER_POSTED; + } + +-static inline void __omap_dm_timer_stop(struct dmtimer *timer, +- unsigned long rate) ++static inline void __omap_dm_timer_stop(struct dmtimer *timer) + { + u32 l; + +@@ -269,7 +270,7 @@ static inline void __omap_dm_timer_stop(struct dmtimer *timer, + * Wait for functional clock period x 3.5 to make sure that + * timer is stopped + */ +- udelay(3500000 / rate + 1); ++ udelay(3500000 / timer->fclk_rate + 1); + #endif + } + +@@ -348,6 +349,21 @@ static int omap_timer_context_notifier(struct notifier_block *nb, + return NOTIFY_OK; + } + ++static int omap_timer_fclk_notifier(struct notifier_block *nb, ++ unsigned long event, void *data) ++{ ++ struct clk_notifier_data *clk_data = data; ++ struct dmtimer *timer = container_of(nb, struct dmtimer, fclk_nb); ++ ++ switch (event) { ++ case POST_RATE_CHANGE: ++ timer->fclk_rate = clk_data->new_rate; ++ return NOTIFY_OK; ++ default: ++ return NOTIFY_DONE; ++ } ++} ++ + static int omap_dm_timer_reset(struct dmtimer *timer) + { + u32 l, timeout = 100000; +@@ -754,7 +770,6 @@ static int omap_dm_timer_stop(struct omap_dm_timer *cookie) + { + struct dmtimer *timer; + struct device *dev; +- unsigned long rate = 0; + + timer = to_dmtimer(cookie); + if (unlikely(!timer)) +@@ -762,10 +777,7 @@ static int omap_dm_timer_stop(struct omap_dm_timer *cookie) + + dev = &timer->pdev->dev; + +- if (!timer->omap1) +- rate = clk_get_rate(timer->fclk); +- +- __omap_dm_timer_stop(timer, rate); ++ __omap_dm_timer_stop(timer); + + pm_runtime_put_sync(dev); + +@@ -1124,6 +1136,14 @@ static int omap_dm_timer_probe(struct platform_device *pdev) + timer->fclk = devm_clk_get(dev, "fck"); + if (IS_ERR(timer->fclk)) + return PTR_ERR(timer->fclk); ++ ++ timer->fclk_nb.notifier_call = omap_timer_fclk_notifier; ++ ret = devm_clk_notifier_register(dev, timer->fclk, ++ &timer->fclk_nb); ++ if (ret) ++ return ret; ++ ++ timer->fclk_rate = clk_get_rate(timer->fclk); + } else { + timer->fclk = ERR_PTR(-ENODEV); + } +-- +2.42.0 + diff --git a/queue-6.6/drivers-perf-hisi-use-cpuhp_state_remove_instance_no.patch b/queue-6.6/drivers-perf-hisi-use-cpuhp_state_remove_instance_no.patch new file mode 100644 index 00000000000..94682a09a3b --- /dev/null +++ b/queue-6.6/drivers-perf-hisi-use-cpuhp_state_remove_instance_no.patch @@ -0,0 +1,70 @@ +From 687186ce1b6f5bf12065e322ffde89b607d40190 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Oct 2023 17:13:52 +0800 +Subject: drivers/perf: hisi: use cpuhp_state_remove_instance_nocalls() for + hisi_hns3_pmu uninit process + +From: Hao Chen + +[ Upstream commit 50b560783f7f71790bcf70e9e9855155fb0af8c1 ] + +When tearing down a 'hisi_hns3' PMU, we mistakenly run the CPU hotplug +callbacks after the device has been unregistered, leading to fireworks +when we try to execute empty function callbacks within the driver: + + | Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 + | CPU: 0 PID: 15 Comm: cpuhp/0 Tainted: G W O 5.12.0-rc4+ #1 + | Hardware name: , BIOS KpxxxFPGA 1P B600 V143 04/22/2021 + | pstate: 80400009 (Nzcv daif +PAN -UAO -TCO BTYPE=--) + | pc : perf_pmu_migrate_context+0x98/0x38c + | lr : perf_pmu_migrate_context+0x94/0x38c + | + | Call trace: + | perf_pmu_migrate_context+0x98/0x38c + | hisi_hns3_pmu_offline_cpu+0x104/0x12c [hisi_hns3_pmu] + +Use cpuhp_state_remove_instance_nocalls() instead of +cpuhp_state_remove_instance() so that the notifiers don't execute after +the PMU device has been unregistered. + +Fixes: 66637ab137b4 ("drivers/perf: hisi: add driver for HNS3 PMU") +Signed-off-by: Hao Chen +Signed-off-by: Jijie Shao +Reviewed-by: Yicong Yang +Link: https://lore.kernel.org/r/20231019091352.998964-1-shaojijie@huawei.com +[will: Rewrote commit message] +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + drivers/perf/hisilicon/hns3_pmu.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/perf/hisilicon/hns3_pmu.c b/drivers/perf/hisilicon/hns3_pmu.c +index e0457d84af6b3..16869bf5bf4cc 100644 +--- a/drivers/perf/hisilicon/hns3_pmu.c ++++ b/drivers/perf/hisilicon/hns3_pmu.c +@@ -1556,8 +1556,8 @@ static int hns3_pmu_init_pmu(struct pci_dev *pdev, struct hns3_pmu *hns3_pmu) + ret = perf_pmu_register(&hns3_pmu->pmu, hns3_pmu->pmu.name, -1); + if (ret) { + pci_err(pdev, "failed to register perf PMU, ret = %d.\n", ret); +- cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE, +- &hns3_pmu->node); ++ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE, ++ &hns3_pmu->node); + } + + return ret; +@@ -1568,8 +1568,8 @@ static void hns3_pmu_uninit_pmu(struct pci_dev *pdev) + struct hns3_pmu *hns3_pmu = pci_get_drvdata(pdev); + + perf_pmu_unregister(&hns3_pmu->pmu); +- cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE, +- &hns3_pmu->node); ++ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE, ++ &hns3_pmu->node); + } + + static int hns3_pmu_init_dev(struct pci_dev *pdev) +-- +2.42.0 + diff --git a/queue-6.6/drivers-perf-hisi_pcie-check-the-type-first-in-pmu-e.patch b/queue-6.6/drivers-perf-hisi_pcie-check-the-type-first-in-pmu-e.patch new file mode 100644 index 00000000000..2644fa2188c --- /dev/null +++ b/queue-6.6/drivers-perf-hisi_pcie-check-the-type-first-in-pmu-e.patch @@ -0,0 +1,53 @@ +From 5c8efe9eec1e7947807df389a8f05c0af533184b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Oct 2023 17:29:53 +0800 +Subject: drivers/perf: hisi_pcie: Check the type first in pmu::event_init() + +From: Yicong Yang + +[ Upstream commit 6d7d51e88e21c0af1ca96a3617afef334bfeffcf ] + +Check whether the event type matches the PMU type firstly in +pmu::event_init() before touching the event. Otherwise we'll +change the events of others and lead to incorrect results. +Since in perf_init_event() we may call every pmu's event_init() +in a certain case, we should not modify the event if it's not +ours. + +Fixes: 8404b0fbc7fb ("drivers/perf: hisi: Add driver for HiSilicon PCIe PMU") +Signed-off-by: Yicong Yang +Link: https://lore.kernel.org/r/20231024092954.42297-2-yangyicong@huawei.com +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + drivers/perf/hisilicon/hisi_pcie_pmu.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c +index 5a00adb2de8c9..051efffc44c82 100644 +--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c ++++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c +@@ -353,6 +353,10 @@ static int hisi_pcie_pmu_event_init(struct perf_event *event) + struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu); + struct hw_perf_event *hwc = &event->hw; + ++ /* Check the type first before going on, otherwise it's not our event */ ++ if (event->attr.type != event->pmu->type) ++ return -ENOENT; ++ + event->cpu = pcie_pmu->on_cpu; + + if (EXT_COUNTER_IS_USED(hisi_pcie_get_event(event))) +@@ -360,9 +364,6 @@ static int hisi_pcie_pmu_event_init(struct perf_event *event) + else + hwc->event_base = HISI_PCIE_CNT; + +- if (event->attr.type != event->pmu->type) +- return -ENOENT; +- + /* Sampling is not supported. */ + if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK) + return -EOPNOTSUPP; +-- +2.42.0 + diff --git a/queue-6.6/drm-amd-display-bail-from-dm_check_crtc_cursor-if-no.patch b/queue-6.6/drm-amd-display-bail-from-dm_check_crtc_cursor-if-no.patch new file mode 100644 index 00000000000..f4f57f9f7a5 --- /dev/null +++ b/queue-6.6/drm-amd-display-bail-from-dm_check_crtc_cursor-if-no.patch @@ -0,0 +1,88 @@ +From e475e695d244f6a350a11c01ffdbb13a166cc14e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Oct 2023 16:16:49 +0200 +Subject: drm/amd/display: Bail from dm_check_crtc_cursor if no relevant change +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michel Dänzer + +[ Upstream commit bc0b79ce2050aa523c38c96b6d26340a96bfbdca ] + +If no plane was newly enabled or changed scaling, there can be no new +scaling mismatch with the cursor plane. + +By not pulling non-cursor plane states into all atomic commits while +the cursor plane is enabled, this avoids synchronizing all cursor plane +changes to vertical blank, which caused the following IGT tests to fail: + +kms_cursor_legacy@cursor-vs-flip.* +kms_cursor_legacy@flip-vs-cursor.* + +Fixes: 003048ddf44b ("drm/amd/display: Check all enabled planes in dm_check_crtc_cursor") +Signed-off-by: Michel Dänzer +Signed-off-by: Hamza Mahfooz +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 33 ++++++++++++++++++- + 1 file changed, 32 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 70477a6b896ab..34f011cedd065 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -9906,10 +9906,12 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state, + struct drm_crtc *crtc, + struct drm_crtc_state *new_crtc_state) + { +- struct drm_plane *cursor = crtc->cursor, *underlying; ++ struct drm_plane *cursor = crtc->cursor, *plane, *underlying; ++ struct drm_plane_state *old_plane_state, *new_plane_state; + struct drm_plane_state *new_cursor_state, *new_underlying_state; + int i; + int cursor_scale_w, cursor_scale_h, underlying_scale_w, underlying_scale_h; ++ bool any_relevant_change = false; + + /* On DCE and DCN there is no dedicated hardware cursor plane. We get a + * cursor per pipe but it's going to inherit the scaling and +@@ -9917,6 +9919,35 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state, + * blending properties match the underlying planes'. + */ + ++ /* If no plane was enabled or changed scaling, no need to check again */ ++ for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { ++ int new_scale_w, new_scale_h, old_scale_w, old_scale_h; ++ ++ if (!new_plane_state || !new_plane_state->fb || new_plane_state->crtc != crtc) ++ continue; ++ ++ if (!old_plane_state || !old_plane_state->fb || old_plane_state->crtc != crtc) { ++ any_relevant_change = true; ++ break; ++ } ++ ++ if (new_plane_state->fb == old_plane_state->fb && ++ new_plane_state->crtc_w == old_plane_state->crtc_w && ++ new_plane_state->crtc_h == old_plane_state->crtc_h) ++ continue; ++ ++ dm_get_plane_scale(new_plane_state, &new_scale_w, &new_scale_h); ++ dm_get_plane_scale(old_plane_state, &old_scale_w, &old_scale_h); ++ ++ if (new_scale_w != old_scale_w || new_scale_h != old_scale_h) { ++ any_relevant_change = true; ++ break; ++ } ++ } ++ ++ if (!any_relevant_change) ++ return 0; ++ + new_cursor_state = drm_atomic_get_plane_state(state, cursor); + if (IS_ERR(new_cursor_state)) + return PTR_ERR(new_cursor_state); +-- +2.42.0 + diff --git a/queue-6.6/drm-amd-display-check-all-enabled-planes-in-dm_check.patch b/queue-6.6/drm-amd-display-check-all-enabled-planes-in-dm_check.patch new file mode 100644 index 00000000000..3852f7e1e4d --- /dev/null +++ b/queue-6.6/drm-amd-display-check-all-enabled-planes-in-dm_check.patch @@ -0,0 +1,64 @@ +From d239de1a7793a91bc4ff096fd8f2b13f2fcaf9ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 12:22:24 +0200 +Subject: drm/amd/display: Check all enabled planes in dm_check_crtc_cursor +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michel Dänzer + +[ Upstream commit 003048ddf44b1a6cfa57afa5a0cf40673e13f1ba ] + +It was only checking planes which had any state changes in the same +commit. However, it also needs to check other enabled planes. + +Not doing this meant that a commit might spuriously "succeed", resulting +in the cursor plane displaying with incorrect scaling. See +https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3177#note_1824263 +for an example. + +Fixes: d1bfbe8a3202 ("amd/display: check cursor plane matches underlying plane") +Reviewed-by: Alex Deucher +Signed-off-by: Michel Dänzer +Signed-off-by: Hamza Mahfooz +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 4120ae9d10248..342988f52d960 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -9908,14 +9908,24 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state, + * blending properties match the underlying planes'. + */ + +- new_cursor_state = drm_atomic_get_new_plane_state(state, cursor); +- if (!new_cursor_state || !new_cursor_state->fb) ++ new_cursor_state = drm_atomic_get_plane_state(state, cursor); ++ if (IS_ERR(new_cursor_state)) ++ return PTR_ERR(new_cursor_state); ++ ++ if (!new_cursor_state->fb) + return 0; + + dm_get_oriented_plane_size(new_cursor_state, &cursor_src_w, &cursor_src_h); + cursor_scale_w = new_cursor_state->crtc_w * 1000 / cursor_src_w; + cursor_scale_h = new_cursor_state->crtc_h * 1000 / cursor_src_h; + ++ /* Need to check all enabled planes, even if this commit doesn't change ++ * their state ++ */ ++ i = drm_atomic_add_affected_planes(state, crtc); ++ if (i) ++ return i; ++ + for_each_new_plane_in_state_reverse(state, underlying, new_underlying_state, i) { + /* Narrow down to non-cursor planes on the same CRTC as the cursor */ + if (new_underlying_state->crtc != crtc || underlying == crtc->cursor) +-- +2.42.0 + diff --git a/queue-6.6/drm-amd-display-fix-null-pointer-dereference-in-erro.patch b/queue-6.6/drm-amd-display-fix-null-pointer-dereference-in-erro.patch new file mode 100644 index 00000000000..a0bee3e5c9f --- /dev/null +++ b/queue-6.6/drm-amd-display-fix-null-pointer-dereference-in-erro.patch @@ -0,0 +1,40 @@ +From 159388b607a9fb6134c9bdfe43ae2c400801bdb3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Sep 2023 13:56:17 +0800 +Subject: drm/amd/display: Fix null pointer dereference in error message + +From: Cong Liu + +[ Upstream commit 0c3601a2fbfb265ce283651480e30c8e60459112 ] + +This patch fixes a null pointer dereference in the error message that is +printed when the Display Core (DC) fails to initialize. The original +message includes the DC version number, which is undefined if the DC is +not initialized. + +Fixes: 9788d087caff ("drm/amd/display: improve the message printed when loading DC") +Signed-off-by: Cong Liu +Reviewed-by: Harry Wentland +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 868946dd7ef12..4120ae9d10248 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -1692,8 +1692,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) + DRM_INFO("Display Core v%s initialized on %s\n", DC_VER, + dce_version_to_string(adev->dm.dc->ctx->dce_version)); + } else { +- DRM_INFO("Display Core v%s failed to initialize on %s\n", DC_VER, +- dce_version_to_string(adev->dm.dc->ctx->dce_version)); ++ DRM_INFO("Display Core failed to initialize with v%s!\n", DC_VER); + goto error; + } + +-- +2.42.0 + diff --git a/queue-6.6/drm-amd-display-refactor-dm_get_plane_scale-helper.patch b/queue-6.6/drm-amd-display-refactor-dm_get_plane_scale-helper.patch new file mode 100644 index 00000000000..3fde30d8f84 --- /dev/null +++ b/queue-6.6/drm-amd-display-refactor-dm_get_plane_scale-helper.patch @@ -0,0 +1,81 @@ +From d1eb036ebe536c7f368e5cfb93572e4168387346 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Oct 2023 16:16:48 +0200 +Subject: drm/amd/display: Refactor dm_get_plane_scale helper +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michel Dänzer + +[ Upstream commit ec4d770bbb155674c2497f255f4199bdc42287a9 ] + +Cleanup, no functional change intended. + +Signed-off-by: Michel Dänzer +Signed-off-by: Hamza Mahfooz +Signed-off-by: Alex Deucher +Stable-dep-of: bc0b79ce2050 ("drm/amd/display: Bail from dm_check_crtc_cursor if no relevant change") +Signed-off-by: Sasha Levin +--- + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 +++++++++++-------- + 1 file changed, 14 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 342988f52d960..70477a6b896ab 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -9891,6 +9891,17 @@ static void dm_get_oriented_plane_size(struct drm_plane_state *plane_state, + } + } + ++static void ++dm_get_plane_scale(struct drm_plane_state *plane_state, ++ int *out_plane_scale_w, int *out_plane_scale_h) ++{ ++ int plane_src_w, plane_src_h; ++ ++ dm_get_oriented_plane_size(plane_state, &plane_src_w, &plane_src_h); ++ *out_plane_scale_w = plane_state->crtc_w * 1000 / plane_src_w; ++ *out_plane_scale_h = plane_state->crtc_h * 1000 / plane_src_h; ++} ++ + static int dm_check_crtc_cursor(struct drm_atomic_state *state, + struct drm_crtc *crtc, + struct drm_crtc_state *new_crtc_state) +@@ -9899,8 +9910,6 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state, + struct drm_plane_state *new_cursor_state, *new_underlying_state; + int i; + int cursor_scale_w, cursor_scale_h, underlying_scale_w, underlying_scale_h; +- int cursor_src_w, cursor_src_h; +- int underlying_src_w, underlying_src_h; + + /* On DCE and DCN there is no dedicated hardware cursor plane. We get a + * cursor per pipe but it's going to inherit the scaling and +@@ -9915,9 +9924,7 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state, + if (!new_cursor_state->fb) + return 0; + +- dm_get_oriented_plane_size(new_cursor_state, &cursor_src_w, &cursor_src_h); +- cursor_scale_w = new_cursor_state->crtc_w * 1000 / cursor_src_w; +- cursor_scale_h = new_cursor_state->crtc_h * 1000 / cursor_src_h; ++ dm_get_plane_scale(new_cursor_state, &cursor_scale_w, &cursor_scale_h); + + /* Need to check all enabled planes, even if this commit doesn't change + * their state +@@ -9935,10 +9942,8 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state, + if (!new_underlying_state->fb) + continue; + +- dm_get_oriented_plane_size(new_underlying_state, +- &underlying_src_w, &underlying_src_h); +- underlying_scale_w = new_underlying_state->crtc_w * 1000 / underlying_src_w; +- underlying_scale_h = new_underlying_state->crtc_h * 1000 / underlying_src_h; ++ dm_get_plane_scale(new_underlying_state, ++ &underlying_scale_w, &underlying_scale_h); + + if (cursor_scale_w != underlying_scale_w || + cursor_scale_h != underlying_scale_h) { +-- +2.42.0 + diff --git a/queue-6.6/drm-amd-pm-fix-a-memory-leak-on-an-error-path.patch b/queue-6.6/drm-amd-pm-fix-a-memory-leak-on-an-error-path.patch new file mode 100644 index 00000000000..c79335eae05 --- /dev/null +++ b/queue-6.6/drm-amd-pm-fix-a-memory-leak-on-an-error-path.patch @@ -0,0 +1,39 @@ +From b46aa676c44db4533c0f6f0c8735cfac55cf722a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 14:10:39 +0800 +Subject: drm/amd/pm: Fix a memory leak on an error path + +From: Kunwu.Chan + +[ Upstream commit 828f8e31379b28fe7f07fb5865b8ed099d223fca ] + +Add missing free on an error path. + +Fixes: 511a95552ec8 ("drm/amd/pm: Add SMU 13.0.6 support") +Reviewed-by: Yang Wang +Signed-off-by: Kunwu.Chan +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +index de80e191a92c4..24d6811438c5c 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +@@ -1968,8 +1968,10 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table + + metrics = kzalloc(sizeof(MetricsTable_t), GFP_KERNEL); + ret = smu_v13_0_6_get_metrics_table(smu, metrics, true); +- if (ret) ++ if (ret) { ++ kfree(metrics); + return ret; ++ } + + smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 3); + +-- +2.42.0 + diff --git a/queue-6.6/drm-amdgpu-don-t-put-mqds-in-vram-on-arm-arm64.patch b/queue-6.6/drm-amdgpu-don-t-put-mqds-in-vram-on-arm-arm64.patch new file mode 100644 index 00000000000..9dac9b409e4 --- /dev/null +++ b/queue-6.6/drm-amdgpu-don-t-put-mqds-in-vram-on-arm-arm64.patch @@ -0,0 +1,51 @@ +From d5f20dc1b975c2c44ecc7298fc63a30346f5a393 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Oct 2023 14:37:31 -0400 +Subject: drm/amdgpu: don't put MQDs in VRAM on ARM | ARM64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Alex Deucher + +[ Upstream commit ba0fb4b48c19a2d2380fc16ca4af236a0871d279 ] + +Issues were reported with commit 1cfb4d612127 +("drm/amdgpu: put MQDs in VRAM") on an ADLINK Ampere +Altra Developer Platform (AVA developer platform). + +Various ARM systems seem to have problems related +to PCIe and MMIO access. In this case, I'm not sure +if this is specific to the ADLINK platform or ARM +in general. Seems to be some coherency issue with +VRAM. For now, just don't put MQDs in VRAM on ARM. + +Link: https://lists.freedesktop.org/archives/amd-gfx/2023-October/100453.html +Fixes: 1cfb4d612127 ("drm/amdgpu: put MQDs in VRAM") +Acked-by: Christian König +Signed-off-by: Alex Deucher +Cc: alexey.klimov@linaro.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +index 2382921710ece..ef4cb921781d7 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +@@ -384,9 +384,11 @@ int amdgpu_gfx_mqd_sw_init(struct amdgpu_device *adev, + struct amdgpu_ring *ring = &kiq->ring; + u32 domain = AMDGPU_GEM_DOMAIN_GTT; + ++#if !defined(CONFIG_ARM) && !defined(CONFIG_ARM64) + /* Only enable on gfx10 and 11 for now to avoid changing behavior on older chips */ + if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 0, 0)) + domain |= AMDGPU_GEM_DOMAIN_VRAM; ++#endif + + /* create MQD for KIQ */ + if (!adev->enable_mes_kiq && !ring->mqd_obj) { +-- +2.42.0 + diff --git a/queue-6.6/drm-amdgpu-gfx10-11-use-memcpy_to-fromio-for-mqds.patch b/queue-6.6/drm-amdgpu-gfx10-11-use-memcpy_to-fromio-for-mqds.patch new file mode 100644 index 00000000000..4039e280123 --- /dev/null +++ b/queue-6.6/drm-amdgpu-gfx10-11-use-memcpy_to-fromio-for-mqds.patch @@ -0,0 +1,127 @@ +From ae4e437be48e5de91a23100f9ec0cb83bef4955d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Oct 2023 14:47:57 -0400 +Subject: drm/amdgpu/gfx10,11: use memcpy_to/fromio for MQDs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Alex Deucher + +[ Upstream commit b3c942bb6c32a8ddc1d52ee6bc24b8cf732dddf4 ] + +Since they were moved to VRAM, we need to use the IO +variants of memcpy. + +Fixes: 1cfb4d612127 ("drm/amdgpu: put MQDs in VRAM") +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 12 ++++++------ + drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 12 ++++++------ + 2 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +index 9032d7a24d7cd..306252cd67fd7 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +@@ -6457,11 +6457,11 @@ static int gfx_v10_0_gfx_init_queue(struct amdgpu_ring *ring) + nv_grbm_select(adev, 0, 0, 0, 0); + mutex_unlock(&adev->srbm_mutex); + if (adev->gfx.me.mqd_backup[mqd_idx]) +- memcpy(adev->gfx.me.mqd_backup[mqd_idx], mqd, sizeof(*mqd)); ++ memcpy_fromio(adev->gfx.me.mqd_backup[mqd_idx], mqd, sizeof(*mqd)); + } else { + /* restore mqd with the backup copy */ + if (adev->gfx.me.mqd_backup[mqd_idx]) +- memcpy(mqd, adev->gfx.me.mqd_backup[mqd_idx], sizeof(*mqd)); ++ memcpy_toio(mqd, adev->gfx.me.mqd_backup[mqd_idx], sizeof(*mqd)); + /* reset the ring */ + ring->wptr = 0; + *ring->wptr_cpu_addr = 0; +@@ -6735,7 +6735,7 @@ static int gfx_v10_0_kiq_init_queue(struct amdgpu_ring *ring) + if (amdgpu_in_reset(adev)) { /* for GPU_RESET case */ + /* reset MQD to a clean status */ + if (adev->gfx.kiq[0].mqd_backup) +- memcpy(mqd, adev->gfx.kiq[0].mqd_backup, sizeof(*mqd)); ++ memcpy_toio(mqd, adev->gfx.kiq[0].mqd_backup, sizeof(*mqd)); + + /* reset ring buffer */ + ring->wptr = 0; +@@ -6758,7 +6758,7 @@ static int gfx_v10_0_kiq_init_queue(struct amdgpu_ring *ring) + mutex_unlock(&adev->srbm_mutex); + + if (adev->gfx.kiq[0].mqd_backup) +- memcpy(adev->gfx.kiq[0].mqd_backup, mqd, sizeof(*mqd)); ++ memcpy_fromio(adev->gfx.kiq[0].mqd_backup, mqd, sizeof(*mqd)); + } + + return 0; +@@ -6779,11 +6779,11 @@ static int gfx_v10_0_kcq_init_queue(struct amdgpu_ring *ring) + mutex_unlock(&adev->srbm_mutex); + + if (adev->gfx.mec.mqd_backup[mqd_idx]) +- memcpy(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(*mqd)); ++ memcpy_fromio(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(*mqd)); + } else { + /* restore MQD to a clean status */ + if (adev->gfx.mec.mqd_backup[mqd_idx]) +- memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(*mqd)); ++ memcpy_toio(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(*mqd)); + /* reset ring buffer */ + ring->wptr = 0; + atomic64_set((atomic64_t *)ring->wptr_cpu_addr, 0); +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +index 762d7a19f1be1..43d066bc5245b 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +@@ -3684,11 +3684,11 @@ static int gfx_v11_0_gfx_init_queue(struct amdgpu_ring *ring) + soc21_grbm_select(adev, 0, 0, 0, 0); + mutex_unlock(&adev->srbm_mutex); + if (adev->gfx.me.mqd_backup[mqd_idx]) +- memcpy(adev->gfx.me.mqd_backup[mqd_idx], mqd, sizeof(*mqd)); ++ memcpy_fromio(adev->gfx.me.mqd_backup[mqd_idx], mqd, sizeof(*mqd)); + } else { + /* restore mqd with the backup copy */ + if (adev->gfx.me.mqd_backup[mqd_idx]) +- memcpy(mqd, adev->gfx.me.mqd_backup[mqd_idx], sizeof(*mqd)); ++ memcpy_toio(mqd, adev->gfx.me.mqd_backup[mqd_idx], sizeof(*mqd)); + /* reset the ring */ + ring->wptr = 0; + *ring->wptr_cpu_addr = 0; +@@ -3977,7 +3977,7 @@ static int gfx_v11_0_kiq_init_queue(struct amdgpu_ring *ring) + if (amdgpu_in_reset(adev)) { /* for GPU_RESET case */ + /* reset MQD to a clean status */ + if (adev->gfx.kiq[0].mqd_backup) +- memcpy(mqd, adev->gfx.kiq[0].mqd_backup, sizeof(*mqd)); ++ memcpy_toio(mqd, adev->gfx.kiq[0].mqd_backup, sizeof(*mqd)); + + /* reset ring buffer */ + ring->wptr = 0; +@@ -4000,7 +4000,7 @@ static int gfx_v11_0_kiq_init_queue(struct amdgpu_ring *ring) + mutex_unlock(&adev->srbm_mutex); + + if (adev->gfx.kiq[0].mqd_backup) +- memcpy(adev->gfx.kiq[0].mqd_backup, mqd, sizeof(*mqd)); ++ memcpy_fromio(adev->gfx.kiq[0].mqd_backup, mqd, sizeof(*mqd)); + } + + return 0; +@@ -4021,11 +4021,11 @@ static int gfx_v11_0_kcq_init_queue(struct amdgpu_ring *ring) + mutex_unlock(&adev->srbm_mutex); + + if (adev->gfx.mec.mqd_backup[mqd_idx]) +- memcpy(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(*mqd)); ++ memcpy_fromio(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(*mqd)); + } else { + /* restore MQD to a clean status */ + if (adev->gfx.mec.mqd_backup[mqd_idx]) +- memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(*mqd)); ++ memcpy_toio(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(*mqd)); + /* reset ring buffer */ + ring->wptr = 0; + atomic64_set((atomic64_t *)ring->wptr_cpu_addr, 0); +-- +2.42.0 + diff --git a/queue-6.6/drm-amdgpu-increase-ih-soft-ring-size-for-gfx-v9.4.3.patch b/queue-6.6/drm-amdgpu-increase-ih-soft-ring-size-for-gfx-v9.4.3.patch new file mode 100644 index 00000000000..01b8b8ba9e0 --- /dev/null +++ b/queue-6.6/drm-amdgpu-increase-ih-soft-ring-size-for-gfx-v9.4.3.patch @@ -0,0 +1,44 @@ +From 081270c290d0616b756e876fbd9630f2e11c5ebb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 15:13:48 -0400 +Subject: drm/amdgpu: Increase IH soft ring size for GFX v9.4.3 dGPU +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Philip Yang + +[ Upstream commit bcfb9cee61207b80f37663ffa08c135657a27ad5 ] + +On GFX v9.4.3 dGPU, applications have random timeout failure when XNACK +on, dmesg log has "amdgpu: IH soft ring buffer overflow 0x900, 0x900", +because dGPU mode has 272 cam entries. After increasing IH soft ring +to 512 entries, no more IH soft ring overflow message and application +passed. + +Fixes: bf80d34b6c58 ("drm/amdgpu: Increase soft IH ring size") +Signed-off-by: Philip Yang +Reviewed-by: Christian König +Reviewed-by: Felix Kuehling +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h +index 6c6184f0dbc17..508f02eb0cf8f 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h +@@ -28,7 +28,7 @@ + #define AMDGPU_IH_MAX_NUM_IVS 32 + + #define IH_RING_SIZE (256 * 1024) +-#define IH_SW_RING_SIZE (8 * 1024) /* enough for 256 CAM entries */ ++#define IH_SW_RING_SIZE (16 * 1024) /* enough for 512 CAM entries */ + + struct amdgpu_device; + struct amdgpu_iv_entry; +-- +2.42.0 + diff --git a/queue-6.6/drm-amdkfd-fix-some-race-conditions-in-vram-buffer-a.patch b/queue-6.6/drm-amdkfd-fix-some-race-conditions-in-vram-buffer-a.patch new file mode 100644 index 00000000000..77b227555c0 --- /dev/null +++ b/queue-6.6/drm-amdkfd-fix-some-race-conditions-in-vram-buffer-a.patch @@ -0,0 +1,50 @@ +From 7f25b66c729778b9fb322b1f8e0768588f160945 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Sep 2023 11:02:51 -0500 +Subject: drm/amdkfd: fix some race conditions in vram buffer alloc/free of svm + code + +From: Xiaogang Chen + +[ Upstream commit 7bfaa160caed8192f8262c4638f552cad94bcf5a ] + +This patch fixes: +1: ref number of prange's svm_bo got decreased by an async call from hmm. When +wait svm_bo of prange got released we shoul also wait prang->svm_bo become NULL, +otherwise prange->svm_bo may be set to null after allocate new vram buffer. + +2: During waiting svm_bo of prange got released in a while loop should reschedule +current task to give other tasks oppotunity to run, specially the the workque +task that handles svm_bo ref release, otherwise we may enter to softlock. + +Signed-off-by: Xiaogang.Chen +Reviewed-by: Felix Kuehling +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +index bb16b795d1bc2..bb65a99439802 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +@@ -495,11 +495,11 @@ svm_range_validate_svm_bo(struct kfd_node *node, struct svm_range *prange) + + /* We need a new svm_bo. Spin-loop to wait for concurrent + * svm_range_bo_release to finish removing this range from +- * its range list. After this, it is safe to reuse the +- * svm_bo pointer and svm_bo_list head. ++ * its range list and set prange->svm_bo to null. After this, ++ * it is safe to reuse the svm_bo pointer and svm_bo_list head. + */ +- while (!list_empty_careful(&prange->svm_bo_list)) +- ; ++ while (!list_empty_careful(&prange->svm_bo_list) || prange->svm_bo) ++ cond_resched(); + + return false; + } +-- +2.42.0 + diff --git a/queue-6.6/drm-amdkfd-handle-errors-from-svm-validate-and-map.patch b/queue-6.6/drm-amdkfd-handle-errors-from-svm-validate-and-map.patch new file mode 100644 index 00000000000..13e1dd8fd35 --- /dev/null +++ b/queue-6.6/drm-amdkfd-handle-errors-from-svm-validate-and-map.patch @@ -0,0 +1,207 @@ +From f3609c593c004985787f2ff504e9273a80227de0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 10:10:23 -0400 +Subject: drm/amdkfd: Handle errors from svm validate and map + +From: Philip Yang + +[ Upstream commit eb3c357bcb286e89386e89302061fe717fe4e562 ] + +If new range is splited to multiple pranges with max_svm_range_pages +alignment and added to update_list, svm validate and map should keep +going after error to make sure prange->mapped_to_gpu flag is up to date +for the whole range. + +svm validate and map update set prange->mapped_to_gpu after mapping to +GPUs successfully, otherwise clear prange->mapped_to_gpu flag (for +update mapping case) instead of setting error flag, we can remove +the redundant error flag to simpliy code. + +Refactor to remove goto and update prange->mapped_to_gpu flag inside +svm_range_lock, to guarant we always evict queues or unmap from GPUs if +there are invalid ranges. + +After svm validate and map return error -EAGIN, the caller retry will +update the mapping for the whole range again. + +Fixes: c22b04407097 ("drm/amdkfd: flag added to handle errors from svm validate and map") +Signed-off-by: Philip Yang +Reviewed-by: Felix Kuehling +Tested-by: James Zhu +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 82 +++++++++++++--------------- + drivers/gpu/drm/amd/amdkfd/kfd_svm.h | 1 - + 2 files changed, 39 insertions(+), 44 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +index dfc11699e79ab..2a42fbddcb7ae 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +@@ -820,7 +820,7 @@ svm_range_is_same_attrs(struct kfd_process *p, struct svm_range *prange, + } + } + +- return !prange->is_error_flag; ++ return true; + } + + /** +@@ -1662,71 +1662,66 @@ static int svm_range_validate_and_map(struct mm_struct *mm, + + start = prange->start << PAGE_SHIFT; + end = (prange->last + 1) << PAGE_SHIFT; +- for (addr = start; addr < end && !r; ) { ++ for (addr = start; !r && addr < end; ) { + struct hmm_range *hmm_range; + struct vm_area_struct *vma; +- unsigned long next; ++ unsigned long next = 0; + unsigned long offset; + unsigned long npages; + bool readonly; + + vma = vma_lookup(mm, addr); +- if (!vma) { ++ if (vma) { ++ readonly = !(vma->vm_flags & VM_WRITE); ++ ++ next = min(vma->vm_end, end); ++ npages = (next - addr) >> PAGE_SHIFT; ++ WRITE_ONCE(p->svms.faulting_task, current); ++ r = amdgpu_hmm_range_get_pages(&prange->notifier, addr, npages, ++ readonly, owner, NULL, ++ &hmm_range); ++ WRITE_ONCE(p->svms.faulting_task, NULL); ++ if (r) { ++ pr_debug("failed %d to get svm range pages\n", r); ++ if (r == -EBUSY) ++ r = -EAGAIN; ++ } ++ } else { + r = -EFAULT; +- goto unreserve_out; +- } +- readonly = !(vma->vm_flags & VM_WRITE); +- +- next = min(vma->vm_end, end); +- npages = (next - addr) >> PAGE_SHIFT; +- WRITE_ONCE(p->svms.faulting_task, current); +- r = amdgpu_hmm_range_get_pages(&prange->notifier, addr, npages, +- readonly, owner, NULL, +- &hmm_range); +- WRITE_ONCE(p->svms.faulting_task, NULL); +- if (r) { +- pr_debug("failed %d to get svm range pages\n", r); +- if (r == -EBUSY) +- r = -EAGAIN; +- goto unreserve_out; + } + +- offset = (addr - start) >> PAGE_SHIFT; +- r = svm_range_dma_map(prange, ctx->bitmap, offset, npages, +- hmm_range->hmm_pfns); +- if (r) { +- pr_debug("failed %d to dma map range\n", r); +- goto unreserve_out; ++ if (!r) { ++ offset = (addr - start) >> PAGE_SHIFT; ++ r = svm_range_dma_map(prange, ctx->bitmap, offset, npages, ++ hmm_range->hmm_pfns); ++ if (r) ++ pr_debug("failed %d to dma map range\n", r); + } + + svm_range_lock(prange); +- if (amdgpu_hmm_range_get_pages_done(hmm_range)) { ++ if (!r && amdgpu_hmm_range_get_pages_done(hmm_range)) { + pr_debug("hmm update the range, need validate again\n"); + r = -EAGAIN; +- goto unlock_out; + } +- if (!list_empty(&prange->child_list)) { ++ ++ if (!r && !list_empty(&prange->child_list)) { + pr_debug("range split by unmap in parallel, validate again\n"); + r = -EAGAIN; +- goto unlock_out; + } + +- r = svm_range_map_to_gpus(prange, offset, npages, readonly, +- ctx->bitmap, wait, flush_tlb); ++ if (!r) ++ r = svm_range_map_to_gpus(prange, offset, npages, readonly, ++ ctx->bitmap, wait, flush_tlb); ++ ++ if (!r && next == end) ++ prange->mapped_to_gpu = true; + +-unlock_out: + svm_range_unlock(prange); + + addr = next; + } + +- if (addr == end) +- prange->mapped_to_gpu = true; +- +-unreserve_out: + svm_range_unreserve_bos(ctx); +- +- prange->is_error_flag = !!r; + if (!r) + prange->validate_timestamp = ktime_get_boottime(); + +@@ -2095,7 +2090,8 @@ svm_range_add(struct kfd_process *p, uint64_t start, uint64_t size, + next = interval_tree_iter_next(node, start, last); + next_start = min(node->last, last) + 1; + +- if (svm_range_is_same_attrs(p, prange, nattr, attrs)) { ++ if (svm_range_is_same_attrs(p, prange, nattr, attrs) && ++ prange->mapped_to_gpu) { + /* nothing to do */ + } else if (node->start < start || node->last > last) { + /* node intersects the update range and its attributes +@@ -3505,7 +3501,7 @@ svm_range_set_attr(struct kfd_process *p, struct mm_struct *mm, + struct svm_range *next; + bool update_mapping = false; + bool flush_tlb; +- int r = 0; ++ int r, ret = 0; + + pr_debug("pasid 0x%x svms 0x%p [0x%llx 0x%llx] pages 0x%llx\n", + p->pasid, &p->svms, start, start + size - 1, size); +@@ -3593,7 +3589,7 @@ svm_range_set_attr(struct kfd_process *p, struct mm_struct *mm, + out_unlock_range: + mutex_unlock(&prange->migrate_mutex); + if (r) +- break; ++ ret = r; + } + + dynamic_svm_range_dump(svms); +@@ -3606,7 +3602,7 @@ svm_range_set_attr(struct kfd_process *p, struct mm_struct *mm, + pr_debug("pasid 0x%x svms 0x%p [0x%llx 0x%llx] done, r=%d\n", p->pasid, + &p->svms, start, start + size - 1, r); + +- return r; ++ return ret ? ret : r; + } + + static int +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h +index c216c8dd13c6c..25f7119057386 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h +@@ -133,7 +133,6 @@ struct svm_range { + DECLARE_BITMAP(bitmap_access, MAX_GPU_INSTANCE); + DECLARE_BITMAP(bitmap_aip, MAX_GPU_INSTANCE); + bool mapped_to_gpu; +- bool is_error_flag; + }; + + static inline void svm_range_lock(struct svm_range *prange) +-- +2.42.0 + diff --git a/queue-6.6/drm-amdkfd-remove-svm-range-validated_once-flag.patch b/queue-6.6/drm-amdkfd-remove-svm-range-validated_once-flag.patch new file mode 100644 index 00000000000..957aa2efc47 --- /dev/null +++ b/queue-6.6/drm-amdkfd-remove-svm-range-validated_once-flag.patch @@ -0,0 +1,54 @@ +From c9fec70309dc87c87552b3cd736fcb5c1853ee05 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Aug 2023 11:38:32 -0400 +Subject: drm/amdkfd: Remove svm range validated_once flag + +From: Philip Yang + +[ Upstream commit c99b16128082de519975aa147d9da3e40380de67 ] + +The validated_once flag is not used after the prefault was removed, The +prefault was needed to ensure validate all system memory pages at least +once before mapping or migrating the range to GPU. + +Signed-off-by: Philip Yang +Reviewed-by: Felix Kuehling +Signed-off-by: Alex Deucher +Stable-dep-of: eb3c357bcb28 ("drm/amdkfd: Handle errors from svm validate and map") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 4 +--- + drivers/gpu/drm/amd/amdkfd/kfd_svm.h | 1 - + 2 files changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +index bb65a99439802..dfc11699e79ab 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +@@ -1720,10 +1720,8 @@ static int svm_range_validate_and_map(struct mm_struct *mm, + addr = next; + } + +- if (addr == end) { +- prange->validated_once = true; ++ if (addr == end) + prange->mapped_to_gpu = true; +- } + + unreserve_out: + svm_range_unreserve_bos(ctx); +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h +index 9e668eeefb32d..c216c8dd13c6c 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h +@@ -132,7 +132,6 @@ struct svm_range { + struct list_head child_list; + DECLARE_BITMAP(bitmap_access, MAX_GPU_INSTANCE); + DECLARE_BITMAP(bitmap_aip, MAX_GPU_INSTANCE); +- bool validated_once; + bool mapped_to_gpu; + bool is_error_flag; + }; +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-for-generic_phy_mipi_dphy-also-select-gen.patch b/queue-6.6/drm-bridge-for-generic_phy_mipi_dphy-also-select-gen.patch new file mode 100644 index 00000000000..d8009ff8884 --- /dev/null +++ b/queue-6.6/drm-bridge-for-generic_phy_mipi_dphy-also-select-gen.patch @@ -0,0 +1,92 @@ +From 93cef828a508f38623a96a7d7f51fb00fcac43b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Aug 2023 20:01:37 -0700 +Subject: drm: bridge: for GENERIC_PHY_MIPI_DPHY also select GENERIC_PHY +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Randy Dunlap + +[ Upstream commit 96413b355a49fd684430a230479bd231d977894f ] + +Three DRM bridge drivers select GENERIC_PHY_MIPI_DPHY when GENERIC_PHY +might not be set. This causes Kconfig warnings and a build error. + +WARNING: unmet direct dependencies detected for GENERIC_PHY_MIPI_DPHY + Depends on [n]: GENERIC_PHY [=n] + Selected by [y]: + - DRM_NWL_MIPI_DSI [=y] && DRM_BRIDGE [=y] && DRM [=y] && COMMON_CLK [=y] && OF [=y] && HAS_IOMEM [=y] + - DRM_SAMSUNG_DSIM [=y] && DRM [=y] && DRM_BRIDGE [=y] && COMMON_CLK [=y] && OF [=y] && HAS_IOMEM [=y] + +(drm/bridge/cadence/Kconfig was found by inspection.) + +aarch64-linux-ld: drivers/gpu/drm/bridge/samsung-dsim.o: in function `samsung_dsim_set_phy_ctrl': +drivers/gpu/drm/bridge/samsung-dsim.c:731: undefined reference to `phy_mipi_dphy_get_default_config_for_hsclk' + +Prevent these warnings and build error by also selecting GENERIC_PHY +whenever selecting GENERIC_PHY_MIPI_DPHY. + +Fixes: fced5a364dee ("drm/bridge: cdns: Convert to phy framework") +Fixes: 44cfc6233447 ("drm/bridge: Add NWL MIPI DSI host controller support") +Fixes: 171b3b1e0f8b ("drm: bridge: samsung-dsim: Select GENERIC_PHY_MIPI_DPHY") +Signed-off-by: Randy Dunlap +Reported-by: Aleksandr Nogikh +Link: lore.kernel.org/r/20230803144227.2187749-1-nogikh@google.com +Cc: Adam Ford +Cc: Maxime Ripard +Cc: Guido Günther +Cc: Robert Chiras +Cc: Sam Ravnborg +Cc: Neil Armstrong +Cc: Andrzej Hajda +Cc: Robert Foss +Cc: David Airlie +Cc: Daniel Vetter +Cc: dri-devel@lists.freedesktop.org +Reviewed-by: Adam Ford +Tested-by: Aleksandr Nogikh +Reviewed-by: Guido Günther +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230804030140.21395-1-rdunlap@infradead.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/Kconfig | 2 ++ + drivers/gpu/drm/bridge/cadence/Kconfig | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig +index 44a660a4bdbfc..ba82a1142adf7 100644 +--- a/drivers/gpu/drm/bridge/Kconfig ++++ b/drivers/gpu/drm/bridge/Kconfig +@@ -181,6 +181,7 @@ config DRM_NWL_MIPI_DSI + select DRM_KMS_HELPER + select DRM_MIPI_DSI + select DRM_PANEL_BRIDGE ++ select GENERIC_PHY + select GENERIC_PHY_MIPI_DPHY + select MFD_SYSCON + select MULTIPLEXER +@@ -227,6 +228,7 @@ config DRM_SAMSUNG_DSIM + select DRM_KMS_HELPER + select DRM_MIPI_DSI + select DRM_PANEL_BRIDGE ++ select GENERIC_PHY + select GENERIC_PHY_MIPI_DPHY + help + The Samsung MIPI DSIM bridge controller driver. +diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig b/drivers/gpu/drm/bridge/cadence/Kconfig +index ec35215a20034..cced81633ddcd 100644 +--- a/drivers/gpu/drm/bridge/cadence/Kconfig ++++ b/drivers/gpu/drm/bridge/cadence/Kconfig +@@ -4,6 +4,7 @@ config DRM_CDNS_DSI + select DRM_KMS_HELPER + select DRM_MIPI_DSI + select DRM_PANEL_BRIDGE ++ select GENERIC_PHY + select GENERIC_PHY_MIPI_DPHY + depends on OF + help +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-it66121-fix-invalid-connector-dereference.patch b/queue-6.6/drm-bridge-it66121-fix-invalid-connector-dereference.patch new file mode 100644 index 00000000000..00b139d9fe0 --- /dev/null +++ b/queue-6.6/drm-bridge-it66121-fix-invalid-connector-dereference.patch @@ -0,0 +1,55 @@ +From f862a430ef705a70b21aacbda649d34bf4ddd89e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Sep 2023 15:01:23 +0530 +Subject: drm: bridge: it66121: Fix invalid connector dereference + +From: Jai Luthra + +[ Upstream commit d0375f6858c4ff7244b62b02eb5e93428e1916cd ] + +Fix the NULL pointer dereference when no monitor is connected, and the +sound card is opened from userspace. + +Instead return an empty buffer (of zeroes) as the EDID information to +the sound framework if there is no connector attached. + +Fixes: e0fd83dbe924 ("drm: bridge: it66121: Add audio support") +Reported-by: Nishanth Menon +Closes: https://lore.kernel.org/all/20230825105849.crhon42qndxqif4i@gondola/ +Reviewed-by: Helen Koike +Signed-off-by: Jai Luthra +Tested-by: Nishanth Menon +Reviewed-by: Aradhya Bhatia +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230901-it66121_edid-v2-1-aa59605336b9@ti.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/ite-it66121.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c +index 466641c77fe91..fc7f5ec5fb381 100644 +--- a/drivers/gpu/drm/bridge/ite-it66121.c ++++ b/drivers/gpu/drm/bridge/ite-it66121.c +@@ -1447,10 +1447,14 @@ static int it66121_audio_get_eld(struct device *dev, void *data, + struct it66121_ctx *ctx = dev_get_drvdata(dev); + + mutex_lock(&ctx->lock); +- +- memcpy(buf, ctx->connector->eld, +- min(sizeof(ctx->connector->eld), len)); +- ++ if (!ctx->connector) { ++ /* Pass en empty ELD if connector not available */ ++ dev_dbg(dev, "No connector present, passing empty EDID data"); ++ memset(buf, 0, len); ++ } else { ++ memcpy(buf, ctx->connector->eld, ++ min(sizeof(ctx->connector->eld), len)); ++ } + mutex_unlock(&ctx->lock); + + return 0; +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-lt8912b-add-missing-drm_bridge_attach-cal.patch b/queue-6.6/drm-bridge-lt8912b-add-missing-drm_bridge_attach-cal.patch new file mode 100644 index 00000000000..66225b05691 --- /dev/null +++ b/queue-6.6/drm-bridge-lt8912b-add-missing-drm_bridge_attach-cal.patch @@ -0,0 +1,46 @@ +From abfaa1d49ad6ede09203ed7bf6340be8dc0603fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Aug 2023 13:48:13 +0300 +Subject: drm/bridge: lt8912b: Add missing drm_bridge_attach call + +From: Tomi Valkeinen + +[ Upstream commit f45acf7acf75921c0409d452f0165f51a19a74fd ] + +The driver does not call drm_bridge_attach(), which causes the next +bridge to not be added to the bridge chain. This causes the pipeline +init to fail when DRM_BRIDGE_ATTACH_NO_CONNECTOR is used. + +Add the call to drm_bridge_attach(). + +Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge") +Signed-off-by: Tomi Valkeinen +Reviewed-by: Robert Foss +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230804-lt8912b-v1-4-c542692c6a2f@ideasonboard.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/lontium-lt8912b.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c +index 9ee639e75a1c2..03532efb893bb 100644 +--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c ++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c +@@ -558,6 +558,13 @@ static int lt8912_bridge_attach(struct drm_bridge *bridge, + struct lt8912 *lt = bridge_to_lt8912(bridge); + int ret; + ++ ret = drm_bridge_attach(bridge->encoder, lt->hdmi_port, bridge, ++ DRM_BRIDGE_ATTACH_NO_CONNECTOR); ++ if (ret < 0) { ++ dev_err(lt->dev, "Failed to attach next bridge (%d)\n", ret); ++ return ret; ++ } ++ + if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) { + ret = lt8912_bridge_connector_init(bridge); + if (ret) { +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-lt8912b-fix-bridge_detach.patch b/queue-6.6/drm-bridge-lt8912b-fix-bridge_detach.patch new file mode 100644 index 00000000000..667d0e69a35 --- /dev/null +++ b/queue-6.6/drm-bridge-lt8912b-fix-bridge_detach.patch @@ -0,0 +1,82 @@ +From 9621476f66f8f51fb65d3ea011670cd426e0b3b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Aug 2023 13:48:10 +0300 +Subject: drm/bridge: lt8912b: Fix bridge_detach + +From: Tomi Valkeinen + +[ Upstream commit 941882a0e96d245f38116e940912b404b6a93c6f ] + +The driver calls lt8912_bridge_detach() from its lt8912_remove() +function. As the DRM core detaches bridges automatically, this leads to +calling lt8912_bridge_detach() twice. The code probably has tried to +manage the double-call with the 'is_attached' variable, but the driver +never sets the variable to false, so its of no help. + +Fix the issue by dropping the call to lt8912_bridge_detach() from +lt8912_remove(), as the DRM core will handle the detach call for us, +and also drop the useless is_attached field. + +Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge") +Signed-off-by: Tomi Valkeinen +Reviewed-by: Robert Foss +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230804-lt8912b-v1-1-c542692c6a2f@ideasonboard.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/lontium-lt8912b.c | 16 +++++----------- + 1 file changed, 5 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c +index 4eaea67fb71c2..0e581f6e3c885 100644 +--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c ++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c +@@ -45,7 +45,6 @@ struct lt8912 { + + u8 data_lanes; + bool is_power_on; +- bool is_attached; + }; + + static int lt8912_write_init_config(struct lt8912 *lt) +@@ -575,8 +574,6 @@ static int lt8912_bridge_attach(struct drm_bridge *bridge, + if (ret) + goto error; + +- lt->is_attached = true; +- + return 0; + + error: +@@ -588,15 +585,13 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge) + { + struct lt8912 *lt = bridge_to_lt8912(bridge); + +- if (lt->is_attached) { +- lt8912_hard_power_off(lt); ++ lt8912_hard_power_off(lt); + +- if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD) +- drm_bridge_hpd_disable(lt->hdmi_port); ++ if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD) ++ drm_bridge_hpd_disable(lt->hdmi_port); + +- drm_connector_unregister(<->connector); +- drm_connector_cleanup(<->connector); +- } ++ drm_connector_unregister(<->connector); ++ drm_connector_cleanup(<->connector); + } + + static enum drm_connector_status +@@ -750,7 +745,6 @@ static void lt8912_remove(struct i2c_client *client) + { + struct lt8912 *lt = i2c_get_clientdata(client); + +- lt8912_bridge_detach(<->bridge); + drm_bridge_remove(<->bridge); + lt8912_free_i2c(lt); + lt8912_put_dt(lt); +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-lt8912b-fix-crash-on-bridge-detach.patch b/queue-6.6/drm-bridge-lt8912b-fix-crash-on-bridge-detach.patch new file mode 100644 index 00000000000..4a5c8abfec8 --- /dev/null +++ b/queue-6.6/drm-bridge-lt8912b-fix-crash-on-bridge-detach.patch @@ -0,0 +1,109 @@ +From a62eb3089ff27ca99c3c8fef4ec61396d8bcff52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Aug 2023 13:48:11 +0300 +Subject: drm/bridge: lt8912b: Fix crash on bridge detach + +From: Tomi Valkeinen + +[ Upstream commit 44283993144a03af9df31934d6c32bbd42d1a347 ] + +The lt8912b driver, in its bridge detach function, calls +drm_connector_unregister() and drm_connector_cleanup(). + +drm_connector_unregister() should be called only for connectors +explicitly registered with drm_connector_register(), which is not the +case in lt8912b. + +The driver's drm_connector_funcs.destroy hook is set to +drm_connector_cleanup(). + +Thus the driver should not call either drm_connector_unregister() nor +drm_connector_cleanup() in its lt8912_bridge_detach(), as they cause a +crash on bridge detach: + +Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 +Mem abort info: + ESR = 0x0000000096000006 + EC = 0x25: DABT (current EL), IL = 32 bits + SET = 0, FnV = 0 + EA = 0, S1PTW = 0 + FSC = 0x06: level 2 translation fault +Data abort info: + ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000 + CM = 0, WnR = 0, TnD = 0, TagAccess = 0 + GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 +user pgtable: 4k pages, 48-bit VAs, pgdp=00000000858f3000 +[0000000000000000] pgd=0800000085918003, p4d=0800000085918003, pud=0800000085431003, pmd=0000000000000000 +Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP +Modules linked in: tidss(-) display_connector lontium_lt8912b tc358768 panel_lvds panel_simple drm_dma_helper drm_kms_helper drm drm_panel_orientation_quirks +CPU: 3 PID: 462 Comm: rmmod Tainted: G W 6.5.0-rc2+ #2 +Hardware name: Toradex Verdin AM62 on Verdin Development Board (DT) +pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) +pc : drm_connector_cleanup+0x78/0x2d4 [drm] +lr : lt8912_bridge_detach+0x54/0x6c [lontium_lt8912b] +sp : ffff800082ed3a90 +x29: ffff800082ed3a90 x28: ffff0000040c1940 x27: 0000000000000000 +x26: 0000000000000000 x25: dead000000000122 x24: dead000000000122 +x23: dead000000000100 x22: ffff000003fb6388 x21: 0000000000000000 +x20: 0000000000000000 x19: ffff000003fb6260 x18: fffffffffffe56e8 +x17: 0000000000000000 x16: 0010000000000000 x15: 0000000000000038 +x14: 0000000000000000 x13: ffff800081914b48 x12: 000000000000040e +x11: 000000000000015a x10: ffff80008196ebb8 x9 : ffff800081914b48 +x8 : 00000000ffffefff x7 : ffff0000040c1940 x6 : ffff80007aa649d0 +x5 : 0000000000000000 x4 : 0000000000000001 x3 : ffff80008159e008 +x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000000000 +Call trace: + drm_connector_cleanup+0x78/0x2d4 [drm] + lt8912_bridge_detach+0x54/0x6c [lontium_lt8912b] + drm_bridge_detach+0x44/0x84 [drm] + drm_encoder_cleanup+0x40/0xb8 [drm] + drmm_encoder_alloc_release+0x1c/0x30 [drm] + drm_managed_release+0xac/0x148 [drm] + drm_dev_put.part.0+0x88/0xb8 [drm] + devm_drm_dev_init_release+0x14/0x24 [drm] + devm_action_release+0x14/0x20 + release_nodes+0x5c/0x90 + devres_release_all+0x8c/0xe0 + device_unbind_cleanup+0x18/0x68 + device_release_driver_internal+0x208/0x23c + driver_detach+0x4c/0x94 + bus_remove_driver+0x70/0xf4 + driver_unregister+0x30/0x60 + platform_driver_unregister+0x14/0x20 + tidss_platform_driver_exit+0x18/0xb2c [tidss] + __arm64_sys_delete_module+0x1a0/0x2b4 + invoke_syscall+0x48/0x110 + el0_svc_common.constprop.0+0x60/0x10c + do_el0_svc_compat+0x1c/0x40 + el0_svc_compat+0x40/0xac + el0t_32_sync_handler+0xb0/0x138 + el0t_32_sync+0x194/0x198 +Code: 9104a276 f2fbd5b7 aa0203e1 91008af8 (f85c0420) + +Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge") +Signed-off-by: Tomi Valkeinen +Reviewed-by: Robert Foss +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230804-lt8912b-v1-2-c542692c6a2f@ideasonboard.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/lontium-lt8912b.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c +index 0e581f6e3c885..2d752e083433f 100644 +--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c ++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c +@@ -589,9 +589,6 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge) + + if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD) + drm_bridge_hpd_disable(lt->hdmi_port); +- +- drm_connector_unregister(<->connector); +- drm_connector_cleanup(<->connector); + } + + static enum drm_connector_status +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-lt8912b-manually-disable-hpd-only-if-it-w.patch b/queue-6.6/drm-bridge-lt8912b-manually-disable-hpd-only-if-it-w.patch new file mode 100644 index 00000000000..393edd81991 --- /dev/null +++ b/queue-6.6/drm-bridge-lt8912b-manually-disable-hpd-only-if-it-w.patch @@ -0,0 +1,44 @@ +From 88cac2b9ec50740c1f08817398956650d3880164 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Aug 2023 13:48:12 +0300 +Subject: drm/bridge: lt8912b: Manually disable HPD only if it was enabled + +From: Tomi Valkeinen + +[ Upstream commit 6985c5efc4057bc79137807295d84ada3123d051 ] + +lt8912b only calls drm_bridge_hpd_enable() if it creates a connector and +the next bridge has DRM_BRIDGE_OP_HPD set. However, when calling +drm_bridge_hpd_disable() it misses checking if a connector was created, +calling drm_bridge_hpd_disable() even if HPD was never enabled. I don't +see any issues caused by this wrong call, though. + +Add the check to avoid wrongly calling drm_bridge_hpd_disable(). + +Fixes: 3b0a01a6a522 ("drm/bridge: lt8912b: Add hot plug detection") +Signed-off-by: Tomi Valkeinen +Tested-by: Marcel Ziswiler +Reviewed-by: Robert Foss +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230804-lt8912b-v1-3-c542692c6a2f@ideasonboard.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/lontium-lt8912b.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c +index 2d752e083433f..9ee639e75a1c2 100644 +--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c ++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c +@@ -587,7 +587,7 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge) + + lt8912_hard_power_off(lt); + +- if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD) ++ if (lt->connector.dev && lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD) + drm_bridge_hpd_disable(lt->hdmi_port); + } + +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-lt9611uxc-fix-the-race-in-the-error-path.patch b/queue-6.6/drm-bridge-lt9611uxc-fix-the-race-in-the-error-path.patch new file mode 100644 index 00000000000..8c19cfec974 --- /dev/null +++ b/queue-6.6/drm-bridge-lt9611uxc-fix-the-race-in-the-error-path.patch @@ -0,0 +1,97 @@ +From 9d88e78a25fc6966101873f4efb15a58c45c7d60 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Oct 2023 01:00:02 +0300 +Subject: drm/bridge: lt9611uxc: fix the race in the error path + +From: Dmitry Baryshkov + +[ Upstream commit 15fe53be46eaf4f6339cd433972ecc90513e3076 ] + +If DSI host attachment fails, the LT9611UXC driver will remove the +bridge without ensuring that there is no outstanding HPD work being +done. In rare cases this can result in the warnings regarding the mutex +being incorrect. Fix this by forcebly freing IRQ and flushing the work. + +DEBUG_LOCKS_WARN_ON(lock->magic != lock) +WARNING: CPU: 0 PID: 10 at kernel/locking/mutex.c:582 __mutex_lock+0x468/0x77c +Modules linked in: +CPU: 0 PID: 10 Comm: kworker/0:1 Tainted: G U 6.6.0-rc5-next-20231011-gd81f81c2b682-dirty #1206 +Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT) +Workqueue: events lt9611uxc_hpd_work +pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) +pc : __mutex_lock+0x468/0x77c +lr : __mutex_lock+0x468/0x77c +sp : ffff8000800a3c70 +x29: ffff8000800a3c70 x28: 0000000000000000 x27: ffffd595fe333000 +x26: ffff7c2f0002c005 x25: ffffd595ff1b3000 x24: ffffd595fccda5a0 +x23: 0000000000000000 x22: 0000000000000002 x21: ffff7c2f056d91c8 +x20: 0000000000000000 x19: ffff7c2f056d91c8 x18: fffffffffffe8db0 +x17: 000000040044ffff x16: 005000f2b5503510 x15: 0000000000000000 +x14: 000000000006efb8 x13: 0000000000000000 x12: 0000000000000037 +x11: 0000000000000001 x10: 0000000000001470 x9 : ffff8000800a3ae0 +x8 : ffff7c2f0027f8d0 x7 : ffff7c2f0027e400 x6 : ffffd595fc702b54 +x5 : 0000000000000000 x4 : ffff8000800a0000 x3 : 0000000000000000 +x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff7c2f0027e400 +Call trace: + __mutex_lock+0x468/0x77c + mutex_lock_nested+0x24/0x30 + drm_bridge_hpd_notify+0x2c/0x5c + lt9611uxc_hpd_work+0x6c/0x80 + process_one_work+0x1ec/0x51c + worker_thread+0x1ec/0x3e4 + kthread+0x120/0x124 + ret_from_fork+0x10/0x20 +irq event stamp: 15799 +hardirqs last enabled at (15799): [] finish_task_switch.isra.0+0xa8/0x278 +hardirqs last disabled at (15798): [] __schedule+0x7b8/0xbd8 +softirqs last enabled at (15794): [] __do_softirq+0x498/0x4e0 +softirqs last disabled at (15771): [] ____do_softirq+0x10/0x1c + +Fixes: bc6fa8676ebb ("drm/bridge/lontium-lt9611uxc: move HPD notification out of IRQ handler") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Robert Foss +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20231011220002.382422-1-dmitry.baryshkov@linaro.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +index 22c84d29c2bc5..6f33bb0dd32aa 100644 +--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c ++++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +@@ -929,9 +929,9 @@ static int lt9611uxc_probe(struct i2c_client *client) + init_waitqueue_head(<9611uxc->wq); + INIT_WORK(<9611uxc->work, lt9611uxc_hpd_work); + +- ret = devm_request_threaded_irq(dev, client->irq, NULL, +- lt9611uxc_irq_thread_handler, +- IRQF_ONESHOT, "lt9611uxc", lt9611uxc); ++ ret = request_threaded_irq(client->irq, NULL, ++ lt9611uxc_irq_thread_handler, ++ IRQF_ONESHOT, "lt9611uxc", lt9611uxc); + if (ret) { + dev_err(dev, "failed to request irq\n"); + goto err_disable_regulators; +@@ -967,6 +967,8 @@ static int lt9611uxc_probe(struct i2c_client *client) + return lt9611uxc_audio_init(dev, lt9611uxc); + + err_remove_bridge: ++ free_irq(client->irq, lt9611uxc); ++ cancel_work_sync(<9611uxc->work); + drm_bridge_remove(<9611uxc->bridge); + + err_disable_regulators: +@@ -983,7 +985,7 @@ static void lt9611uxc_remove(struct i2c_client *client) + { + struct lt9611uxc *lt9611uxc = i2c_get_clientdata(client); + +- disable_irq(client->irq); ++ free_irq(client->irq, lt9611uxc); + cancel_work_sync(<9611uxc->work); + lt9611uxc_audio_exit(lt9611uxc); + drm_bridge_remove(<9611uxc->bridge); +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-samsung-dsim-fix-waiting-for-empty-cmd-tr.patch b/queue-6.6/drm-bridge-samsung-dsim-fix-waiting-for-empty-cmd-tr.patch new file mode 100644 index 00000000000..34eeb419e31 --- /dev/null +++ b/queue-6.6/drm-bridge-samsung-dsim-fix-waiting-for-empty-cmd-tr.patch @@ -0,0 +1,84 @@ +From eca802c18a8f28b2202d97ffb996ae05bbb176ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Aug 2023 16:56:41 +0200 +Subject: drm: bridge: samsung-dsim: Fix waiting for empty cmd transfer FIFO on + older Exynos + +From: Marek Szyprowski + +[ Upstream commit 15f389da11257b806da75a070cfa41ca0cc15aae ] + +Samsung DSIM used in older Exynos SoCs (like Exynos 4210, 4x12, 3250) +doesn't report empty level of packer header FIFO. In case of those SoCs, +use the old way of waiting for empty command tranfsfer FIFO, removed +recently by commit 14806c641582 ("drm: bridge: samsung-dsim: Drain command transfer FIFO before transfer"). + +Fixes: 14806c641582 ("drm: bridge: samsung-dsim: Drain command transfer FIFO before transfer") +Signed-off-by: Marek Szyprowski +Reviewed-by: Marek Vasut +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230809145641.3213210-1-m.szyprowski@samsung.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/samsung-dsim.c | 18 ++++++++++++++++-- + include/drm/bridge/samsung-dsim.h | 1 + + 2 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c +index 6f2ca74238d14..19bdb32dbc9aa 100644 +--- a/drivers/gpu/drm/bridge/samsung-dsim.c ++++ b/drivers/gpu/drm/bridge/samsung-dsim.c +@@ -413,6 +413,7 @@ static const struct samsung_dsim_driver_data exynos3_dsi_driver_data = { + .m_min = 41, + .m_max = 125, + .min_freq = 500, ++ .has_broken_fifoctrl_emptyhdr = 1, + }; + + static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = { +@@ -429,6 +430,7 @@ static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = { + .m_min = 41, + .m_max = 125, + .min_freq = 500, ++ .has_broken_fifoctrl_emptyhdr = 1, + }; + + static const struct samsung_dsim_driver_data exynos5_dsi_driver_data = { +@@ -1010,8 +1012,20 @@ static int samsung_dsim_wait_for_hdr_fifo(struct samsung_dsim *dsi) + do { + u32 reg = samsung_dsim_read(dsi, DSIM_FIFOCTRL_REG); + +- if (reg & DSIM_SFR_HEADER_EMPTY) +- return 0; ++ if (!dsi->driver_data->has_broken_fifoctrl_emptyhdr) { ++ if (reg & DSIM_SFR_HEADER_EMPTY) ++ return 0; ++ } else { ++ if (!(reg & DSIM_SFR_HEADER_FULL)) { ++ /* ++ * Wait a little bit, so the pending data can ++ * actually leave the FIFO to avoid overflow. ++ */ ++ if (!cond_resched()) ++ usleep_range(950, 1050); ++ return 0; ++ } ++ } + + if (!cond_resched()) + usleep_range(950, 1050); +diff --git a/include/drm/bridge/samsung-dsim.h b/include/drm/bridge/samsung-dsim.h +index 05100e91ecb96..6fc9bb2979e45 100644 +--- a/include/drm/bridge/samsung-dsim.h ++++ b/include/drm/bridge/samsung-dsim.h +@@ -53,6 +53,7 @@ struct samsung_dsim_driver_data { + unsigned int plltmr_reg; + unsigned int has_freqband:1; + unsigned int has_clklane_stop:1; ++ unsigned int has_broken_fifoctrl_emptyhdr:1; + unsigned int num_clks; + unsigned int min_freq; + unsigned int max_freq; +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-samsung-dsim-initialize-ulps-exit-for-i.m.patch b/queue-6.6/drm-bridge-samsung-dsim-initialize-ulps-exit-for-i.m.patch new file mode 100644 index 00000000000..9e8c78c5d2c --- /dev/null +++ b/queue-6.6/drm-bridge-samsung-dsim-initialize-ulps-exit-for-i.m.patch @@ -0,0 +1,39 @@ +From e6d2de84a2fad95dace5e2164a94572a68376de5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Jul 2023 15:48:27 +0200 +Subject: drm: bridge: samsung-dsim: Initialize ULPS EXIT for i.MX8M DSIM + +From: Marek Vasut + +[ Upstream commit 192948f6a923bedf461b4aa09e70a25cfb8a6041 ] + +The ULPS EXIT is initialized to 0xaf in downstream BSP as well as older +revisions of this patchset, in newer revisions of the DSIM patchset it +was left out and set to 0. Fix it. + +Fixes: 4d562c70c4dc ("drm: bridge: samsung-dsim: Add i.MX8M Mini/Nano support") +Signed-off-by: Marek Vasut +Reviewed-by: Robert Foss +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230709134827.449185-1-marex@denx.de +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/samsung-dsim.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c +index cf777bdb25d2a..6f2ca74238d14 100644 +--- a/drivers/gpu/drm/bridge/samsung-dsim.c ++++ b/drivers/gpu/drm/bridge/samsung-dsim.c +@@ -385,7 +385,7 @@ static const unsigned int imx8mm_dsim_reg_values[] = { + [RESET_TYPE] = DSIM_SWRST, + [PLL_TIMER] = 500, + [STOP_STATE_CNT] = 0xf, +- [PHYCTRL_ULPS_EXIT] = 0, ++ [PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0xaf), + [PHYCTRL_VREG_LP] = 0, + [PHYCTRL_SLEW_UP] = 0, + [PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x06), +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-tc358768-clean-up-clock-period-code.patch b/queue-6.6/drm-bridge-tc358768-clean-up-clock-period-code.patch new file mode 100644 index 00000000000..ffcd014efb4 --- /dev/null +++ b/queue-6.6/drm-bridge-tc358768-clean-up-clock-period-code.patch @@ -0,0 +1,175 @@ +From cd7c03f662bd10993f0580a49c989119a52d3d3d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 09:50:57 +0300 +Subject: drm/bridge: tc358768: Clean up clock period code + +From: Tomi Valkeinen + +[ Upstream commit b3aa7b34924a9ed64cf96899cac4d8ea08cd829e ] + +The driver defines TC358768_PRECISION as 1000, and uses "nsk" to refer +to clock periods. The original author does not remember where all this +came from. Effectively the driver is using picoseconds as the unit for +clock periods, yet referring to them by "nsk". + +Clean this up by just saying the periods are in picoseconds. + +Reviewed-by: Peter Ujfalusi +Tested-by: Maxim Schwalm # Asus TF700T +Tested-by: Marcel Ziswiler +Signed-off-by: Tomi Valkeinen +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230906-tc358768-v4-10-31725f008a50@ideasonboard.com +Stable-dep-of: f1dabbe64506 ("drm/bridge: tc358768: Fix tc358768_ns_to_cnt()") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/tc358768.c | 60 +++++++++++++++---------------- + 1 file changed, 29 insertions(+), 31 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c +index 0388093f703cc..d1000d1f69f4e 100644 +--- a/drivers/gpu/drm/bridge/tc358768.c ++++ b/drivers/gpu/drm/bridge/tc358768.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -627,15 +628,14 @@ static int tc358768_setup_pll(struct tc358768_priv *priv, + return tc358768_clear_error(priv); + } + +-#define TC358768_PRECISION 1000 +-static u32 tc358768_ns_to_cnt(u32 ns, u32 period_nsk) ++static u32 tc358768_ns_to_cnt(u32 ns, u32 period_ps) + { +- return (ns * TC358768_PRECISION + period_nsk) / period_nsk; ++ return (ns * 1000 + period_ps) / period_ps; + } + +-static u32 tc358768_to_ns(u32 nsk) ++static u32 tc358768_ps_to_ns(u32 ps) + { +- return (nsk / TC358768_PRECISION); ++ return ps / 1000; + } + + static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) +@@ -646,7 +646,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + u32 val, val2, lptxcnt, hact, data_type; + s32 raw_val; + const struct drm_display_mode *mode; +- u32 hsbyteclk_nsk, dsiclk_nsk, ui_nsk; ++ u32 hsbyteclk_ps, dsiclk_ps, ui_ps; + u32 dsiclk, hsbyteclk, video_start; + const u32 internal_delay = 40; + int ret, i; +@@ -730,67 +730,65 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + tc358768_write(priv, TC358768_D0W_CNTRL + i * 4, 0x0000); + + /* DSI Timings */ +- hsbyteclk_nsk = (u32)div_u64((u64)1000000000 * TC358768_PRECISION, +- hsbyteclk); +- dsiclk_nsk = (u32)div_u64((u64)1000000000 * TC358768_PRECISION, dsiclk); +- ui_nsk = dsiclk_nsk / 2; +- dev_dbg(dev, "dsiclk_nsk: %u\n", dsiclk_nsk); +- dev_dbg(dev, "ui_nsk: %u\n", ui_nsk); +- dev_dbg(dev, "hsbyteclk_nsk: %u\n", hsbyteclk_nsk); ++ hsbyteclk_ps = (u32)div_u64(PICO, hsbyteclk); ++ dsiclk_ps = (u32)div_u64(PICO, dsiclk); ++ ui_ps = dsiclk_ps / 2; ++ dev_dbg(dev, "dsiclk: %u ps, ui %u ps, hsbyteclk %u ps\n", dsiclk_ps, ++ ui_ps, hsbyteclk_ps); + + /* LP11 > 100us for D-PHY Rx Init */ +- val = tc358768_ns_to_cnt(100 * 1000, hsbyteclk_nsk) - 1; ++ val = tc358768_ns_to_cnt(100 * 1000, hsbyteclk_ps) - 1; + dev_dbg(dev, "LINEINITCNT: %u\n", val); + tc358768_write(priv, TC358768_LINEINITCNT, val); + + /* LPTimeCnt > 50ns */ +- val = tc358768_ns_to_cnt(50, hsbyteclk_nsk) - 1; ++ val = tc358768_ns_to_cnt(50, hsbyteclk_ps) - 1; + lptxcnt = val; + dev_dbg(dev, "LPTXTIMECNT: %u\n", val); + tc358768_write(priv, TC358768_LPTXTIMECNT, val); + + /* 38ns < TCLK_PREPARE < 95ns */ +- val = tc358768_ns_to_cnt(65, hsbyteclk_nsk) - 1; ++ val = tc358768_ns_to_cnt(65, hsbyteclk_ps) - 1; + dev_dbg(dev, "TCLK_PREPARECNT %u\n", val); + /* TCLK_PREPARE + TCLK_ZERO > 300ns */ +- val2 = tc358768_ns_to_cnt(300 - tc358768_to_ns(2 * ui_nsk), +- hsbyteclk_nsk) - 2; ++ val2 = tc358768_ns_to_cnt(300 - tc358768_ps_to_ns(2 * ui_ps), ++ hsbyteclk_ps) - 2; + dev_dbg(dev, "TCLK_ZEROCNT %u\n", val2); + val |= val2 << 8; + tc358768_write(priv, TC358768_TCLK_HEADERCNT, val); + + /* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */ +- raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), hsbyteclk_nsk) - 5; ++ raw_val = tc358768_ns_to_cnt(60 + tc358768_ps_to_ns(2 * ui_ps), hsbyteclk_ps) - 5; + val = clamp(raw_val, 0, 127); + dev_dbg(dev, "TCLK_TRAILCNT: %u\n", val); + tc358768_write(priv, TC358768_TCLK_TRAILCNT, val); + + /* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */ +- val = 50 + tc358768_to_ns(4 * ui_nsk); +- val = tc358768_ns_to_cnt(val, hsbyteclk_nsk) - 1; ++ val = 50 + tc358768_ps_to_ns(4 * ui_ps); ++ val = tc358768_ns_to_cnt(val, hsbyteclk_ps) - 1; + dev_dbg(dev, "THS_PREPARECNT %u\n", val); + /* THS_PREPARE + THS_ZERO > 145ns + 10*UI */ +- raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), hsbyteclk_nsk) - 10; ++ raw_val = tc358768_ns_to_cnt(145 - tc358768_ps_to_ns(3 * ui_ps), hsbyteclk_ps) - 10; + val2 = clamp(raw_val, 0, 127); + dev_dbg(dev, "THS_ZEROCNT %u\n", val2); + val |= val2 << 8; + tc358768_write(priv, TC358768_THS_HEADERCNT, val); + + /* TWAKEUP > 1ms in lptxcnt steps */ +- val = tc358768_ns_to_cnt(1020000, hsbyteclk_nsk); ++ val = tc358768_ns_to_cnt(1020000, hsbyteclk_ps); + val = val / (lptxcnt + 1) - 1; + dev_dbg(dev, "TWAKEUP: %u\n", val); + tc358768_write(priv, TC358768_TWAKEUP, val); + + /* TCLK_POSTCNT > 60ns + 52*UI */ +- val = tc358768_ns_to_cnt(60 + tc358768_to_ns(52 * ui_nsk), +- hsbyteclk_nsk) - 3; ++ val = tc358768_ns_to_cnt(60 + tc358768_ps_to_ns(52 * ui_ps), ++ hsbyteclk_ps) - 3; + dev_dbg(dev, "TCLK_POSTCNT: %u\n", val); + tc358768_write(priv, TC358768_TCLK_POSTCNT, val); + + /* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */ +- raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(18 * ui_nsk), +- hsbyteclk_nsk) - 4; ++ raw_val = tc358768_ns_to_cnt(60 + tc358768_ps_to_ns(18 * ui_ps), ++ hsbyteclk_ps) - 4; + val = clamp(raw_val, 0, 15); + dev_dbg(dev, "THS_TRAILCNT: %u\n", val); + tc358768_write(priv, TC358768_THS_TRAILCNT, val); +@@ -804,11 +802,11 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) ? 0 : BIT(0)); + + /* TXTAGOCNT[26:16] RXTASURECNT[10:0] */ +- val = tc358768_to_ns((lptxcnt + 1) * hsbyteclk_nsk * 4); +- val = tc358768_ns_to_cnt(val, hsbyteclk_nsk) / 4 - 1; ++ val = tc358768_ps_to_ns((lptxcnt + 1) * hsbyteclk_ps * 4); ++ val = tc358768_ns_to_cnt(val, hsbyteclk_ps) / 4 - 1; + dev_dbg(dev, "TXTAGOCNT: %u\n", val); +- val2 = tc358768_ns_to_cnt(tc358768_to_ns((lptxcnt + 1) * hsbyteclk_nsk), +- hsbyteclk_nsk) - 2; ++ val2 = tc358768_ns_to_cnt(tc358768_ps_to_ns((lptxcnt + 1) * hsbyteclk_ps), ++ hsbyteclk_ps) - 2; + dev_dbg(dev, "RXTASURECNT: %u\n", val2); + val = val << 16 | val2; + tc358768_write(priv, TC358768_BTACNTRL1, val); +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-tc358768-fix-bit-updates.patch b/queue-6.6/drm-bridge-tc358768-fix-bit-updates.patch new file mode 100644 index 00000000000..88f8533649b --- /dev/null +++ b/queue-6.6/drm-bridge-tc358768-fix-bit-updates.patch @@ -0,0 +1,66 @@ +From 00150d541081d8aaf31b41843a0c382314e761d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 09:50:51 +0300 +Subject: drm/bridge: tc358768: Fix bit updates + +From: Tomi Valkeinen + +[ Upstream commit 66962d5c3c51377b9b90cae35b7e038950438e02 ] + +The driver has a few places where it does: + +if (thing_is_enabled_in_config) + update_thing_bit_in_hw() + +This means that if the thing is _not_ enabled, the bit never gets +cleared. This affects the h/vsyncs and continuous DSI clock bits. + +Fix the driver to always update the bit. + +Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") +Reviewed-by: Peter Ujfalusi +Tested-by: Maxim Schwalm # Asus TF700T +Tested-by: Marcel Ziswiler +Signed-off-by: Tomi Valkeinen +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230906-tc358768-v4-4-31725f008a50@ideasonboard.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/tc358768.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c +index bc97a837955ba..b668f77673c3d 100644 +--- a/drivers/gpu/drm/bridge/tc358768.c ++++ b/drivers/gpu/drm/bridge/tc358768.c +@@ -794,8 +794,8 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + val |= BIT(i + 1); + tc358768_write(priv, TC358768_HSTXVREGEN, val); + +- if (!(mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)) +- tc358768_write(priv, TC358768_TXOPTIONCNTRL, 0x1); ++ tc358768_write(priv, TC358768_TXOPTIONCNTRL, ++ (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) ? 0 : BIT(0)); + + /* TXTAGOCNT[26:16] RXTASURECNT[10:0] */ + val = tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk * 4); +@@ -861,11 +861,12 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + tc358768_write(priv, TC358768_DSI_HACT, hact); + + /* VSYNC polarity */ +- if (!(mode->flags & DRM_MODE_FLAG_NVSYNC)) +- tc358768_update_bits(priv, TC358768_CONFCTL, BIT(5), BIT(5)); ++ tc358768_update_bits(priv, TC358768_CONFCTL, BIT(5), ++ (mode->flags & DRM_MODE_FLAG_PVSYNC) ? BIT(5) : 0); ++ + /* HSYNC polarity */ +- if (mode->flags & DRM_MODE_FLAG_PHSYNC) +- tc358768_update_bits(priv, TC358768_PP_MISC, BIT(0), BIT(0)); ++ tc358768_update_bits(priv, TC358768_PP_MISC, BIT(0), ++ (mode->flags & DRM_MODE_FLAG_PHSYNC) ? BIT(0) : 0); + + /* Start DSI Tx */ + tc358768_write(priv, TC358768_DSI_START, 0x1); +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-tc358768-fix-tc358768_ns_to_cnt.patch b/queue-6.6/drm-bridge-tc358768-fix-tc358768_ns_to_cnt.patch new file mode 100644 index 00000000000..42ac8d2460b --- /dev/null +++ b/queue-6.6/drm-bridge-tc358768-fix-tc358768_ns_to_cnt.patch @@ -0,0 +1,42 @@ +From 74871f8f83c9bd2302a066870fc0561b07649c02 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 09:50:58 +0300 +Subject: drm/bridge: tc358768: Fix tc358768_ns_to_cnt() + +From: Tomi Valkeinen + +[ Upstream commit f1dabbe645065d20ca863c8d446c74c59ca1ca9d ] + +The tc358768_ns_to_cnt() is, most likely, supposed to do a div-round-up +operation, but it misses subtracting one from the dividend. + +Fix this by just using DIV_ROUND_UP(). + +Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") +Reviewed-by: Peter Ujfalusi +Tested-by: Maxim Schwalm # Asus TF700T +Tested-by: Marcel Ziswiler +Signed-off-by: Tomi Valkeinen +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230906-tc358768-v4-11-31725f008a50@ideasonboard.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/tc358768.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c +index d1000d1f69f4e..6eed5c4232956 100644 +--- a/drivers/gpu/drm/bridge/tc358768.c ++++ b/drivers/gpu/drm/bridge/tc358768.c +@@ -630,7 +630,7 @@ static int tc358768_setup_pll(struct tc358768_priv *priv, + + static u32 tc358768_ns_to_cnt(u32 ns, u32 period_ps) + { +- return (ns * 1000 + period_ps) / period_ps; ++ return DIV_ROUND_UP(ns * 1000, period_ps); + } + + static u32 tc358768_ps_to_ns(u32 ps) +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-tc358768-fix-use-of-uninitialized-variabl.patch b/queue-6.6/drm-bridge-tc358768-fix-use-of-uninitialized-variabl.patch new file mode 100644 index 00000000000..c970ab61e59 --- /dev/null +++ b/queue-6.6/drm-bridge-tc358768-fix-use-of-uninitialized-variabl.patch @@ -0,0 +1,46 @@ +From a1ac191b92159f113068c8a88759eda19492cb9a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 09:50:49 +0300 +Subject: drm/bridge: tc358768: Fix use of uninitialized variable + +From: Tomi Valkeinen + +[ Upstream commit a2d9036615f0adfa5b0a46bb2ce42ef1d9a04fbe ] + +smatch reports: + +drivers/gpu/drm/bridge/tc358768.c:223 tc358768_update_bits() error: uninitialized symbol 'orig'. + +Fix this by bailing out from tc358768_update_bits() if the +tc358768_read() produces an error. + +Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver") +Reviewed-by: Peter Ujfalusi +Tested-by: Maxim Schwalm # Asus TF700T +Tested-by: Marcel Ziswiler +Signed-off-by: Tomi Valkeinen +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230906-tc358768-v4-2-31725f008a50@ideasonboard.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/tc358768.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c +index 819a4b6ec2a07..bc97a837955ba 100644 +--- a/drivers/gpu/drm/bridge/tc358768.c ++++ b/drivers/gpu/drm/bridge/tc358768.c +@@ -216,6 +216,10 @@ static void tc358768_update_bits(struct tc358768_priv *priv, u32 reg, u32 mask, + u32 tmp, orig; + + tc358768_read(priv, reg, &orig); ++ ++ if (priv->error) ++ return; ++ + tmp = orig & ~mask; + tmp |= val & mask; + if (tmp != orig) +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-tc358768-print-logical-values-not-raw-reg.patch b/queue-6.6/drm-bridge-tc358768-print-logical-values-not-raw-reg.patch new file mode 100644 index 00000000000..f6f94650a1d --- /dev/null +++ b/queue-6.6/drm-bridge-tc358768-print-logical-values-not-raw-reg.patch @@ -0,0 +1,117 @@ +From b9dcc7fb94e159d6d427810eb2e1a139abf8032c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 09:50:54 +0300 +Subject: drm/bridge: tc358768: Print logical values, not raw register values + +From: Tomi Valkeinen + +[ Upstream commit 013ea98cdfccef3b7c38b087c1f629488d2ef683 ] + +The driver debug prints DSI related timings as raw register values in +hex. It is much more useful to see the "logical" value of the timing, +not the register value. + +Change the prints to print the values separately, in case a single +register contains multiple values, and use %u to have it in a more human +consumable form. + +Reviewed-by: Peter Ujfalusi +Tested-by: Maxim Schwalm # Asus TF700T +Tested-by: Marcel Ziswiler +Signed-off-by: Tomi Valkeinen +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230906-tc358768-v4-7-31725f008a50@ideasonboard.com +Stable-dep-of: f1dabbe64506 ("drm/bridge: tc358768: Fix tc358768_ns_to_cnt()") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/tc358768.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c +index e42b5259ea344..163477ec91a9c 100644 +--- a/drivers/gpu/drm/bridge/tc358768.c ++++ b/drivers/gpu/drm/bridge/tc358768.c +@@ -739,57 +739,59 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + + /* LP11 > 100us for D-PHY Rx Init */ + val = tc358768_ns_to_cnt(100 * 1000, dsibclk_nsk) - 1; +- dev_dbg(priv->dev, "LINEINITCNT: 0x%x\n", val); ++ dev_dbg(priv->dev, "LINEINITCNT: %u\n", val); + tc358768_write(priv, TC358768_LINEINITCNT, val); + + /* LPTimeCnt > 50ns */ + val = tc358768_ns_to_cnt(50, dsibclk_nsk) - 1; + lptxcnt = val; +- dev_dbg(priv->dev, "LPTXTIMECNT: 0x%x\n", val); ++ dev_dbg(priv->dev, "LPTXTIMECNT: %u\n", val); + tc358768_write(priv, TC358768_LPTXTIMECNT, val); + + /* 38ns < TCLK_PREPARE < 95ns */ + val = tc358768_ns_to_cnt(65, dsibclk_nsk) - 1; ++ dev_dbg(priv->dev, "TCLK_PREPARECNT %u\n", val); + /* TCLK_PREPARE + TCLK_ZERO > 300ns */ + val2 = tc358768_ns_to_cnt(300 - tc358768_to_ns(2 * ui_nsk), + dsibclk_nsk) - 2; ++ dev_dbg(priv->dev, "TCLK_ZEROCNT %u\n", val2); + val |= val2 << 8; +- dev_dbg(priv->dev, "TCLK_HEADERCNT: 0x%x\n", val); + tc358768_write(priv, TC358768_TCLK_HEADERCNT, val); + + /* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */ + raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), dsibclk_nsk) - 5; + val = clamp(raw_val, 0, 127); +- dev_dbg(priv->dev, "TCLK_TRAILCNT: 0x%x\n", val); ++ dev_dbg(priv->dev, "TCLK_TRAILCNT: %u\n", val); + tc358768_write(priv, TC358768_TCLK_TRAILCNT, val); + + /* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */ + val = 50 + tc358768_to_ns(4 * ui_nsk); + val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1; ++ dev_dbg(priv->dev, "THS_PREPARECNT %u\n", val); + /* THS_PREPARE + THS_ZERO > 145ns + 10*UI */ + raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), dsibclk_nsk) - 10; + val2 = clamp(raw_val, 0, 127); ++ dev_dbg(priv->dev, "THS_ZEROCNT %u\n", val2); + val |= val2 << 8; +- dev_dbg(priv->dev, "THS_HEADERCNT: 0x%x\n", val); + tc358768_write(priv, TC358768_THS_HEADERCNT, val); + + /* TWAKEUP > 1ms in lptxcnt steps */ + val = tc358768_ns_to_cnt(1020000, dsibclk_nsk); + val = val / (lptxcnt + 1) - 1; +- dev_dbg(priv->dev, "TWAKEUP: 0x%x\n", val); ++ dev_dbg(priv->dev, "TWAKEUP: %u\n", val); + tc358768_write(priv, TC358768_TWAKEUP, val); + + /* TCLK_POSTCNT > 60ns + 52*UI */ + val = tc358768_ns_to_cnt(60 + tc358768_to_ns(52 * ui_nsk), + dsibclk_nsk) - 3; +- dev_dbg(priv->dev, "TCLK_POSTCNT: 0x%x\n", val); ++ dev_dbg(priv->dev, "TCLK_POSTCNT: %u\n", val); + tc358768_write(priv, TC358768_TCLK_POSTCNT, val); + + /* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */ + raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(18 * ui_nsk), + dsibclk_nsk) - 4; + val = clamp(raw_val, 0, 15); +- dev_dbg(priv->dev, "THS_TRAILCNT: 0x%x\n", val); ++ dev_dbg(priv->dev, "THS_TRAILCNT: %u\n", val); + tc358768_write(priv, TC358768_THS_TRAILCNT, val); + + val = BIT(0); +@@ -803,10 +805,11 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + /* TXTAGOCNT[26:16] RXTASURECNT[10:0] */ + val = tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk * 4); + val = tc358768_ns_to_cnt(val, dsibclk_nsk) / 4 - 1; ++ dev_dbg(priv->dev, "TXTAGOCNT: %u\n", val); + val2 = tc358768_ns_to_cnt(tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk), + dsibclk_nsk) - 2; ++ dev_dbg(priv->dev, "RXTASURECNT: %u\n", val2); + val = val << 16 | val2; +- dev_dbg(priv->dev, "BTACNTRL1: 0x%x\n", val); + tc358768_write(priv, TC358768_BTACNTRL1, val); + + /* START[0] */ +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-tc358768-rename-dsibclk-to-hsbyteclk.patch b/queue-6.6/drm-bridge-tc358768-rename-dsibclk-to-hsbyteclk.patch new file mode 100644 index 00000000000..c71ba15ba0d --- /dev/null +++ b/queue-6.6/drm-bridge-tc358768-rename-dsibclk-to-hsbyteclk.patch @@ -0,0 +1,188 @@ +From 3d6b000f6a94acc6914656f4787bfd49bb103112 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 09:50:56 +0300 +Subject: drm/bridge: tc358768: Rename dsibclk to hsbyteclk + +From: Tomi Valkeinen + +[ Upstream commit 699cf62a7d4550759f4a50e614b1952f93de4783 ] + +The Toshiba documentation talks about HSByteClk when referring to the +DSI HS byte clock, whereas the driver uses 'dsibclk' name. Also, in a +few places the driver calculates the byte clock from the DSI clock, even +if the byte clock is already available in a variable. + +To align the driver with the documentation, change the 'dsibclk' +variable to 'hsbyteclk'. This also make it easier to visually separate +'dsibclk' and 'dsiclk' variables. + +Reviewed-by: Peter Ujfalusi +Tested-by: Maxim Schwalm # Asus TF700T +Tested-by: Marcel Ziswiler +Signed-off-by: Tomi Valkeinen +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230906-tc358768-v4-9-31725f008a50@ideasonboard.com +Stable-dep-of: f1dabbe64506 ("drm/bridge: tc358768: Fix tc358768_ns_to_cnt()") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/tc358768.c | 48 +++++++++++++++---------------- + 1 file changed, 24 insertions(+), 24 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c +index d909590ab31b8..0388093f703cc 100644 +--- a/drivers/gpu/drm/bridge/tc358768.c ++++ b/drivers/gpu/drm/bridge/tc358768.c +@@ -604,7 +604,7 @@ static int tc358768_setup_pll(struct tc358768_priv *priv, + + dev_dbg(priv->dev, "PLL: refclk %lu, fbd %u, prd %u, frs %u\n", + clk_get_rate(priv->refclk), fbd, prd, frs); +- dev_dbg(priv->dev, "PLL: pll_clk: %u, DSIClk %u, DSIByteClk %u\n", ++ dev_dbg(priv->dev, "PLL: pll_clk: %u, DSIClk %u, HSByteClk %u\n", + priv->dsiclk * 2, priv->dsiclk, priv->dsiclk / 4); + dev_dbg(priv->dev, "PLL: pclk %u (panel: %u)\n", + tc358768_pll_to_pclk(priv, priv->dsiclk * 2), +@@ -646,8 +646,8 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + u32 val, val2, lptxcnt, hact, data_type; + s32 raw_val; + const struct drm_display_mode *mode; +- u32 dsibclk_nsk, dsiclk_nsk, ui_nsk; +- u32 dsiclk, dsibclk, video_start; ++ u32 hsbyteclk_nsk, dsiclk_nsk, ui_nsk; ++ u32 dsiclk, hsbyteclk, video_start; + const u32 internal_delay = 40; + int ret, i; + struct videomode vm; +@@ -678,7 +678,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + drm_display_mode_to_videomode(mode, &vm); + + dsiclk = priv->dsiclk; +- dsibclk = dsiclk / 4; ++ hsbyteclk = dsiclk / 4; + + /* Data Format Control Register */ + val = BIT(2) | BIT(1) | BIT(0); /* rdswap_en | dsitx_en | txdt_en */ +@@ -730,67 +730,67 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + tc358768_write(priv, TC358768_D0W_CNTRL + i * 4, 0x0000); + + /* DSI Timings */ +- dsibclk_nsk = (u32)div_u64((u64)1000000000 * TC358768_PRECISION, +- dsibclk); ++ hsbyteclk_nsk = (u32)div_u64((u64)1000000000 * TC358768_PRECISION, ++ hsbyteclk); + dsiclk_nsk = (u32)div_u64((u64)1000000000 * TC358768_PRECISION, dsiclk); + ui_nsk = dsiclk_nsk / 2; + dev_dbg(dev, "dsiclk_nsk: %u\n", dsiclk_nsk); + dev_dbg(dev, "ui_nsk: %u\n", ui_nsk); +- dev_dbg(dev, "dsibclk_nsk: %u\n", dsibclk_nsk); ++ dev_dbg(dev, "hsbyteclk_nsk: %u\n", hsbyteclk_nsk); + + /* LP11 > 100us for D-PHY Rx Init */ +- val = tc358768_ns_to_cnt(100 * 1000, dsibclk_nsk) - 1; ++ val = tc358768_ns_to_cnt(100 * 1000, hsbyteclk_nsk) - 1; + dev_dbg(dev, "LINEINITCNT: %u\n", val); + tc358768_write(priv, TC358768_LINEINITCNT, val); + + /* LPTimeCnt > 50ns */ +- val = tc358768_ns_to_cnt(50, dsibclk_nsk) - 1; ++ val = tc358768_ns_to_cnt(50, hsbyteclk_nsk) - 1; + lptxcnt = val; + dev_dbg(dev, "LPTXTIMECNT: %u\n", val); + tc358768_write(priv, TC358768_LPTXTIMECNT, val); + + /* 38ns < TCLK_PREPARE < 95ns */ +- val = tc358768_ns_to_cnt(65, dsibclk_nsk) - 1; ++ val = tc358768_ns_to_cnt(65, hsbyteclk_nsk) - 1; + dev_dbg(dev, "TCLK_PREPARECNT %u\n", val); + /* TCLK_PREPARE + TCLK_ZERO > 300ns */ + val2 = tc358768_ns_to_cnt(300 - tc358768_to_ns(2 * ui_nsk), +- dsibclk_nsk) - 2; ++ hsbyteclk_nsk) - 2; + dev_dbg(dev, "TCLK_ZEROCNT %u\n", val2); + val |= val2 << 8; + tc358768_write(priv, TC358768_TCLK_HEADERCNT, val); + + /* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */ +- raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), dsibclk_nsk) - 5; ++ raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), hsbyteclk_nsk) - 5; + val = clamp(raw_val, 0, 127); + dev_dbg(dev, "TCLK_TRAILCNT: %u\n", val); + tc358768_write(priv, TC358768_TCLK_TRAILCNT, val); + + /* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */ + val = 50 + tc358768_to_ns(4 * ui_nsk); +- val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1; ++ val = tc358768_ns_to_cnt(val, hsbyteclk_nsk) - 1; + dev_dbg(dev, "THS_PREPARECNT %u\n", val); + /* THS_PREPARE + THS_ZERO > 145ns + 10*UI */ +- raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), dsibclk_nsk) - 10; ++ raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), hsbyteclk_nsk) - 10; + val2 = clamp(raw_val, 0, 127); + dev_dbg(dev, "THS_ZEROCNT %u\n", val2); + val |= val2 << 8; + tc358768_write(priv, TC358768_THS_HEADERCNT, val); + + /* TWAKEUP > 1ms in lptxcnt steps */ +- val = tc358768_ns_to_cnt(1020000, dsibclk_nsk); ++ val = tc358768_ns_to_cnt(1020000, hsbyteclk_nsk); + val = val / (lptxcnt + 1) - 1; + dev_dbg(dev, "TWAKEUP: %u\n", val); + tc358768_write(priv, TC358768_TWAKEUP, val); + + /* TCLK_POSTCNT > 60ns + 52*UI */ + val = tc358768_ns_to_cnt(60 + tc358768_to_ns(52 * ui_nsk), +- dsibclk_nsk) - 3; ++ hsbyteclk_nsk) - 3; + dev_dbg(dev, "TCLK_POSTCNT: %u\n", val); + tc358768_write(priv, TC358768_TCLK_POSTCNT, val); + + /* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */ + raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(18 * ui_nsk), +- dsibclk_nsk) - 4; ++ hsbyteclk_nsk) - 4; + val = clamp(raw_val, 0, 15); + dev_dbg(dev, "THS_TRAILCNT: %u\n", val); + tc358768_write(priv, TC358768_THS_TRAILCNT, val); +@@ -804,11 +804,11 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) ? 0 : BIT(0)); + + /* TXTAGOCNT[26:16] RXTASURECNT[10:0] */ +- val = tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk * 4); +- val = tc358768_ns_to_cnt(val, dsibclk_nsk) / 4 - 1; ++ val = tc358768_to_ns((lptxcnt + 1) * hsbyteclk_nsk * 4); ++ val = tc358768_ns_to_cnt(val, hsbyteclk_nsk) / 4 - 1; + dev_dbg(dev, "TXTAGOCNT: %u\n", val); +- val2 = tc358768_ns_to_cnt(tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk), +- dsibclk_nsk) - 2; ++ val2 = tc358768_ns_to_cnt(tc358768_to_ns((lptxcnt + 1) * hsbyteclk_nsk), ++ hsbyteclk_nsk) - 2; + dev_dbg(dev, "RXTASURECNT: %u\n", val2); + val = val << 16 | val2; + tc358768_write(priv, TC358768_BTACNTRL1, val); +@@ -831,13 +831,13 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + + /* hsw * byteclk * ndl / pclk */ + val = (u32)div_u64(vm.hsync_len * +- ((u64)priv->dsiclk / 4) * priv->dsi_lanes, ++ (u64)hsbyteclk * priv->dsi_lanes, + vm.pixelclock); + tc358768_write(priv, TC358768_DSI_HSW, val); + + /* hbp * byteclk * ndl / pclk */ + val = (u32)div_u64(vm.hback_porch * +- ((u64)priv->dsiclk / 4) * priv->dsi_lanes, ++ (u64)hsbyteclk * priv->dsi_lanes, + vm.pixelclock); + tc358768_write(priv, TC358768_DSI_HBPR, val); + } else { +@@ -856,7 +856,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + + /* (hsw + hbp) * byteclk * ndl / pclk */ + val = (u32)div_u64((vm.hsync_len + vm.hback_porch) * +- ((u64)priv->dsiclk / 4) * priv->dsi_lanes, ++ (u64)hsbyteclk * priv->dsi_lanes, + vm.pixelclock); + tc358768_write(priv, TC358768_DSI_HSW, val); + +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-tc358768-use-dev-for-dbg-prints-not-priv-.patch b/queue-6.6/drm-bridge-tc358768-use-dev-for-dbg-prints-not-priv-.patch new file mode 100644 index 00000000000..759b039284d --- /dev/null +++ b/queue-6.6/drm-bridge-tc358768-use-dev-for-dbg-prints-not-priv-.patch @@ -0,0 +1,171 @@ +From 5ebab4ddbb1cfd2966233786c28ab64530e5f5ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 09:50:55 +0300 +Subject: drm/bridge: tc358768: Use dev for dbg prints, not priv->dev + +From: Tomi Valkeinen + +[ Upstream commit 89cfd50e13f1bead4350998a3a77422bef1ee0a5 ] + +Simplify the code by capturing the priv->dev value to dev variable, and +use it. + +Reviewed-by: Peter Ujfalusi +Tested-by: Maxim Schwalm # Asus TF700T +Tested-by: Marcel Ziswiler +Signed-off-by: Tomi Valkeinen +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230906-tc358768-v4-8-31725f008a50@ideasonboard.com +Stable-dep-of: f1dabbe64506 ("drm/bridge: tc358768: Fix tc358768_ns_to_cnt()") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/tc358768.c | 41 ++++++++++++++++--------------- + 1 file changed, 21 insertions(+), 20 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c +index 163477ec91a9c..d909590ab31b8 100644 +--- a/drivers/gpu/drm/bridge/tc358768.c ++++ b/drivers/gpu/drm/bridge/tc358768.c +@@ -651,9 +651,10 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + const u32 internal_delay = 40; + int ret, i; + struct videomode vm; ++ struct device *dev = priv->dev; + + if (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) { +- dev_warn_once(priv->dev, "Non-continuous mode unimplemented, falling back to continuous\n"); ++ dev_warn_once(dev, "Non-continuous mode unimplemented, falling back to continuous\n"); + mode_flags &= ~MIPI_DSI_CLOCK_NON_CONTINUOUS; + } + +@@ -661,7 +662,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + + ret = tc358768_sw_reset(priv); + if (ret) { +- dev_err(priv->dev, "Software reset failed: %d\n", ret); ++ dev_err(dev, "Software reset failed: %d\n", ret); + tc358768_hw_disable(priv); + return; + } +@@ -669,7 +670,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + mode = &bridge->encoder->crtc->state->adjusted_mode; + ret = tc358768_setup_pll(priv, mode); + if (ret) { +- dev_err(priv->dev, "PLL setup failed: %d\n", ret); ++ dev_err(dev, "PLL setup failed: %d\n", ret); + tc358768_hw_disable(priv); + return; + } +@@ -709,7 +710,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16; + break; + default: +- dev_err(priv->dev, "Invalid data format (%u)\n", ++ dev_err(dev, "Invalid data format (%u)\n", + dsi_dev->format); + tc358768_hw_disable(priv); + return; +@@ -733,65 +734,65 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + dsibclk); + dsiclk_nsk = (u32)div_u64((u64)1000000000 * TC358768_PRECISION, dsiclk); + ui_nsk = dsiclk_nsk / 2; +- dev_dbg(priv->dev, "dsiclk_nsk: %u\n", dsiclk_nsk); +- dev_dbg(priv->dev, "ui_nsk: %u\n", ui_nsk); +- dev_dbg(priv->dev, "dsibclk_nsk: %u\n", dsibclk_nsk); ++ dev_dbg(dev, "dsiclk_nsk: %u\n", dsiclk_nsk); ++ dev_dbg(dev, "ui_nsk: %u\n", ui_nsk); ++ dev_dbg(dev, "dsibclk_nsk: %u\n", dsibclk_nsk); + + /* LP11 > 100us for D-PHY Rx Init */ + val = tc358768_ns_to_cnt(100 * 1000, dsibclk_nsk) - 1; +- dev_dbg(priv->dev, "LINEINITCNT: %u\n", val); ++ dev_dbg(dev, "LINEINITCNT: %u\n", val); + tc358768_write(priv, TC358768_LINEINITCNT, val); + + /* LPTimeCnt > 50ns */ + val = tc358768_ns_to_cnt(50, dsibclk_nsk) - 1; + lptxcnt = val; +- dev_dbg(priv->dev, "LPTXTIMECNT: %u\n", val); ++ dev_dbg(dev, "LPTXTIMECNT: %u\n", val); + tc358768_write(priv, TC358768_LPTXTIMECNT, val); + + /* 38ns < TCLK_PREPARE < 95ns */ + val = tc358768_ns_to_cnt(65, dsibclk_nsk) - 1; +- dev_dbg(priv->dev, "TCLK_PREPARECNT %u\n", val); ++ dev_dbg(dev, "TCLK_PREPARECNT %u\n", val); + /* TCLK_PREPARE + TCLK_ZERO > 300ns */ + val2 = tc358768_ns_to_cnt(300 - tc358768_to_ns(2 * ui_nsk), + dsibclk_nsk) - 2; +- dev_dbg(priv->dev, "TCLK_ZEROCNT %u\n", val2); ++ dev_dbg(dev, "TCLK_ZEROCNT %u\n", val2); + val |= val2 << 8; + tc358768_write(priv, TC358768_TCLK_HEADERCNT, val); + + /* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */ + raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), dsibclk_nsk) - 5; + val = clamp(raw_val, 0, 127); +- dev_dbg(priv->dev, "TCLK_TRAILCNT: %u\n", val); ++ dev_dbg(dev, "TCLK_TRAILCNT: %u\n", val); + tc358768_write(priv, TC358768_TCLK_TRAILCNT, val); + + /* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */ + val = 50 + tc358768_to_ns(4 * ui_nsk); + val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1; +- dev_dbg(priv->dev, "THS_PREPARECNT %u\n", val); ++ dev_dbg(dev, "THS_PREPARECNT %u\n", val); + /* THS_PREPARE + THS_ZERO > 145ns + 10*UI */ + raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), dsibclk_nsk) - 10; + val2 = clamp(raw_val, 0, 127); +- dev_dbg(priv->dev, "THS_ZEROCNT %u\n", val2); ++ dev_dbg(dev, "THS_ZEROCNT %u\n", val2); + val |= val2 << 8; + tc358768_write(priv, TC358768_THS_HEADERCNT, val); + + /* TWAKEUP > 1ms in lptxcnt steps */ + val = tc358768_ns_to_cnt(1020000, dsibclk_nsk); + val = val / (lptxcnt + 1) - 1; +- dev_dbg(priv->dev, "TWAKEUP: %u\n", val); ++ dev_dbg(dev, "TWAKEUP: %u\n", val); + tc358768_write(priv, TC358768_TWAKEUP, val); + + /* TCLK_POSTCNT > 60ns + 52*UI */ + val = tc358768_ns_to_cnt(60 + tc358768_to_ns(52 * ui_nsk), + dsibclk_nsk) - 3; +- dev_dbg(priv->dev, "TCLK_POSTCNT: %u\n", val); ++ dev_dbg(dev, "TCLK_POSTCNT: %u\n", val); + tc358768_write(priv, TC358768_TCLK_POSTCNT, val); + + /* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */ + raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(18 * ui_nsk), + dsibclk_nsk) - 4; + val = clamp(raw_val, 0, 15); +- dev_dbg(priv->dev, "THS_TRAILCNT: %u\n", val); ++ dev_dbg(dev, "THS_TRAILCNT: %u\n", val); + tc358768_write(priv, TC358768_THS_TRAILCNT, val); + + val = BIT(0); +@@ -805,10 +806,10 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + /* TXTAGOCNT[26:16] RXTASURECNT[10:0] */ + val = tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk * 4); + val = tc358768_ns_to_cnt(val, dsibclk_nsk) / 4 - 1; +- dev_dbg(priv->dev, "TXTAGOCNT: %u\n", val); ++ dev_dbg(dev, "TXTAGOCNT: %u\n", val); + val2 = tc358768_ns_to_cnt(tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk), + dsibclk_nsk) - 2; +- dev_dbg(priv->dev, "RXTASURECNT: %u\n", val2); ++ dev_dbg(dev, "RXTASURECNT: %u\n", val2); + val = val << 16 | val2; + tc358768_write(priv, TC358768_BTACNTRL1, val); + +@@ -902,7 +903,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + + ret = tc358768_clear_error(priv); + if (ret) { +- dev_err(priv->dev, "Bridge pre_enable failed: %d\n", ret); ++ dev_err(dev, "Bridge pre_enable failed: %d\n", ret); + tc358768_bridge_disable(bridge); + tc358768_bridge_post_disable(bridge); + } +-- +2.42.0 + diff --git a/queue-6.6/drm-bridge-tc358768-use-struct-videomode.patch b/queue-6.6/drm-bridge-tc358768-use-struct-videomode.patch new file mode 100644 index 00000000000..11f94e98689 --- /dev/null +++ b/queue-6.6/drm-bridge-tc358768-use-struct-videomode.patch @@ -0,0 +1,148 @@ +From 5d529d6af2643a2cfe496f182abd9fdd59a5e7f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 09:50:53 +0300 +Subject: drm/bridge: tc358768: Use struct videomode + +From: Tomi Valkeinen + +[ Upstream commit e5fb21678136a9d009d5c43821881eb4c34fae97 ] + +The TC358768 documentation uses HFP, HBP, etc. values to deal with the +video mode, while the driver currently uses the DRM display mode +(htotal, hsync_start, etc). + +Change the driver to convert the DRM display mode to struct videomode, +which then allows us to use the same units the documentation uses. This +makes it much easier to work on the code when using the TC358768 +documentation as a reference. + +Reviewed-by: Peter Ujfalusi +Tested-by: Maxim Schwalm # Asus TF700T +Tested-by: Marcel Ziswiler +Signed-off-by: Tomi Valkeinen +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20230906-tc358768-v4-6-31725f008a50@ideasonboard.com +Stable-dep-of: f1dabbe64506 ("drm/bridge: tc358768: Fix tc358768_ns_to_cnt()") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/tc358768.c | 45 ++++++++++++++++--------------- + 1 file changed, 24 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c +index b668f77673c3d..e42b5259ea344 100644 +--- a/drivers/gpu/drm/bridge/tc358768.c ++++ b/drivers/gpu/drm/bridge/tc358768.c +@@ -650,6 +650,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + u32 dsiclk, dsibclk, video_start; + const u32 internal_delay = 40; + int ret, i; ++ struct videomode vm; + + if (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) { + dev_warn_once(priv->dev, "Non-continuous mode unimplemented, falling back to continuous\n"); +@@ -673,6 +674,8 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + return; + } + ++ drm_display_mode_to_videomode(mode, &vm); ++ + dsiclk = priv->dsiclk; + dsibclk = dsiclk / 4; + +@@ -681,28 +684,28 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + switch (dsi_dev->format) { + case MIPI_DSI_FMT_RGB888: + val |= (0x3 << 4); +- hact = mode->hdisplay * 3; +- video_start = (mode->htotal - mode->hsync_start) * 3; ++ hact = vm.hactive * 3; ++ video_start = (vm.hsync_len + vm.hback_porch) * 3; + data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24; + break; + case MIPI_DSI_FMT_RGB666: + val |= (0x4 << 4); +- hact = mode->hdisplay * 3; +- video_start = (mode->htotal - mode->hsync_start) * 3; ++ hact = vm.hactive * 3; ++ video_start = (vm.hsync_len + vm.hback_porch) * 3; + data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18; + break; + + case MIPI_DSI_FMT_RGB666_PACKED: + val |= (0x4 << 4) | BIT(3); +- hact = mode->hdisplay * 18 / 8; +- video_start = (mode->htotal - mode->hsync_start) * 18 / 8; ++ hact = vm.hactive * 18 / 8; ++ video_start = (vm.hsync_len + vm.hback_porch) * 18 / 8; + data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18; + break; + + case MIPI_DSI_FMT_RGB565: + val |= (0x5 << 4); +- hact = mode->hdisplay * 2; +- video_start = (mode->htotal - mode->hsync_start) * 2; ++ hact = vm.hactive * 2; ++ video_start = (vm.hsync_len + vm.hback_porch) * 2; + data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16; + break; + default: +@@ -814,43 +817,43 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) + tc358768_write(priv, TC358768_DSI_EVENT, 0); + + /* vact */ +- tc358768_write(priv, TC358768_DSI_VACT, mode->vdisplay); ++ tc358768_write(priv, TC358768_DSI_VACT, vm.vactive); + + /* vsw */ +- tc358768_write(priv, TC358768_DSI_VSW, +- mode->vsync_end - mode->vsync_start); ++ tc358768_write(priv, TC358768_DSI_VSW, vm.vsync_len); ++ + /* vbp */ +- tc358768_write(priv, TC358768_DSI_VBPR, +- mode->vtotal - mode->vsync_end); ++ tc358768_write(priv, TC358768_DSI_VBPR, vm.vback_porch); + + /* hsw * byteclk * ndl / pclk */ +- val = (u32)div_u64((mode->hsync_end - mode->hsync_start) * ++ val = (u32)div_u64(vm.hsync_len * + ((u64)priv->dsiclk / 4) * priv->dsi_lanes, +- mode->clock * 1000); ++ vm.pixelclock); + tc358768_write(priv, TC358768_DSI_HSW, val); + + /* hbp * byteclk * ndl / pclk */ +- val = (u32)div_u64((mode->htotal - mode->hsync_end) * ++ val = (u32)div_u64(vm.hback_porch * + ((u64)priv->dsiclk / 4) * priv->dsi_lanes, +- mode->clock * 1000); ++ vm.pixelclock); + tc358768_write(priv, TC358768_DSI_HBPR, val); + } else { + /* Set event mode */ + tc358768_write(priv, TC358768_DSI_EVENT, 1); + + /* vact */ +- tc358768_write(priv, TC358768_DSI_VACT, mode->vdisplay); ++ tc358768_write(priv, TC358768_DSI_VACT, vm.vactive); + + /* vsw (+ vbp) */ + tc358768_write(priv, TC358768_DSI_VSW, +- mode->vtotal - mode->vsync_start); ++ vm.vsync_len + vm.vback_porch); ++ + /* vbp (not used in event mode) */ + tc358768_write(priv, TC358768_DSI_VBPR, 0); + + /* (hsw + hbp) * byteclk * ndl / pclk */ +- val = (u32)div_u64((mode->htotal - mode->hsync_start) * ++ val = (u32)div_u64((vm.hsync_len + vm.hback_porch) * + ((u64)priv->dsiclk / 4) * priv->dsi_lanes, +- mode->clock * 1000); ++ vm.pixelclock); + tc358768_write(priv, TC358768_DSI_HSW, val); + + /* hbp (not used in event mode) */ +-- +2.42.0 + diff --git a/queue-6.6/drm-call-drm_atomic_helper_shutdown-at-shutdown-remo.patch b/queue-6.6/drm-call-drm_atomic_helper_shutdown-at-shutdown-remo.patch new file mode 100644 index 00000000000..9cb542d4df4 --- /dev/null +++ b/queue-6.6/drm-call-drm_atomic_helper_shutdown-at-shutdown-remo.patch @@ -0,0 +1,298 @@ +From ffa92623bf0e0c32ca4f8f6ec381284c4ba9b22a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Sep 2023 16:39:56 -0700 +Subject: drm: Call drm_atomic_helper_shutdown() at shutdown/remove time for + misc drivers + +From: Douglas Anderson + +[ Upstream commit 3c4babae3c4a1ae05f8f3f5f3d50c440ead7ca6a ] + +Based on grepping through the source code these drivers appear to be +missing a call to drm_atomic_helper_shutdown() at system shutdown time +and at driver remove (or unbind) time. Among other things, this means +that if a panel is in use that it won't be cleanly powered off at +system shutdown time. + +The fact that we should call drm_atomic_helper_shutdown() in the case +of OS shutdown/restart and at driver remove (or unbind) time comes +straight out of the kernel doc "driver instance overview" in +drm_drv.c. + +A few notes about these fixes: +- I confirmed that these drivers were all DRIVER_MODESET type drivers, + which I believe makes this relevant. +- I confirmed that these drivers were all DRIVER_ATOMIC. +- When adding drm_atomic_helper_shutdown() to the remove/unbind path, + I added it after drm_kms_helper_poll_fini() when the driver had + it. This seemed to be what other drivers did. If + drm_kms_helper_poll_fini() wasn't there I added it straight after + drm_dev_unregister(). +- This patch deals with drivers using the component model in similar + ways as the patch ("drm: Call drm_atomic_helper_shutdown() at + shutdown time for misc drivers") +- These fixes rely on the patch ("drm/atomic-helper: + drm_atomic_helper_shutdown(NULL) should be a noop") to simplify + shutdown. + +Suggested-by: Maxime Ripard +Reviewed-by: Tomi Valkeinen +Tested-by: Tomi Valkeinen # tilcdc +Acked-by: Maxime Ripard +Signed-off-by: Douglas Anderson +Link: https://patchwork.freedesktop.org/patch/msgid/20230901163944.RFT.5.I771eb4bd03d8772b19e7dcfaef3e2c167bce5846@changeid +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/aspeed/aspeed_gfx_drv.c | 7 +++++++ + drivers/gpu/drm/mgag200/mgag200_drv.c | 8 ++++++++ + drivers/gpu/drm/pl111/pl111_drv.c | 7 +++++++ + drivers/gpu/drm/stm/drv.c | 7 +++++++ + drivers/gpu/drm/tilcdc/tilcdc_drv.c | 11 ++++++++++- + drivers/gpu/drm/tve200/tve200_drv.c | 7 +++++++ + drivers/gpu/drm/vboxvideo/vbox_drv.c | 10 ++++++++++ + 7 files changed, 56 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c +index d207b03f8357c..78122b35a0cbb 100644 +--- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c ++++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c +@@ -358,11 +358,18 @@ static void aspeed_gfx_remove(struct platform_device *pdev) + sysfs_remove_group(&pdev->dev.kobj, &aspeed_sysfs_attr_group); + drm_dev_unregister(drm); + aspeed_gfx_unload(drm); ++ drm_atomic_helper_shutdown(drm); ++} ++ ++static void aspeed_gfx_shutdown(struct platform_device *pdev) ++{ ++ drm_atomic_helper_shutdown(platform_get_drvdata(pdev)); + } + + static struct platform_driver aspeed_gfx_platform_driver = { + .probe = aspeed_gfx_probe, + .remove_new = aspeed_gfx_remove, ++ .shutdown = aspeed_gfx_shutdown, + .driver = { + .name = "aspeed_gfx", + .of_match_table = aspeed_gfx_match, +diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c +index abddf37f0ea11..2fb18b782b053 100644 +--- a/drivers/gpu/drm/mgag200/mgag200_drv.c ++++ b/drivers/gpu/drm/mgag200/mgag200_drv.c +@@ -10,6 +10,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -278,6 +279,12 @@ static void mgag200_pci_remove(struct pci_dev *pdev) + struct drm_device *dev = pci_get_drvdata(pdev); + + drm_dev_unregister(dev); ++ drm_atomic_helper_shutdown(dev); ++} ++ ++static void mgag200_pci_shutdown(struct pci_dev *pdev) ++{ ++ drm_atomic_helper_shutdown(pci_get_drvdata(pdev)); + } + + static struct pci_driver mgag200_pci_driver = { +@@ -285,6 +292,7 @@ static struct pci_driver mgag200_pci_driver = { + .id_table = mgag200_pciidlist, + .probe = mgag200_pci_probe, + .remove = mgag200_pci_remove, ++ .shutdown = mgag200_pci_shutdown, + }; + + drm_module_pci_driver_if_modeset(mgag200_pci_driver, mgag200_modeset); +diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c +index ba3b5b5f0cdfe..02e6b74d50166 100644 +--- a/drivers/gpu/drm/pl111/pl111_drv.c ++++ b/drivers/gpu/drm/pl111/pl111_drv.c +@@ -323,12 +323,18 @@ static void pl111_amba_remove(struct amba_device *amba_dev) + struct pl111_drm_dev_private *priv = drm->dev_private; + + drm_dev_unregister(drm); ++ drm_atomic_helper_shutdown(drm); + if (priv->panel) + drm_panel_bridge_remove(priv->bridge); + drm_dev_put(drm); + of_reserved_mem_device_release(dev); + } + ++static void pl111_amba_shutdown(struct amba_device *amba_dev) ++{ ++ drm_atomic_helper_shutdown(amba_get_drvdata(amba_dev)); ++} ++ + /* + * This early variant lacks the 565 and 444 pixel formats. + */ +@@ -431,6 +437,7 @@ static struct amba_driver pl111_amba_driver __maybe_unused = { + }, + .probe = pl111_amba_probe, + .remove = pl111_amba_remove, ++ .shutdown = pl111_amba_shutdown, + .id_table = pl111_id_table, + }; + +diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c +index c68c831136c9b..e8523abef27a5 100644 +--- a/drivers/gpu/drm/stm/drv.c ++++ b/drivers/gpu/drm/stm/drv.c +@@ -114,6 +114,7 @@ static void drv_unload(struct drm_device *ddev) + DRM_DEBUG("%s\n", __func__); + + drm_kms_helper_poll_fini(ddev); ++ drm_atomic_helper_shutdown(ddev); + ltdc_unload(ddev); + } + +@@ -225,6 +226,11 @@ static void stm_drm_platform_remove(struct platform_device *pdev) + drm_dev_put(ddev); + } + ++static void stm_drm_platform_shutdown(struct platform_device *pdev) ++{ ++ drm_atomic_helper_shutdown(platform_get_drvdata(pdev)); ++} ++ + static const struct of_device_id drv_dt_ids[] = { + { .compatible = "st,stm32-ltdc"}, + { /* end node */ }, +@@ -234,6 +240,7 @@ MODULE_DEVICE_TABLE(of, drv_dt_ids); + static struct platform_driver stm_drm_platform_driver = { + .probe = stm_drm_platform_probe, + .remove_new = stm_drm_platform_remove, ++ .shutdown = stm_drm_platform_shutdown, + .driver = { + .name = "stm32-display", + .of_match_table = drv_dt_ids, +diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c +index fe56beea3e93f..8ebd7134ee21b 100644 +--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c ++++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c +@@ -175,6 +175,7 @@ static void tilcdc_fini(struct drm_device *dev) + drm_dev_unregister(dev); + + drm_kms_helper_poll_fini(dev); ++ drm_atomic_helper_shutdown(dev); + tilcdc_irq_uninstall(dev); + drm_mode_config_cleanup(dev); + +@@ -389,6 +390,7 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) + + init_failed: + tilcdc_fini(ddev); ++ platform_set_drvdata(pdev, NULL); + + return ret; + } +@@ -537,7 +539,8 @@ static void tilcdc_unbind(struct device *dev) + if (!ddev->dev_private) + return; + +- tilcdc_fini(dev_get_drvdata(dev)); ++ tilcdc_fini(ddev); ++ dev_set_drvdata(dev, NULL); + } + + static const struct component_master_ops tilcdc_comp_ops = { +@@ -582,6 +585,11 @@ static int tilcdc_pdev_remove(struct platform_device *pdev) + return 0; + } + ++static void tilcdc_pdev_shutdown(struct platform_device *pdev) ++{ ++ drm_atomic_helper_shutdown(platform_get_drvdata(pdev)); ++} ++ + static const struct of_device_id tilcdc_of_match[] = { + { .compatible = "ti,am33xx-tilcdc", }, + { .compatible = "ti,da850-tilcdc", }, +@@ -592,6 +600,7 @@ MODULE_DEVICE_TABLE(of, tilcdc_of_match); + static struct platform_driver tilcdc_platform_driver = { + .probe = tilcdc_pdev_probe, + .remove = tilcdc_pdev_remove, ++ .shutdown = tilcdc_pdev_shutdown, + .driver = { + .name = "tilcdc", + .pm = pm_sleep_ptr(&tilcdc_pm_ops), +diff --git a/drivers/gpu/drm/tve200/tve200_drv.c b/drivers/gpu/drm/tve200/tve200_drv.c +index 0bb56d0635366..acce210e25547 100644 +--- a/drivers/gpu/drm/tve200/tve200_drv.c ++++ b/drivers/gpu/drm/tve200/tve200_drv.c +@@ -242,6 +242,7 @@ static void tve200_remove(struct platform_device *pdev) + struct tve200_drm_dev_private *priv = drm->dev_private; + + drm_dev_unregister(drm); ++ drm_atomic_helper_shutdown(drm); + if (priv->panel) + drm_panel_bridge_remove(priv->bridge); + drm_mode_config_cleanup(drm); +@@ -249,6 +250,11 @@ static void tve200_remove(struct platform_device *pdev) + drm_dev_put(drm); + } + ++static void tve200_shutdown(struct platform_device *pdev) ++{ ++ drm_atomic_helper_shutdown(platform_get_drvdata(pdev)); ++} ++ + static const struct of_device_id tve200_of_match[] = { + { + .compatible = "faraday,tve200", +@@ -263,6 +269,7 @@ static struct platform_driver tve200_driver = { + }, + .probe = tve200_probe, + .remove_new = tve200_remove, ++ .shutdown = tve200_shutdown, + }; + drm_module_platform_driver(tve200_driver); + +diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c +index 4fee15c97c341..047b958123341 100644 +--- a/drivers/gpu/drm/vboxvideo/vbox_drv.c ++++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c +@@ -12,6 +12,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -97,11 +98,19 @@ static void vbox_pci_remove(struct pci_dev *pdev) + struct vbox_private *vbox = pci_get_drvdata(pdev); + + drm_dev_unregister(&vbox->ddev); ++ drm_atomic_helper_shutdown(&vbox->ddev); + vbox_irq_fini(vbox); + vbox_mode_fini(vbox); + vbox_hw_fini(vbox); + } + ++static void vbox_pci_shutdown(struct pci_dev *pdev) ++{ ++ struct vbox_private *vbox = pci_get_drvdata(pdev); ++ ++ drm_atomic_helper_shutdown(&vbox->ddev); ++} ++ + static int vbox_pm_suspend(struct device *dev) + { + struct vbox_private *vbox = dev_get_drvdata(dev); +@@ -165,6 +174,7 @@ static struct pci_driver vbox_pci_driver = { + .id_table = pciidlist, + .probe = vbox_pci_probe, + .remove = vbox_pci_remove, ++ .shutdown = vbox_pci_shutdown, + .driver.pm = pm_sleep_ptr(&vbox_pm_ops), + }; + +-- +2.42.0 + diff --git a/queue-6.6/drm-loongson-fix-error-handling-in-lsdc_pixel_pll_se.patch b/queue-6.6/drm-loongson-fix-error-handling-in-lsdc_pixel_pll_se.patch new file mode 100644 index 00000000000..b36b72acab8 --- /dev/null +++ b/queue-6.6/drm-loongson-fix-error-handling-in-lsdc_pixel_pll_se.patch @@ -0,0 +1,49 @@ +From 70e30e1c13574c385ae250eaefac7b7b1f89f088 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Jul 2023 05:39:50 -0700 +Subject: drm/loongson: Fix error handling in lsdc_pixel_pll_setup() + +From: Harshit Mogalapalli + +[ Upstream commit 5976a28b344ecb6810882a01b76a320cac21d307 ] + +There are two problems in lsdc_pixel_pll_setup() +1. If kzalloc() fails then call iounmap() to release the resources. +2. Both kzalloc and ioremap does not return error pointers on failure, so + using IS_ERR_OR_NULL() checks is a bit confusing and not very right, + fix this by changing those to NULL checks instead. + +Fixes: f39db26c5428 ("drm: Add kms driver for loongson display controller") +Signed-off-by: Harshit Mogalapalli +Reviewed-by: Sui Jingfeng +Signed-off-by: Sui Jingfeng +Link: https://patchwork.freedesktop.org/patch/msgid/20230720123950.543082-1-harshit.m.mogalapalli@oracle.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/loongson/lsdc_pixpll.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/loongson/lsdc_pixpll.c b/drivers/gpu/drm/loongson/lsdc_pixpll.c +index 04c15b4697e21..2609a2256da4b 100644 +--- a/drivers/gpu/drm/loongson/lsdc_pixpll.c ++++ b/drivers/gpu/drm/loongson/lsdc_pixpll.c +@@ -120,12 +120,14 @@ static int lsdc_pixel_pll_setup(struct lsdc_pixpll * const this) + struct lsdc_pixpll_parms *pparms; + + this->mmio = ioremap(this->reg_base, this->reg_size); +- if (IS_ERR_OR_NULL(this->mmio)) ++ if (!this->mmio) + return -ENOMEM; + + pparms = kzalloc(sizeof(*pparms), GFP_KERNEL); +- if (IS_ERR_OR_NULL(pparms)) ++ if (!pparms) { ++ iounmap(this->mmio); + return -ENOMEM; ++ } + + pparms->ref_clock = LSDC_PLL_REF_CLK_KHZ; + +-- +2.42.0 + diff --git a/queue-6.6/drm-mediatek-add-mmsys_dev_num-to-mt8188-vdosys0-dri.patch b/queue-6.6/drm-mediatek-add-mmsys_dev_num-to-mt8188-vdosys0-dri.patch new file mode 100644 index 00000000000..197639ad5df --- /dev/null +++ b/queue-6.6/drm-mediatek-add-mmsys_dev_num-to-mt8188-vdosys0-dri.patch @@ -0,0 +1,39 @@ +From 6f05b98a1594db7d701e83a7d2ea303f7712f2ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 10:40:05 +0800 +Subject: drm/mediatek: Add mmsys_dev_num to mt8188 vdosys0 driver data + +From: Jason-JH.Lin + +[ Upstream commit ff64e4c31d969cdba20a41969edb3def15f3aaa0 ] + +Add missing mmsys_dev_num to mt8188 vdosys0 driver data. + +Fixes: 54b48080278a ("drm/mediatek: Add mediatek-drm of vdosys0 support for mt8188") +Signed-off-by: Jason-JH.Lin +Reviewed-by: CK Hu +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Fei Shao +Tested-by: Fei Shao +Link: https://patchwork.kernel.org/project/dri-devel/patch/20231004024013.18956-2-jason-jh.lin@mediatek.com/ +Signed-off-by: Chun-Kuang Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_drm_drv.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c +index 93552d76b6e77..2d6a979afe8f9 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c +@@ -288,6 +288,7 @@ static const struct mtk_mmsys_driver_data mt8186_mmsys_driver_data = { + static const struct mtk_mmsys_driver_data mt8188_vdosys0_driver_data = { + .main_path = mt8188_mtk_ddp_main, + .main_len = ARRAY_SIZE(mt8188_mtk_ddp_main), ++ .mmsys_dev_num = 1, + }; + + static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = { +-- +2.42.0 + diff --git a/queue-6.6/drm-mediatek-fix-coverity-issue-with-unintentional-i.patch b/queue-6.6/drm-mediatek-fix-coverity-issue-with-unintentional-i.patch new file mode 100644 index 00000000000..115a151f6bd --- /dev/null +++ b/queue-6.6/drm-mediatek-fix-coverity-issue-with-unintentional-i.patch @@ -0,0 +1,122 @@ +From 39db8371f795b5bf19fb82f831e4b608cb93af1b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 17:14:25 +0800 +Subject: drm/mediatek: Fix coverity issue with unintentional integer overflow + +From: Jason-JH.Lin + +[ Upstream commit b0b0d811eac6b4c52cb9ad632fa6384cf48869e7 ] + +1. Instead of multiplying 2 variable of different types. Change to +assign a value of one variable and then multiply the other variable. + +2. Add a int variable for multiplier calculation instead of calculating +different types multiplier with dma_addr_t variable directly. + +Fixes: 1a64a7aff8da ("drm/mediatek: Fix cursor plane no update") +Signed-off-by: Jason-JH.Lin +Reviewed-by: Alexandre Mergnat +Reviewed-by: AngeloGioacchino Del Regno +Link: https://patchwork.kernel.org/project/dri-devel/patch/20230907091425.9526-1-jason-jh.lin@mediatek.com/ +Signed-off-by: Chun-Kuang Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_drm_gem.c | 9 +++++- + drivers/gpu/drm/mediatek/mtk_drm_plane.c | 39 ++++++++++++++++++------ + 2 files changed, 38 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c +index 0e0a41b2f57f0..4f2e3feabc0f8 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c +@@ -121,7 +121,14 @@ int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev, + int ret; + + args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8); +- args->size = args->pitch * args->height; ++ ++ /* ++ * Multiply 2 variables of different types, ++ * for example: args->size = args->spacing * args->height; ++ * may cause coverity issue with unintentional overflow. ++ */ ++ args->size = args->pitch; ++ args->size *= args->height; + + mtk_gem = mtk_drm_gem_create(dev, args->size, false); + if (IS_ERR(mtk_gem)) +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c +index db2f70ae060d6..5acb03b7c6fe5 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c +@@ -141,6 +141,7 @@ static void mtk_plane_update_new_state(struct drm_plane_state *new_state, + dma_addr_t addr; + dma_addr_t hdr_addr = 0; + unsigned int hdr_pitch = 0; ++ int offset; + + gem = fb->obj[0]; + mtk_gem = to_mtk_gem_obj(gem); +@@ -150,8 +151,15 @@ static void mtk_plane_update_new_state(struct drm_plane_state *new_state, + modifier = fb->modifier; + + if (modifier == DRM_FORMAT_MOD_LINEAR) { +- addr += (new_state->src.x1 >> 16) * fb->format->cpp[0]; +- addr += (new_state->src.y1 >> 16) * pitch; ++ /* ++ * Using dma_addr_t variable to calculate with multiplier of different types, ++ * for example: addr += (new_state->src.x1 >> 16) * fb->format->cpp[0]; ++ * may cause coverity issue with unintentional overflow. ++ */ ++ offset = (new_state->src.x1 >> 16) * fb->format->cpp[0]; ++ addr += offset; ++ offset = (new_state->src.y1 >> 16) * pitch; ++ addr += offset; + } else { + int width_in_blocks = ALIGN(fb->width, AFBC_DATA_BLOCK_WIDTH) + / AFBC_DATA_BLOCK_WIDTH; +@@ -159,21 +167,34 @@ static void mtk_plane_update_new_state(struct drm_plane_state *new_state, + / AFBC_DATA_BLOCK_HEIGHT; + int x_offset_in_blocks = (new_state->src.x1 >> 16) / AFBC_DATA_BLOCK_WIDTH; + int y_offset_in_blocks = (new_state->src.y1 >> 16) / AFBC_DATA_BLOCK_HEIGHT; +- int hdr_size; ++ int hdr_size, hdr_offset; + + hdr_pitch = width_in_blocks * AFBC_HEADER_BLOCK_SIZE; + pitch = width_in_blocks * AFBC_DATA_BLOCK_WIDTH * + AFBC_DATA_BLOCK_HEIGHT * fb->format->cpp[0]; + + hdr_size = ALIGN(hdr_pitch * height_in_blocks, AFBC_HEADER_ALIGNMENT); ++ hdr_offset = hdr_pitch * y_offset_in_blocks + ++ AFBC_HEADER_BLOCK_SIZE * x_offset_in_blocks; ++ ++ /* ++ * Using dma_addr_t variable to calculate with multiplier of different types, ++ * for example: addr += hdr_pitch * y_offset_in_blocks; ++ * may cause coverity issue with unintentional overflow. ++ */ ++ hdr_addr = addr + hdr_offset; + +- hdr_addr = addr + hdr_pitch * y_offset_in_blocks + +- AFBC_HEADER_BLOCK_SIZE * x_offset_in_blocks; + /* The data plane is offset by 1 additional block. */ +- addr = addr + hdr_size + +- pitch * y_offset_in_blocks + +- AFBC_DATA_BLOCK_WIDTH * AFBC_DATA_BLOCK_HEIGHT * +- fb->format->cpp[0] * (x_offset_in_blocks + 1); ++ offset = pitch * y_offset_in_blocks + ++ AFBC_DATA_BLOCK_WIDTH * AFBC_DATA_BLOCK_HEIGHT * ++ fb->format->cpp[0] * (x_offset_in_blocks + 1); ++ ++ /* ++ * Using dma_addr_t variable to calculate with multiplier of different types, ++ * for example: addr += pitch * y_offset_in_blocks; ++ * may cause coverity issue with unintentional overflow. ++ */ ++ addr = addr + hdr_size + offset; + } + + mtk_plane_state->pending.enable = true; +-- +2.42.0 + diff --git a/queue-6.6/drm-mediatek-fix-iommu-fault-by-swapping-fbs-after-u.patch b/queue-6.6/drm-mediatek-fix-iommu-fault-by-swapping-fbs-after-u.patch new file mode 100644 index 00000000000..6a878a28d98 --- /dev/null +++ b/queue-6.6/drm-mediatek-fix-iommu-fault-by-swapping-fbs-after-u.patch @@ -0,0 +1,47 @@ +From 5c72a753225345b7f0fe9c98c61cd14590e8f606 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Aug 2023 20:57:21 +0800 +Subject: drm/mediatek: Fix iommu fault by swapping FBs after updating plane + state + +From: Jason-JH.Lin + +[ Upstream commit 3ec71e05ae6e7f46512e568ed81c92be589003dd ] + +According to the comment in drm_atomic_helper_async_commit(), +we should make sure FBs have been swapped, so that cleanups in the +new_state performs a cleanup in the old FB. + +So we should move swapping FBs after calling mtk_plane_update_new_state(), +to avoid using the old FB which could be freed. + +Fixes: 1a64a7aff8da ("drm/mediatek: Fix cursor plane no update") +Signed-off-by: Jason-JH.Lin +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: CK Hu +Reviewed-by: Alexandre Mergnat +Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20230809125722.24112-2-jason-jh.lin@mediatek.com/ +Signed-off-by: Chun-Kuang Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_drm_plane.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c +index 5acb03b7c6fe5..ddc9355b06d51 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c +@@ -227,9 +227,9 @@ static void mtk_plane_atomic_async_update(struct drm_plane *plane, + plane->state->src_y = new_state->src_y; + plane->state->src_h = new_state->src_h; + plane->state->src_w = new_state->src_w; +- swap(plane->state->fb, new_state->fb); + + mtk_plane_update_new_state(new_state, new_plane_state); ++ swap(plane->state->fb, new_state->fb); + wmb(); /* Make sure the above parameters are set before update */ + new_plane_state->pending.async_dirty = true; + mtk_drm_crtc_async_update(new_state->crtc, plane, state); +-- +2.42.0 + diff --git a/queue-6.6/drm-mediatek-fix-iommu-fault-during-crtc-enabling.patch b/queue-6.6/drm-mediatek-fix-iommu-fault-during-crtc-enabling.patch new file mode 100644 index 00000000000..8e0522a9eb4 --- /dev/null +++ b/queue-6.6/drm-mediatek-fix-iommu-fault-during-crtc-enabling.patch @@ -0,0 +1,55 @@ +From 01cafe032c4c29666644ab864867b4136a8e4f53 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Aug 2023 20:57:22 +0800 +Subject: drm/mediatek: Fix iommu fault during crtc enabling + +From: Jason-JH.Lin + +[ Upstream commit 53412dc2905401207f264dc30890f6b9e41524a6 ] + +The difference between drm_atomic_helper_commit_tail() and +drm_atomic_helper_commit_tail_rpm() is +drm_atomic_helper_commit_tail() will commit plane first and +then enable crtc, drm_atomic_helper_commit_tail_rpm() will +enable crtc first and then commit plane. + +Before mediatek-drm enables crtc, the power and clk required +by OVL have not been turned on, so the commit plane cannot be +committed before crtc is enabled. That means OVL layer should +not be enabled before crtc is enabled. +Therefore, the atomic_commit_tail of mediatek-drm is hooked with +drm_atomic_helper_commit_tail_rpm(). + +Another reason is that the plane_state of drm_atomic_state is not +synchronized with the plane_state stored in mtk_crtc during crtc enablng, +so just set all planes to disabled. + +Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.") +Signed-off-by: Jason-JH.Lin +Reviewed-by: Alexandre Mergnat +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: CK Hu +Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20230809125722.24112-3-jason-jh.lin@mediatek.com/ +Signed-off-by: Chun-Kuang Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +index b6fa4ad2f94dc..0a511d7688a3a 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +@@ -408,6 +408,9 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc) + unsigned int local_layer; + + plane_state = to_mtk_plane_state(plane->state); ++ ++ /* should not enable layer before crtc enabled */ ++ plane_state->pending.enable = false; + comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer); + if (comp) + mtk_ddp_comp_layer_config(comp, local_layer, +-- +2.42.0 + diff --git a/queue-6.6/drm-mediatek-mtk_dsi-fix-no_eot_packet-settings-hand.patch b/queue-6.6/drm-mediatek-mtk_dsi-fix-no_eot_packet-settings-hand.patch new file mode 100644 index 00000000000..d9c86c88ebe --- /dev/null +++ b/queue-6.6/drm-mediatek-mtk_dsi-fix-no_eot_packet-settings-hand.patch @@ -0,0 +1,67 @@ +From bcf14fbdaa179eec1ad8d55f58d5f9f7b8355b44 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 May 2023 12:42:34 +0200 +Subject: drm: mediatek: mtk_dsi: Fix NO_EOT_PACKET settings/handling + +From: AngeloGioacchino Del Regno + +[ Upstream commit 5855d422a6f250f3518f43b49092c8e87a5e42be ] + +Due to the initial confusion about MIPI_DSI_MODE_EOT_PACKET, properly +renamed to MIPI_DSI_MODE_NO_EOT_PACKET, reflecting its actual meaning, +both the DSI_TXRX_CON register setting for bit (HSTX_)DIS_EOT and the +later calculation for horizontal sync-active (HSA), back (HBP) and +front (HFP) porches got incorrect due to the logic being inverted. + +This means that a number of settings were wrong because....: + - DSI_TXRX_CON register setting: bit (HSTX_)DIS_EOT should be + set in order to disable the End of Transmission packet; + - Horizontal Sync and Back/Front porches: The delta used to + calculate all of HSA, HBP and HFP should account for the + additional EOT packet. + +Before this change... + - Bit (HSTX_)DIS_EOT was being set when EOT packet was enabled; + - For HSA/HBP/HFP delta... all three were wrong, as words were + added when EOT disabled, instead of when EOT packet enabled! + +Invert the logic around flag MIPI_DSI_MODE_NO_EOT_PACKET in the +MediaTek DSI driver to fix the aforementioned issues. + +Fixes: 8b2b99fd7931 ("drm/mediatek: dsi: Fine tune the line time caused by EOTp") +Fixes: c87d1c4b5b9a ("drm/mediatek: dsi: Use symbolized register definition") +Signed-off-by: AngeloGioacchino Del Regno +Reviewed-by: Alexandre Mergnat +Tested-by: Michael Walle +Link: https://patchwork.kernel.org/project/dri-devel/patch/20230523104234.7849-1-angelogioacchino.delregno@collabora.com/ +Signed-off-by: Chun-Kuang Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_dsi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c +index d8bfc2cce54dc..290f328c6a421 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dsi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dsi.c +@@ -407,7 +407,7 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi) + if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) + tmp_reg |= HSTX_CKLP_EN; + +- if (!(dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)) ++ if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET) + tmp_reg |= DIS_EOT; + + writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL); +@@ -484,7 +484,7 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi) + timing->da_hs_zero + timing->da_hs_exit + 3; + + delta = dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST ? 18 : 12; +- delta += dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET ? 2 : 0; ++ delta += dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET ? 0 : 2; + + horizontal_frontporch_byte = vm->hfront_porch * dsi_tmp_buf_bpp; + horizontal_front_back_byte = horizontal_frontporch_byte + horizontal_backporch_byte; +-- +2.42.0 + diff --git a/queue-6.6/drm-msm-a6xx-fix-unknown-speedbin-case.patch b/queue-6.6/drm-msm-a6xx-fix-unknown-speedbin-case.patch new file mode 100644 index 00000000000..2aef525e0b4 --- /dev/null +++ b/queue-6.6/drm-msm-a6xx-fix-unknown-speedbin-case.patch @@ -0,0 +1,47 @@ +From dad77d300d06f8f50c0f1b65cecb62cf1a899377 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Sep 2023 20:24:36 +0200 +Subject: drm/msm/a6xx: Fix unknown speedbin case + +From: Konrad Dybcio + +[ Upstream commit 75cb60d4f5f762b12643b67cbefefcf05ecfd7eb ] + +When opp-supported-hw is present under an OPP node, but no form of +opp_set_supported_hw() has been called, that OPP is ignored by the API +and marked as unsupported. + +Before Commit c928a05e4415 ("drm/msm/adreno: Move speedbin mapping to +device table"), an unknown speedbin would result in marking all OPPs +as available, but it's better to avoid potentially overclocking the +silicon - the GMU will simply refuse to power up the chip. + +Currently, the Adreno speedbin code does just that (AND returns an +invalid error, (int)UINT_MAX). Fix that by defaulting to speedbin 0 +(which is conveniently always bound to fuseval == 0). + +Fixes: c928a05e4415 ("drm/msm/adreno: Move speedbin mapping to device table") +Signed-off-by: Konrad Dybcio +Patchwork: https://patchwork.freedesktop.org/patch/559604/ +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +index d4e85e24002fb..522ca7fe67625 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +@@ -2237,7 +2237,7 @@ static int a6xx_set_supported_hw(struct device *dev, const struct adreno_info *i + DRM_DEV_ERROR(dev, + "missing support for speed-bin: %u. Some OPPs may not be supported by hardware\n", + speedbin); +- return UINT_MAX; ++ supp_hw = BIT(0); /* Default */ + } + + ret = devm_pm_opp_set_supported_hw(dev, &supp_hw, 1); +-- +2.42.0 + diff --git a/queue-6.6/drm-msm-adreno-fix-sm6375-gpu-id.patch b/queue-6.6/drm-msm-adreno-fix-sm6375-gpu-id.patch new file mode 100644 index 00000000000..65b572853cc --- /dev/null +++ b/queue-6.6/drm-msm-adreno-fix-sm6375-gpu-id.patch @@ -0,0 +1,36 @@ +From f22ad9058ed2c4a805e0186845021fcefe9cc042 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Aug 2023 23:11:19 +0200 +Subject: drm/msm/adreno: Fix SM6375 GPU ID + +From: Konrad Dybcio + +[ Upstream commit beb3542320479cd59a08273be0b19dfea0b36042 ] + +SM6375 comes with a patchlevel=1. Fix the chipid up to reflect that. + +Fixes: 90b593ce1c9e ("drm/msm/adreno: Switch to chip-id for identifying GPU") +Signed-off-by: Konrad Dybcio +Patchwork: https://patchwork.freedesktop.org/patch/554527/ +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/adreno_device.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c +index 575e7c56219ff..f2d9d34ed50f9 100644 +--- a/drivers/gpu/drm/msm/adreno/adreno_device.c ++++ b/drivers/gpu/drm/msm/adreno/adreno_device.c +@@ -331,7 +331,7 @@ static const struct adreno_info gpulist[] = { + ), + }, { + .machine = "qcom,sm6375", +- .chip_ids = ADRENO_CHIP_IDS(0x06010900), ++ .chip_ids = ADRENO_CHIP_IDS(0x06010901), + .family = ADRENO_6XX_GEN1, + .revn = 619, + .fw = { +-- +2.42.0 + diff --git a/queue-6.6/drm-msm-dsi-free-tx-buffer-in-unbind.patch b/queue-6.6/drm-msm-dsi-free-tx-buffer-in-unbind.patch new file mode 100644 index 00000000000..70d94243dd8 --- /dev/null +++ b/queue-6.6/drm-msm-dsi-free-tx-buffer-in-unbind.patch @@ -0,0 +1,120 @@ +From 6fa615050b04eb63c97db227da637c8724d45f2f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Oct 2023 04:29:09 +0300 +Subject: drm/msm/dsi: free TX buffer in unbind + +From: Dmitry Baryshkov + +[ Upstream commit 5e05be78264594634860087953649487f486ffcc ] + +If the drm/msm init code gets an error during output modeset +initialisation, the kernel will report an error regarding DRM memory +manager not being clean during shutdown. This is because +msm_dsi_modeset_init() allocates a piece of GEM memory for the TX +buffer, but destruction of the buffer happens only at +msm_dsi_host_destroy(), which is called during DSI driver's remove() +time, much later than the DRM MM shutdown. + +To solve this issue, move the TX buffer destruction to dsi_unbind(), so +that the buffer is destructed at the correct time. Note, we also have to +store a reference to the address space, because priv->kms->aspace is +cleared before components are unbound. + +Reported-by: Bjorn Andersson +Fixes: 8f59ee9a570c ("drm/msm/dsi: Adjust probe order") +Signed-off-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/562238/ +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/dsi/dsi.c | 1 + + drivers/gpu/drm/msm/dsi/dsi.h | 1 + + drivers/gpu/drm/msm/dsi/dsi_host.c | 15 +++++++++------ + 3 files changed, 11 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c +index baab79ab6e745..32f965bacdc30 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi.c ++++ b/drivers/gpu/drm/msm/dsi/dsi.c +@@ -126,6 +126,7 @@ static void dsi_unbind(struct device *dev, struct device *master, + struct msm_drm_private *priv = dev_get_drvdata(master); + struct msm_dsi *msm_dsi = dev_get_drvdata(dev); + ++ msm_dsi_tx_buf_free(msm_dsi->host); + priv->dsi[msm_dsi->id] = NULL; + } + +diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h +index bd3763a5d7234..3b46617a59f20 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi.h ++++ b/drivers/gpu/drm/msm/dsi/dsi.h +@@ -125,6 +125,7 @@ int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size); + void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host); + void *dsi_tx_buf_get_v2(struct msm_dsi_host *msm_host); + void dsi_tx_buf_put_6g(struct msm_dsi_host *msm_host); ++void msm_dsi_tx_buf_free(struct mipi_dsi_host *mipi_host); + int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *iova); + int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *iova); + int dsi_clk_init_v2(struct msm_dsi_host *msm_host); +diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c +index 2395d5a586189..470866896b9b8 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi_host.c ++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c +@@ -147,6 +147,7 @@ struct msm_dsi_host { + + /* DSI 6G TX buffer*/ + struct drm_gem_object *tx_gem_obj; ++ struct msm_gem_address_space *aspace; + + /* DSI v2 TX buffer */ + void *tx_buf; +@@ -1111,8 +1112,10 @@ int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size) + uint64_t iova; + u8 *data; + ++ msm_host->aspace = msm_gem_address_space_get(priv->kms->aspace); ++ + data = msm_gem_kernel_new(dev, size, MSM_BO_WC, +- priv->kms->aspace, ++ msm_host->aspace, + &msm_host->tx_gem_obj, &iova); + + if (IS_ERR(data)) { +@@ -1141,10 +1144,10 @@ int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size) + return 0; + } + +-static void dsi_tx_buf_free(struct msm_dsi_host *msm_host) ++void msm_dsi_tx_buf_free(struct mipi_dsi_host *host) + { ++ struct msm_dsi_host *msm_host = to_msm_dsi_host(host); + struct drm_device *dev = msm_host->dev; +- struct msm_drm_private *priv; + + /* + * This is possible if we're tearing down before we've had a chance to +@@ -1155,10 +1158,11 @@ static void dsi_tx_buf_free(struct msm_dsi_host *msm_host) + if (!dev) + return; + +- priv = dev->dev_private; + if (msm_host->tx_gem_obj) { +- msm_gem_kernel_put(msm_host->tx_gem_obj, priv->kms->aspace); ++ msm_gem_kernel_put(msm_host->tx_gem_obj, msm_host->aspace); ++ msm_gem_address_space_put(msm_host->aspace); + msm_host->tx_gem_obj = NULL; ++ msm_host->aspace = NULL; + } + + if (msm_host->tx_buf) +@@ -1944,7 +1948,6 @@ void msm_dsi_host_destroy(struct mipi_dsi_host *host) + struct msm_dsi_host *msm_host = to_msm_dsi_host(host); + + DBG(""); +- dsi_tx_buf_free(msm_host); + if (msm_host->workqueue) { + destroy_workqueue(msm_host->workqueue); + msm_host->workqueue = NULL; +-- +2.42.0 + diff --git a/queue-6.6/drm-msm-dsi-use-msm_gem_kernel_put-to-free-tx-buffer.patch b/queue-6.6/drm-msm-dsi-use-msm_gem_kernel_put-to-free-tx-buffer.patch new file mode 100644 index 00000000000..959408df2ea --- /dev/null +++ b/queue-6.6/drm-msm-dsi-use-msm_gem_kernel_put-to-free-tx-buffer.patch @@ -0,0 +1,41 @@ +From 5c1eba12bc0a3e1a46c3559c6376f2dc91109999 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Oct 2023 04:29:08 +0300 +Subject: drm/msm/dsi: use msm_gem_kernel_put to free TX buffer + +From: Dmitry Baryshkov + +[ Upstream commit 69b321b2c3df4f7e51a9de587e41f324b0b717b0 ] + +Use exiting function to free the allocated GEM object instead of +open-coding it. This has a bonus of internally calling +msm_gem_put_vaddr() to compensate for msm_gem_get_vaddr() in +msm_get_kernel_new(). + +Fixes: 1e29dff00400 ("drm/msm: Add a common function to free kernel buffer objects") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Abhinav Kumar +Patchwork: https://patchwork.freedesktop.org/patch/562239/ +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/dsi/dsi_host.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c +index 3d6fb708dc223..2395d5a586189 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi_host.c ++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c +@@ -1157,8 +1157,7 @@ static void dsi_tx_buf_free(struct msm_dsi_host *msm_host) + + priv = dev->dev_private; + if (msm_host->tx_gem_obj) { +- msm_gem_unpin_iova(msm_host->tx_gem_obj, priv->kms->aspace); +- drm_gem_object_put(msm_host->tx_gem_obj); ++ msm_gem_kernel_put(msm_host->tx_gem_obj, priv->kms->aspace); + msm_host->tx_gem_obj = NULL; + } + +-- +2.42.0 + diff --git a/queue-6.6/drm-radeon-possible-buffer-overflow.patch b/queue-6.6/drm-radeon-possible-buffer-overflow.patch new file mode 100644 index 00000000000..9d8194ee907 --- /dev/null +++ b/queue-6.6/drm-radeon-possible-buffer-overflow.patch @@ -0,0 +1,47 @@ +From 21c39684f19f9f1f07e2ee81903fdc5e436645cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Aug 2023 19:33:49 +0800 +Subject: drm/radeon: possible buffer overflow + +From: Konstantin Meskhidze + +[ Upstream commit dd05484f99d16715a88eedfca363828ef9a4c2d4 ] + +Buffer 'afmt_status' of size 6 could overflow, since index 'afmt_idx' is +checked after access. + +Fixes: 5cc4e5fc293b ("drm/radeon: Cleanup HDMI audio interrupt handling for evergreen") +Co-developed-by: Ivanov Mikhail +Signed-off-by: Konstantin Meskhidze +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/radeon/evergreen.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c +index 4f06356d9ce2e..f0ae087be914e 100644 +--- a/drivers/gpu/drm/radeon/evergreen.c ++++ b/drivers/gpu/drm/radeon/evergreen.c +@@ -4821,14 +4821,15 @@ int evergreen_irq_process(struct radeon_device *rdev) + break; + case 44: /* hdmi */ + afmt_idx = src_data; +- if (!(afmt_status[afmt_idx] & AFMT_AZ_FORMAT_WTRIG)) +- DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); +- + if (afmt_idx > 5) { + DRM_ERROR("Unhandled interrupt: %d %d\n", + src_id, src_data); + break; + } ++ ++ if (!(afmt_status[afmt_idx] & AFMT_AZ_FORMAT_WTRIG)) ++ DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); ++ + afmt_status[afmt_idx] &= ~AFMT_AZ_FORMAT_WTRIG; + queue_hdmi = true; + DRM_DEBUG("IH: HDMI%d\n", afmt_idx + 1); +-- +2.42.0 + diff --git a/queue-6.6/drm-radeon-remove-the-references-of-radeon_gem_-prea.patch b/queue-6.6/drm-radeon-remove-the-references-of-radeon_gem_-prea.patch new file mode 100644 index 00000000000..67b3e384939 --- /dev/null +++ b/queue-6.6/drm-radeon-remove-the-references-of-radeon_gem_-prea.patch @@ -0,0 +1,88 @@ +From c5e03813d2bd487a61045b48d0a62b943dbadaf8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Jul 2023 19:17:12 +0530 +Subject: drm/radeon: Remove the references of radeon_gem_ pread & pwrite + ioctls +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Srinivasan Shanmugam + +[ Upstream commit 52548038496fd58b762067b946f943c9bbcbd01e ] + +Removing the functions of pread & pwrite & IOCTL defines, as their +existence allows an authorized client to spam the system logs. + +Fixes: db996e64b293 ("drm/radeon: Fix ENOSYS with better fitting error codes in radeon_gem.c") +Suggested-by: Christian König +Cc: Christian König +Cc: Alex Deucher +Signed-off-by: Srinivasan Shanmugam +Acked-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/radeon/radeon.h | 4 ---- + drivers/gpu/drm/radeon/radeon_drv.c | 2 -- + drivers/gpu/drm/radeon/radeon_gem.c | 16 ---------------- + 3 files changed, 22 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index 8afb03bbce298..3d3d2109dfebc 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -2215,10 +2215,6 @@ int radeon_gem_pin_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +-int radeon_gem_pwrite_ioctl(struct drm_device *dev, void *data, +- struct drm_file *file_priv); +-int radeon_gem_pread_ioctl(struct drm_device *dev, void *data, +- struct drm_file *file_priv); + int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp); + int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, +diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c +index fa531493b1113..7bf08164140ef 100644 +--- a/drivers/gpu/drm/radeon/radeon_drv.c ++++ b/drivers/gpu/drm/radeon/radeon_drv.c +@@ -555,8 +555,6 @@ static const struct drm_ioctl_desc radeon_ioctls_kms[] = { + DRM_IOCTL_DEF_DRV(RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), +- DRM_IOCTL_DEF_DRV(RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH), +- DRM_IOCTL_DEF_DRV(RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), +diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c +index 358d19242f4ba..3fec3acdaf284 100644 +--- a/drivers/gpu/drm/radeon/radeon_gem.c ++++ b/drivers/gpu/drm/radeon/radeon_gem.c +@@ -311,22 +311,6 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data, + return 0; + } + +-int radeon_gem_pread_ioctl(struct drm_device *dev, void *data, +- struct drm_file *filp) +-{ +- /* TODO: implement */ +- DRM_ERROR("unimplemented %s\n", __func__); +- return -EOPNOTSUPP; +-} +- +-int radeon_gem_pwrite_ioctl(struct drm_device *dev, void *data, +- struct drm_file *filp) +-{ +- /* TODO: implement */ +- DRM_ERROR("unimplemented %s\n", __func__); +- return -EOPNOTSUPP; +-} +- + int radeon_gem_create_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp) + { +-- +2.42.0 + diff --git a/queue-6.6/drm-rockchip-cdn-dp-fix-some-error-handling-paths-in.patch b/queue-6.6/drm-rockchip-cdn-dp-fix-some-error-handling-paths-in.patch new file mode 100644 index 00000000000..e30475b830f --- /dev/null +++ b/queue-6.6/drm-rockchip-cdn-dp-fix-some-error-handling-paths-in.patch @@ -0,0 +1,60 @@ +From 79deec8f1b3cb7c5a694af73c5bfc785cb31c634 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 2 Sep 2023 19:34:31 +0200 +Subject: drm/rockchip: cdn-dp: Fix some error handling paths in cdn_dp_probe() + +From: Christophe JAILLET + +[ Upstream commit 44b968d0d0868b7a9b7a5c64464ada464ff4d532 ] + +cdn_dp_audio_codec_init() can fail. So add some error handling. + +If component_add() fails, the previous cdn_dp_audio_codec_init() call +should be undone, as already done in the remove function. + +Fixes: 88582f564692 ("drm/rockchip: cdn-dp: Don't unregister audio dev when unbinding") +Signed-off-by: Christophe JAILLET +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/8494a41602fadb7439630921a9779640698f2f9f.1693676045.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/rockchip/cdn-dp-core.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c +index a29fbafce3936..3793863c210eb 100644 +--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c ++++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c +@@ -1177,6 +1177,7 @@ static int cdn_dp_probe(struct platform_device *pdev) + struct cdn_dp_device *dp; + struct extcon_dev *extcon; + struct phy *phy; ++ int ret; + int i; + + dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); +@@ -1217,9 +1218,19 @@ static int cdn_dp_probe(struct platform_device *pdev) + mutex_init(&dp->lock); + dev_set_drvdata(dev, dp); + +- cdn_dp_audio_codec_init(dp, dev); ++ ret = cdn_dp_audio_codec_init(dp, dev); ++ if (ret) ++ return ret; ++ ++ ret = component_add(dev, &cdn_dp_component_ops); ++ if (ret) ++ goto err_audio_deinit; + +- return component_add(dev, &cdn_dp_component_ops); ++ return 0; ++ ++err_audio_deinit: ++ platform_device_unregister(dp->audio_pdev); ++ return ret; + } + + static void cdn_dp_remove(struct platform_device *pdev) +-- +2.42.0 + diff --git a/queue-6.6/drm-rockchip-fix-type-promotion-bug-in-rockchip_gem_.patch b/queue-6.6/drm-rockchip-fix-type-promotion-bug-in-rockchip_gem_.patch new file mode 100644 index 00000000000..765d46408f9 --- /dev/null +++ b/queue-6.6/drm-rockchip-fix-type-promotion-bug-in-rockchip_gem_.patch @@ -0,0 +1,40 @@ +From 28df89680030e4bf40b35eb174a43241f3248e4b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 11:01:48 +0300 +Subject: drm/rockchip: Fix type promotion bug in rockchip_gem_iommu_map() + +From: Dan Carpenter + +[ Upstream commit 6471da5ee311d53ef46eebcb7725bc94266cc0cf ] + +The "ret" variable is declared as ssize_t and it can hold negative error +codes but the "rk_obj->base.size" variable is type size_t. This means +that when we compare them, they are both type promoted to size_t and the +negative error code becomes a high unsigned value and is treated as +success. Add a cast to fix this. + +Fixes: 38f993b7c59e ("drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain") +Signed-off-by: Dan Carpenter +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/2bfa28b5-145d-4b9e-a18a-98819dd686ce@moroto.mountain +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +index b8f8b45ebf594..93ed841f5dcea 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +@@ -40,7 +40,7 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj) + + ret = iommu_map_sgtable(private->domain, rk_obj->dma_addr, rk_obj->sgt, + prot); +- if (ret < rk_obj->base.size) { ++ if (ret < (ssize_t)rk_obj->base.size) { + DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n", + ret, rk_obj->base.size); + ret = -ENOMEM; +-- +2.42.0 + diff --git a/queue-6.6/drm-rockchip-vop-fix-call-to-crtc-reset-helper.patch b/queue-6.6/drm-rockchip-vop-fix-call-to-crtc-reset-helper.patch new file mode 100644 index 00000000000..7d75532a98d --- /dev/null +++ b/queue-6.6/drm-rockchip-vop-fix-call-to-crtc-reset-helper.patch @@ -0,0 +1,43 @@ +From 703fa2923b8f173f0f0da55a0a4c788b80ca9358 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Jun 2023 22:33:20 +0000 +Subject: drm/rockchip: vop: Fix call to crtc reset helper + +From: Jonas Karlman + +[ Upstream commit 5aacd290837828c089a83ac9795c74c4c9e2c923 ] + +Allocation of crtc_state may fail in vop_crtc_reset, causing an invalid +pointer to be passed to __drm_atomic_helper_crtc_reset. + +Fix this by adding a NULL check of crtc_state, similar to other drivers. + +Fixes: 01e2eaf40c9d ("drm/rockchip: Convert to using __drm_atomic_helper_crtc_reset() for reset.") +Signed-off-by: Jonas Karlman +Reviewed-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20230621223311.2239547-4-jonas@kwiboo.se +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index 06f647a20fe44..41cd12d5f2fa2 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -1640,7 +1640,10 @@ static void vop_crtc_reset(struct drm_crtc *crtc) + if (crtc->state) + vop_crtc_destroy_state(crtc, crtc->state); + +- __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base); ++ if (crtc_state) ++ __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base); ++ else ++ __drm_atomic_helper_crtc_reset(crtc, NULL); + } + + #ifdef CONFIG_DRM_ANALOGIX_DP +-- +2.42.0 + diff --git a/queue-6.6/drm-rockchip-vop-fix-reset-of-state-in-duplicate-sta.patch b/queue-6.6/drm-rockchip-vop-fix-reset-of-state-in-duplicate-sta.patch new file mode 100644 index 00000000000..4a3b0e33210 --- /dev/null +++ b/queue-6.6/drm-rockchip-vop-fix-reset-of-state-in-duplicate-sta.patch @@ -0,0 +1,42 @@ +From 33afe2f5194445744673697571e5c2fce01defe3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Jun 2023 22:33:17 +0000 +Subject: drm/rockchip: vop: Fix reset of state in duplicate state crtc funcs + +From: Jonas Karlman + +[ Upstream commit 13fc28804bf10ca0b7bce3efbba95c534836d7ca ] + +struct rockchip_crtc_state members such as output_type, output_bpc and +enable_afbc is always reset to zero in the atomic_duplicate_state crtc +funcs. + +Fix this by using kmemdup on the subclass rockchip_crtc_state struct. + +Fixes: 4e257d9eee23 ("drm/rockchip: get rid of rockchip_drm_crtc_mode_config") +Signed-off-by: Jonas Karlman +Reviewed-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20230621223311.2239547-2-jonas@kwiboo.se +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index 14320bc73e5bf..06f647a20fe44 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -1614,7 +1614,8 @@ static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc) + if (WARN_ON(!crtc->state)) + return NULL; + +- rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL); ++ rockchip_state = kmemdup(to_rockchip_crtc_state(crtc->state), ++ sizeof(*rockchip_state), GFP_KERNEL); + if (!rockchip_state) + return NULL; + +-- +2.42.0 + diff --git a/queue-6.6/drm-rockchip-vop2-add-missing-call-to-crtc-reset-hel.patch b/queue-6.6/drm-rockchip-vop2-add-missing-call-to-crtc-reset-hel.patch new file mode 100644 index 00000000000..34da4920ecc --- /dev/null +++ b/queue-6.6/drm-rockchip-vop2-add-missing-call-to-crtc-reset-hel.patch @@ -0,0 +1,76 @@ +From e50eef14c50b72690358d186d71abfdb7f503037 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Jun 2023 22:33:23 +0000 +Subject: drm/rockchip: vop2: Add missing call to crtc reset helper + +From: Jonas Karlman + +[ Upstream commit 4d49d87b3606369c6e29b9d051892ee1a6fc4e75 ] + +Add missing call to crtc reset helper to properly vblank reset. + +Also move vop2_crtc_reset and call vop2_crtc_destroy_state to simplify +and remove duplicated code. + +Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver") +Signed-off-by: Jonas Karlman +Reviewed-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20230621223311.2239547-6-jonas@kwiboo.se +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 31 +++++++++----------- + 1 file changed, 14 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +index d843c19c146db..c306806aa3dea 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -2079,23 +2079,6 @@ static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = { + .atomic_disable = vop2_crtc_atomic_disable, + }; + +-static void vop2_crtc_reset(struct drm_crtc *crtc) +-{ +- struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); +- +- if (crtc->state) { +- __drm_atomic_helper_crtc_destroy_state(crtc->state); +- kfree(vcstate); +- } +- +- vcstate = kzalloc(sizeof(*vcstate), GFP_KERNEL); +- if (!vcstate) +- return; +- +- crtc->state = &vcstate->base; +- crtc->state->crtc = crtc; +-} +- + static struct drm_crtc_state *vop2_crtc_duplicate_state(struct drm_crtc *crtc) + { + struct rockchip_crtc_state *vcstate; +@@ -2122,6 +2105,20 @@ static void vop2_crtc_destroy_state(struct drm_crtc *crtc, + kfree(vcstate); + } + ++static void vop2_crtc_reset(struct drm_crtc *crtc) ++{ ++ struct rockchip_crtc_state *vcstate = ++ kzalloc(sizeof(*vcstate), GFP_KERNEL); ++ ++ if (crtc->state) ++ vop2_crtc_destroy_state(crtc, crtc->state); ++ ++ if (vcstate) ++ __drm_atomic_helper_crtc_reset(crtc, &vcstate->base); ++ else ++ __drm_atomic_helper_crtc_reset(crtc, NULL); ++} ++ + static const struct drm_crtc_funcs vop2_crtc_funcs = { + .set_config = drm_atomic_helper_set_config, + .page_flip = drm_atomic_helper_page_flip, +-- +2.42.0 + diff --git a/queue-6.6/drm-rockchip-vop2-don-t-crash-for-invalid-duplicate_.patch b/queue-6.6/drm-rockchip-vop2-don-t-crash-for-invalid-duplicate_.patch new file mode 100644 index 00000000000..c9ded165c9f --- /dev/null +++ b/queue-6.6/drm-rockchip-vop2-don-t-crash-for-invalid-duplicate_.patch @@ -0,0 +1,48 @@ +From 83fdb1898f163f030cfaec9a196d14bea8a76a76 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Jun 2023 22:33:21 +0000 +Subject: drm/rockchip: vop2: Don't crash for invalid duplicate_state + +From: Jonas Karlman + +[ Upstream commit 342f7e4967d02b0ec263b15916304fc54841b608 ] + +It's possible for users to try to duplicate the CRTC state even when the +state doesn't exist. drm_atomic_helper_crtc_duplicate_state() (and other +users of __drm_atomic_helper_crtc_duplicate_state()) already guard this +with a WARN_ON() instead of crashing, so let's do that here too. + +Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver") +Signed-off-by: Jonas Karlman +Reviewed-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20230621223311.2239547-5-jonas@kwiboo.se +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +index 583df4d22f7e9..d843c19c146db 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -2098,11 +2098,13 @@ static void vop2_crtc_reset(struct drm_crtc *crtc) + + static struct drm_crtc_state *vop2_crtc_duplicate_state(struct drm_crtc *crtc) + { +- struct rockchip_crtc_state *vcstate, *old_vcstate; ++ struct rockchip_crtc_state *vcstate; + +- old_vcstate = to_rockchip_crtc_state(crtc->state); ++ if (WARN_ON(!crtc->state)) ++ return NULL; + +- vcstate = kmemdup(old_vcstate, sizeof(*old_vcstate), GFP_KERNEL); ++ vcstate = kmemdup(to_rockchip_crtc_state(crtc->state), ++ sizeof(*vcstate), GFP_KERNEL); + if (!vcstate) + return NULL; + +-- +2.42.0 + diff --git a/queue-6.6/drm-ssd130x-fix-screen-clearing.patch b/queue-6.6/drm-ssd130x-fix-screen-clearing.patch new file mode 100644 index 00000000000..8ae4077b380 --- /dev/null +++ b/queue-6.6/drm-ssd130x-fix-screen-clearing.patch @@ -0,0 +1,89 @@ +From a9371e0639c72717926fb4d6a120c106b1b86667 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Aug 2023 17:08:40 +0200 +Subject: drm/ssd130x: Fix screen clearing + +From: Geert Uytterhoeven + +[ Upstream commit 4dbce3d6fea59e1df1d1a35aacea0c186f72107a ] + +Due to the reuse of buffers, ssd130x_clear_screen() no longers clears +the screen, but merely redraws the last image that is residing in the +intermediate buffer. + +As there is no point in clearing the intermediate buffer and transposing +an all-black image, fix this by just clearing the HW format buffer, and +writing it to the panel. + +Fixes: 49d7d581ceaf4cf8 ("drm/ssd130x: Don't allocate buffers on each plane update") +Signed-off-by: Geert Uytterhoeven +Reviewed-by: Javier Martinez Canillas +Tested-by: Javier Martinez Canillas +Signed-off-by: Javier Martinez Canillas +Link: https://patchwork.freedesktop.org/patch/msgid/c19cd5a57205597bb38a446c3871092993498f01.1692888745.git.geert@linux-m68k.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/solomon/ssd130x.c | 47 +++++++++++++++++++++++++------ + 1 file changed, 39 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c +index 5a80b228d18ca..78272b1f9d5b1 100644 +--- a/drivers/gpu/drm/solomon/ssd130x.c ++++ b/drivers/gpu/drm/solomon/ssd130x.c +@@ -553,14 +553,45 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, + static void ssd130x_clear_screen(struct ssd130x_device *ssd130x, + struct ssd130x_plane_state *ssd130x_state) + { +- struct drm_rect fullscreen = { +- .x1 = 0, +- .x2 = ssd130x->width, +- .y1 = 0, +- .y2 = ssd130x->height, +- }; +- +- ssd130x_update_rect(ssd130x, ssd130x_state, &fullscreen); ++ unsigned int page_height = ssd130x->device_info->page_height; ++ unsigned int pages = DIV_ROUND_UP(ssd130x->height, page_height); ++ u8 *data_array = ssd130x_state->data_array; ++ unsigned int width = ssd130x->width; ++ int ret, i; ++ ++ if (!ssd130x->page_address_mode) { ++ memset(data_array, 0, width * pages); ++ ++ /* Set address range for horizontal addressing mode */ ++ ret = ssd130x_set_col_range(ssd130x, ssd130x->col_offset, width); ++ if (ret < 0) ++ return; ++ ++ ret = ssd130x_set_page_range(ssd130x, ssd130x->page_offset, pages); ++ if (ret < 0) ++ return; ++ ++ /* Write out update in one go if we aren't using page addressing mode */ ++ ssd130x_write_data(ssd130x, data_array, width * pages); ++ } else { ++ /* ++ * In page addressing mode, the start address needs to be reset, ++ * and each page then needs to be written out separately. ++ */ ++ memset(data_array, 0, width); ++ ++ for (i = 0; i < pages; i++) { ++ ret = ssd130x_set_page_pos(ssd130x, ++ ssd130x->page_offset + i, ++ ssd130x->col_offset); ++ if (ret < 0) ++ return; ++ ++ ret = ssd130x_write_data(ssd130x, data_array, width); ++ if (ret < 0) ++ return; ++ } ++ } + } + + static int ssd130x_fb_blit_rect(struct drm_plane_state *state, +-- +2.42.0 + diff --git a/queue-6.6/dt-bindings-mfd-mt6397-split-out-compatible-for-medi.patch b/queue-6.6/dt-bindings-mfd-mt6397-split-out-compatible-for-medi.patch new file mode 100644 index 00000000000..773efc24636 --- /dev/null +++ b/queue-6.6/dt-bindings-mfd-mt6397-split-out-compatible-for-medi.patch @@ -0,0 +1,58 @@ +From d87b8a3f800d609113b7066a62087b68f7cc3bd5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Sep 2023 16:55:24 +0800 +Subject: dt-bindings: mfd: mt6397: Split out compatible for MediaTek MT6366 + PMIC + +From: Chen-Yu Tsai + +[ Upstream commit 61fdd1f1d2c183ec256527d16d75e75c3582af82 ] + +The MT6366 PMIC is mostly, but not fully, compatible with MT6358. It has +a different set of regulators. Specifically, it lacks the camera related +VCAM* LDOs and VLDO28, but has additional VM18, VMDDR, and VSRAM_CORE LDOs. + +The PMICs contain a chip ID register that can be used to detect which +exact model is preset, so it is possible to share a common base +compatible string. + +Add a separate compatible for the MT6366 PMIC, with a fallback to the +MT6358 PMIC. + +Fixes: 49be16305587 ("dt-bindings: mfd: Add compatible for the MediaTek MT6366 PMIC") +Signed-off-by: Chen-Yu Tsai +Acked-by: Krzysztof Kozlowski +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230928085537.3246669-2-wenst@chromium.org +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + Documentation/devicetree/bindings/mfd/mt6397.txt | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt +index 294693a8906cf..10540aa7afa1a 100644 +--- a/Documentation/devicetree/bindings/mfd/mt6397.txt ++++ b/Documentation/devicetree/bindings/mfd/mt6397.txt +@@ -22,8 +22,9 @@ compatible: + "mediatek,mt6323" for PMIC MT6323 + "mediatek,mt6331" for PMIC MT6331 and MT6332 + "mediatek,mt6357" for PMIC MT6357 +- "mediatek,mt6358" for PMIC MT6358 and MT6366 ++ "mediatek,mt6358" for PMIC MT6358 + "mediatek,mt6359" for PMIC MT6359 ++ "mediatek,mt6366", "mediatek,mt6358" for PMIC MT6366 + "mediatek,mt6397" for PMIC MT6397 + + Optional subnodes: +@@ -40,6 +41,7 @@ Optional subnodes: + - compatible: "mediatek,mt6323-regulator" + see ../regulator/mt6323-regulator.txt + - compatible: "mediatek,mt6358-regulator" ++ - compatible: "mediatek,mt6366-regulator", "mediatek-mt6358-regulator" + see ../regulator/mt6358-regulator.txt + - compatible: "mediatek,mt6397-regulator" + see ../regulator/mt6397-regulator.txt +-- +2.42.0 + diff --git a/queue-6.6/erofs-fix-erofs_insert_workgroup-lockref-usage.patch b/queue-6.6/erofs-fix-erofs_insert_workgroup-lockref-usage.patch new file mode 100644 index 00000000000..4107ddd6dc9 --- /dev/null +++ b/queue-6.6/erofs-fix-erofs_insert_workgroup-lockref-usage.patch @@ -0,0 +1,72 @@ +From b35e70d7cd38d94c192c755754565334098d3305 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Oct 2023 14:05:24 +0800 +Subject: erofs: fix erofs_insert_workgroup() lockref usage + +From: Gao Xiang + +[ Upstream commit 1a0ac8bd7a4fa5b2f4ef14c3b1e9d6e5a5faae06 ] + +As Linus pointed out [1], lockref_put_return() is fundamentally +designed to be something that can fail. It behaves as a fastpath-only +thing, and the failure case needs to be handled anyway. + +Actually, since the new pcluster was just allocated without being +populated, it won't be accessed by others until it is inserted into +XArray, so lockref helpers are actually unneeded here. + +Let's just set the proper reference count on initializing. + +[1] https://lore.kernel.org/r/CAHk-=whCga8BeQnJ3ZBh_Hfm9ctba_wpF444LpwRybVNMzO6Dw@mail.gmail.com + +Fixes: 7674a42f35ea ("erofs: use struct lockref to replace handcrafted approach") +Reviewed-by: Chao Yu +Link: https://lore.kernel.org/r/20231031060524.1103921-1-hsiangkao@linux.alibaba.com +Signed-off-by: Gao Xiang +Signed-off-by: Sasha Levin +--- + fs/erofs/utils.c | 8 +------- + fs/erofs/zdata.c | 1 + + 2 files changed, 2 insertions(+), 7 deletions(-) + +diff --git a/fs/erofs/utils.c b/fs/erofs/utils.c +index cc6fb9e988991..4256a85719a1d 100644 +--- a/fs/erofs/utils.c ++++ b/fs/erofs/utils.c +@@ -77,12 +77,7 @@ struct erofs_workgroup *erofs_insert_workgroup(struct super_block *sb, + struct erofs_sb_info *const sbi = EROFS_SB(sb); + struct erofs_workgroup *pre; + +- /* +- * Bump up before making this visible to others for the XArray in order +- * to avoid potential UAF without serialized by xa_lock. +- */ +- lockref_get(&grp->lockref); +- ++ DBG_BUGON(grp->lockref.count < 1); + repeat: + xa_lock(&sbi->managed_pslots); + pre = __xa_cmpxchg(&sbi->managed_pslots, grp->index, +@@ -96,7 +91,6 @@ struct erofs_workgroup *erofs_insert_workgroup(struct super_block *sb, + cond_resched(); + goto repeat; + } +- lockref_put_return(&grp->lockref); + grp = pre; + } + xa_unlock(&sbi->managed_pslots); +diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c +index 036f610e044b6..a7e6847f6f8f1 100644 +--- a/fs/erofs/zdata.c ++++ b/fs/erofs/zdata.c +@@ -796,6 +796,7 @@ static int z_erofs_register_pcluster(struct z_erofs_decompress_frontend *fe) + return PTR_ERR(pcl); + + spin_lock_init(&pcl->obj.lockref.lock); ++ pcl->obj.lockref.count = 1; /* one ref for this request */ + pcl->algorithmformat = map->m_algorithmformat; + pcl->length = 0; + pcl->partial = true; +-- +2.42.0 + diff --git a/queue-6.6/ext4-add-missing-initialization-of-call_notify_error.patch b/queue-6.6/ext4-add-missing-initialization-of-call_notify_error.patch new file mode 100644 index 00000000000..23e5c4e7230 --- /dev/null +++ b/queue-6.6/ext4-add-missing-initialization-of-call_notify_error.patch @@ -0,0 +1,34 @@ +From d61e45aba8ab7fdcefaee307df80f1c444061cae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Oct 2023 21:42:47 -0400 +Subject: ext4: add missing initialization of call_notify_error in + update_super_work() + +From: Theodore Ts'o + +[ Upstream commit ee6a12d0d4d85f3833d177cd382cd417f0ef011b ] + +Fixes: ff0722de896e ("ext4: add periodic superblock update check") +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/super.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index dbebd8b3127e5..6f48dec19f4a2 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -768,7 +768,8 @@ static void update_super_work(struct work_struct *work) + */ + if (!sb_rdonly(sbi->s_sb) && journal) { + struct buffer_head *sbh = sbi->s_sbh; +- bool call_notify_err; ++ bool call_notify_err = false; ++ + handle = jbd2_journal_start(journal, 1); + if (IS_ERR(handle)) + goto write_directly; +-- +2.42.0 + diff --git a/queue-6.6/ext4-move-ix-sanity-check-to-corrent-position.patch b/queue-6.6/ext4-move-ix-sanity-check-to-corrent-position.patch new file mode 100644 index 00000000000..c5ec7e19275 --- /dev/null +++ b/queue-6.6/ext4-move-ix-sanity-check-to-corrent-position.patch @@ -0,0 +1,51 @@ +From 72b4ac4914052d8b94ebf17cfb37c81f4d2ab75c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 09:33:41 +0800 +Subject: ext4: move 'ix' sanity check to corrent position + +From: Gou Hao + +[ Upstream commit af90a8f4a09ec4a3de20142e37f37205d4687f28 ] + +Check 'ix' before it is used. + +Fixes: 80e675f906db ("ext4: optimize memmmove lengths in extent/index insertions") +Signed-off-by: Gou Hao +Link: https://lore.kernel.org/r/20230906013341.7199-1-gouhao@uniontech.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/extents.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index 202c76996b621..4d8496d1a8ac4 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -1010,6 +1010,11 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode, + ix = curp->p_idx; + } + ++ if (unlikely(ix > EXT_MAX_INDEX(curp->p_hdr))) { ++ EXT4_ERROR_INODE(inode, "ix > EXT_MAX_INDEX!"); ++ return -EFSCORRUPTED; ++ } ++ + len = EXT_LAST_INDEX(curp->p_hdr) - ix + 1; + BUG_ON(len < 0); + if (len > 0) { +@@ -1019,11 +1024,6 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode, + memmove(ix + 1, ix, len * sizeof(struct ext4_extent_idx)); + } + +- if (unlikely(ix > EXT_MAX_INDEX(curp->p_hdr))) { +- EXT4_ERROR_INODE(inode, "ix > EXT_MAX_INDEX!"); +- return -EFSCORRUPTED; +- } +- + ix->ei_block = cpu_to_le32(logical); + ext4_idx_store_pblock(ix, ptr); + le16_add_cpu(&curp->p_hdr->eh_entries, 1); +-- +2.42.0 + diff --git a/queue-6.6/f2fs-compress-fix-deadloop-in-f2fs_write_cache_pages.patch b/queue-6.6/f2fs-compress-fix-deadloop-in-f2fs_write_cache_pages.patch new file mode 100644 index 00000000000..a493efa6339 --- /dev/null +++ b/queue-6.6/f2fs-compress-fix-deadloop-in-f2fs_write_cache_pages.patch @@ -0,0 +1,114 @@ +From 8d0498f760d050288d49e74f5d943854d6601efc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Aug 2023 22:04:14 +0800 +Subject: f2fs: compress: fix deadloop in f2fs_write_cache_pages() + +From: Chao Yu + +[ Upstream commit c5d3f9b7649abb20aa5ab3ebff9421a171eaeb22 ] + +With below mount option and testcase, it hangs kernel. + +1. mount -t f2fs -o compress_log_size=5 /dev/vdb /mnt/f2fs +2. touch /mnt/f2fs/file +3. chattr +c /mnt/f2fs/file +4. dd if=/dev/zero of=/mnt/f2fs/file bs=1MB count=1 +5. sync +6. dd if=/dev/zero of=/mnt/f2fs/file bs=111 count=11 conv=notrunc +7. sync + +INFO: task sync:4788 blocked for more than 120 seconds. + Not tainted 6.5.0-rc1+ #322 +"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +task:sync state:D stack:0 pid:4788 ppid:509 flags:0x00000002 +Call Trace: + + __schedule+0x335/0xf80 + schedule+0x6f/0xf0 + wb_wait_for_completion+0x5e/0x90 + sync_inodes_sb+0xd8/0x2a0 + sync_inodes_one_sb+0x1d/0x30 + iterate_supers+0x99/0xf0 + ksys_sync+0x46/0xb0 + __do_sys_sync+0x12/0x20 + do_syscall_64+0x3f/0x90 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +The reason is f2fs_all_cluster_page_ready() assumes that pages array should +cover at least one cluster, otherwise, it will always return false, result +in deadloop. + +By default, pages array size is 16, and it can cover the case cluster_size +is equal or less than 16, for the case cluster_size is larger than 16, let's +allocate memory of pages array dynamically. + +Fixes: 4c8ff7095bef ("f2fs: support data compression") +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/data.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c +index 916e317ac925f..3f33e14dc7f81 100644 +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -3023,7 +3023,8 @@ static int f2fs_write_cache_pages(struct address_space *mapping, + { + int ret = 0; + int done = 0, retry = 0; +- struct page *pages[F2FS_ONSTACK_PAGES]; ++ struct page *pages_local[F2FS_ONSTACK_PAGES]; ++ struct page **pages = pages_local; + struct folio_batch fbatch; + struct f2fs_sb_info *sbi = F2FS_M_SB(mapping); + struct bio *bio = NULL; +@@ -3047,6 +3048,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping, + #endif + int nr_folios, p, idx; + int nr_pages; ++ unsigned int max_pages = F2FS_ONSTACK_PAGES; + pgoff_t index; + pgoff_t end; /* Inclusive */ + pgoff_t done_index; +@@ -3056,6 +3058,15 @@ static int f2fs_write_cache_pages(struct address_space *mapping, + int submitted = 0; + int i; + ++#ifdef CONFIG_F2FS_FS_COMPRESSION ++ if (f2fs_compressed_file(inode) && ++ 1 << cc.log_cluster_size > F2FS_ONSTACK_PAGES) { ++ pages = f2fs_kzalloc(sbi, sizeof(struct page *) << ++ cc.log_cluster_size, GFP_NOFS | __GFP_NOFAIL); ++ max_pages = 1 << cc.log_cluster_size; ++ } ++#endif ++ + folio_batch_init(&fbatch); + + if (get_dirty_pages(mapping->host) <= +@@ -3101,7 +3112,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping, + add_more: + pages[nr_pages] = folio_page(folio, idx); + folio_get(folio); +- if (++nr_pages == F2FS_ONSTACK_PAGES) { ++ if (++nr_pages == max_pages) { + index = folio->index + idx + 1; + folio_batch_release(&fbatch); + goto write; +@@ -3283,6 +3294,11 @@ static int f2fs_write_cache_pages(struct address_space *mapping, + if (bio) + f2fs_submit_merged_ipu_write(sbi, &bio, NULL); + ++#ifdef CONFIG_F2FS_FS_COMPRESSION ++ if (pages != pages_local) ++ kfree(pages); ++#endif ++ + return ret; + } + +-- +2.42.0 + diff --git a/queue-6.6/f2fs-compress-fix-to-avoid-redundant-compress-extens.patch b/queue-6.6/f2fs-compress-fix-to-avoid-redundant-compress-extens.patch new file mode 100644 index 00000000000..dffdbaa7e7f --- /dev/null +++ b/queue-6.6/f2fs-compress-fix-to-avoid-redundant-compress-extens.patch @@ -0,0 +1,89 @@ +From 63fc483fcef23f2b1d49a39f9ae83d78076cb924 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Aug 2023 22:04:17 +0800 +Subject: f2fs: compress: fix to avoid redundant compress extension + +From: Chao Yu + +[ Upstream commit 7e1b150fece033703a824df1bbc03df091ea53cc ] + +With below script, redundant compress extension will be parsed and added +by parse_options(), because parse_options() doesn't check whether the +extension is existed or not, fix it. + +1. mount -t f2fs -o compress_extension=so /dev/vdb /mnt/f2fs +2. mount -t f2fs -o remount,compress_extension=so /mnt/f2fs +3. mount|grep f2fs + +/dev/vdb on /mnt/f2fs type f2fs (...,compress_extension=so,compress_extension=so,...) + +Fixes: 4c8ff7095bef ("f2fs: support data compression") +Fixes: 151b1982be5d ("f2fs: compress: add nocompress extensions support") +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/super.c | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c +index a8c8232852bb1..12790bc6e0739 100644 +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -547,6 +547,29 @@ static int f2fs_set_test_dummy_encryption(struct super_block *sb, + } + + #ifdef CONFIG_F2FS_FS_COMPRESSION ++static bool is_compress_extension_exist(struct f2fs_sb_info *sbi, ++ const char *new_ext, bool is_ext) ++{ ++ unsigned char (*ext)[F2FS_EXTENSION_LEN]; ++ int ext_cnt; ++ int i; ++ ++ if (is_ext) { ++ ext = F2FS_OPTION(sbi).extensions; ++ ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; ++ } else { ++ ext = F2FS_OPTION(sbi).noextensions; ++ ext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; ++ } ++ ++ for (i = 0; i < ext_cnt; i++) { ++ if (!strcasecmp(new_ext, ext[i])) ++ return true; ++ } ++ ++ return false; ++} ++ + /* + * 1. The same extension name cannot not appear in both compress and non-compress extension + * at the same time. +@@ -1149,6 +1172,11 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) + return -EINVAL; + } + ++ if (is_compress_extension_exist(sbi, name, true)) { ++ kfree(name); ++ break; ++ } ++ + strcpy(ext[ext_cnt], name); + F2FS_OPTION(sbi).compress_ext_cnt++; + kfree(name); +@@ -1173,6 +1201,11 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) + return -EINVAL; + } + ++ if (is_compress_extension_exist(sbi, name, false)) { ++ kfree(name); ++ break; ++ } ++ + strcpy(noext[noext_cnt], name); + F2FS_OPTION(sbi).nocompress_ext_cnt++; + kfree(name); +-- +2.42.0 + diff --git a/queue-6.6/f2fs-compress-fix-to-avoid-use-after-free-on-dic.patch b/queue-6.6/f2fs-compress-fix-to-avoid-use-after-free-on-dic.patch new file mode 100644 index 00000000000..0f5df148650 --- /dev/null +++ b/queue-6.6/f2fs-compress-fix-to-avoid-use-after-free-on-dic.patch @@ -0,0 +1,57 @@ +From 776d288c1ee24908d60507e549de1044dbc0bd79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Aug 2023 22:04:15 +0800 +Subject: f2fs: compress: fix to avoid use-after-free on dic + +From: Chao Yu + +[ Upstream commit b0327c84e91a0f4f0abced8cb83ec86a7083f086 ] + +Call trace: + __memcpy+0x128/0x250 + f2fs_read_multi_pages+0x940/0xf7c + f2fs_mpage_readpages+0x5a8/0x624 + f2fs_readahead+0x5c/0x110 + page_cache_ra_unbounded+0x1b8/0x590 + do_sync_mmap_readahead+0x1dc/0x2e4 + filemap_fault+0x254/0xa8c + f2fs_filemap_fault+0x2c/0x104 + __do_fault+0x7c/0x238 + do_handle_mm_fault+0x11bc/0x2d14 + do_mem_abort+0x3a8/0x1004 + el0_da+0x3c/0xa0 + el0t_64_sync_handler+0xc4/0xec + el0t_64_sync+0x1b4/0x1b8 + +In f2fs_read_multi_pages(), once f2fs_decompress_cluster() was called if +we hit cached page in compress_inode's cache, dic may be released, it needs +break the loop rather than continuing it, in order to avoid accessing +invalid dic pointer. + +Fixes: 6ce19aff0b8c ("f2fs: compress: add compress_inode to cache compressed blocks") +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/data.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c +index 3f33e14dc7f81..1ac34eb49a0e8 100644 +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -2344,8 +2344,10 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, + f2fs_wait_on_block_writeback(inode, blkaddr); + + if (f2fs_load_compressed_page(sbi, page, blkaddr)) { +- if (atomic_dec_and_test(&dic->remaining_pages)) ++ if (atomic_dec_and_test(&dic->remaining_pages)) { + f2fs_decompress_cluster(dic, true); ++ break; ++ } + continue; + } + +-- +2.42.0 + diff --git a/queue-6.6/f2fs-fix-to-drop-meta_inode-s-page-cache-in-f2fs_put.patch b/queue-6.6/f2fs-fix-to-drop-meta_inode-s-page-cache-in-f2fs_put.patch new file mode 100644 index 00000000000..3886f6e5d7f --- /dev/null +++ b/queue-6.6/f2fs-fix-to-drop-meta_inode-s-page-cache-in-f2fs_put.patch @@ -0,0 +1,65 @@ +From 3880a6f9f34f01e52e73411d6c748768f5d9ca7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Sep 2023 12:57:53 +0800 +Subject: f2fs: fix to drop meta_inode's page cache in f2fs_put_super() + +From: Chao Yu + +[ Upstream commit a4639380bbe66172df329f8b54aa7d2e943f0f64 ] + +syzbot reports a kernel bug as below: + +F2FS-fs (loop1): detect filesystem reference count leak during umount, type: 10, count: 1 +kernel BUG at fs/f2fs/super.c:1639! +CPU: 0 PID: 15451 Comm: syz-executor.1 Not tainted 6.5.0-syzkaller-09338-ge0152e7481c6 #0 +RIP: 0010:f2fs_put_super+0xce1/0xed0 fs/f2fs/super.c:1639 +Call Trace: + generic_shutdown_super+0x161/0x3c0 fs/super.c:693 + kill_block_super+0x3b/0x70 fs/super.c:1646 + kill_f2fs_super+0x2b7/0x3d0 fs/f2fs/super.c:4879 + deactivate_locked_super+0x9a/0x170 fs/super.c:481 + deactivate_super+0xde/0x100 fs/super.c:514 + cleanup_mnt+0x222/0x3d0 fs/namespace.c:1254 + task_work_run+0x14d/0x240 kernel/task_work.c:179 + resume_user_mode_work include/linux/resume_user_mode.h:49 [inline] + exit_to_user_mode_loop kernel/entry/common.c:171 [inline] + exit_to_user_mode_prepare+0x210/0x240 kernel/entry/common.c:204 + __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] + syscall_exit_to_user_mode+0x1d/0x60 kernel/entry/common.c:296 + do_syscall_64+0x44/0xb0 arch/x86/entry/common.c:86 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + +In f2fs_put_super(), it tries to do sanity check on dirty and IO +reference count of f2fs, once there is any reference count leak, +it will trigger panic. + +The root case is, during f2fs_put_super(), if there is any IO error +in f2fs_wait_on_all_pages(), we missed to truncate meta_inode's page +cache later, result in panic, fix this case. + +Fixes: 20872584b8c0 ("f2fs: fix to drop all dirty meta/node pages during umount()") +Reported-by: syzbot+ebd7072191e2eddd7d6e@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/linux-f2fs-devel/000000000000a14f020604a62a98@google.com +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/super.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c +index 12790bc6e0739..bc303a0522155 100644 +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -1662,7 +1662,7 @@ static void f2fs_put_super(struct super_block *sb) + + f2fs_wait_on_all_pages(sbi, F2FS_WB_CP_DATA); + +- if (err) { ++ if (err || f2fs_cp_error(sbi)) { + truncate_inode_pages_final(NODE_MAPPING(sbi)); + truncate_inode_pages_final(META_MAPPING(sbi)); + } +-- +2.42.0 + diff --git a/queue-6.6/f2fs-fix-to-initialize-map.m_pblk-in-f2fs_precache_e.patch b/queue-6.6/f2fs-fix-to-initialize-map.m_pblk-in-f2fs_precache_e.patch new file mode 100644 index 00000000000..529a1ed1fe2 --- /dev/null +++ b/queue-6.6/f2fs-fix-to-initialize-map.m_pblk-in-f2fs_precache_e.patch @@ -0,0 +1,37 @@ +From 48e06b4795558164fad239e7f495d17ca42f82ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Oct 2023 15:45:52 +0800 +Subject: f2fs: fix to initialize map.m_pblk in f2fs_precache_extents() + +From: Chao Yu + +[ Upstream commit 8b07c1fb0f1ad139373c8253f2fad8bc43fab07d ] + +Otherwise, it may print random physical block address in tracepoint +of f2fs_map_blocks() as below: + +f2fs_map_blocks: dev = (253,16), ino = 2297, file offset = 0, start blkaddr = 0xa356c421, len = 0x0, flags = 0 + +Fixes: c4020b2da4c9 ("f2fs: support F2FS_IOC_PRECACHE_EXTENTS") +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/file.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c +index ca5904129b162..d034703eb323a 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -3258,6 +3258,7 @@ int f2fs_precache_extents(struct inode *inode) + return -EOPNOTSUPP; + + map.m_lblk = 0; ++ map.m_pblk = 0; + map.m_next_pgofs = NULL; + map.m_next_extent = &m_next_extent; + map.m_seg_type = NO_CHECK_TYPE; +-- +2.42.0 + diff --git a/queue-6.6/firmware-arm_ffa-allow-the-ff-a-drivers-to-use-32bit.patch b/queue-6.6/firmware-arm_ffa-allow-the-ff-a-drivers-to-use-32bit.patch new file mode 100644 index 00000000000..989c11e4c83 --- /dev/null +++ b/queue-6.6/firmware-arm_ffa-allow-the-ff-a-drivers-to-use-32bit.patch @@ -0,0 +1,66 @@ +From aa0a884c03a834ff75948cd8589d92c72165969f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Oct 2023 15:28:23 +0100 +Subject: firmware: arm_ffa: Allow the FF-A drivers to use 32bit mode of + messaging + +From: Sudeep Holla + +[ Upstream commit 2d698e8b4fd22374dac0a2d5150ab24d57a222ab ] + +An FF-A ABI could support both the SMC32 and SMC64 conventions. +A callee that runs in the AArch64 execution state and implements such +an ABI must implement both SMC32 and SMC64 conventions of the ABI. + +So the FF-A drivers will need the option to choose the mode irrespective +of FF-A version and the partition execution mode flag in the partition +information. + +Let us remove the check on the FF-A version for allowing the selection +of 32bit mode of messaging. The driver will continue to set the 32-bit +mode if the partition execution mode flag specified that the partition +supports only 32-bit execution. + +Fixes: 106b11b1ccd5 ("firmware: arm_ffa: Set up 32bit execution mode flag using partiion property") +Link: https://lore.kernel.org/r/20231005142823.278121-1-sudeep.holla@arm.com +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_ffa/driver.c | 12 ++---------- + 1 file changed, 2 insertions(+), 10 deletions(-) + +diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c +index 121f4fc903cd5..7cd6b1564e801 100644 +--- a/drivers/firmware/arm_ffa/driver.c ++++ b/drivers/firmware/arm_ffa/driver.c +@@ -587,17 +587,9 @@ static int ffa_partition_info_get(const char *uuid_str, + return 0; + } + +-static void _ffa_mode_32bit_set(struct ffa_device *dev) +-{ +- dev->mode_32bit = true; +-} +- + static void ffa_mode_32bit_set(struct ffa_device *dev) + { +- if (drv_info->version > FFA_VERSION_1_0) +- return; +- +- _ffa_mode_32bit_set(dev); ++ dev->mode_32bit = true; + } + + static int ffa_sync_send_receive(struct ffa_device *dev, +@@ -706,7 +698,7 @@ static void ffa_setup_partitions(void) + + if (drv_info->version > FFA_VERSION_1_0 && + !(tpbuf->properties & FFA_PARTITION_AARCH64_EXEC)) +- _ffa_mode_32bit_set(ffa_dev); ++ ffa_mode_32bit_set(ffa_dev); + } + kfree(pbuf); + } +-- +2.42.0 + diff --git a/queue-6.6/firmware-arm_ffa-assign-the-missing-idr-allocation-i.patch b/queue-6.6/firmware-arm_ffa-assign-the-missing-idr-allocation-i.patch new file mode 100644 index 00000000000..e8c8b5db264 --- /dev/null +++ b/queue-6.6/firmware-arm_ffa-assign-the-missing-idr-allocation-i.patch @@ -0,0 +1,70 @@ +From 2a66977135f500f49d51d58aec0f4d7731d35130 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Oct 2023 09:59:32 +0100 +Subject: firmware: arm_ffa: Assign the missing IDR allocation ID to the FFA + device + +From: Sudeep Holla + +[ Upstream commit 7d0bc6360f17ea323ab25939a34857123d7d87e5 ] + +Commit 19b8766459c4 ("firmware: arm_ffa: Fix FFA device names for logical +partitions") added an ID to the FFA device using ida_alloc() and append +the same to "arm-ffa" to make up a unique device name. However it missed +to stash the id value in ffa_dev to help freeing the ID later when the +device is destroyed. + +Due to the missing/unassigned ID in FFA device, we get the following +warning when the FF-A device is unregistered. + + | ida_free called for id=0 which is not allocated. + | WARNING: CPU: 7 PID: 1 at lib/idr.c:525 ida_free+0x114/0x164 + | CPU: 7 PID: 1 Comm: swapper/0 Not tainted 6.6.0-rc4 #209 + | pstate: 61400009 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--) + | pc : ida_free+0x114/0x164 + | lr : ida_free+0x114/0x164 + | Call trace: + | ida_free+0x114/0x164 + | ffa_release_device+0x24/0x3c + | device_release+0x34/0x8c + | kobject_put+0x94/0xf8 + | put_device+0x18/0x24 + | klist_devices_put+0x14/0x20 + | klist_next+0xc8/0x114 + | bus_for_each_dev+0xd8/0x144 + | arm_ffa_bus_exit+0x30/0x54 + | ffa_init+0x68/0x330 + | do_one_initcall+0xdc/0x250 + | do_initcall_level+0x8c/0xac + | do_initcalls+0x54/0x94 + | do_basic_setup+0x1c/0x28 + | kernel_init_freeable+0x104/0x170 + | kernel_init+0x20/0x1a0 + | ret_from_fork+0x10/0x20 + +Fix the same by actually assigning the ID in the FFA device this time +for real. + +Fixes: 19b8766459c4 ("firmware: arm_ffa: Fix FFA device names for logical partitions") +Link: https://lore.kernel.org/r/20231003085932.3553985-1-sudeep.holla@arm.com +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_ffa/bus.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c +index 2b8bfcd010f5f..7865438b36960 100644 +--- a/drivers/firmware/arm_ffa/bus.c ++++ b/drivers/firmware/arm_ffa/bus.c +@@ -193,6 +193,7 @@ struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id, + dev->release = ffa_release_device; + dev_set_name(&ffa_dev->dev, "arm-ffa-%d", id); + ++ ffa_dev->id = id; + ffa_dev->vm_id = vm_id; + ffa_dev->ops = ops; + uuid_copy(&ffa_dev->uuid, uuid); +-- +2.42.0 + diff --git a/queue-6.6/firmware-tegra-add-suspend-hook-and-reset-bpmp-ipc-e.patch b/queue-6.6/firmware-tegra-add-suspend-hook-and-reset-bpmp-ipc-e.patch new file mode 100644 index 00000000000..85a4ee0cdbc --- /dev/null +++ b/queue-6.6/firmware-tegra-add-suspend-hook-and-reset-bpmp-ipc-e.patch @@ -0,0 +1,140 @@ +From ff7d0f1669f461a3deefa64dac2b9254f5c5974c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 15:35:56 +0530 +Subject: firmware: tegra: Add suspend hook and reset BPMP IPC early on resume + +From: Sumit Gupta + +[ Upstream commit ea608a01d4ee66f8b51070e623f9adb8684c0dd4 ] + +Add suspend hook and a 'suspended' field in the 'struct tegra_bpmp' +to mark if BPMP is suspended. Also, add a 'flags' field in the +'struct tegra_bpmp_message' whose 'TEGRA_BPMP_MESSAGE_RESET' bit can be +set from the Tegra MC driver to signal that the reset of BPMP IPC +channels is required before sending MRQ to the BPMP FW. Together both +the fields allow us to handle any requests that might be sent too soon +as they can cause hang during system resume. + +One case where we see BPMP requests being sent before the BPMP driver +has resumed is the memory bandwidth requests which are triggered by +onlining the CPUs during system resume. The CPUs are onlined before the +BPMP has resumed and we need to reset the BPMP IPC channels to handle +these requests. + +The additional check for 'flags' is done to avoid any un-intended BPMP +IPC reset if the tegra_bpmp_transfer*() API gets called during suspend +sequence after the BPMP driver is suspended. + +Fixes: f41e1442ac5b ("cpufreq: tegra194: add OPP support and set bandwidth") +Co-developed-by: Thierry Reding +Signed-off-by: Sumit Gupta +Acked-by: Thierry Reding +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + drivers/firmware/tegra/bpmp.c | 30 ++++++++++++++++++++++++++++++ + include/soc/tegra/bpmp.h | 6 ++++++ + 2 files changed, 36 insertions(+) + +diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c +index 51d062e0c3f12..c1590d3aa9cb7 100644 +--- a/drivers/firmware/tegra/bpmp.c ++++ b/drivers/firmware/tegra/bpmp.c +@@ -313,6 +313,8 @@ static ssize_t tegra_bpmp_channel_write(struct tegra_bpmp_channel *channel, + return __tegra_bpmp_channel_write(channel, mrq, flags, data, size); + } + ++static int __maybe_unused tegra_bpmp_resume(struct device *dev); ++ + int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp, + struct tegra_bpmp_message *msg) + { +@@ -325,6 +327,14 @@ int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp, + if (!tegra_bpmp_message_valid(msg)) + return -EINVAL; + ++ if (bpmp->suspended) { ++ /* Reset BPMP IPC channels during resume based on flags passed */ ++ if (msg->flags & TEGRA_BPMP_MESSAGE_RESET) ++ tegra_bpmp_resume(bpmp->dev); ++ else ++ return -EAGAIN; ++ } ++ + channel = bpmp->tx_channel; + + spin_lock(&bpmp->atomic_tx_lock); +@@ -364,6 +374,14 @@ int tegra_bpmp_transfer(struct tegra_bpmp *bpmp, + if (!tegra_bpmp_message_valid(msg)) + return -EINVAL; + ++ if (bpmp->suspended) { ++ /* Reset BPMP IPC channels during resume based on flags passed */ ++ if (msg->flags & TEGRA_BPMP_MESSAGE_RESET) ++ tegra_bpmp_resume(bpmp->dev); ++ else ++ return -EAGAIN; ++ } ++ + channel = tegra_bpmp_write_threaded(bpmp, msg->mrq, msg->tx.data, + msg->tx.size); + if (IS_ERR(channel)) +@@ -796,10 +814,21 @@ static int tegra_bpmp_probe(struct platform_device *pdev) + return err; + } + ++static int __maybe_unused tegra_bpmp_suspend(struct device *dev) ++{ ++ struct tegra_bpmp *bpmp = dev_get_drvdata(dev); ++ ++ bpmp->suspended = true; ++ ++ return 0; ++} ++ + static int __maybe_unused tegra_bpmp_resume(struct device *dev) + { + struct tegra_bpmp *bpmp = dev_get_drvdata(dev); + ++ bpmp->suspended = false; ++ + if (bpmp->soc->ops->resume) + return bpmp->soc->ops->resume(bpmp); + else +@@ -807,6 +836,7 @@ static int __maybe_unused tegra_bpmp_resume(struct device *dev) + } + + static const struct dev_pm_ops tegra_bpmp_pm_ops = { ++ .suspend_noirq = tegra_bpmp_suspend, + .resume_noirq = tegra_bpmp_resume, + }; + +diff --git a/include/soc/tegra/bpmp.h b/include/soc/tegra/bpmp.h +index 5842e38bb2880..f5e4ac5b8cce8 100644 +--- a/include/soc/tegra/bpmp.h ++++ b/include/soc/tegra/bpmp.h +@@ -102,8 +102,12 @@ struct tegra_bpmp { + #ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_mirror; + #endif ++ ++ bool suspended; + }; + ++#define TEGRA_BPMP_MESSAGE_RESET BIT(0) ++ + struct tegra_bpmp_message { + unsigned int mrq; + +@@ -117,6 +121,8 @@ struct tegra_bpmp_message { + size_t size; + int ret; + } rx; ++ ++ unsigned long flags; + }; + + #if IS_ENABLED(CONFIG_TEGRA_BPMP) +-- +2.42.0 + diff --git a/queue-6.6/firmware-ti_sci-mark-driver-as-non-removable.patch b/queue-6.6/firmware-ti_sci-mark-driver-as-non-removable.patch new file mode 100644 index 00000000000..e38f24fa670 --- /dev/null +++ b/queue-6.6/firmware-ti_sci-mark-driver-as-non-removable.patch @@ -0,0 +1,113 @@ +From e94efde7919e8b984a83c1c64a96334b5a35b699 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 14:40:26 +0530 +Subject: firmware: ti_sci: Mark driver as non removable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Dhruva Gole + +[ Upstream commit 7b7a224b1ba1703583b25a3641ad9798f34d832a ] + +The TI-SCI message protocol provides a way to communicate between +various compute processors with a central system controller entity. It +provides the fundamental device management capability and clock control +in the SOCs that it's used in. + +The remove function failed to do all the necessary cleanup if +there are registered users. Some things are freed however which +likely results in an oops later on. + +Ensure that the driver isn't unbound by suppressing its bind and unbind +sysfs attributes. As the driver is built-in there is no way to remove +device once bound. + +We can also remove the ti_sci_remove call along with the +ti_sci_debugfs_destroy as there are no callers for it any longer. + +Fixes: aa276781a64a ("firmware: Add basic support for TI System Control Interface (TI-SCI) protocol") +Reported-by: Uwe Kleine-König +Closes: https://lore.kernel.org/linux-arm-kernel/20230216083908.mvmydic5lpi3ogo7@pengutronix.de/ +Suggested-by: Uwe Kleine-König +Acked-by: Uwe Kleine-König +Signed-off-by: Dhruva Gole +Link: https://lore.kernel.org/r/20230921091025.133130-1-d-gole@ti.com +Signed-off-by: Nishanth Menon +Signed-off-by: Sasha Levin +--- + drivers/firmware/ti_sci.c | 46 +-------------------------------------- + 1 file changed, 1 insertion(+), 45 deletions(-) + +diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c +index 26a37f47f4ca5..66c3846c91476 100644 +--- a/drivers/firmware/ti_sci.c ++++ b/drivers/firmware/ti_sci.c +@@ -190,19 +190,6 @@ static int ti_sci_debugfs_create(struct platform_device *pdev, + return 0; + } + +-/** +- * ti_sci_debugfs_destroy() - clean up log debug file +- * @pdev: platform device pointer +- * @info: Pointer to SCI entity information +- */ +-static void ti_sci_debugfs_destroy(struct platform_device *pdev, +- struct ti_sci_info *info) +-{ +- if (IS_ERR(info->debug_region)) +- return; +- +- debugfs_remove(info->d); +-} + #else /* CONFIG_DEBUG_FS */ + static inline int ti_sci_debugfs_create(struct platform_device *dev, + struct ti_sci_info *info) +@@ -3449,43 +3436,12 @@ static int ti_sci_probe(struct platform_device *pdev) + return ret; + } + +-static int ti_sci_remove(struct platform_device *pdev) +-{ +- struct ti_sci_info *info; +- struct device *dev = &pdev->dev; +- int ret = 0; +- +- of_platform_depopulate(dev); +- +- info = platform_get_drvdata(pdev); +- +- if (info->nb.notifier_call) +- unregister_restart_handler(&info->nb); +- +- mutex_lock(&ti_sci_list_mutex); +- if (info->users) +- ret = -EBUSY; +- else +- list_del(&info->node); +- mutex_unlock(&ti_sci_list_mutex); +- +- if (!ret) { +- ti_sci_debugfs_destroy(pdev, info); +- +- /* Safe to free channels since no more users */ +- mbox_free_channel(info->chan_tx); +- mbox_free_channel(info->chan_rx); +- } +- +- return ret; +-} +- + static struct platform_driver ti_sci_driver = { + .probe = ti_sci_probe, +- .remove = ti_sci_remove, + .driver = { + .name = "ti-sci", + .of_match_table = of_match_ptr(ti_sci_of_match), ++ .suppress_bind_attrs = true, + }, + }; + module_platform_driver(ti_sci_driver); +-- +2.42.0 + diff --git a/queue-6.6/fs-dlm-fix-the-size-of-a-buffer-in-dlm_create_debug_.patch b/queue-6.6/fs-dlm-fix-the-size-of-a-buffer-in-dlm_create_debug_.patch new file mode 100644 index 00000000000..3c122a50207 --- /dev/null +++ b/queue-6.6/fs-dlm-fix-the-size-of-a-buffer-in-dlm_create_debug_.patch @@ -0,0 +1,59 @@ +From 9692f9ca3803c87836e738ca04fce78f75d55734 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 18:04:42 -0400 +Subject: fs: dlm: Fix the size of a buffer in dlm_create_debug_file() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Christophe JAILLET + +[ Upstream commit b859e01054354033f480d9df41b0ebc2c7537379 ] + +8 is not the maximum size of the suffix used when creating debugfs files. + +Let the compiler compute the correct size, and only give a hint about the +longest possible string that is used. + +When building with W=1, this fixes the following warnings: + + fs/dlm/debug_fs.c: In function ‘dlm_create_debug_file’: + fs/dlm/debug_fs.c:1020:58: error: ‘snprintf’ output may be truncated before the last format character [-Werror=format-truncation=] + 1020 | snprintf(name, DLM_LOCKSPACE_LEN + 8, "%s_waiters", ls->ls_name); + | ^ + fs/dlm/debug_fs.c:1020:9: note: ‘snprintf’ output between 9 and 73 bytes into a destination of size 72 + 1020 | snprintf(name, DLM_LOCKSPACE_LEN + 8, "%s_waiters", ls->ls_name); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + fs/dlm/debug_fs.c:1031:50: error: ‘_queued_asts’ directive output may be truncated writing 12 bytes into a region of size between 8 and 72 [-Werror=format-truncation=] + 1031 | snprintf(name, DLM_LOCKSPACE_LEN + 8, "%s_queued_asts", ls->ls_name); + | ^~~~~~~~~~~~ + fs/dlm/debug_fs.c:1031:9: note: ‘snprintf’ output between 13 and 77 bytes into a destination of size 72 + 1031 | snprintf(name, DLM_LOCKSPACE_LEN + 8, "%s_queued_asts", ls->ls_name); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Fixes: 541adb0d4d10b ("fs: dlm: debugfs for queued callbacks") +Signed-off-by: Christophe JAILLET +Signed-off-by: Alexander Aring +Signed-off-by: David Teigland +Signed-off-by: Sasha Levin +--- + fs/dlm/debug_fs.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c +index 5aabcb6f0f157..fc44ab6657cab 100644 +--- a/fs/dlm/debug_fs.c ++++ b/fs/dlm/debug_fs.c +@@ -973,7 +973,8 @@ void dlm_delete_debug_comms_file(void *ctx) + + void dlm_create_debug_file(struct dlm_ls *ls) + { +- char name[DLM_LOCKSPACE_LEN + 8]; ++ /* Reserve enough space for the longest file name */ ++ char name[DLM_LOCKSPACE_LEN + sizeof("_queued_asts")]; + + /* format 1 */ + +-- +2.42.0 + diff --git a/queue-6.6/futex-don-t-include-process-mm-in-futex-key-on-no-mm.patch b/queue-6.6/futex-don-t-include-process-mm-in-futex-key-on-no-mm.patch new file mode 100644 index 00000000000..b81d971b2d9 --- /dev/null +++ b/queue-6.6/futex-don-t-include-process-mm-in-futex-key-on-no-mm.patch @@ -0,0 +1,62 @@ +From 694b22e3419c65e7b189c8f495561bb82d8ae5d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Oct 2023 16:45:49 -0400 +Subject: futex: Don't include process MM in futex key on no-MMU +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ben Wolsieffer + +[ Upstream commit c73801ae4f22b390228ebf471d55668e824198b6 ] + +On no-MMU, all futexes are treated as private because there is no need +to map a virtual address to physical to match the futex across +processes. This doesn't quite work though, because private futexes +include the current process's mm_struct as part of their key. This makes +it impossible for one process to wake up a shared futex being waited on +in another process. + +Fix this bug by excluding the mm_struct from the key. With +a single address space, the futex address is already a unique key. + +Fixes: 784bdf3bb694 ("futex: Assume all mappings are private on !MMU systems") +Signed-off-by: Ben Wolsieffer +Signed-off-by: Ingo Molnar +Acked-by: Peter Zijlstra +Cc: Thomas Gleixner +Cc: Darren Hart +Cc: Davidlohr Bueso +Cc: André Almeida +Link: https://lore.kernel.org/r/20231019204548.1236437-2-ben.wolsieffer@hefring.com +Signed-off-by: Sasha Levin +--- + kernel/futex/core.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/kernel/futex/core.c b/kernel/futex/core.c +index f10587d1d4817..f30a93e50f65e 100644 +--- a/kernel/futex/core.c ++++ b/kernel/futex/core.c +@@ -248,7 +248,17 @@ int get_futex_key(u32 __user *uaddr, bool fshared, union futex_key *key, + * but access_ok() should be faster than find_vma() + */ + if (!fshared) { +- key->private.mm = mm; ++ /* ++ * On no-MMU, shared futexes are treated as private, therefore ++ * we must not include the current process in the key. Since ++ * there is only one address space, the address is a unique key ++ * on its own. ++ */ ++ if (IS_ENABLED(CONFIG_MMU)) ++ key->private.mm = mm; ++ else ++ key->private.mm = NULL; ++ + key->private.address = address; + return 0; + } +-- +2.42.0 + diff --git a/queue-6.6/genirq-matrix-exclude-managed-interrupts-in-irq_matr.patch b/queue-6.6/genirq-matrix-exclude-managed-interrupts-in-irq_matr.patch new file mode 100644 index 00000000000..6977c093984 --- /dev/null +++ b/queue-6.6/genirq-matrix-exclude-managed-interrupts-in-irq_matr.patch @@ -0,0 +1,73 @@ +From b85b59de79d08b66af6268cf645c766b9f947460 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 15:25:22 +0800 +Subject: genirq/matrix: Exclude managed interrupts in irq_matrix_allocated() + +From: Chen Yu + +[ Upstream commit a0b0bad10587ae2948a7c36ca4ffc206007fbcf3 ] + +When a CPU is about to be offlined, x86 validates that all active +interrupts which are targeted to this CPU can be migrated to the remaining +online CPUs. If not, the offline operation is aborted. + +The validation uses irq_matrix_allocated() to retrieve the number of +vectors which are allocated on the outgoing CPU. The returned number of +allocated vectors includes also vectors which are associated to managed +interrupts. + +That's overaccounting because managed interrupts are: + + - not migrated when the affinity mask of the interrupt targets only + the outgoing CPU + + - migrated to another CPU, but in that case the vector is already + pre-allocated on the potential target CPUs and must not be taken into + account. + +As a consequence the check whether the remaining online CPUs have enough +capacity for migrating the allocated vectors from the outgoing CPU might +fail incorrectly. + +Let irq_matrix_allocated() return only the number of allocated non-managed +interrupts to make this validation check correct. + +[ tglx: Amend changelog and fixup kernel-doc comment ] + +Fixes: 2f75d9e1c905 ("genirq: Implement bitmap matrix allocator") +Reported-by: Wendy Wang +Signed-off-by: Chen Yu +Signed-off-by: Thomas Gleixner +Link: https://lore.kernel.org/r/20231020072522.557846-1-yu.c.chen@intel.com +Signed-off-by: Sasha Levin +--- + kernel/irq/matrix.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c +index 1698e77645acf..75d0ae490e29c 100644 +--- a/kernel/irq/matrix.c ++++ b/kernel/irq/matrix.c +@@ -466,16 +466,16 @@ unsigned int irq_matrix_reserved(struct irq_matrix *m) + } + + /** +- * irq_matrix_allocated - Get the number of allocated irqs on the local cpu ++ * irq_matrix_allocated - Get the number of allocated non-managed irqs on the local CPU + * @m: Pointer to the matrix to search + * +- * This returns number of allocated irqs ++ * This returns number of allocated non-managed interrupts. + */ + unsigned int irq_matrix_allocated(struct irq_matrix *m) + { + struct cpumap *cm = this_cpu_ptr(m->maps); + +- return cm->allocated; ++ return cm->allocated - cm->managed_allocated; + } + + #ifdef CONFIG_GENERIC_IRQ_DEBUGFS +-- +2.42.0 + diff --git a/queue-6.6/gpio-sim-initialize-a-managed-pointer-when-declaring.patch b/queue-6.6/gpio-sim-initialize-a-managed-pointer-when-declaring.patch new file mode 100644 index 00000000000..dfcf3e72df0 --- /dev/null +++ b/queue-6.6/gpio-sim-initialize-a-managed-pointer-when-declaring.patch @@ -0,0 +1,42 @@ +From 66e70f66de0669c2ea8fc9064882480962aab553 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 17 Sep 2023 10:58:37 +0200 +Subject: gpio: sim: initialize a managed pointer when declaring it + +From: Bartosz Golaszewski + +[ Upstream commit 9f93f18305f5777820491e6ab9b34422c160371b ] + +Variables managed with __free() should typically be initialized where +they are declared so that the __free() callback is paired with its +counterpart resource allocator. Fix the second instance of using +__free() in gpio-sim to follow this pattern. + +Fixes: 3faf89f27aab ("gpio: sim: simplify code with cleanup helpers") +Suggested-by: Linus Torvalds +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-sim.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c +index 44bf1709a6488..a8e5ac95cf170 100644 +--- a/drivers/gpio/gpio-sim.c ++++ b/drivers/gpio/gpio-sim.c +@@ -1438,10 +1438,10 @@ static const struct config_item_type gpio_sim_device_config_group_type = { + static struct config_group * + gpio_sim_config_make_device_group(struct config_group *group, const char *name) + { +- struct gpio_sim_device *dev __free(kfree) = NULL; + int id; + +- dev = kzalloc(sizeof(*dev), GFP_KERNEL); ++ struct gpio_sim_device *dev __free(kfree) = kzalloc(sizeof(*dev), ++ GFP_KERNEL); + if (!dev) + return ERR_PTR(-ENOMEM); + +-- +2.42.0 + diff --git a/queue-6.6/gpu-host1x-correct-allocated-size-for-contexts.patch b/queue-6.6/gpu-host1x-correct-allocated-size-for-contexts.patch new file mode 100644 index 00000000000..ef764d30d11 --- /dev/null +++ b/queue-6.6/gpu-host1x-correct-allocated-size-for-contexts.patch @@ -0,0 +1,43 @@ +From d3a98bb457427d9bbfaf1a5c019670b9845285d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Sep 2023 14:59:09 +0300 +Subject: gpu: host1x: Correct allocated size for contexts + +From: Johnny Liu + +[ Upstream commit e889a311f74f4ae8bd40755a2c58d02e1c684fef ] + +Original implementation over allocates the memory size for the +contexts list. The size of memory for the contexts list is based +on the number of iommu groups specified in the device tree. + +Fixes: 8aa5bcb61612 ("gpu: host1x: Add context device management code") +Signed-off-by: Johnny Liu +Signed-off-by: Mikko Perttunen +Signed-off-by: Thierry Reding +Link: https://patchwork.freedesktop.org/patch/msgid/20230901115910.701518-1-cyndis@kapsi.fi +Signed-off-by: Sasha Levin +--- + drivers/gpu/host1x/context.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/host1x/context.c b/drivers/gpu/host1x/context.c +index a3f336edd991b..955c971c528d4 100644 +--- a/drivers/gpu/host1x/context.c ++++ b/drivers/gpu/host1x/context.c +@@ -34,10 +34,10 @@ int host1x_memory_context_list_init(struct host1x *host1x) + if (err < 0) + return 0; + +- cdl->devs = kcalloc(err, sizeof(*cdl->devs), GFP_KERNEL); ++ cdl->len = err / 4; ++ cdl->devs = kcalloc(cdl->len, sizeof(*cdl->devs), GFP_KERNEL); + if (!cdl->devs) + return -ENOMEM; +- cdl->len = err / 4; + + for (i = 0; i < cdl->len; i++) { + ctx = &cdl->devs[i]; +-- +2.42.0 + diff --git a/queue-6.6/gve-use-size_add-in-call-to-struct_size.patch b/queue-6.6/gve-use-size_add-in-call-to-struct_size.patch new file mode 100644 index 00000000000..b4b00ed988f --- /dev/null +++ b/queue-6.6/gve-use-size_add-in-call-to-struct_size.patch @@ -0,0 +1,38 @@ +From d9c4152d008d4b25fbfcee70d7e96931b6c901be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 12:17:49 -0600 +Subject: gve: Use size_add() in call to struct_size() + +From: Gustavo A. R. Silva + +[ Upstream commit d692873cbe861a870cdc9cbfb120eefd113c3dfd ] + +If, for any reason, `tx_stats_num + rx_stats_num` wraps around, the +protection that struct_size() adds against potential integer overflows +is defeated. Fix this by hardening call to struct_size() with size_add(). + +Fixes: 691f4077d560 ("gve: Replace zero-length array with flexible-array member") +Signed-off-by: Gustavo A. R. Silva +Reviewed-by: Kees Cook +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/google/gve/gve_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c +index 5704b5f57cd0d..83b09dcfafc4f 100644 +--- a/drivers/net/ethernet/google/gve/gve_main.c ++++ b/drivers/net/ethernet/google/gve/gve_main.c +@@ -190,7 +190,7 @@ static int gve_alloc_stats_report(struct gve_priv *priv) + rx_stats_num = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) * + priv->rx_cfg.num_queues; + priv->stats_report_len = struct_size(priv->stats_report, stats, +- tx_stats_num + rx_stats_num); ++ size_add(tx_stats_num, rx_stats_num)); + priv->stats_report = + dma_alloc_coherent(&priv->pdev->dev, priv->stats_report_len, + &priv->stats_report_bus, GFP_KERNEL); +-- +2.42.0 + diff --git a/queue-6.6/hid-cp2112-fix-duplicate-workqueue-initialization.patch b/queue-6.6/hid-cp2112-fix-duplicate-workqueue-initialization.patch new file mode 100644 index 00000000000..0322f22113e --- /dev/null +++ b/queue-6.6/hid-cp2112-fix-duplicate-workqueue-initialization.patch @@ -0,0 +1,50 @@ +From 090a33d3bdb35de1efcf14afacc0319bba8af9b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 16:22:45 -0500 +Subject: hid: cp2112: Fix duplicate workqueue initialization + +From: Danny Kaehn + +[ Upstream commit e3c2d2d144c082dd71596953193adf9891491f42 ] + +Previously the cp2112 driver called INIT_DELAYED_WORK within +cp2112_gpio_irq_startup, resulting in duplicate initilizations of the +workqueue on subsequent IRQ startups following an initial request. This +resulted in a warning in set_work_data in workqueue.c, as well as a rare +NULL dereference within process_one_work in workqueue.c. + +Initialize the workqueue within _probe instead. + +Fixes: 13de9cca514e ("HID: cp2112: add IRQ chip handling") +Signed-off-by: Danny Kaehn +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-cp2112.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c +index 54c33a24f8442..36f76c6dfa202 100644 +--- a/drivers/hid/hid-cp2112.c ++++ b/drivers/hid/hid-cp2112.c +@@ -1151,8 +1151,6 @@ static unsigned int cp2112_gpio_irq_startup(struct irq_data *d) + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct cp2112_device *dev = gpiochip_get_data(gc); + +- INIT_DELAYED_WORK(&dev->gpio_poll_worker, cp2112_gpio_poll_callback); +- + if (!dev->gpio_poll) { + dev->gpio_poll = true; + schedule_delayed_work(&dev->gpio_poll_worker, 0); +@@ -1307,6 +1305,8 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id) + girq->handler = handle_simple_irq; + girq->threaded = true; + ++ INIT_DELAYED_WORK(&dev->gpio_poll_worker, cp2112_gpio_poll_callback); ++ + ret = gpiochip_add_data(&dev->gc, dev); + if (ret < 0) { + hid_err(hdev, "error registering gpio chip\n"); +-- +2.42.0 + diff --git a/queue-6.6/hid-cp2112-fix-irq-shutdown-stopping-polling-for-all.patch b/queue-6.6/hid-cp2112-fix-irq-shutdown-stopping-polling-for-all.patch new file mode 100644 index 00000000000..fa16fdc742a --- /dev/null +++ b/queue-6.6/hid-cp2112-fix-irq-shutdown-stopping-polling-for-all.patch @@ -0,0 +1,48 @@ +From 463ee679a338422a939dcb036865b142646a3dc1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 13:23:17 -0500 +Subject: hid: cp2112: Fix IRQ shutdown stopping polling for all IRQs on chip + +From: Danny Kaehn + +[ Upstream commit dc3115e6c5d9863ec1a9ff1acf004ede93c34361 ] + +Previously cp2112_gpio_irq_shutdown() always cancelled the +gpio_poll_worker, even if other IRQs were still active, and did not set +the gpio_poll flag to false. This resulted in any call to _shutdown() +resulting in interrupts no longer functioning on the chip until a +_remove() occurred (a.e. the cp2112 is unplugged or system rebooted). + +Only cancel polling if all IRQs are disabled/masked, and correctly set +the gpio_poll flag, allowing polling to restart when an interrupt is +next enabled. + +Signed-off-by: Danny Kaehn +Fixes: 13de9cca514e ("HID: cp2112: add IRQ chip handling") +Link: https://lore.kernel.org/r/20231011182317.1053344-1-danny.kaehn@plexus.com +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-cp2112.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c +index 36f76c6dfa202..20a0d1315d90f 100644 +--- a/drivers/hid/hid-cp2112.c ++++ b/drivers/hid/hid-cp2112.c +@@ -1166,7 +1166,11 @@ static void cp2112_gpio_irq_shutdown(struct irq_data *d) + struct cp2112_device *dev = gpiochip_get_data(gc); + + cp2112_gpio_irq_mask(d); +- cancel_delayed_work_sync(&dev->gpio_poll_worker); ++ ++ if (!dev->irq_mask) { ++ dev->gpio_poll = false; ++ cancel_delayed_work_sync(&dev->gpio_poll_worker); ++ } + } + + static int cp2112_gpio_irq_type(struct irq_data *d, unsigned int type) +-- +2.42.0 + diff --git a/queue-6.6/hid-logitech-hidpp-don-t-restart-io-instead-defer-hi.patch b/queue-6.6/hid-logitech-hidpp-don-t-restart-io-instead-defer-hi.patch new file mode 100644 index 00000000000..9d8dce57299 --- /dev/null +++ b/queue-6.6/hid-logitech-hidpp-don-t-restart-io-instead-defer-hi.patch @@ -0,0 +1,119 @@ +From 32ec716bd4b09668e7cc044b1a9a7205a60fa778 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 12:20:18 +0200 +Subject: HID: logitech-hidpp: Don't restart IO, instead defer hid_connect() + only + +From: Hans de Goede + +[ Upstream commit 11ca0322a41920df2b462d2e45b0731e47ff475b ] + +Restarting IO causes 2 problems: + +1. Some devices do not like IO being restarted this was addressed in + commit 498ba2069035 ("HID: logitech-hidpp: Don't restart communication + if not necessary"), but that change has issues of its own and needs to + be reverted. + +2. Restarting IO and specifically calling hid_device_io_stop() causes + received packets to be missed, which may cause connect-events to + get missed. + +Restarting IO was introduced in commit 91cf9a98ae41 ("HID: logitech-hidpp: +make .probe usbhid capable") to allow to retrieve the device's name and +serial number and store these in hdev->name and hdev->uniq before +connecting any hid subdrivers (hid-input, hidraw) exporting this info +to userspace. + +But this does not require restarting IO, this merely requires deferring +calling hid_connect(). Calling hid_hw_start() with a connect-mask of +0 makes it skip calling hid_connect(), so hidpp_probe() can simply call +hid_connect() later without needing to restart IO. + +Remove the stop + restart of IO and instead just call hid_connect() later +to avoid the issues caused by restarting IO. + +Now that IO is no longer stopped, hid_hw_close() must be called at the end +of probe() to balance the hid_hw_open() done at the beginning probe(). + +This series has been tested on the following devices: +Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0) +Logitech M720 Triathlon (bluetooth, HID++ 4.5) +Logitech M720 Triathlon (unifying, HID++ 4.5) +Logitech K400 Pro (unifying, HID++ 4.1) +Logitech K270 (eQUAD nano Lite, HID++ 2.0) +Logitech M185 (eQUAD nano Lite, HID++ 4.5) +Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0) +Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0) + +And by bentiss: +Logitech Touchpad T650 (unifying) +Logitech Touchpad T651 (bluetooth) +Logitech MX Master 3B (BLE) +Logitech G403 (plain USB / Gaming receiver) + +Fixes: 498ba2069035 ("HID: logitech-hidpp: Don't restart communication if not necessary") +Suggested-by: Benjamin Tissoires +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20231010102029.111003-2-hdegoede@redhat.com +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-logitech-hidpp.c | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c +index a209d51bd2476..aa4f232c4518a 100644 +--- a/drivers/hid/hid-logitech-hidpp.c ++++ b/drivers/hid/hid-logitech-hidpp.c +@@ -4460,8 +4460,10 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) + hdev->name); + + /* +- * Plain USB connections need to actually call start and open +- * on the transport driver to allow incoming data. ++ * First call hid_hw_start(hdev, 0) to allow IO without connecting any ++ * hid subdrivers (hid-input, hidraw). This allows retrieving the dev's ++ * name and serial number and store these in hdev->name and hdev->uniq, ++ * before the hid-input and hidraw drivers expose these to userspace. + */ + ret = hid_hw_start(hdev, will_restart ? 0 : connect_mask); + if (ret) { +@@ -4519,19 +4521,14 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) + flush_work(&hidpp->work); + + if (will_restart) { +- /* Reset the HID node state */ +- hid_device_io_stop(hdev); +- hid_hw_close(hdev); +- hid_hw_stop(hdev); +- + if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) + connect_mask &= ~HID_CONNECT_HIDINPUT; + + /* Now export the actual inputs and hidraw nodes to the world */ +- ret = hid_hw_start(hdev, connect_mask); ++ ret = hid_connect(hdev, connect_mask); + if (ret) { +- hid_err(hdev, "%s:hid_hw_start returned error\n", __func__); +- goto hid_hw_start_fail; ++ hid_err(hdev, "%s:hid_connect returned error %d\n", __func__, ret); ++ goto hid_hw_init_fail; + } + } + +@@ -4543,6 +4540,11 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) + ret); + } + ++ /* ++ * This relies on logi_dj_ll_close() being a no-op so that DJ connection ++ * events will still be received. ++ */ ++ hid_hw_close(hdev); + return ret; + + hid_hw_init_fail: +-- +2.42.0 + diff --git a/queue-6.6/hid-logitech-hidpp-move-get_wireless_feature_index-c.patch b/queue-6.6/hid-logitech-hidpp-move-get_wireless_feature_index-c.patch new file mode 100644 index 00000000000..20f48e69fa8 --- /dev/null +++ b/queue-6.6/hid-logitech-hidpp-move-get_wireless_feature_index-c.patch @@ -0,0 +1,98 @@ +From 685cef6dff26dfdf51618740eae62ecefab6fa4e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 12:20:20 +0200 +Subject: HID: logitech-hidpp: Move get_wireless_feature_index() check to + hidpp_connect_event() + +From: Hans de Goede + +[ Upstream commit ba9de350509504fb748837b71e23d7e84c83d93c ] + +Calling get_wireless_feature_index() from probe() causes +the wireless_feature_index to only get set for unifying devices which +are already connected at probe() time. It does not get set for devices +which connect later. + +Fix this by moving get_wireless_feature_index() to hidpp_connect_event(), +this does not make a difference for devices connected at probe() since +probe() will queue the hidpp_connect_event() for those at probe time. + +This series has been tested on the following devices: +Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0) +Logitech M720 Triathlon (bluetooth, HID++ 4.5) +Logitech M720 Triathlon (unifying, HID++ 4.5) +Logitech K400 Pro (unifying, HID++ 4.1) +Logitech K270 (eQUAD nano Lite, HID++ 2.0) +Logitech M185 (eQUAD nano Lite, HID++ 4.5) +Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0) +Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0) + +And by bentiss: +Logitech Touchpad T650 (unifying) +Logitech Touchpad T651 (bluetooth) +Logitech MX Master 3B (BLE) +Logitech G403 (plain USB / Gaming receiver) + +Fixes: 0da0a63b7cba ("HID: logitech-hidpp: Support WirelessDeviceStatus connect events") +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20231010102029.111003-4-hdegoede@redhat.com +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-logitech-hidpp.c | 20 +++++++++----------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c +index c582d19b11d6c..7bf12ca0eb4a9 100644 +--- a/drivers/hid/hid-logitech-hidpp.c ++++ b/drivers/hid/hid-logitech-hidpp.c +@@ -1835,15 +1835,14 @@ static int hidpp_battery_get_property(struct power_supply *psy, + /* -------------------------------------------------------------------------- */ + #define HIDPP_PAGE_WIRELESS_DEVICE_STATUS 0x1d4b + +-static int hidpp_set_wireless_feature_index(struct hidpp_device *hidpp) ++static int hidpp_get_wireless_feature_index(struct hidpp_device *hidpp, u8 *feature_index) + { + u8 feature_type; + int ret; + + ret = hidpp_root_get_feature(hidpp, + HIDPP_PAGE_WIRELESS_DEVICE_STATUS, +- &hidpp->wireless_feature_index, +- &feature_type); ++ feature_index, &feature_type); + + return ret; + } +@@ -4249,6 +4248,13 @@ static void hidpp_connect_event(struct hidpp_device *hidpp) + } + } + ++ if (hidpp->protocol_major >= 2) { ++ u8 feature_index; ++ ++ if (!hidpp_get_wireless_feature_index(hidpp, &feature_index)) ++ hidpp->wireless_feature_index = feature_index; ++ } ++ + if (hidpp->name == hdev->name && hidpp->protocol_major >= 2) { + name = hidpp_get_device_name(hidpp); + if (name) { +@@ -4493,14 +4499,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) + hidpp_overwrite_name(hdev); + } + +- if (connected && hidpp->protocol_major >= 2) { +- ret = hidpp_set_wireless_feature_index(hidpp); +- if (ret == -ENOENT) +- hidpp->wireless_feature_index = 0; +- else if (ret) +- goto hid_hw_init_fail; +- } +- + if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) { + ret = wtp_get_config(hidpp); + if (ret) +-- +2.42.0 + diff --git a/queue-6.6/hid-logitech-hidpp-revert-don-t-restart-communicatio.patch b/queue-6.6/hid-logitech-hidpp-revert-don-t-restart-communicatio.patch new file mode 100644 index 00000000000..dc2104b75d6 --- /dev/null +++ b/queue-6.6/hid-logitech-hidpp-revert-don-t-restart-communicatio.patch @@ -0,0 +1,129 @@ +From 6fc8cb5ff35f1c228f3f196ff62ed15e2bd2b3f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 12:20:19 +0200 +Subject: HID: logitech-hidpp: Revert "Don't restart communication if not + necessary" + +From: Hans de Goede + +[ Upstream commit 55bf70362ffc4ddd7c8745e2fe880edac00e4aff ] + +Commit 91cf9a98ae41 ("HID: logitech-hidpp: make .probe usbhid capable") +makes hidpp_probe() first call hid_hw_start(hdev, 0) to allow IO +without connecting any hid subdrivers (hid-input, hidraw). + +This is done to allow to retrieve the device's name and serial number +and store these in hdev->name and hdev->uniq. + +Then later on IO was stopped and started again with hid_hw_start(hdev, +HID_CONNECT_DEFAULT) connecting hid-input and hidraw after the name +and serial number have been setup. + +Commit 498ba2069035 ("HID: logitech-hidpp: Don't restart communication +if not necessary") changed the probe() code to only do the start with +a 0 connect-mask + restart later for unifying devices. + +But for non unifying devices hdev->name and hdev->uniq are updated too. +So this change re-introduces the problem for which the start with +a 0 connect-mask + restart later behavior was introduced. + +The previous patch in this series changes the unifying path to instead of +restarting IO only call hid_connect() later. This avoids possible issues +with restarting IO seen on non unifying devices. + +Revert the change to limit the restart behavior to unifying devices to +fix hdev->name changing after userspace facing devices have already been +registered. + +This series has been tested on the following devices: +Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0) +Logitech M720 Triathlon (bluetooth, HID++ 4.5) +Logitech M720 Triathlon (unifying, HID++ 4.5) +Logitech K400 Pro (unifying, HID++ 4.1) +Logitech K270 (eQUAD nano Lite, HID++ 2.0) +Logitech M185 (eQUAD nano Lite, HID++ 4.5) +Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0) +Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0) + +And by bentiss: +Logitech Touchpad T650 (unifying) +Logitech Touchpad T651 (bluetooth) +Logitech MX Master 3B (BLE) +Logitech G403 (plain USB / Gaming receiver) + +Fixes: 498ba2069035 ("HID: logitech-hidpp: Don't restart communication if not necessary") +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20231010102029.111003-3-hdegoede@redhat.com +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-logitech-hidpp.c | 24 ++++++++---------------- + 1 file changed, 8 insertions(+), 16 deletions(-) + +diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c +index aa4f232c4518a..c582d19b11d6c 100644 +--- a/drivers/hid/hid-logitech-hidpp.c ++++ b/drivers/hid/hid-logitech-hidpp.c +@@ -4394,7 +4394,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) + bool connected; + unsigned int connect_mask = HID_CONNECT_DEFAULT; + struct hidpp_ff_private_data data; +- bool will_restart = false; + + /* report_fixup needs drvdata to be set before we call hid_parse */ + hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL); +@@ -4445,10 +4444,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) + return ret; + } + +- if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT || +- hidpp->quirks & HIDPP_QUIRK_UNIFYING) +- will_restart = true; +- + INIT_WORK(&hidpp->work, delayed_work_cb); + mutex_init(&hidpp->send_mutex); + init_waitqueue_head(&hidpp->wait); +@@ -4465,7 +4460,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) + * name and serial number and store these in hdev->name and hdev->uniq, + * before the hid-input and hidraw drivers expose these to userspace. + */ +- ret = hid_hw_start(hdev, will_restart ? 0 : connect_mask); ++ ret = hid_hw_start(hdev, 0); + if (ret) { + hid_err(hdev, "hw start failed\n"); + goto hid_hw_start_fail; +@@ -4504,7 +4499,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) + hidpp->wireless_feature_index = 0; + else if (ret) + goto hid_hw_init_fail; +- ret = 0; + } + + if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) { +@@ -4520,16 +4514,14 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) + schedule_work(&hidpp->work); + flush_work(&hidpp->work); + +- if (will_restart) { +- if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) +- connect_mask &= ~HID_CONNECT_HIDINPUT; ++ if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) ++ connect_mask &= ~HID_CONNECT_HIDINPUT; + +- /* Now export the actual inputs and hidraw nodes to the world */ +- ret = hid_connect(hdev, connect_mask); +- if (ret) { +- hid_err(hdev, "%s:hid_connect returned error %d\n", __func__, ret); +- goto hid_hw_init_fail; +- } ++ /* Now export the actual inputs and hidraw nodes to the world */ ++ ret = hid_connect(hdev, connect_mask); ++ if (ret) { ++ hid_err(hdev, "%s:hid_connect returned error %d\n", __func__, ret); ++ goto hid_hw_init_fail; + } + + if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { +-- +2.42.0 + diff --git a/queue-6.6/hid-uclogic-fix-a-work-entry-not-empty-bug-in-__queu.patch b/queue-6.6/hid-uclogic-fix-a-work-entry-not-empty-bug-in-__queu.patch new file mode 100644 index 00000000000..dca87f84bac --- /dev/null +++ b/queue-6.6/hid-uclogic-fix-a-work-entry-not-empty-bug-in-__queu.patch @@ -0,0 +1,110 @@ +From 91833ba66a8e7aa57fc5ed2bd75facce72f35d17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 14:42:45 +0800 +Subject: HID: uclogic: Fix a work->entry not empty bug in __queue_work() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jinjie Ruan + +[ Upstream commit d45f72b3c275101a620dd69881343e0dda72f877 ] + +When CONFIG_HID_UCLOGIC=y and CONFIG_KUNIT_ALL_TESTS=y, launch +kernel and then the below work->entry not empty bug occurs. + +In hid_test_uclogic_exec_event_hook_test(), the filter->work is not +initialized to be added to p.event_hooks->list, and then the +schedule_work() in uclogic_exec_event_hook() will call __queue_work(), +which check whether the work->entry is empty and cause the below +warning call trace. + +So call INIT_WORK() with a fake work to solve the issue. After applying +this patch, the below work->entry not empty bug never occurs. + + WARNING: CPU: 0 PID: 2177 at kernel/workqueue.c:1787 __queue_work.part.0+0x780/0xad0 + Modules linked in: + CPU: 0 PID: 2177 Comm: kunit_try_catch Tainted: G B W N 6.6.0-rc2+ #30 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 + RIP: 0010:__queue_work.part.0+0x780/0xad0 + Code: 44 24 20 0f b6 00 84 c0 74 08 3c 03 0f 8e 52 03 00 00 f6 83 00 01 00 00 02 74 6f 4c 89 ef e8 c7 d8 f1 02 f3 90 e9 e5 f8 ff ff <0f> 0b e9 63 fc ff ff 89 e9 49 8d 57 68 4c 89 e6 4c 89 ff 83 c9 02 + RSP: 0000:ffff888102bb7ce8 EFLAGS: 00010086 + RAX: 0000000000000000 RBX: ffff888106b8e460 RCX: ffffffff84141cc7 + RDX: 1ffff11020d71c8c RSI: 0000000000000004 RDI: ffff8881001d0118 + RBP: dffffc0000000000 R08: 0000000000000001 R09: ffffed1020576f92 + R10: 0000000000000003 R11: ffff888102bb7980 R12: ffff888106b8e458 + R13: ffff888119c38800 R14: 0000000000000000 R15: ffff8881001d0100 + FS: 0000000000000000(0000) GS:ffff888119c00000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: ffff888119506000 CR3: 0000000005286001 CR4: 0000000000770ef0 + DR0: ffffffff8fdd6ce0 DR1: ffffffff8fdd6ce1 DR2: ffffffff8fdd6ce3 + DR3: ffffffff8fdd6ce5 DR6: 00000000fffe0ff0 DR7: 0000000000000600 + PKRU: 55555554 + Call Trace: + + ? __warn+0xc9/0x260 + ? __queue_work.part.0+0x780/0xad0 + ? report_bug+0x345/0x400 + ? handle_bug+0x3c/0x70 + ? exc_invalid_op+0x14/0x40 + ? asm_exc_invalid_op+0x16/0x20 + ? _raw_spin_lock+0x87/0xe0 + ? __queue_work.part.0+0x780/0xad0 + ? __queue_work.part.0+0x249/0xad0 + queue_work_on+0x48/0x50 + uclogic_exec_event_hook.isra.0+0xf7/0x160 + hid_test_uclogic_exec_event_hook_test+0x2f1/0x5d0 + ? try_to_wake_up+0x151/0x13e0 + ? uclogic_exec_event_hook.isra.0+0x160/0x160 + ? _raw_spin_lock_irqsave+0x8d/0xe0 + ? __sched_text_end+0xa/0xa + ? __sched_text_end+0xa/0xa + ? migrate_enable+0x260/0x260 + ? kunit_try_run_case_cleanup+0xe0/0xe0 + kunit_generic_run_threadfn_adapter+0x4a/0x90 + ? kunit_try_catch_throw+0x80/0x80 + kthread+0x2b5/0x380 + ? kthread_complete_and_exit+0x20/0x20 + ret_from_fork+0x2d/0x70 + ? kthread_complete_and_exit+0x20/0x20 + ret_from_fork_asm+0x11/0x20 + + +Fixes: a251d6576d2a ("HID: uclogic: Handle wireless device reconnection") +Signed-off-by: Jinjie Ruan +Reviewed-by: José Expósito +Link: https://lore.kernel.org/r/20231009064245.3573397-3-ruanjinjie@huawei.com +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-uclogic-core-test.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/hid/hid-uclogic-core-test.c b/drivers/hid/hid-uclogic-core-test.c +index 2bb916226a389..cb274cde3ad23 100644 +--- a/drivers/hid/hid-uclogic-core-test.c ++++ b/drivers/hid/hid-uclogic-core-test.c +@@ -56,6 +56,11 @@ static struct uclogic_raw_event_hook_test test_events[] = { + }, + }; + ++static void fake_work(struct work_struct *work) ++{ ++ ++} ++ + static void hid_test_uclogic_exec_event_hook_test(struct kunit *test) + { + struct uclogic_params p = {0, }; +@@ -77,6 +82,8 @@ static void hid_test_uclogic_exec_event_hook_test(struct kunit *test) + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, filter->event); + memcpy(filter->event, &hook_events[n].event[0], filter->size); + ++ INIT_WORK(&filter->work, fake_work); ++ + list_add_tail(&filter->list, &p.event_hooks->list); + } + +-- +2.42.0 + diff --git a/queue-6.6/hid-uclogic-fix-user-memory-access-bug-in-uclogic_pa.patch b/queue-6.6/hid-uclogic-fix-user-memory-access-bug-in-uclogic_pa.patch new file mode 100644 index 00000000000..42b50eb9760 --- /dev/null +++ b/queue-6.6/hid-uclogic-fix-user-memory-access-bug-in-uclogic_pa.patch @@ -0,0 +1,138 @@ +From fb3d738c1a930ef23f490af1dd269b0542b65c94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 14:42:44 +0800 +Subject: HID: uclogic: Fix user-memory-access bug in + uclogic_params_ugee_v2_init_event_hooks() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jinjie Ruan + +[ Upstream commit 91cfe0bbaa1c434d4271eb6e1d7aaa1fe8d121f6 ] + +When CONFIG_HID_UCLOGIC=y and CONFIG_KUNIT_ALL_TESTS=y, launch kernel and +then the below user-memory-access bug occurs. + +In hid_test_uclogic_params_cleanup_event_hooks(),it call +uclogic_params_ugee_v2_init_event_hooks() with the first arg=NULL, so +when it calls uclogic_params_ugee_v2_has_battery(), the hid_get_drvdata() +will access hdev->dev with hdev=NULL, which will cause below +user-memory-access. + +So add a fake_device with quirks member and call hid_set_drvdata() +to assign hdev->dev->driver_data which avoids the null-ptr-def bug +for drvdata->quirks in uclogic_params_ugee_v2_has_battery(). After applying +this patch, the below user-memory-access bug never occurs. + + general protection fault, probably for non-canonical address 0xdffffc0000000329: 0000 [#1] PREEMPT SMP KASAN + KASAN: probably user-memory-access in range [0x0000000000001948-0x000000000000194f] + CPU: 5 PID: 2189 Comm: kunit_try_catch Tainted: G B W N 6.6.0-rc2+ #30 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 + RIP: 0010:uclogic_params_ugee_v2_init_event_hooks+0x87/0x600 + Code: f3 f3 65 48 8b 14 25 28 00 00 00 48 89 54 24 60 31 d2 48 89 fa c7 44 24 30 00 00 00 00 48 c7 44 24 28 02 f8 02 01 48 c1 ea 03 <80> 3c 02 00 0f 85 2c 04 00 00 48 8b 9d 48 19 00 00 48 b8 00 00 00 + RSP: 0000:ffff88810679fc88 EFLAGS: 00010202 + RAX: dffffc0000000000 RBX: 0000000000000004 RCX: 0000000000000000 + RDX: 0000000000000329 RSI: ffff88810679fd88 RDI: 0000000000001948 + RBP: 0000000000000000 R08: 0000000000000000 R09: ffffed1020f639f0 + R10: ffff888107b1cf87 R11: 0000000000000400 R12: 1ffff11020cf3f92 + R13: ffff88810679fd88 R14: ffff888100b97b08 R15: ffff8881030bb080 + FS: 0000000000000000(0000) GS:ffff888119e80000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000000 CR3: 0000000005286001 CR4: 0000000000770ee0 + DR0: ffffffff8fdd6cf4 DR1: ffffffff8fdd6cf5 DR2: ffffffff8fdd6cf6 + DR3: ffffffff8fdd6cf7 DR6: 00000000fffe0ff0 DR7: 0000000000000600 + PKRU: 55555554 + Call Trace: + + ? die_addr+0x3d/0xa0 + ? exc_general_protection+0x144/0x220 + ? asm_exc_general_protection+0x22/0x30 + ? uclogic_params_ugee_v2_init_event_hooks+0x87/0x600 + ? sched_clock_cpu+0x69/0x550 + ? uclogic_parse_ugee_v2_desc_gen_params+0x70/0x70 + ? load_balance+0x2950/0x2950 + ? rcu_trc_cmpxchg_need_qs+0x67/0xa0 + hid_test_uclogic_params_cleanup_event_hooks+0x9e/0x1a0 + ? uclogic_params_ugee_v2_init_event_hooks+0x600/0x600 + ? __switch_to+0x5cf/0xe60 + ? migrate_enable+0x260/0x260 + ? __kthread_parkme+0x83/0x150 + ? kunit_try_run_case_cleanup+0xe0/0xe0 + kunit_generic_run_threadfn_adapter+0x4a/0x90 + ? kunit_try_catch_throw+0x80/0x80 + kthread+0x2b5/0x380 + ? kthread_complete_and_exit+0x20/0x20 + ret_from_fork+0x2d/0x70 + ? kthread_complete_and_exit+0x20/0x20 + ret_from_fork_asm+0x11/0x20 + + Modules linked in: + Dumping ftrace buffer: + (ftrace buffer empty) + ---[ end trace 0000000000000000 ]--- + RIP: 0010:uclogic_params_ugee_v2_init_event_hooks+0x87/0x600 + Code: f3 f3 65 48 8b 14 25 28 00 00 00 48 89 54 24 60 31 d2 48 89 fa c7 44 24 30 00 00 00 00 48 c7 44 24 28 02 f8 02 01 48 c1 ea 03 <80> 3c 02 00 0f 85 2c 04 00 00 48 8b 9d 48 19 00 00 48 b8 00 00 00 + RSP: 0000:ffff88810679fc88 EFLAGS: 00010202 + RAX: dffffc0000000000 RBX: 0000000000000004 RCX: 0000000000000000 + RDX: 0000000000000329 RSI: ffff88810679fd88 RDI: 0000000000001948 + RBP: 0000000000000000 R08: 0000000000000000 R09: ffffed1020f639f0 + R10: ffff888107b1cf87 R11: 0000000000000400 R12: 1ffff11020cf3f92 + R13: ffff88810679fd88 R14: ffff888100b97b08 R15: ffff8881030bb080 + FS: 0000000000000000(0000) GS:ffff888119e80000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000000 CR3: 0000000005286001 CR4: 0000000000770ee0 + DR0: ffffffff8fdd6cf4 DR1: ffffffff8fdd6cf5 DR2: ffffffff8fdd6cf6 + DR3: ffffffff8fdd6cf7 DR6: 00000000fffe0ff0 DR7: 0000000000000600 + PKRU: 55555554 + Kernel panic - not syncing: Fatal exception + Dumping ftrace buffer: + (ftrace buffer empty) + Kernel Offset: disabled + Rebooting in 1 seconds.. + +Fixes: a251d6576d2a ("HID: uclogic: Handle wireless device reconnection") +Signed-off-by: Jinjie Ruan +Reviewed-by: José Expósito +Link: https://lore.kernel.org/r/20231009064245.3573397-2-ruanjinjie@huawei.com +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-uclogic-params-test.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-uclogic-params-test.c b/drivers/hid/hid-uclogic-params-test.c +index 678f50cbb160b..a30121419a292 100644 +--- a/drivers/hid/hid-uclogic-params-test.c ++++ b/drivers/hid/hid-uclogic-params-test.c +@@ -174,12 +174,26 @@ static void hid_test_uclogic_parse_ugee_v2_desc(struct kunit *test) + KUNIT_EXPECT_EQ(test, params->frame_type, frame_type); + } + ++struct fake_device { ++ unsigned long quirks; ++}; ++ + static void hid_test_uclogic_params_cleanup_event_hooks(struct kunit *test) + { + int res, n; ++ struct hid_device *hdev; ++ struct fake_device *fake_dev; + struct uclogic_params p = {0, }; + +- res = uclogic_params_ugee_v2_init_event_hooks(NULL, &p); ++ hdev = kunit_kzalloc(test, sizeof(struct hid_device), GFP_KERNEL); ++ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hdev); ++ ++ fake_dev = kunit_kzalloc(test, sizeof(struct fake_device), GFP_KERNEL); ++ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fake_dev); ++ ++ hid_set_drvdata(hdev, fake_dev); ++ ++ res = uclogic_params_ugee_v2_init_event_hooks(hdev, &p); + KUNIT_ASSERT_EQ(test, res, 0); + + /* Check that the function can be called repeatedly */ +-- +2.42.0 + diff --git a/queue-6.6/hte-tegra-fix-missing-error-code-in-tegra_hte_test_p.patch b/queue-6.6/hte-tegra-fix-missing-error-code-in-tegra_hte_test_p.patch new file mode 100644 index 00000000000..1e2fb40cf3f --- /dev/null +++ b/queue-6.6/hte-tegra-fix-missing-error-code-in-tegra_hte_test_p.patch @@ -0,0 +1,41 @@ +From ac277d8b08d59c280967af020c4bac8893e760d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Oct 2023 00:53:28 -0700 +Subject: hte: tegra: Fix missing error code in tegra_hte_test_probe() + +From: Harshit Mogalapalli + +[ Upstream commit b7c3ca3553d1de5e86c85636828e186d30cd0628 ] + +The value of 'ret' is zero when of_hte_req_count() fails to get number +of entitties to timestamp. And returning success(zero) on this failure +path is incorrect. + +Fixes: 9a75a7cd03c9 ("hte: Add Tegra HTE test driver") +Signed-off-by: Harshit Mogalapalli +Reviewed-by: Dipen Patel +Signed-off-by: Dipen Patel +Signed-off-by: Sasha Levin +--- + drivers/hte/hte-tegra194-test.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/hte/hte-tegra194-test.c b/drivers/hte/hte-tegra194-test.c +index ba37a5efbf820..ab2edff018eb6 100644 +--- a/drivers/hte/hte-tegra194-test.c ++++ b/drivers/hte/hte-tegra194-test.c +@@ -153,8 +153,10 @@ static int tegra_hte_test_probe(struct platform_device *pdev) + } + + cnt = of_hte_req_count(hte.pdev); +- if (cnt < 0) ++ if (cnt < 0) { ++ ret = cnt; + goto free_irq; ++ } + + dev_info(&pdev->dev, "Total requested lines:%d\n", cnt); + +-- +2.42.0 + diff --git a/queue-6.6/hwmon-axi-fan-control-fix-possible-null-pointer-dere.patch b/queue-6.6/hwmon-axi-fan-control-fix-possible-null-pointer-dere.patch new file mode 100644 index 00000000000..b8fc5e5782e --- /dev/null +++ b/queue-6.6/hwmon-axi-fan-control-fix-possible-null-pointer-dere.patch @@ -0,0 +1,74 @@ +From e05d9d18430d84ef271aac727d3e1eab7c62dee0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 15:21:00 +0200 +Subject: hwmon: (axi-fan-control) Fix possible NULL pointer dereference + +From: Dragos Bogdan + +[ Upstream commit 2a5b3370a1d9750eca325292e291c8c7cb8cf2e0 ] + +axi_fan_control_irq_handler(), dependent on the private +axi_fan_control_data structure, might be called before the hwmon +device is registered. That will cause an "Unable to handle kernel +NULL pointer dereference" error. + +Fixes: 8412b410fa5e ("hwmon: Support ADI Fan Control IP") +Signed-off-by: Dragos Bogdan +Signed-off-by: Nuno Sa +Link: https://lore.kernel.org/r/20231025132100.649499-1-nuno.sa@analog.com +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/axi-fan-control.c | 29 ++++++++++++++++------------- + 1 file changed, 16 insertions(+), 13 deletions(-) + +diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c +index 5fd136baf1cd3..19b9bf3d75ef9 100644 +--- a/drivers/hwmon/axi-fan-control.c ++++ b/drivers/hwmon/axi-fan-control.c +@@ -496,6 +496,21 @@ static int axi_fan_control_probe(struct platform_device *pdev) + return -ENODEV; + } + ++ ret = axi_fan_control_init(ctl, pdev->dev.of_node); ++ if (ret) { ++ dev_err(&pdev->dev, "Failed to initialize device\n"); ++ return ret; ++ } ++ ++ ctl->hdev = devm_hwmon_device_register_with_info(&pdev->dev, ++ name, ++ ctl, ++ &axi_chip_info, ++ axi_fan_control_groups); ++ ++ if (IS_ERR(ctl->hdev)) ++ return PTR_ERR(ctl->hdev); ++ + ctl->irq = platform_get_irq(pdev, 0); + if (ctl->irq < 0) + return ctl->irq; +@@ -509,19 +524,7 @@ static int axi_fan_control_probe(struct platform_device *pdev) + return ret; + } + +- ret = axi_fan_control_init(ctl, pdev->dev.of_node); +- if (ret) { +- dev_err(&pdev->dev, "Failed to initialize device\n"); +- return ret; +- } +- +- ctl->hdev = devm_hwmon_device_register_with_info(&pdev->dev, +- name, +- ctl, +- &axi_chip_info, +- axi_fan_control_groups); +- +- return PTR_ERR_OR_ZERO(ctl->hdev); ++ return 0; + } + + static struct platform_driver axi_fan_control_driver = { +-- +2.42.0 + diff --git a/queue-6.6/hwmon-coretemp-fix-potentially-truncated-sysfs-attri.patch b/queue-6.6/hwmon-coretemp-fix-potentially-truncated-sysfs-attri.patch new file mode 100644 index 00000000000..d40ea89b83b --- /dev/null +++ b/queue-6.6/hwmon-coretemp-fix-potentially-truncated-sysfs-attri.patch @@ -0,0 +1,59 @@ +From 8883d185b1a5758ab7b4057c9cda4c8aa3348e1f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 20:23:16 +0800 +Subject: hwmon: (coretemp) Fix potentially truncated sysfs attribute name + +From: Zhang Rui + +[ Upstream commit bbfff736d30e5283ad09e748caff979d75ddef7f ] + +When build with W=1 and "-Werror=format-truncation", below error is +observed in coretemp driver, + + drivers/hwmon/coretemp.c: In function 'create_core_data': +>> drivers/hwmon/coretemp.c:393:34: error: '%s' directive output may be truncated writing likely 5 or more bytes into a region of size between 3 and 13 [-Werror=format-truncation=] + 393 | "temp%d_%s", attr_no, suffixes[i]); + | ^~ + drivers/hwmon/coretemp.c:393:26: note: assuming directive output of 5 bytes + 393 | "temp%d_%s", attr_no, suffixes[i]); + | ^~~~~~~~~~~ + drivers/hwmon/coretemp.c:392:17: note: 'snprintf' output 7 or more bytes (assuming 22) into a destination of size 19 + 392 | snprintf(tdata->attr_name[i], CORETEMP_NAME_LENGTH, + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 393 | "temp%d_%s", attr_no, suffixes[i]); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + cc1: all warnings being treated as errors + +Given that +1. '%d' could take 10 charactors, +2. '%s' could take 10 charactors ("crit_alarm"), +3. "temp", "_" and the NULL terminator take 6 charactors, +fix the problem by increasing CORETEMP_NAME_LENGTH to 28. + +Signed-off-by: Zhang Rui +Fixes: 7108b80a542b ("hwmon/coretemp: Handle large core ID value") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202310200443.iD3tUbbK-lkp@intel.com/ +Link: https://lore.kernel.org/r/20231025122316.836400-1-rui.zhang@intel.com +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/coretemp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c +index eba94f68585a8..ba82d1e79c131 100644 +--- a/drivers/hwmon/coretemp.c ++++ b/drivers/hwmon/coretemp.c +@@ -42,7 +42,7 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); + #define PKG_SYSFS_ATTR_NO 1 /* Sysfs attribute for package temp */ + #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ + #define NUM_REAL_CORES 128 /* Number of Real cores per cpu */ +-#define CORETEMP_NAME_LENGTH 19 /* String Length of attrs */ ++#define CORETEMP_NAME_LENGTH 28 /* String Length of attrs */ + #define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */ + #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) + #define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO) +-- +2.42.0 + diff --git a/queue-6.6/hwmon-pmbus-mp2975-move-pgood-fix.patch b/queue-6.6/hwmon-pmbus-mp2975-move-pgood-fix.patch new file mode 100644 index 00000000000..ca9b5120c02 --- /dev/null +++ b/queue-6.6/hwmon-pmbus-mp2975-move-pgood-fix.patch @@ -0,0 +1,51 @@ +From a75f1cddcdfd0e8d089187b38fcb40fd29620da5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Oct 2023 10:33:52 +0000 +Subject: hwmon: (pmbus/mp2975) Move PGOOD fix + +From: Naresh Solanki + +[ Upstream commit 9da2901c47332b030ea4d2a2302bc7c0b83fc67c ] + +The PGOOD fix was intended for MP2973 & MP2971 & not for MP2975. + +Fixes: acda945afb46 ("hwmon: (pmbus/mp2975) Fix PGOOD in READ_STATUS_WORD") +Signed-off-by: Naresh Solanki +Link: https://lore.kernel.org/r/20231027103352.918895-1-naresh.solanki@9elements.com +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/pmbus/mp2975.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/hwmon/pmbus/mp2975.c b/drivers/hwmon/pmbus/mp2975.c +index 26ba506331007..b9bb469e2d8fe 100644 +--- a/drivers/hwmon/pmbus/mp2975.c ++++ b/drivers/hwmon/pmbus/mp2975.c +@@ -297,6 +297,11 @@ static int mp2973_read_word_data(struct i2c_client *client, int page, + int ret; + + switch (reg) { ++ case PMBUS_STATUS_WORD: ++ /* MP2973 & MP2971 return PGOOD instead of PB_STATUS_POWER_GOOD_N. */ ++ ret = pmbus_read_word_data(client, page, phase, reg); ++ ret ^= PB_STATUS_POWER_GOOD_N; ++ break; + case PMBUS_OT_FAULT_LIMIT: + ret = mp2975_read_word_helper(client, page, phase, reg, + GENMASK(7, 0)); +@@ -380,11 +385,6 @@ static int mp2975_read_word_data(struct i2c_client *client, int page, + int ret; + + switch (reg) { +- case PMBUS_STATUS_WORD: +- /* MP2973 & MP2971 return PGOOD instead of PB_STATUS_POWER_GOOD_N. */ +- ret = pmbus_read_word_data(client, page, phase, reg); +- ret ^= PB_STATUS_POWER_GOOD_N; +- break; + case PMBUS_OT_FAULT_LIMIT: + ret = mp2975_read_word_helper(client, page, phase, reg, + GENMASK(7, 0)); +-- +2.42.0 + diff --git a/queue-6.6/hwmon-sch5627-disallow-write-access-if-virtual-regis.patch b/queue-6.6/hwmon-sch5627-disallow-write-access-if-virtual-regis.patch new file mode 100644 index 00000000000..40c9c606c44 --- /dev/null +++ b/queue-6.6/hwmon-sch5627-disallow-write-access-if-virtual-regis.patch @@ -0,0 +1,55 @@ +From ddcf88f4bc7c69de73d49f65e4cab135191d2c4b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 07:26:36 +0200 +Subject: hwmon: (sch5627) Disallow write access if virtual registers are + locked + +From: Armin Wolf + +[ Upstream commit 7da8a635436029957c5350da3acf51d78ed64071 ] + +When the lock bit inside SCH5627_REG_CTRL is set, then the virtual +registers become read-only until the next power cycle. +Disallow write access to those registers in such a case. + +Tested on a Fujitsu Esprimo P720. + +Fixes: aa9f833dfc12 ("hwmon: (sch5627) Add pwmX_auto_channels_temp support") +Signed-off-by: Armin Wolf +Link: https://lore.kernel.org/r/20230907052639.16491-3-W_Armin@gmx.de +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/sch5627.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/hwmon/sch5627.c b/drivers/hwmon/sch5627.c +index 0eefb8c0aef25..bf408e35e2c32 100644 +--- a/drivers/hwmon/sch5627.c ++++ b/drivers/hwmon/sch5627.c +@@ -34,6 +34,7 @@ + #define SCH5627_REG_CTRL 0x40 + + #define SCH5627_CTRL_START BIT(0) ++#define SCH5627_CTRL_LOCK BIT(1) + #define SCH5627_CTRL_VBAT BIT(4) + + #define SCH5627_NO_TEMPS 8 +@@ -231,6 +232,14 @@ static int reg_to_rpm(u16 reg) + static umode_t sch5627_is_visible(const void *drvdata, enum hwmon_sensor_types type, u32 attr, + int channel) + { ++ const struct sch5627_data *data = drvdata; ++ ++ /* Once the lock bit is set, the virtual registers become read-only ++ * until the next power cycle. ++ */ ++ if (data->control & SCH5627_CTRL_LOCK) ++ return 0444; ++ + if (type == hwmon_pwm && attr == hwmon_pwm_auto_channels_temp) + return 0644; + +-- +2.42.0 + diff --git a/queue-6.6/hwmon-sch5627-use-bit-macros-when-accessing-the-cont.patch b/queue-6.6/hwmon-sch5627-use-bit-macros-when-accessing-the-cont.patch new file mode 100644 index 00000000000..4eab6b76b4c --- /dev/null +++ b/queue-6.6/hwmon-sch5627-use-bit-macros-when-accessing-the-cont.patch @@ -0,0 +1,76 @@ +From 425453a36da3c418d5ee0805c99638cd601dced2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 07:26:35 +0200 +Subject: hwmon: (sch5627) Use bit macros when accessing the control register + +From: Armin Wolf + +[ Upstream commit 7f0b28e0653f36b51542d25dd54ed312c397ecfc ] + +Use bit macros then accessing SCH5627_REG_CTRL, so that people +do not need to look at the datasheet to find out what each bit +does. + +Tested on a Fujitsu Esprimo P720. + +Signed-off-by: Armin Wolf +Link: https://lore.kernel.org/r/20230907052639.16491-2-W_Armin@gmx.de +Signed-off-by: Guenter Roeck +Stable-dep-of: 7da8a6354360 ("hwmon: (sch5627) Disallow write access if virtual registers are locked") +Signed-off-by: Sasha Levin +--- + drivers/hwmon/sch5627.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/hwmon/sch5627.c b/drivers/hwmon/sch5627.c +index 1bbda3b05532e..0eefb8c0aef25 100644 +--- a/drivers/hwmon/sch5627.c ++++ b/drivers/hwmon/sch5627.c +@@ -6,6 +6,7 @@ + + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + ++#include + #include + #include + #include +@@ -32,6 +33,9 @@ + #define SCH5627_REG_PRIMARY_ID 0x3f + #define SCH5627_REG_CTRL 0x40 + ++#define SCH5627_CTRL_START BIT(0) ++#define SCH5627_CTRL_VBAT BIT(4) ++ + #define SCH5627_NO_TEMPS 8 + #define SCH5627_NO_FANS 4 + #define SCH5627_NO_IN 5 +@@ -147,7 +151,8 @@ static int sch5627_update_in(struct sch5627_data *data) + + /* Trigger a Vbat voltage measurement every 5 minutes */ + if (time_after(jiffies, data->last_battery + 300 * HZ)) { +- sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL, data->control | 0x10); ++ sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL, ++ data->control | SCH5627_CTRL_VBAT); + data->last_battery = jiffies; + } + +@@ -483,14 +488,13 @@ static int sch5627_probe(struct platform_device *pdev) + return val; + + data->control = val; +- if (!(data->control & 0x01)) { ++ if (!(data->control & SCH5627_CTRL_START)) { + pr_err("hardware monitoring not enabled\n"); + return -ENODEV; + } + /* Trigger a Vbat voltage measurement, so that we get a valid reading + the first time we read Vbat */ +- sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL, +- data->control | 0x10); ++ sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL, data->control | SCH5627_CTRL_VBAT); + data->last_battery = jiffies; + + /* +-- +2.42.0 + diff --git a/queue-6.6/hwrng-bcm2835-fix-hwrng-throughput-regression.patch b/queue-6.6/hwrng-bcm2835-fix-hwrng-throughput-regression.patch new file mode 100644 index 00000000000..682a7eede5b --- /dev/null +++ b/queue-6.6/hwrng-bcm2835-fix-hwrng-throughput-regression.patch @@ -0,0 +1,79 @@ +From 090be81f782e0962b3ee148ccc778d84e8ee12b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 01:27:57 +0200 +Subject: hwrng: bcm2835 - Fix hwrng throughput regression + +From: Stefan Wahren + +[ Upstream commit b58a36008bfa1aadf55f516bcbfae40c779eb54b ] + +The last RCU stall fix caused a massive throughput regression of the +hwrng on Raspberry Pi 0 - 3. hwrng_msleep doesn't sleep precisely enough +and usleep_range doesn't allow scheduling. So try to restore the +best possible throughput by introducing hwrng_yield which interruptable +sleeps for one jiffy. + +Some performance measurements on Raspberry Pi 3B+ (arm64/defconfig): + +sudo dd if=/dev/hwrng of=/dev/null count=1 bs=10000 + +cpu_relax ~138025 Bytes / sec +hwrng_msleep(1000) ~13 Bytes / sec +hwrng_yield ~2510 Bytes / sec + +Fixes: 96cb9d055445 ("hwrng: bcm2835 - use hwrng_msleep() instead of cpu_relax()") +Link: https://lore.kernel.org/linux-arm-kernel/bc97ece5-44a3-4c4e-77da-2db3eb66b128@gmx.net/ +Signed-off-by: Stefan Wahren +Reviewed-by: Jason A. Donenfeld +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/char/hw_random/bcm2835-rng.c | 2 +- + drivers/char/hw_random/core.c | 6 ++++++ + include/linux/hw_random.h | 1 + + 3 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/char/hw_random/bcm2835-rng.c b/drivers/char/hw_random/bcm2835-rng.c +index e19b0f9f48b97..4c08efe7f3753 100644 +--- a/drivers/char/hw_random/bcm2835-rng.c ++++ b/drivers/char/hw_random/bcm2835-rng.c +@@ -70,7 +70,7 @@ static int bcm2835_rng_read(struct hwrng *rng, void *buf, size_t max, + while ((rng_readl(priv, RNG_STATUS) >> 24) == 0) { + if (!wait) + return 0; +- hwrng_msleep(rng, 1000); ++ hwrng_yield(rng); + } + + num_words = rng_readl(priv, RNG_STATUS) >> 24; +diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c +index e3598ec9cfca8..420f155d251fb 100644 +--- a/drivers/char/hw_random/core.c ++++ b/drivers/char/hw_random/core.c +@@ -678,6 +678,12 @@ long hwrng_msleep(struct hwrng *rng, unsigned int msecs) + } + EXPORT_SYMBOL_GPL(hwrng_msleep); + ++long hwrng_yield(struct hwrng *rng) ++{ ++ return wait_for_completion_interruptible_timeout(&rng->dying, 1); ++} ++EXPORT_SYMBOL_GPL(hwrng_yield); ++ + static int __init hwrng_modinit(void) + { + int ret; +diff --git a/include/linux/hw_random.h b/include/linux/hw_random.h +index 8a3115516a1ba..136e9842120e8 100644 +--- a/include/linux/hw_random.h ++++ b/include/linux/hw_random.h +@@ -63,5 +63,6 @@ extern void hwrng_unregister(struct hwrng *rng); + extern void devm_hwrng_unregister(struct device *dve, struct hwrng *rng); + + extern long hwrng_msleep(struct hwrng *rng, unsigned int msecs); ++extern long hwrng_yield(struct hwrng *rng); + + #endif /* LINUX_HWRANDOM_H_ */ +-- +2.42.0 + diff --git a/queue-6.6/hwrng-geode-fix-accessing-registers.patch b/queue-6.6/hwrng-geode-fix-accessing-registers.patch new file mode 100644 index 00000000000..fe4053b25d8 --- /dev/null +++ b/queue-6.6/hwrng-geode-fix-accessing-registers.patch @@ -0,0 +1,58 @@ +From fd2d058a9377068902d27687f389a1cb2f0446ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 10 Sep 2023 10:34:17 +0200 +Subject: hwrng: geode - fix accessing registers + +From: Jonas Gorski + +[ Upstream commit 464bd8ec2f06707f3773676a1bd2c64832a3c805 ] + +When the membase and pci_dev pointer were moved to a new struct in priv, +the actual membase users were left untouched, and they started reading +out arbitrary memory behind the struct instead of registers. This +unfortunately turned the RNG into a constant number generator, depending +on the content of what was at that offset. + +To fix this, update geode_rng_data_{read,present}() to also get the +membase via amd_geode_priv, and properly read from the right addresses +again. + +Fixes: 9f6ec8dc574e ("hwrng: geode - Fix PCI device refcount leak") +Reported-by: Timur I. Davletshin +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217882 +Tested-by: Timur I. Davletshin +Suggested-by: Jo-Philipp Wich +Signed-off-by: Jonas Gorski +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/char/hw_random/geode-rng.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/char/hw_random/geode-rng.c b/drivers/char/hw_random/geode-rng.c +index 12fbe80918319..159baf00a8675 100644 +--- a/drivers/char/hw_random/geode-rng.c ++++ b/drivers/char/hw_random/geode-rng.c +@@ -58,7 +58,8 @@ struct amd_geode_priv { + + static int geode_rng_data_read(struct hwrng *rng, u32 *data) + { +- void __iomem *mem = (void __iomem *)rng->priv; ++ struct amd_geode_priv *priv = (struct amd_geode_priv *)rng->priv; ++ void __iomem *mem = priv->membase; + + *data = readl(mem + GEODE_RNG_DATA_REG); + +@@ -67,7 +68,8 @@ static int geode_rng_data_read(struct hwrng *rng, u32 *data) + + static int geode_rng_data_present(struct hwrng *rng, int wait) + { +- void __iomem *mem = (void __iomem *)rng->priv; ++ struct amd_geode_priv *priv = (struct amd_geode_priv *)rng->priv; ++ void __iomem *mem = priv->membase; + int data, i; + + for (i = 0; i < 20; i++) { +-- +2.42.0 + diff --git a/queue-6.6/i3c-fix-potential-refcount-leak-in-i3c_master_regist.patch b/queue-6.6/i3c-fix-potential-refcount-leak-in-i3c_master_regist.patch new file mode 100644 index 00000000000..d92511bbb36 --- /dev/null +++ b/queue-6.6/i3c-fix-potential-refcount-leak-in-i3c_master_regist.patch @@ -0,0 +1,41 @@ +From 90e6974e93c3eb58afd81fbe2e048e203c811ae1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 16:24:10 +0800 +Subject: i3c: Fix potential refcount leak in i3c_master_register_new_i3c_devs + +From: Dinghao Liu + +[ Upstream commit cab63f64887616e3c4e31cfd8103320be6ebc8d3 ] + +put_device() needs to be called on failure of device_register() +to give up the reference initialized in it to avoid refcount leak. + +Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure") +Signed-off-by: Dinghao Liu +Link: https://lore.kernel.org/r/20230921082410.25548-1-dinghao.liu@zju.edu.cn +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index 87283e4a46076..0e9ff5500a777 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -1525,9 +1525,11 @@ i3c_master_register_new_i3c_devs(struct i3c_master_controller *master) + desc->dev->dev.of_node = desc->boardinfo->of_node; + + ret = device_register(&desc->dev->dev); +- if (ret) ++ if (ret) { + dev_err(&master->dev, + "Failed to add I3C device (err = %d)\n", ret); ++ put_device(&desc->dev->dev); ++ } + } + } + +-- +2.42.0 + diff --git a/queue-6.6/i40e-fix-potential-memory-leaks-in-i40e_remove.patch b/queue-6.6/i40e-fix-potential-memory-leaks-in-i40e_remove.patch new file mode 100644 index 00000000000..ccbe370b7fe --- /dev/null +++ b/queue-6.6/i40e-fix-potential-memory-leaks-in-i40e_remove.patch @@ -0,0 +1,50 @@ +From 75b127ffdec83fe2205a61693736e126d9c83888 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Sep 2023 14:42:01 +0200 +Subject: i40e: fix potential memory leaks in i40e_remove() + +From: Andrii Staikov + +[ Upstream commit 5ca636d927a106780451d957734f02589b972e2b ] + +Instead of freeing memory of a single VSI, make sure +the memory for all VSIs is cleared before releasing VSIs. +Add releasing of their resources in a loop with the iteration +number equal to the number of allocated VSIs. + +Fixes: 41c445ff0f48 ("i40e: main driver core") +Signed-off-by: Andrii Staikov +Signed-off-by: Aleksandr Loktionov +Reviewed-by: Simon Horman +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/i40e/i40e_main.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index de7fd43dc11c8..00ca2b88165cb 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -16320,11 +16320,15 @@ static void i40e_remove(struct pci_dev *pdev) + i40e_switch_branch_release(pf->veb[i]); + } + +- /* Now we can shutdown the PF's VSI, just before we kill ++ /* Now we can shutdown the PF's VSIs, just before we kill + * adminq and hmc. + */ +- if (pf->vsi[pf->lan_vsi]) +- i40e_vsi_release(pf->vsi[pf->lan_vsi]); ++ for (i = pf->num_alloc_vsi; i--;) ++ if (pf->vsi[i]) { ++ i40e_vsi_close(pf->vsi[i]); ++ i40e_vsi_release(pf->vsi[i]); ++ pf->vsi[i] = NULL; ++ } + + i40e_cloud_filter_exit(pf); + +-- +2.42.0 + diff --git a/queue-6.6/iavf-fix-promiscuous-mode-configuration-flow-message.patch b/queue-6.6/iavf-fix-promiscuous-mode-configuration-flow-message.patch new file mode 100644 index 00000000000..33c215c6004 --- /dev/null +++ b/queue-6.6/iavf-fix-promiscuous-mode-configuration-flow-message.patch @@ -0,0 +1,291 @@ +From 18996efcfa9a0b8816117cd158493c3ea822a3d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Aug 2023 17:01:44 -0600 +Subject: iavf: Fix promiscuous mode configuration flow messages + +From: Brett Creeley + +[ Upstream commit 221465de6bd8090ab61267f019866e8d2dd4ea3d ] + +Currently when configuring promiscuous mode on the AVF we detect a +change in the netdev->flags. We use IFF_PROMISC and IFF_ALLMULTI to +determine whether or not we need to request/release promiscuous mode +and/or multicast promiscuous mode. The problem is that the AQ calls for +setting/clearing promiscuous/multicast mode are treated separately. This +leads to a case where we can trigger two promiscuous mode AQ calls in +a row with the incorrect state. To fix this make a few changes. + +Use IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE instead of the previous +IAVF_FLAG_AQ_[REQUEST|RELEASE]_[PROMISC|ALLMULTI] flags. + +In iavf_set_rx_mode() detect if there is a change in the +netdev->flags in comparison with adapter->flags and set the +IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE aq_required bit. Then in +iavf_process_aq_command() only check for IAVF_FLAG_CONFIGURE_PROMISC_MODE +and call iavf_set_promiscuous() if it's set. + +In iavf_set_promiscuous() check again to see which (if any) promiscuous +mode bits have changed when comparing the netdev->flags with the +adapter->flags. Use this to set the flags which get sent to the PF +driver. + +Add a spinlock that is used for updating current_netdev_promisc_flags +and only allows one promiscuous mode AQ at a time. + +[1] Fixes the fact that we will only have one AQ call in the aq_required +queue at any one time. + +[2] Streamlines the change in promiscuous mode to only set one AQ +required bit. + +[3] This allows us to keep track of the current state of the flags and +also makes it so we can take the most recent netdev->flags promiscuous +mode state. + +[4] This fixes the problem where a change in the netdev->flags can cause +IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE to be set in iavf_set_rx_mode(), +but cleared in iavf_set_promiscuous() before the change is ever made via +AQ call. + +Fixes: 47d3483988f6 ("i40evf: Add driver support for promiscuous mode") +Signed-off-by: Brett Creeley +Signed-off-by: Ahmed Zaki +Tested-by: Rafal Romanowski +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/iavf/iavf.h | 16 ++-- + drivers/net/ethernet/intel/iavf/iavf_main.c | 43 +++++------ + .../net/ethernet/intel/iavf/iavf_virtchnl.c | 75 ++++++++++++------- + 3 files changed, 74 insertions(+), 60 deletions(-) + +diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h +index e110ba3461857..d8d7b62ceb24e 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf.h ++++ b/drivers/net/ethernet/intel/iavf/iavf.h +@@ -298,8 +298,6 @@ struct iavf_adapter { + #define IAVF_FLAG_CLIENT_NEEDS_OPEN BIT(10) + #define IAVF_FLAG_CLIENT_NEEDS_CLOSE BIT(11) + #define IAVF_FLAG_CLIENT_NEEDS_L2_PARAMS BIT(12) +-#define IAVF_FLAG_PROMISC_ON BIT(13) +-#define IAVF_FLAG_ALLMULTI_ON BIT(14) + #define IAVF_FLAG_LEGACY_RX BIT(15) + #define IAVF_FLAG_REINIT_ITR_NEEDED BIT(16) + #define IAVF_FLAG_QUEUES_DISABLED BIT(17) +@@ -325,10 +323,7 @@ struct iavf_adapter { + #define IAVF_FLAG_AQ_SET_HENA BIT_ULL(12) + #define IAVF_FLAG_AQ_SET_RSS_KEY BIT_ULL(13) + #define IAVF_FLAG_AQ_SET_RSS_LUT BIT_ULL(14) +-#define IAVF_FLAG_AQ_REQUEST_PROMISC BIT_ULL(15) +-#define IAVF_FLAG_AQ_RELEASE_PROMISC BIT_ULL(16) +-#define IAVF_FLAG_AQ_REQUEST_ALLMULTI BIT_ULL(17) +-#define IAVF_FLAG_AQ_RELEASE_ALLMULTI BIT_ULL(18) ++#define IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE BIT_ULL(15) + #define IAVF_FLAG_AQ_ENABLE_VLAN_STRIPPING BIT_ULL(19) + #define IAVF_FLAG_AQ_DISABLE_VLAN_STRIPPING BIT_ULL(20) + #define IAVF_FLAG_AQ_ENABLE_CHANNELS BIT_ULL(21) +@@ -365,6 +360,12 @@ struct iavf_adapter { + (IAVF_EXTENDED_CAP_SEND_VLAN_V2 | \ + IAVF_EXTENDED_CAP_RECV_VLAN_V2) + ++ /* Lock to prevent possible clobbering of ++ * current_netdev_promisc_flags ++ */ ++ spinlock_t current_netdev_promisc_flags_lock; ++ netdev_features_t current_netdev_promisc_flags; ++ + /* OS defined structs */ + struct net_device *netdev; + struct pci_dev *pdev; +@@ -551,7 +552,8 @@ void iavf_add_ether_addrs(struct iavf_adapter *adapter); + void iavf_del_ether_addrs(struct iavf_adapter *adapter); + void iavf_add_vlans(struct iavf_adapter *adapter); + void iavf_del_vlans(struct iavf_adapter *adapter); +-void iavf_set_promiscuous(struct iavf_adapter *adapter, int flags); ++void iavf_set_promiscuous(struct iavf_adapter *adapter); ++bool iavf_promiscuous_mode_changed(struct iavf_adapter *adapter); + void iavf_request_stats(struct iavf_adapter *adapter); + int iavf_request_reset(struct iavf_adapter *adapter); + void iavf_get_hena(struct iavf_adapter *adapter); +diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c +index b3434dbc90d6f..68783a7b70962 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_main.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c +@@ -1186,6 +1186,16 @@ static int iavf_addr_unsync(struct net_device *netdev, const u8 *addr) + return 0; + } + ++/** ++ * iavf_promiscuous_mode_changed - check if promiscuous mode bits changed ++ * @adapter: device specific adapter ++ */ ++bool iavf_promiscuous_mode_changed(struct iavf_adapter *adapter) ++{ ++ return (adapter->current_netdev_promisc_flags ^ adapter->netdev->flags) & ++ (IFF_PROMISC | IFF_ALLMULTI); ++} ++ + /** + * iavf_set_rx_mode - NDO callback to set the netdev filters + * @netdev: network interface device structure +@@ -1199,19 +1209,10 @@ static void iavf_set_rx_mode(struct net_device *netdev) + __dev_mc_sync(netdev, iavf_addr_sync, iavf_addr_unsync); + spin_unlock_bh(&adapter->mac_vlan_list_lock); + +- if (netdev->flags & IFF_PROMISC && +- !(adapter->flags & IAVF_FLAG_PROMISC_ON)) +- adapter->aq_required |= IAVF_FLAG_AQ_REQUEST_PROMISC; +- else if (!(netdev->flags & IFF_PROMISC) && +- adapter->flags & IAVF_FLAG_PROMISC_ON) +- adapter->aq_required |= IAVF_FLAG_AQ_RELEASE_PROMISC; +- +- if (netdev->flags & IFF_ALLMULTI && +- !(adapter->flags & IAVF_FLAG_ALLMULTI_ON)) +- adapter->aq_required |= IAVF_FLAG_AQ_REQUEST_ALLMULTI; +- else if (!(netdev->flags & IFF_ALLMULTI) && +- adapter->flags & IAVF_FLAG_ALLMULTI_ON) +- adapter->aq_required |= IAVF_FLAG_AQ_RELEASE_ALLMULTI; ++ spin_lock_bh(&adapter->current_netdev_promisc_flags_lock); ++ if (iavf_promiscuous_mode_changed(adapter)) ++ adapter->aq_required |= IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE; ++ spin_unlock_bh(&adapter->current_netdev_promisc_flags_lock); + } + + /** +@@ -2162,19 +2163,8 @@ static int iavf_process_aq_command(struct iavf_adapter *adapter) + return 0; + } + +- if (adapter->aq_required & IAVF_FLAG_AQ_REQUEST_PROMISC) { +- iavf_set_promiscuous(adapter, FLAG_VF_UNICAST_PROMISC | +- FLAG_VF_MULTICAST_PROMISC); +- return 0; +- } +- +- if (adapter->aq_required & IAVF_FLAG_AQ_REQUEST_ALLMULTI) { +- iavf_set_promiscuous(adapter, FLAG_VF_MULTICAST_PROMISC); +- return 0; +- } +- if ((adapter->aq_required & IAVF_FLAG_AQ_RELEASE_PROMISC) || +- (adapter->aq_required & IAVF_FLAG_AQ_RELEASE_ALLMULTI)) { +- iavf_set_promiscuous(adapter, 0); ++ if (adapter->aq_required & IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE) { ++ iavf_set_promiscuous(adapter); + return 0; + } + +@@ -4970,6 +4960,7 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + spin_lock_init(&adapter->cloud_filter_list_lock); + spin_lock_init(&adapter->fdir_fltr_lock); + spin_lock_init(&adapter->adv_rss_lock); ++ spin_lock_init(&adapter->current_netdev_promisc_flags_lock); + + INIT_LIST_HEAD(&adapter->mac_filter_list); + INIT_LIST_HEAD(&adapter->vlan_filter_list); +diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +index f9727e9c3d630..0b97b424e487a 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +@@ -936,14 +936,14 @@ void iavf_del_vlans(struct iavf_adapter *adapter) + /** + * iavf_set_promiscuous + * @adapter: adapter structure +- * @flags: bitmask to control unicast/multicast promiscuous. + * + * Request that the PF enable promiscuous mode for our VSI. + **/ +-void iavf_set_promiscuous(struct iavf_adapter *adapter, int flags) ++void iavf_set_promiscuous(struct iavf_adapter *adapter) + { ++ struct net_device *netdev = adapter->netdev; + struct virtchnl_promisc_info vpi; +- int promisc_all; ++ unsigned int flags; + + if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) { + /* bail because we already have a command pending */ +@@ -952,36 +952,57 @@ void iavf_set_promiscuous(struct iavf_adapter *adapter, int flags) + return; + } + +- promisc_all = FLAG_VF_UNICAST_PROMISC | +- FLAG_VF_MULTICAST_PROMISC; +- if ((flags & promisc_all) == promisc_all) { +- adapter->flags |= IAVF_FLAG_PROMISC_ON; +- adapter->aq_required &= ~IAVF_FLAG_AQ_REQUEST_PROMISC; +- dev_info(&adapter->pdev->dev, "Entering promiscuous mode\n"); +- } ++ /* prevent changes to promiscuous flags */ ++ spin_lock_bh(&adapter->current_netdev_promisc_flags_lock); + +- if (flags & FLAG_VF_MULTICAST_PROMISC) { +- adapter->flags |= IAVF_FLAG_ALLMULTI_ON; +- adapter->aq_required &= ~IAVF_FLAG_AQ_REQUEST_ALLMULTI; +- dev_info(&adapter->pdev->dev, "%s is entering multicast promiscuous mode\n", +- adapter->netdev->name); ++ /* sanity check to prevent duplicate AQ calls */ ++ if (!iavf_promiscuous_mode_changed(adapter)) { ++ adapter->aq_required &= ~IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE; ++ dev_dbg(&adapter->pdev->dev, "No change in promiscuous mode\n"); ++ /* allow changes to promiscuous flags */ ++ spin_unlock_bh(&adapter->current_netdev_promisc_flags_lock); ++ return; + } + +- if (!flags) { +- if (adapter->flags & IAVF_FLAG_PROMISC_ON) { +- adapter->flags &= ~IAVF_FLAG_PROMISC_ON; +- adapter->aq_required &= ~IAVF_FLAG_AQ_RELEASE_PROMISC; +- dev_info(&adapter->pdev->dev, "Leaving promiscuous mode\n"); +- } ++ /* there are 2 bits, but only 3 states */ ++ if (!(netdev->flags & IFF_PROMISC) && ++ netdev->flags & IFF_ALLMULTI) { ++ /* State 1 - only multicast promiscuous mode enabled ++ * - !IFF_PROMISC && IFF_ALLMULTI ++ */ ++ flags = FLAG_VF_MULTICAST_PROMISC; ++ adapter->current_netdev_promisc_flags |= IFF_ALLMULTI; ++ adapter->current_netdev_promisc_flags &= ~IFF_PROMISC; ++ dev_info(&adapter->pdev->dev, "Entering multicast promiscuous mode\n"); ++ } else if (!(netdev->flags & IFF_PROMISC) && ++ !(netdev->flags & IFF_ALLMULTI)) { ++ /* State 2 - unicast/multicast promiscuous mode disabled ++ * - !IFF_PROMISC && !IFF_ALLMULTI ++ */ ++ flags = 0; ++ adapter->current_netdev_promisc_flags &= ++ ~(IFF_PROMISC | IFF_ALLMULTI); ++ dev_info(&adapter->pdev->dev, "Leaving promiscuous mode\n"); ++ } else { ++ /* State 3 - unicast/multicast promiscuous mode enabled ++ * - IFF_PROMISC && IFF_ALLMULTI ++ * - IFF_PROMISC && !IFF_ALLMULTI ++ */ ++ flags = FLAG_VF_UNICAST_PROMISC | FLAG_VF_MULTICAST_PROMISC; ++ adapter->current_netdev_promisc_flags |= IFF_PROMISC; ++ if (netdev->flags & IFF_ALLMULTI) ++ adapter->current_netdev_promisc_flags |= IFF_ALLMULTI; ++ else ++ adapter->current_netdev_promisc_flags &= ~IFF_ALLMULTI; + +- if (adapter->flags & IAVF_FLAG_ALLMULTI_ON) { +- adapter->flags &= ~IAVF_FLAG_ALLMULTI_ON; +- adapter->aq_required &= ~IAVF_FLAG_AQ_RELEASE_ALLMULTI; +- dev_info(&adapter->pdev->dev, "%s is leaving multicast promiscuous mode\n", +- adapter->netdev->name); +- } ++ dev_info(&adapter->pdev->dev, "Entering promiscuous mode\n"); + } + ++ adapter->aq_required &= ~IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE; ++ ++ /* allow changes to promiscuous flags */ ++ spin_unlock_bh(&adapter->current_netdev_promisc_flags_lock); ++ + adapter->current_op = VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE; + vpi.vsi_id = adapter->vsi_res->vsi_id; + vpi.flags = flags; +-- +2.42.0 + diff --git a/queue-6.6/ib-mlx5-fix-init-stage-error-handling-to-avoid-doubl.patch b/queue-6.6/ib-mlx5-fix-init-stage-error-handling-to-avoid-doubl.patch new file mode 100644 index 00000000000..ceb29c914b3 --- /dev/null +++ b/queue-6.6/ib-mlx5-fix-init-stage-error-handling-to-avoid-doubl.patch @@ -0,0 +1,90 @@ +From f97b407f5f11c3e82e2307837dca27649dc2b6fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Oct 2023 13:01:58 -0500 +Subject: IB/mlx5: Fix init stage error handling to avoid double free of same + QP and UAF + +From: George Kennedy + +[ Upstream commit 2ef422f063b74adcc4a4a9004b0a87bb55e0a836 ] + +In the unlikely event that workqueue allocation fails and returns NULL in +mlx5_mkey_cache_init(), delete the call to +mlx5r_umr_resource_cleanup() (which frees the QP) in +mlx5_ib_stage_post_ib_reg_umr_init(). This will avoid attempted double +free of the same QP when __mlx5_ib_add() does its cleanup. + +Resolves a splat: + + Syzkaller reported a UAF in ib_destroy_qp_user + + workqueue: Failed to create a rescuer kthread for wq "mkey_cache": -EINTR + infiniband mlx5_0: mlx5_mkey_cache_init:981:(pid 1642): + failed to create work queue + infiniband mlx5_0: mlx5_ib_stage_post_ib_reg_umr_init:4075:(pid 1642): + mr cache init failed -12 + ================================================================== + BUG: KASAN: slab-use-after-free in ib_destroy_qp_user (drivers/infiniband/core/verbs.c:2073) + Read of size 8 at addr ffff88810da310a8 by task repro_upstream/1642 + + Call Trace: + + kasan_report (mm/kasan/report.c:590) + ib_destroy_qp_user (drivers/infiniband/core/verbs.c:2073) + mlx5r_umr_resource_cleanup (drivers/infiniband/hw/mlx5/umr.c:198) + __mlx5_ib_add (drivers/infiniband/hw/mlx5/main.c:4178) + mlx5r_probe (drivers/infiniband/hw/mlx5/main.c:4402) + ... + + + Allocated by task 1642: + __kmalloc (./include/linux/kasan.h:198 mm/slab_common.c:1026 + mm/slab_common.c:1039) + create_qp (./include/linux/slab.h:603 ./include/linux/slab.h:720 + ./include/rdma/ib_verbs.h:2795 drivers/infiniband/core/verbs.c:1209) + ib_create_qp_kernel (drivers/infiniband/core/verbs.c:1347) + mlx5r_umr_resource_init (drivers/infiniband/hw/mlx5/umr.c:164) + mlx5_ib_stage_post_ib_reg_umr_init (drivers/infiniband/hw/mlx5/main.c:4070) + __mlx5_ib_add (drivers/infiniband/hw/mlx5/main.c:4168) + mlx5r_probe (drivers/infiniband/hw/mlx5/main.c:4402) + ... + + Freed by task 1642: + __kmem_cache_free (mm/slub.c:1826 mm/slub.c:3809 mm/slub.c:3822) + ib_destroy_qp_user (drivers/infiniband/core/verbs.c:2112) + mlx5r_umr_resource_cleanup (drivers/infiniband/hw/mlx5/umr.c:198) + mlx5_ib_stage_post_ib_reg_umr_init (drivers/infiniband/hw/mlx5/main.c:4076 + drivers/infiniband/hw/mlx5/main.c:4065) + __mlx5_ib_add (drivers/infiniband/hw/mlx5/main.c:4168) + mlx5r_probe (drivers/infiniband/hw/mlx5/main.c:4402) + ... + +Fixes: 04876c12c19e ("RDMA/mlx5: Move init and cleanup of UMR to umr.c") +Link: https://lore.kernel.org/r/1698170518-4006-1-git-send-email-george.kennedy@oracle.com +Suggested-by: Leon Romanovsky +Signed-off-by: George Kennedy +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/mlx5/main.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c +index 555629b798b95..5d963abb7e609 100644 +--- a/drivers/infiniband/hw/mlx5/main.c ++++ b/drivers/infiniband/hw/mlx5/main.c +@@ -4071,10 +4071,8 @@ static int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev) + return ret; + + ret = mlx5_mkey_cache_init(dev); +- if (ret) { ++ if (ret) + mlx5_ib_warn(dev, "mr cache init failed %d\n", ret); +- mlx5r_umr_resource_cleanup(dev); +- } + return ret; + } + +-- +2.42.0 + diff --git a/queue-6.6/ib-mlx5-fix-rdma-counter-binding-for-raw-qp.patch b/queue-6.6/ib-mlx5-fix-rdma-counter-binding-for-raw-qp.patch new file mode 100644 index 00000000000..7b628250310 --- /dev/null +++ b/queue-6.6/ib-mlx5-fix-rdma-counter-binding-for-raw-qp.patch @@ -0,0 +1,76 @@ +From ecf3d30362062cb3339b3cf828de824a5ab6eac5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 13:41:20 +0300 +Subject: IB/mlx5: Fix rdma counter binding for RAW QP + +From: Patrisious Haddad + +[ Upstream commit c1336bb4aa5e809a622a87d74311275514086596 ] + +Previously when we had a RAW QP, we bound a counter to it when it moved +to INIT state, using the counter context inside RQC. + +But when we try to modify that counter later in RTS state we used +modify QP which tries to change the counter inside QPC instead of RQC. + +Now we correctly modify the counter set_id inside of RQC instead of QPC +for the RAW QP. + +Fixes: d14133dd4161 ("IB/mlx5: Support set qp counter") +Signed-off-by: Patrisious Haddad +Reviewed-by: Mark Zhang +Link: https://lore.kernel.org/r/2e5ab6713784a8fe997d19c508187a0dfecf2dfc.1696847964.git.leon@kernel.org +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/mlx5/qp.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c +index 78b96bfb4e6ac..2340baaba8e67 100644 +--- a/drivers/infiniband/hw/mlx5/qp.c ++++ b/drivers/infiniband/hw/mlx5/qp.c +@@ -4045,6 +4045,30 @@ static unsigned int get_tx_affinity(struct ib_qp *qp, + return tx_affinity; + } + ++static int __mlx5_ib_qp_set_raw_qp_counter(struct mlx5_ib_qp *qp, u32 set_id, ++ struct mlx5_core_dev *mdev) ++{ ++ struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp; ++ struct mlx5_ib_rq *rq = &raw_packet_qp->rq; ++ u32 in[MLX5_ST_SZ_DW(modify_rq_in)] = {}; ++ void *rqc; ++ ++ if (!qp->rq.wqe_cnt) ++ return 0; ++ ++ MLX5_SET(modify_rq_in, in, rq_state, rq->state); ++ MLX5_SET(modify_rq_in, in, uid, to_mpd(qp->ibqp.pd)->uid); ++ ++ rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx); ++ MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RDY); ++ ++ MLX5_SET64(modify_rq_in, in, modify_bitmask, ++ MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_RQ_COUNTER_SET_ID); ++ MLX5_SET(rqc, rqc, counter_set_id, set_id); ++ ++ return mlx5_core_modify_rq(mdev, rq->base.mqp.qpn, in); ++} ++ + static int __mlx5_ib_qp_set_counter(struct ib_qp *qp, + struct rdma_counter *counter) + { +@@ -4060,6 +4084,9 @@ static int __mlx5_ib_qp_set_counter(struct ib_qp *qp, + else + set_id = mlx5_ib_get_counters_id(dev, mqp->port - 1); + ++ if (mqp->type == IB_QPT_RAW_PACKET) ++ return __mlx5_ib_qp_set_raw_qp_counter(mqp, set_id, dev->mdev); ++ + base = &mqp->trans_qp.base; + MLX5_SET(rts2rts_qp_in, in, opcode, MLX5_CMD_OP_RTS2RTS_QP); + MLX5_SET(rts2rts_qp_in, in, qpn, base->mqp.qpn); +-- +2.42.0 + diff --git a/queue-6.6/ice-fix-pin-assignment-for-e810-t-without-sma-contro.patch b/queue-6.6/ice-fix-pin-assignment-for-e810-t-without-sma-contro.patch new file mode 100644 index 00000000000..c59969a1a75 --- /dev/null +++ b/queue-6.6/ice-fix-pin-assignment-for-e810-t-without-sma-contro.patch @@ -0,0 +1,71 @@ +From 693edbca67af81f52e240b5c8a056d2f76b27a48 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Aug 2023 17:00:55 -0700 +Subject: ice: fix pin assignment for E810-T without SMA control + +From: Jacob Keller + +[ Upstream commit 5a7cee1cb4b9ef99fe7acd571e1bd51b023b099a ] + +Since commit 43c4958a3ddb ("ice: Merge pin initialization of E810 and E810T +adapters"), the ice_ptp_setup_pins_e810() function has been used for both +E810 and E810-T devices. The new implementation only distinguishes between +whether the device has SMA control or not. It was assumed this is always +true for E810-T devices. In addition, it does not set the n_per_out value +appropriately when SMA control is enabled. + +In some cases, the E810-T device may not have access to SMA control. In +that case, the E810-T device actually has access to fewer pins than a +standard E810 device. + +Fix the implementation to correctly assign the appropriate pin counts for +E810-T devices both with and without SMA control. The mentioned commit +already includes the appropriate macro values for these pin counts but they +were unused. + +Instead of assigning the default E810 values and then overwriting them, +handle the cases separately in order of E810-T with SMA, E810-T without +SMA, and then standard E810. This flow makes following the logic easier. + +Fixes: 43c4958a3ddb ("ice: Merge pin initialization of E810 and E810T adapters") +Signed-off-by: Jacob Keller +Tested-by: Sunitha Mekala (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_ptp.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c +index 81d96a40d5a74..c4270708a7694 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c +@@ -2246,18 +2246,20 @@ ice_ptp_setup_sma_pins_e810t(struct ice_pf *pf, struct ptp_clock_info *info) + static void + ice_ptp_setup_pins_e810(struct ice_pf *pf, struct ptp_clock_info *info) + { +- info->n_per_out = N_PER_OUT_E810; +- +- if (ice_is_feature_supported(pf, ICE_F_PTP_EXTTS)) +- info->n_ext_ts = N_EXT_TS_E810; +- + if (ice_is_feature_supported(pf, ICE_F_SMA_CTRL)) { + info->n_ext_ts = N_EXT_TS_E810; ++ info->n_per_out = N_PER_OUT_E810T; + info->n_pins = NUM_PTP_PINS_E810T; + info->verify = ice_verify_pin_e810t; + + /* Complete setup of the SMA pins */ + ice_ptp_setup_sma_pins_e810t(pf, info); ++ } else if (ice_is_e810t(&pf->hw)) { ++ info->n_ext_ts = N_EXT_TS_NO_SMA_E810T; ++ info->n_per_out = N_PER_OUT_NO_SMA_E810T; ++ } else { ++ info->n_per_out = N_PER_OUT_E810; ++ info->n_ext_ts = N_EXT_TS_E810; + } + } + +-- +2.42.0 + diff --git a/queue-6.6/iio-frequency-adf4350-use-device-managed-functions-a.patch b/queue-6.6/iio-frequency-adf4350-use-device-managed-functions-a.patch new file mode 100644 index 00000000000..8ee63a075df --- /dev/null +++ b/queue-6.6/iio-frequency-adf4350-use-device-managed-functions-a.patch @@ -0,0 +1,180 @@ +From 97764ee5738b6645470eb90c6f1af58ea9abdd73 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Aug 2023 14:27:16 +0800 +Subject: iio: frequency: adf4350: Use device managed functions and fix power + down issue. + +From: Jinjie Ruan + +[ Upstream commit 9979cc64853b598518a485c2e554657d5c7a00c8 ] + +The devm_clk_get_enabled() helper: + - calls devm_clk_get() + - calls clk_prepare_enable() and registers what is needed in order to + call clk_disable_unprepare() when needed, as a managed resource. + +Also replace devm_regulator_get() and regulator_enable() with +devm_regulator_get_enable() helper and remove regulator_disable(). + +Replace iio_device_register() with devm_iio_device_register() and remove +iio_device_unregister(). + +And st->reg is not used anymore, so remove it. + +As Jonathan pointed out, couple of things that are wrong: + +1) The device is powered down 'before' we unregister it with the + subsystem and as such userspace interfaces are still exposed which + probably won't do the right thing if the chip is powered down. + +2) This isn't done in the error paths in probe. + +To solve this problem, register a new callback adf4350_power_down() +with devm_add_action_or_reset(), to enable software power down in both +error and device detach path. So the remove function can be removed. + +Remove spi_set_drvdata() from the probe function, since spi_get_drvdata() +is not used anymore. + +Fixes: e31166f0fd48 ("iio: frequency: New driver for Analog Devices ADF4350/ADF4351 Wideband Synthesizers") +Signed-off-by: Jinjie Ruan +Link: https://lore.kernel.org/r/20230828062717.2310219-1-ruanjinjie@huawei.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/frequency/adf4350.c | 75 ++++++++++----------------------- + 1 file changed, 23 insertions(+), 52 deletions(-) + +diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c +index 85e289700c3c5..4abf80f75ef5d 100644 +--- a/drivers/iio/frequency/adf4350.c ++++ b/drivers/iio/frequency/adf4350.c +@@ -33,7 +33,6 @@ enum { + + struct adf4350_state { + struct spi_device *spi; +- struct regulator *reg; + struct gpio_desc *lock_detect_gpiod; + struct adf4350_platform_data *pdata; + struct clk *clk; +@@ -469,6 +468,15 @@ static struct adf4350_platform_data *adf4350_parse_dt(struct device *dev) + return pdata; + } + ++static void adf4350_power_down(void *data) ++{ ++ struct iio_dev *indio_dev = data; ++ struct adf4350_state *st = iio_priv(indio_dev); ++ ++ st->regs[ADF4350_REG2] |= ADF4350_REG2_POWER_DOWN_EN; ++ adf4350_sync_config(st); ++} ++ + static int adf4350_probe(struct spi_device *spi) + { + struct adf4350_platform_data *pdata; +@@ -491,31 +499,21 @@ static int adf4350_probe(struct spi_device *spi) + } + + if (!pdata->clkin) { +- clk = devm_clk_get(&spi->dev, "clkin"); ++ clk = devm_clk_get_enabled(&spi->dev, "clkin"); + if (IS_ERR(clk)) +- return -EPROBE_DEFER; +- +- ret = clk_prepare_enable(clk); +- if (ret < 0) +- return ret; ++ return PTR_ERR(clk); + } + + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); +- if (indio_dev == NULL) { +- ret = -ENOMEM; +- goto error_disable_clk; +- } ++ if (indio_dev == NULL) ++ return -ENOMEM; + + st = iio_priv(indio_dev); + +- st->reg = devm_regulator_get(&spi->dev, "vcc"); +- if (!IS_ERR(st->reg)) { +- ret = regulator_enable(st->reg); +- if (ret) +- goto error_disable_clk; +- } ++ ret = devm_regulator_get_enable(&spi->dev, "vcc"); ++ if (ret) ++ return ret; + +- spi_set_drvdata(spi, indio_dev); + st->spi = spi; + st->pdata = pdata; + +@@ -544,47 +542,21 @@ static int adf4350_probe(struct spi_device *spi) + + st->lock_detect_gpiod = devm_gpiod_get_optional(&spi->dev, NULL, + GPIOD_IN); +- if (IS_ERR(st->lock_detect_gpiod)) { +- ret = PTR_ERR(st->lock_detect_gpiod); +- goto error_disable_reg; +- } ++ if (IS_ERR(st->lock_detect_gpiod)) ++ return PTR_ERR(st->lock_detect_gpiod); + + if (pdata->power_up_frequency) { + ret = adf4350_set_freq(st, pdata->power_up_frequency); + if (ret) +- goto error_disable_reg; ++ return ret; + } + +- ret = iio_device_register(indio_dev); ++ ret = devm_add_action_or_reset(&spi->dev, adf4350_power_down, indio_dev); + if (ret) +- goto error_disable_reg; +- +- return 0; +- +-error_disable_reg: +- if (!IS_ERR(st->reg)) +- regulator_disable(st->reg); +-error_disable_clk: +- clk_disable_unprepare(clk); +- +- return ret; +-} +- +-static void adf4350_remove(struct spi_device *spi) +-{ +- struct iio_dev *indio_dev = spi_get_drvdata(spi); +- struct adf4350_state *st = iio_priv(indio_dev); +- struct regulator *reg = st->reg; +- +- st->regs[ADF4350_REG2] |= ADF4350_REG2_POWER_DOWN_EN; +- adf4350_sync_config(st); +- +- iio_device_unregister(indio_dev); +- +- clk_disable_unprepare(st->clk); ++ return dev_err_probe(&spi->dev, ret, ++ "Failed to add action to managed power down\n"); + +- if (!IS_ERR(reg)) +- regulator_disable(reg); ++ return devm_iio_device_register(&spi->dev, indio_dev); + } + + static const struct of_device_id adf4350_of_match[] = { +@@ -607,7 +579,6 @@ static struct spi_driver adf4350_driver = { + .of_match_table = adf4350_of_match, + }, + .probe = adf4350_probe, +- .remove = adf4350_remove, + .id_table = adf4350_id, + }; + module_spi_driver(adf4350_driver); +-- +2.42.0 + diff --git a/queue-6.6/interconnect-fix-error-handling-in-qnoc_probe.patch b/queue-6.6/interconnect-fix-error-handling-in-qnoc_probe.patch new file mode 100644 index 00000000000..1fefd32d990 --- /dev/null +++ b/queue-6.6/interconnect-fix-error-handling-in-qnoc_probe.patch @@ -0,0 +1,77 @@ +From 42449301be5ea7ec290cf89efbf26589b384eec0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Aug 2023 21:05:21 +0800 +Subject: interconnect: fix error handling in qnoc_probe() + +From: Yang Yingliang + +[ Upstream commit 273f74a2e7d15a5c216a4a26b84b1563c7092c9d ] + +Add missing clk_disable_unprepare() and clk_bulk_disable_unprepare() +in the error path in qnoc_probe(). And when qcom_icc_qos_set() fails, +it needs remove nodes and disable clks. + +Fixes: 2e2113c8a64f ("interconnect: qcom: rpm: Handle interface clocks") +Signed-off-by: Yang Yingliang +Link: https://lore.kernel.org/r/20230803130521.959487-1-yangyingliang@huawei.com +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/icc-rpm.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/drivers/interconnect/qcom/icc-rpm.c b/drivers/interconnect/qcom/icc-rpm.c +index 2c16917ba1fda..e76356f91125f 100644 +--- a/drivers/interconnect/qcom/icc-rpm.c ++++ b/drivers/interconnect/qcom/icc-rpm.c +@@ -497,7 +497,7 @@ int qnoc_probe(struct platform_device *pdev) + + ret = devm_clk_bulk_get(dev, qp->num_intf_clks, qp->intf_clks); + if (ret) +- return ret; ++ goto err_disable_unprepare_clk; + + provider = &qp->provider; + provider->dev = dev; +@@ -512,13 +512,15 @@ int qnoc_probe(struct platform_device *pdev) + /* If this fails, bus accesses will crash the platform! */ + ret = clk_bulk_prepare_enable(qp->num_intf_clks, qp->intf_clks); + if (ret) +- return ret; ++ goto err_disable_unprepare_clk; + + for (i = 0; i < num_nodes; i++) { + size_t j; + + node = icc_node_create(qnodes[i]->id); + if (IS_ERR(node)) { ++ clk_bulk_disable_unprepare(qp->num_intf_clks, ++ qp->intf_clks); + ret = PTR_ERR(node); + goto err_remove_nodes; + } +@@ -534,8 +536,11 @@ int qnoc_probe(struct platform_device *pdev) + if (qnodes[i]->qos.ap_owned && + qnodes[i]->qos.qos_mode != NOC_QOS_MODE_INVALID) { + ret = qcom_icc_qos_set(node); +- if (ret) +- return ret; ++ if (ret) { ++ clk_bulk_disable_unprepare(qp->num_intf_clks, ++ qp->intf_clks); ++ goto err_remove_nodes; ++ } + } + + data->nodes[i] = node; +@@ -563,6 +568,7 @@ int qnoc_probe(struct platform_device *pdev) + icc_provider_deregister(provider); + err_remove_nodes: + icc_nodes_remove(provider); ++err_disable_unprepare_clk: + clk_disable_unprepare(qp->bus_clk); + + return ret; +-- +2.42.0 + diff --git a/queue-6.6/interconnect-qcom-osm-l3-replace-custom-implementati.patch b/queue-6.6/interconnect-qcom-osm-l3-replace-custom-implementati.patch new file mode 100644 index 00000000000..a457ef3ae3b --- /dev/null +++ b/queue-6.6/interconnect-qcom-osm-l3-replace-custom-implementati.patch @@ -0,0 +1,45 @@ +From ce609bbc6c6ce16d479f4fe5d89a29bbbb8a9d14 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Sep 2023 18:49:27 +0300 +Subject: interconnect: qcom: osm-l3: Replace custom implementation of + COUNT_ARGS() + +From: Andy Shevchenko + +[ Upstream commit 577a3c5af1fe87b65931ea94d5515266da301f56 ] + +Replace custom and non-portable implementation of COUNT_ARGS(). + +Fixes: 5bc9900addaf ("interconnect: qcom: Add OSM L3 interconnect provider support") +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20230920154927.2090732-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/osm-l3.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/interconnect/qcom/osm-l3.c b/drivers/interconnect/qcom/osm-l3.c +index dc321bb86d0be..e97478bbc2825 100644 +--- a/drivers/interconnect/qcom/osm-l3.c ++++ b/drivers/interconnect/qcom/osm-l3.c +@@ -3,6 +3,7 @@ + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + */ + ++#include + #include + #include + #include +@@ -78,7 +79,7 @@ enum { + .name = #_name, \ + .id = _id, \ + .buswidth = _buswidth, \ +- .num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })), \ ++ .num_links = COUNT_ARGS(__VA_ARGS__), \ + .links = { __VA_ARGS__ }, \ + } + +-- +2.42.0 + diff --git a/queue-6.6/interconnect-qcom-qdu1000-set-acv-enable_mask.patch b/queue-6.6/interconnect-qcom-qdu1000-set-acv-enable_mask.patch new file mode 100644 index 00000000000..bf35ca53492 --- /dev/null +++ b/queue-6.6/interconnect-qcom-qdu1000-set-acv-enable_mask.patch @@ -0,0 +1,35 @@ +From 90e1ef21deedebe13f9a5e92157e17eef95ca61a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Aug 2023 01:20:44 +0200 +Subject: interconnect: qcom: qdu1000: Set ACV enable_mask + +From: Konrad Dybcio + +[ Upstream commit 8517824f0e94d52ab82742106314f0b8875e03c4 ] + +ACV expects an enable_mask corresponding to the APPS RSC, fill it in. + +Fixes: 1f51339f7dd0 ("interconnect: qcom: Add QDU1000/QRU1000 interconnect driver") +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230811-topic-acv-v2-1-765ad70e539a@linaro.org +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/qdu1000.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/interconnect/qcom/qdu1000.c b/drivers/interconnect/qcom/qdu1000.c +index bf800dd7d4ba1..a7392eb73d4a9 100644 +--- a/drivers/interconnect/qcom/qdu1000.c ++++ b/drivers/interconnect/qcom/qdu1000.c +@@ -769,6 +769,7 @@ static struct qcom_icc_node xs_sys_tcu_cfg = { + + static struct qcom_icc_bcm bcm_acv = { + .name = "ACV", ++ .enable_mask = BIT(3), + .num_nodes = 1, + .nodes = { &ebi }, + }; +-- +2.42.0 + diff --git a/queue-6.6/interconnect-qcom-sc7180-set-acv-enable_mask.patch b/queue-6.6/interconnect-qcom-sc7180-set-acv-enable_mask.patch new file mode 100644 index 00000000000..ac8a374b5c5 --- /dev/null +++ b/queue-6.6/interconnect-qcom-sc7180-set-acv-enable_mask.patch @@ -0,0 +1,35 @@ +From 317b72b832f5848e8855f3f8579bb3561b262608 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Aug 2023 01:20:45 +0200 +Subject: interconnect: qcom: sc7180: Set ACV enable_mask + +From: Konrad Dybcio + +[ Upstream commit 1ad83c4792722fe134c1352591420702ff7b9091 ] + +ACV expects an enable_mask corresponding to the APPS RSC, fill it in. + +Fixes: 2d1f95ab9feb ("interconnect: qcom: Add SC7180 interconnect provider driver") +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230811-topic-acv-v2-2-765ad70e539a@linaro.org +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/sc7180.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/interconnect/qcom/sc7180.c b/drivers/interconnect/qcom/sc7180.c +index d94ab9b39f3db..af2be15438403 100644 +--- a/drivers/interconnect/qcom/sc7180.c ++++ b/drivers/interconnect/qcom/sc7180.c +@@ -1238,6 +1238,7 @@ static struct qcom_icc_node xs_sys_tcu_cfg = { + + static struct qcom_icc_bcm bcm_acv = { + .name = "ACV", ++ .enable_mask = BIT(3), + .keepalive = false, + .num_nodes = 1, + .nodes = { &ebi }, +-- +2.42.0 + diff --git a/queue-6.6/interconnect-qcom-sc7280-set-acv-enable_mask.patch b/queue-6.6/interconnect-qcom-sc7280-set-acv-enable_mask.patch new file mode 100644 index 00000000000..c4c6b5ab02f --- /dev/null +++ b/queue-6.6/interconnect-qcom-sc7280-set-acv-enable_mask.patch @@ -0,0 +1,35 @@ +From e8375856545422e225804e3777e243852b3a454d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Aug 2023 01:20:46 +0200 +Subject: interconnect: qcom: sc7280: Set ACV enable_mask + +From: Konrad Dybcio + +[ Upstream commit 437b8e7fcd5df792cb8b8095e9f6eccefec6c099 ] + +ACV expects an enable_mask corresponding to the APPS RSC, fill it in. + +Fixes: 46bdcac533cc ("interconnect: qcom: Add SC7280 interconnect provider driver") +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230811-topic-acv-v2-3-765ad70e539a@linaro.org +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/sc7280.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/interconnect/qcom/sc7280.c b/drivers/interconnect/qcom/sc7280.c +index 6592839b4d94b..a626dbc719995 100644 +--- a/drivers/interconnect/qcom/sc7280.c ++++ b/drivers/interconnect/qcom/sc7280.c +@@ -1285,6 +1285,7 @@ static struct qcom_icc_node srvc_snoc = { + + static struct qcom_icc_bcm bcm_acv = { + .name = "ACV", ++ .enable_mask = BIT(3), + .num_nodes = 1, + .nodes = { &ebi }, + }; +-- +2.42.0 + diff --git a/queue-6.6/interconnect-qcom-sc8180x-set-acv-enable_mask.patch b/queue-6.6/interconnect-qcom-sc8180x-set-acv-enable_mask.patch new file mode 100644 index 00000000000..658120608e6 --- /dev/null +++ b/queue-6.6/interconnect-qcom-sc8180x-set-acv-enable_mask.patch @@ -0,0 +1,35 @@ +From 28a8cb67b6fd14f633faab256a0f2510662959ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Aug 2023 01:20:47 +0200 +Subject: interconnect: qcom: sc8180x: Set ACV enable_mask + +From: Konrad Dybcio + +[ Upstream commit 0fcaaed3ff4b99e5b688b799f48989f1e4bb8a8b ] + +ACV expects an enable_mask corresponding to the APPS RSC, fill it in. + +Fixes: 9c8c6bac1ae8 ("interconnect: qcom: Add SC8180x providers") +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230811-topic-acv-v2-4-765ad70e539a@linaro.org +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/sc8180x.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/interconnect/qcom/sc8180x.c b/drivers/interconnect/qcom/sc8180x.c +index 0fb4898dabcfe..bdd3471d4ac89 100644 +--- a/drivers/interconnect/qcom/sc8180x.c ++++ b/drivers/interconnect/qcom/sc8180x.c +@@ -1345,6 +1345,7 @@ static struct qcom_icc_node slv_qup_core_2 = { + + static struct qcom_icc_bcm bcm_acv = { + .name = "ACV", ++ .enable_mask = BIT(3), + .num_nodes = 1, + .nodes = { &slv_ebi } + }; +-- +2.42.0 + diff --git a/queue-6.6/interconnect-qcom-sc8280xp-set-acv-enable_mask.patch b/queue-6.6/interconnect-qcom-sc8280xp-set-acv-enable_mask.patch new file mode 100644 index 00000000000..26effab4d7a --- /dev/null +++ b/queue-6.6/interconnect-qcom-sc8280xp-set-acv-enable_mask.patch @@ -0,0 +1,35 @@ +From 4613c88fb5d591444b25af819dda7d4a9545ff9e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Aug 2023 01:20:48 +0200 +Subject: interconnect: qcom: sc8280xp: Set ACV enable_mask + +From: Konrad Dybcio + +[ Upstream commit 688ffb3dcf85fc4b7ea82af842493013747a9e2c ] + +ACV expects an enable_mask corresponding to the APPS RSC, fill it in. + +Fixes: f29dabda7917 ("interconnect: qcom: Add SC8280XP interconnect provider") +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230811-topic-acv-v2-5-765ad70e539a@linaro.org +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/sc8280xp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/interconnect/qcom/sc8280xp.c b/drivers/interconnect/qcom/sc8280xp.c +index b82c5493cbb56..0270f6c64481a 100644 +--- a/drivers/interconnect/qcom/sc8280xp.c ++++ b/drivers/interconnect/qcom/sc8280xp.c +@@ -1712,6 +1712,7 @@ static struct qcom_icc_node srvc_snoc = { + + static struct qcom_icc_bcm bcm_acv = { + .name = "ACV", ++ .enable_mask = BIT(3), + .num_nodes = 1, + .nodes = { &ebi }, + }; +-- +2.42.0 + diff --git a/queue-6.6/interconnect-qcom-sdm670-set-acv-enable_mask.patch b/queue-6.6/interconnect-qcom-sdm670-set-acv-enable_mask.patch new file mode 100644 index 00000000000..43e6da96a80 --- /dev/null +++ b/queue-6.6/interconnect-qcom-sdm670-set-acv-enable_mask.patch @@ -0,0 +1,35 @@ +From 96b2fe8b9a1ef2985bcc8fb694058a811dc9a99b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Aug 2023 01:20:49 +0200 +Subject: interconnect: qcom: sdm670: Set ACV enable_mask + +From: Konrad Dybcio + +[ Upstream commit 7b85ea8b9300be5c2818e1f61a274ff2c4c063ee ] + +ACV expects an enable_mask corresponding to the APPS RSC, fill it in. + +Fixes: 7e438e18874e ("interconnect: qcom: add sdm670 interconnects") +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230811-topic-acv-v2-6-765ad70e539a@linaro.org +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/sdm670.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/interconnect/qcom/sdm670.c b/drivers/interconnect/qcom/sdm670.c +index 540a2108b77c1..907e1ff4ff817 100644 +--- a/drivers/interconnect/qcom/sdm670.c ++++ b/drivers/interconnect/qcom/sdm670.c +@@ -1047,6 +1047,7 @@ static struct qcom_icc_node xs_sys_tcu_cfg = { + + static struct qcom_icc_bcm bcm_acv = { + .name = "ACV", ++ .enable_mask = BIT(3), + .keepalive = false, + .num_nodes = 1, + .nodes = { &ebi }, +-- +2.42.0 + diff --git a/queue-6.6/interconnect-qcom-sdm845-set-acv-enable_mask.patch b/queue-6.6/interconnect-qcom-sdm845-set-acv-enable_mask.patch new file mode 100644 index 00000000000..7b69c3ce899 --- /dev/null +++ b/queue-6.6/interconnect-qcom-sdm845-set-acv-enable_mask.patch @@ -0,0 +1,35 @@ +From 7df64a6f430d369b7d429cb154229b29d6f9fd18 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Aug 2023 01:20:50 +0200 +Subject: interconnect: qcom: sdm845: Set ACV enable_mask + +From: Konrad Dybcio + +[ Upstream commit f8fe97a9fd2098de0570387029065eef657d50ee ] + +ACV expects an enable_mask corresponding to the APPS RSC, fill it in. + +Fixes: b5d2f741077a ("interconnect: qcom: Add sdm845 interconnect provider driver") +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230811-topic-acv-v2-7-765ad70e539a@linaro.org +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/sdm845.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/interconnect/qcom/sdm845.c b/drivers/interconnect/qcom/sdm845.c +index b9243c0aa626c..855802be93fea 100644 +--- a/drivers/interconnect/qcom/sdm845.c ++++ b/drivers/interconnect/qcom/sdm845.c +@@ -1265,6 +1265,7 @@ static struct qcom_icc_node xs_sys_tcu_cfg = { + + static struct qcom_icc_bcm bcm_acv = { + .name = "ACV", ++ .enable_mask = BIT(3), + .keepalive = false, + .num_nodes = 1, + .nodes = { &ebi }, +-- +2.42.0 + diff --git a/queue-6.6/interconnect-qcom-sm6350-set-acv-enable_mask.patch b/queue-6.6/interconnect-qcom-sm6350-set-acv-enable_mask.patch new file mode 100644 index 00000000000..95b88efe625 --- /dev/null +++ b/queue-6.6/interconnect-qcom-sm6350-set-acv-enable_mask.patch @@ -0,0 +1,35 @@ +From 1918d1485b983fe24da15f180497f0346435517e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Aug 2023 01:20:51 +0200 +Subject: interconnect: qcom: sm6350: Set ACV enable_mask + +From: Konrad Dybcio + +[ Upstream commit fe7a3abf4111992af3de51d22383a8e8a0affe1e ] + +ACV expects an enable_mask corresponding to the APPS RSC, fill it in. + +Fixes: 6a6eff73a954 ("interconnect: qcom: Add SM6350 driver support") +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230811-topic-acv-v2-8-765ad70e539a@linaro.org +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/sm6350.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/interconnect/qcom/sm6350.c b/drivers/interconnect/qcom/sm6350.c +index 49aed492e9b80..f41d7e19ba269 100644 +--- a/drivers/interconnect/qcom/sm6350.c ++++ b/drivers/interconnect/qcom/sm6350.c +@@ -1164,6 +1164,7 @@ static struct qcom_icc_node xs_sys_tcu_cfg = { + + static struct qcom_icc_bcm bcm_acv = { + .name = "ACV", ++ .enable_mask = BIT(3), + .keepalive = false, + .num_nodes = 1, + .nodes = { &ebi }, +-- +2.42.0 + diff --git a/queue-6.6/interconnect-qcom-sm8150-set-acv-enable_mask.patch b/queue-6.6/interconnect-qcom-sm8150-set-acv-enable_mask.patch new file mode 100644 index 00000000000..d76185ebe61 --- /dev/null +++ b/queue-6.6/interconnect-qcom-sm8150-set-acv-enable_mask.patch @@ -0,0 +1,35 @@ +From f15e9f2f5eab0116a907f259893594cebcca9549 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Aug 2023 01:20:52 +0200 +Subject: interconnect: qcom: sm8150: Set ACV enable_mask + +From: Konrad Dybcio + +[ Upstream commit 7ed42176406e5a2c9a5767d0d75690c7d1588027 ] + +ACV expects an enable_mask corresponding to the APPS RSC, fill it in. + +Fixes: a09b817c8bad ("interconnect: qcom: Add SM8150 interconnect provider driver") +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230811-topic-acv-v2-9-765ad70e539a@linaro.org +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/sm8150.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/interconnect/qcom/sm8150.c b/drivers/interconnect/qcom/sm8150.c +index c7c9cf7f746b0..edfe824cad353 100644 +--- a/drivers/interconnect/qcom/sm8150.c ++++ b/drivers/interconnect/qcom/sm8150.c +@@ -1282,6 +1282,7 @@ static struct qcom_icc_node xs_sys_tcu_cfg = { + + static struct qcom_icc_bcm bcm_acv = { + .name = "ACV", ++ .enable_mask = BIT(3), + .keepalive = false, + .num_nodes = 1, + .nodes = { &ebi }, +-- +2.42.0 + diff --git a/queue-6.6/interconnect-qcom-sm8250-set-acv-enable_mask.patch b/queue-6.6/interconnect-qcom-sm8250-set-acv-enable_mask.patch new file mode 100644 index 00000000000..1f117a9aff1 --- /dev/null +++ b/queue-6.6/interconnect-qcom-sm8250-set-acv-enable_mask.patch @@ -0,0 +1,35 @@ +From 49f51795c3655e624c8eb75affce084f829e4cb4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Aug 2023 01:20:53 +0200 +Subject: interconnect: qcom: sm8250: Set ACV enable_mask + +From: Konrad Dybcio + +[ Upstream commit 9434c6896123141ac1f8f18b3d1751abbecdd03f ] + +ACV expects an enable_mask corresponding to the APPS RSC, fill it in. + +Fixes: 6df5b349491e ("interconnect: qcom: Add SM8250 interconnect provider driver") +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230811-topic-acv-v2-10-765ad70e539a@linaro.org +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/sm8250.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/interconnect/qcom/sm8250.c b/drivers/interconnect/qcom/sm8250.c +index d4a4ecef11f01..661dc18d99dba 100644 +--- a/drivers/interconnect/qcom/sm8250.c ++++ b/drivers/interconnect/qcom/sm8250.c +@@ -1397,6 +1397,7 @@ static struct qcom_icc_node qup2_core_slave = { + + static struct qcom_icc_bcm bcm_acv = { + .name = "ACV", ++ .enable_mask = BIT(3), + .keepalive = false, + .num_nodes = 1, + .nodes = { &ebi }, +-- +2.42.0 + diff --git a/queue-6.6/interconnect-qcom-sm8350-set-acv-enable_mask.patch b/queue-6.6/interconnect-qcom-sm8350-set-acv-enable_mask.patch new file mode 100644 index 00000000000..bd90ad97c2d --- /dev/null +++ b/queue-6.6/interconnect-qcom-sm8350-set-acv-enable_mask.patch @@ -0,0 +1,35 @@ +From 6a44cc38173c8ace95e1ec72e7a0961fd39bc2d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Aug 2023 01:20:54 +0200 +Subject: interconnect: qcom: sm8350: Set ACV enable_mask + +From: Konrad Dybcio + +[ Upstream commit df1b8356a80ab47a7623e08facf36fe434ea9722 ] + +ACV expects an enable_mask corresponding to the APPS RSC, fill it in. + +Fixes: d26a56674497 ("interconnect: qcom: Add SM8350 interconnect provider driver") +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230811-topic-acv-v2-11-765ad70e539a@linaro.org +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/sm8350.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/interconnect/qcom/sm8350.c b/drivers/interconnect/qcom/sm8350.c +index bdf75839e6d17..562322d4fc3c4 100644 +--- a/drivers/interconnect/qcom/sm8350.c ++++ b/drivers/interconnect/qcom/sm8350.c +@@ -1356,6 +1356,7 @@ static struct qcom_icc_node qns_mem_noc_sf_disp = { + + static struct qcom_icc_bcm bcm_acv = { + .name = "ACV", ++ .enable_mask = BIT(3), + .keepalive = false, + .num_nodes = 1, + .nodes = { &ebi }, +-- +2.42.0 + diff --git a/queue-6.6/io_uring-kbuf-allow-the-full-buffer-id-space-for-pro.patch b/queue-6.6/io_uring-kbuf-allow-the-full-buffer-id-space-for-pro.patch new file mode 100644 index 00000000000..9d7cc31632f --- /dev/null +++ b/queue-6.6/io_uring-kbuf-allow-the-full-buffer-id-space-for-pro.patch @@ -0,0 +1,74 @@ +From 3d0553aa4249ef3e8f2336e9ce10d6ddb1ada1cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 20:05:30 -0400 +Subject: io_uring/kbuf: Allow the full buffer id space for provided buffers + +From: Gabriel Krisman Bertazi + +[ Upstream commit f74c746e476b9dad51448b9a9421aae72b60e25f ] + +nbufs tracks the number of buffers and not the last bgid. In 16-bit, we +have 2^16 valid buffers, but the check mistakenly rejects the last +bid. Let's fix it to make the interface consistent with the +documentation. + +Fixes: ddf0322db79c ("io_uring: add IORING_OP_PROVIDE_BUFFERS") +Signed-off-by: Gabriel Krisman Bertazi +Link: https://lore.kernel.org/r/20231005000531.30800-3-krisman@suse.de +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/kbuf.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c +index 74a4f9600642f..f6e5ae026e4be 100644 +--- a/io_uring/kbuf.c ++++ b/io_uring/kbuf.c +@@ -19,12 +19,15 @@ + + #define BGID_ARRAY 64 + ++/* BIDs are addressed by a 16-bit field in a CQE */ ++#define MAX_BIDS_PER_BGID (1 << 16) ++ + struct io_provide_buf { + struct file *file; + __u64 addr; + __u32 len; + __u32 bgid; +- __u16 nbufs; ++ __u32 nbufs; + __u16 bid; + }; + +@@ -289,7 +292,7 @@ int io_remove_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) + return -EINVAL; + + tmp = READ_ONCE(sqe->fd); +- if (!tmp || tmp > USHRT_MAX) ++ if (!tmp || tmp > MAX_BIDS_PER_BGID) + return -EINVAL; + + memset(p, 0, sizeof(*p)); +@@ -332,7 +335,7 @@ int io_provide_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe + return -EINVAL; + + tmp = READ_ONCE(sqe->fd); +- if (!tmp || tmp > USHRT_MAX) ++ if (!tmp || tmp > MAX_BIDS_PER_BGID) + return -E2BIG; + p->nbufs = tmp; + p->addr = READ_ONCE(sqe->addr); +@@ -352,7 +355,7 @@ int io_provide_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe + tmp = READ_ONCE(sqe->off); + if (tmp > USHRT_MAX) + return -E2BIG; +- if (tmp + p->nbufs > USHRT_MAX) ++ if (tmp + p->nbufs > MAX_BIDS_PER_BGID) + return -EINVAL; + p->bid = tmp; + return 0; +-- +2.42.0 + diff --git a/queue-6.6/io_uring-kbuf-fix-check-of-bid-wrapping-in-provided-.patch b/queue-6.6/io_uring-kbuf-fix-check-of-bid-wrapping-in-provided-.patch new file mode 100644 index 00000000000..084d5a57d92 --- /dev/null +++ b/queue-6.6/io_uring-kbuf-fix-check-of-bid-wrapping-in-provided-.patch @@ -0,0 +1,43 @@ +From 7312e55b720aeb10da92bbb3b377212ca6090a6b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 20:05:29 -0400 +Subject: io_uring/kbuf: Fix check of BID wrapping in provided buffers + +From: Gabriel Krisman Bertazi + +[ Upstream commit ab69838e7c75b0edb699c1a8f42752b30333c46f ] + +Commit 3851d25c75ed0 ("io_uring: check for rollover of buffer ID when +providing buffers") introduced a check to prevent wrapping the BID +counter when sqe->off is provided, but it's off-by-one too +restrictive, rejecting the last possible BID (65534). + +i.e., the following fails with -EINVAL. + + io_uring_prep_provide_buffers(sqe, addr, size, 0xFFFF, 0, 0); + +Fixes: 3851d25c75ed ("io_uring: check for rollover of buffer ID when providing buffers") +Signed-off-by: Gabriel Krisman Bertazi +Link: https://lore.kernel.org/r/20231005000531.30800-2-krisman@suse.de +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/kbuf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c +index 9123138aa9f48..74a4f9600642f 100644 +--- a/io_uring/kbuf.c ++++ b/io_uring/kbuf.c +@@ -352,7 +352,7 @@ int io_provide_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe + tmp = READ_ONCE(sqe->off); + if (tmp > USHRT_MAX) + return -E2BIG; +- if (tmp + p->nbufs >= USHRT_MAX) ++ if (tmp + p->nbufs > USHRT_MAX) + return -EINVAL; + p->bid = tmp; + return 0; +-- +2.42.0 + diff --git a/queue-6.6/iommufd-add-iopt_area_alloc.patch b/queue-6.6/iommufd-add-iopt_area_alloc.patch new file mode 100644 index 00000000000..185f69da498 --- /dev/null +++ b/queue-6.6/iommufd-add-iopt_area_alloc.patch @@ -0,0 +1,84 @@ +From 5a1b12c372f03a7c77d14ccdc2fae6c5bd6ec57f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Oct 2023 11:26:33 -0300 +Subject: iommufd: Add iopt_area_alloc() + +From: Jason Gunthorpe + +[ Upstream commit 361d744ddd61de065fbeb042aaed590d32dd92ec ] + +We never initialize the two interval tree nodes, and zero fill is not the +same as RB_CLEAR_NODE. This can hide issues where we missed adding the +area to the trees. Factor out the allocation and clear the two nodes. + +Fixes: 51fe6141f0f6 ("iommufd: Data structure to provide IOVA to PFN mapping") +Link: https://lore.kernel.org/r/20231030145035.GG691768@ziepe.ca +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/iommu/iommufd/io_pagetable.c | 18 +++++++++++++++--- + drivers/iommu/iommufd/pages.c | 2 ++ + 2 files changed, 17 insertions(+), 3 deletions(-) + +diff --git a/drivers/iommu/iommufd/io_pagetable.c b/drivers/iommu/iommufd/io_pagetable.c +index 3a598182b7619..a4da1817e19dd 100644 +--- a/drivers/iommu/iommufd/io_pagetable.c ++++ b/drivers/iommu/iommufd/io_pagetable.c +@@ -221,6 +221,18 @@ static int iopt_insert_area(struct io_pagetable *iopt, struct iopt_area *area, + return 0; + } + ++static struct iopt_area *iopt_area_alloc(void) ++{ ++ struct iopt_area *area; ++ ++ area = kzalloc(sizeof(*area), GFP_KERNEL_ACCOUNT); ++ if (!area) ++ return NULL; ++ RB_CLEAR_NODE(&area->node.rb); ++ RB_CLEAR_NODE(&area->pages_node.rb); ++ return area; ++} ++ + static int iopt_alloc_area_pages(struct io_pagetable *iopt, + struct list_head *pages_list, + unsigned long length, unsigned long *dst_iova, +@@ -231,7 +243,7 @@ static int iopt_alloc_area_pages(struct io_pagetable *iopt, + int rc = 0; + + list_for_each_entry(elm, pages_list, next) { +- elm->area = kzalloc(sizeof(*elm->area), GFP_KERNEL_ACCOUNT); ++ elm->area = iopt_area_alloc(); + if (!elm->area) + return -ENOMEM; + } +@@ -1005,11 +1017,11 @@ static int iopt_area_split(struct iopt_area *area, unsigned long iova) + iopt_area_start_byte(area, new_start) & (alignment - 1)) + return -EINVAL; + +- lhs = kzalloc(sizeof(*area), GFP_KERNEL_ACCOUNT); ++ lhs = iopt_area_alloc(); + if (!lhs) + return -ENOMEM; + +- rhs = kzalloc(sizeof(*area), GFP_KERNEL_ACCOUNT); ++ rhs = iopt_area_alloc(); + if (!rhs) { + rc = -ENOMEM; + goto err_free_lhs; +diff --git a/drivers/iommu/iommufd/pages.c b/drivers/iommu/iommufd/pages.c +index 8d9aa297c117e..528f356238b34 100644 +--- a/drivers/iommu/iommufd/pages.c ++++ b/drivers/iommu/iommufd/pages.c +@@ -1507,6 +1507,8 @@ void iopt_area_unfill_domains(struct iopt_area *area, struct iopt_pages *pages) + area, domain, iopt_area_index(area), + iopt_area_last_index(area)); + ++ if (IS_ENABLED(CONFIG_IOMMUFD_TEST)) ++ WARN_ON(RB_EMPTY_NODE(&area->pages_node.rb)); + interval_tree_remove(&area->pages_node, &pages->domains_itree); + iopt_area_unfill_domain(area, pages, area->storage_domain); + area->storage_domain = NULL; +-- +2.42.0 + diff --git a/queue-6.6/iov_iter-x86-be-consistent-about-the-__user-tag-on-c.patch b/queue-6.6/iov_iter-x86-be-consistent-about-the-__user-tag-on-c.patch new file mode 100644 index 00000000000..7054a9f3e08 --- /dev/null +++ b/queue-6.6/iov_iter-x86-be-consistent-about-the-__user-tag-on-c.patch @@ -0,0 +1,90 @@ +From 201d0714b48d9a219263a4639a41a33f173fdd1e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Sep 2023 13:02:59 +0100 +Subject: iov_iter, x86: Be consistent about the __user tag on + copy_mc_to_user() + +From: David Howells + +[ Upstream commit 066baf92bed934c9fb4bcee97a193f47aa63431c ] + +copy_mc_to_user() has the destination marked __user on powerpc, but not on +x86; the latter results in a sparse warning in lib/iov_iter.c. + +Fix this by applying the tag on x86 too. + +Fixes: ec6347bb4339 ("x86, powerpc: Rename memcpy_mcsafe() to copy_mc_to_{user, kernel}()") +Signed-off-by: David Howells +Link: https://lore.kernel.org/r/20230925120309.1731676-3-dhowells@redhat.com +cc: Dan Williams +cc: Thomas Gleixner +cc: Ingo Molnar +cc: Borislav Petkov +cc: Dave Hansen +cc: "H. Peter Anvin" +cc: Alexander Viro +cc: Jens Axboe +cc: Christoph Hellwig +cc: Christian Brauner +cc: Matthew Wilcox +cc: Linus Torvalds +cc: David Laight +cc: x86@kernel.org +cc: linux-block@vger.kernel.org +cc: linux-fsdevel@vger.kernel.org +cc: linux-mm@kvack.org +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/uaccess.h | 2 +- + arch/x86/lib/copy_mc.c | 8 ++++---- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h +index 8bae40a662827..5c367c1290c35 100644 +--- a/arch/x86/include/asm/uaccess.h ++++ b/arch/x86/include/asm/uaccess.h +@@ -496,7 +496,7 @@ copy_mc_to_kernel(void *to, const void *from, unsigned len); + #define copy_mc_to_kernel copy_mc_to_kernel + + unsigned long __must_check +-copy_mc_to_user(void *to, const void *from, unsigned len); ++copy_mc_to_user(void __user *to, const void *from, unsigned len); + #endif + + /* +diff --git a/arch/x86/lib/copy_mc.c b/arch/x86/lib/copy_mc.c +index 80efd45a77617..6e8b7e600def5 100644 +--- a/arch/x86/lib/copy_mc.c ++++ b/arch/x86/lib/copy_mc.c +@@ -70,23 +70,23 @@ unsigned long __must_check copy_mc_to_kernel(void *dst, const void *src, unsigne + } + EXPORT_SYMBOL_GPL(copy_mc_to_kernel); + +-unsigned long __must_check copy_mc_to_user(void *dst, const void *src, unsigned len) ++unsigned long __must_check copy_mc_to_user(void __user *dst, const void *src, unsigned len) + { + unsigned long ret; + + if (copy_mc_fragile_enabled) { + __uaccess_begin(); +- ret = copy_mc_fragile(dst, src, len); ++ ret = copy_mc_fragile((__force void *)dst, src, len); + __uaccess_end(); + return ret; + } + + if (static_cpu_has(X86_FEATURE_ERMS)) { + __uaccess_begin(); +- ret = copy_mc_enhanced_fast_string(dst, src, len); ++ ret = copy_mc_enhanced_fast_string((__force void *)dst, src, len); + __uaccess_end(); + return ret; + } + +- return copy_user_generic(dst, src, len); ++ return copy_user_generic((__force void *)dst, src, len); + } +-- +2.42.0 + diff --git a/queue-6.6/ipv6-avoid-atomic-fragment-on-gso-packets.patch b/queue-6.6/ipv6-avoid-atomic-fragment-on-gso-packets.patch new file mode 100644 index 00000000000..b9dc2582108 --- /dev/null +++ b/queue-6.6/ipv6-avoid-atomic-fragment-on-gso-packets.patch @@ -0,0 +1,54 @@ +From 61af93e6755a430f8afb557ced0076a44000be26 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Oct 2023 07:26:40 -0700 +Subject: ipv6: avoid atomic fragment on GSO packets + +From: Yan Zhai + +[ Upstream commit 03d6c848bfb406e9ef6d9846d759e97beaeea113 ] + +When the ipv6 stack output a GSO packet, if its gso_size is larger than +dst MTU, then all segments would be fragmented. However, it is possible +for a GSO packet to have a trailing segment with smaller actual size +than both gso_size as well as the MTU, which leads to an "atomic +fragment". Atomic fragments are considered harmful in RFC-8021. An +Existing report from APNIC also shows that atomic fragments are more +likely to be dropped even it is equivalent to a no-op [1]. + +Add an extra check in the GSO slow output path. For each segment from +the original over-sized packet, if it fits with the path MTU, then avoid +generating an atomic fragment. + +Link: https://www.potaroo.net/presentations/2022-03-01-ipv6-frag.pdf [1] +Fixes: b210de4f8c97 ("net: ipv6: Validate GSO SKB before finish IPv6 processing") +Reported-by: David Wragg +Signed-off-by: Yan Zhai +Link: https://lore.kernel.org/r/90912e3503a242dca0bc36958b11ed03a2696e5e.1698156966.git.yan@cloudflare.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/ip6_output.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index 54fc4c711f2c5..1121082901b99 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -162,7 +162,13 @@ ip6_finish_output_gso_slowpath_drop(struct net *net, struct sock *sk, + int err; + + skb_mark_not_on_list(segs); +- err = ip6_fragment(net, sk, segs, ip6_finish_output2); ++ /* Last GSO segment can be smaller than gso_size (and MTU). ++ * Adding a fragment header would produce an "atomic fragment", ++ * which is considered harmful (RFC-8021). Avoid that. ++ */ ++ err = segs->len > mtu ? ++ ip6_fragment(net, sk, segs, ip6_finish_output2) : ++ ip6_finish_output2(net, sk, segs); + if (err && ret == 0) + ret = err; + } +-- +2.42.0 + diff --git a/queue-6.6/ipvlan-properly-track-tx_errors.patch b/queue-6.6/ipvlan-properly-track-tx_errors.patch new file mode 100644 index 00000000000..8cbf3e5dfa9 --- /dev/null +++ b/queue-6.6/ipvlan-properly-track-tx_errors.patch @@ -0,0 +1,81 @@ +From 85ed66abc9827236b4993b93006b4bb5945d35de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Oct 2023 13:14:46 +0000 +Subject: ipvlan: properly track tx_errors + +From: Eric Dumazet + +[ Upstream commit ff672b9ffeb3f82135488ac16c5c5eb4b992999b ] + +Both ipvlan_process_v4_outbound() and ipvlan_process_v6_outbound() +increment dev->stats.tx_errors in case of errors. + +Unfortunately there are two issues : + +1) ipvlan_get_stats64() does not propagate dev->stats.tx_errors to user. + +2) Increments are not atomic. KCSAN would complain eventually. + +Use DEV_STATS_INC() to not miss an update, and change ipvlan_get_stats64() +to copy the value back to user. + +Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.") +Signed-off-by: Eric Dumazet +Cc: Mahesh Bandewar +Link: https://lore.kernel.org/r/20231026131446.3933175-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ipvlan/ipvlan_core.c | 8 ++++---- + drivers/net/ipvlan/ipvlan_main.c | 1 + + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c +index c0c49f1813673..21e9cac731218 100644 +--- a/drivers/net/ipvlan/ipvlan_core.c ++++ b/drivers/net/ipvlan/ipvlan_core.c +@@ -441,12 +441,12 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb) + + err = ip_local_out(net, skb->sk, skb); + if (unlikely(net_xmit_eval(err))) +- dev->stats.tx_errors++; ++ DEV_STATS_INC(dev, tx_errors); + else + ret = NET_XMIT_SUCCESS; + goto out; + err: +- dev->stats.tx_errors++; ++ DEV_STATS_INC(dev, tx_errors); + kfree_skb(skb); + out: + return ret; +@@ -482,12 +482,12 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) + + err = ip6_local_out(net, skb->sk, skb); + if (unlikely(net_xmit_eval(err))) +- dev->stats.tx_errors++; ++ DEV_STATS_INC(dev, tx_errors); + else + ret = NET_XMIT_SUCCESS; + goto out; + err: +- dev->stats.tx_errors++; ++ DEV_STATS_INC(dev, tx_errors); + kfree_skb(skb); + out: + return ret; +diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c +index 1b55928e89b8a..57c79f5f29916 100644 +--- a/drivers/net/ipvlan/ipvlan_main.c ++++ b/drivers/net/ipvlan/ipvlan_main.c +@@ -324,6 +324,7 @@ static void ipvlan_get_stats64(struct net_device *dev, + s->rx_dropped = rx_errs; + s->tx_dropped = tx_drps; + } ++ s->tx_errors = DEV_STATS_READ(dev, tx_errors); + } + + static int ipvlan_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) +-- +2.42.0 + diff --git a/queue-6.6/irqchip-sifive-plic-fix-syscore-registration-for-mul.patch b/queue-6.6/irqchip-sifive-plic-fix-syscore-registration-for-mul.patch new file mode 100644 index 00000000000..bd71bcb5cab --- /dev/null +++ b/queue-6.6/irqchip-sifive-plic-fix-syscore-registration-for-mul.patch @@ -0,0 +1,57 @@ +From eb18a91443953bc8014174190a7a3c695c93efc7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 19:58:20 +0530 +Subject: irqchip/sifive-plic: Fix syscore registration for multi-socket + systems + +From: Anup Patel + +[ Upstream commit f99b926f6543faeadba1b4524d8dc9c102489135 ] + +Multi-socket systems have a separate PLIC in each socket, so __plic_init() +is invoked for each PLIC. __plic_init() registers syscore operations, which +obviously fails on the second invocation. + +Move it into the already existing condition for installing the CPU hotplug +state so it is only invoked once when the first PLIC is initialized. + +[ tglx: Massaged changelog ] + +Fixes: e80f0b6a2cf3 ("irqchip/irq-sifive-plic: Add syscore callbacks for hibernation") +Signed-off-by: Anup Patel +Signed-off-by: Thomas Gleixner +Link: https://lore.kernel.org/r/20231025142820.390238-4-apatel@ventanamicro.com +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-sifive-plic.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c +index e1484905b7bdb..5b7bc4fd9517c 100644 +--- a/drivers/irqchip/irq-sifive-plic.c ++++ b/drivers/irqchip/irq-sifive-plic.c +@@ -532,17 +532,18 @@ static int __init __plic_init(struct device_node *node, + } + + /* +- * We can have multiple PLIC instances so setup cpuhp state only +- * when context handler for current/boot CPU is present. ++ * We can have multiple PLIC instances so setup cpuhp state ++ * and register syscore operations only when context handler ++ * for current/boot CPU is present. + */ + handler = this_cpu_ptr(&plic_handlers); + if (handler->present && !plic_cpuhp_setup_done) { + cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING, + "irqchip/sifive/plic:starting", + plic_starting_cpu, plic_dying_cpu); ++ register_syscore_ops(&plic_irq_syscore_ops); + plic_cpuhp_setup_done = true; + } +- register_syscore_ops(&plic_irq_syscore_ops); + + pr_info("%pOFP: mapped %d interrupts with %d handlers for" + " %d contexts.\n", node, nr_irqs, nr_handlers, nr_contexts); +-- +2.42.0 + diff --git a/queue-6.6/keys-include-linux-errno.h-in-linux-verification.h.patch b/queue-6.6/keys-include-linux-errno.h-in-linux-verification.h.patch new file mode 100644 index 00000000000..68f38cb3768 --- /dev/null +++ b/queue-6.6/keys-include-linux-errno.h-in-linux-verification.h.patch @@ -0,0 +1,36 @@ +From 3df3f103d5f4a786f219267fe1ee8214e494cd9d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Aug 2023 16:36:41 +0800 +Subject: KEYS: Include linux/errno.h in linux/verification.h + +From: Herbert Xu + +[ Upstream commit 0a596b0682a7ce37e26c36629816f105c6459d06 ] + +Add inclusion of linux/errno.h as otherwise the reference to EINVAL +may be invalid. + +Fixes: f3cf4134c5c6 ("bpf: Add bpf_lookup_*_key() and bpf_key_put() kfuncs") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202308261414.HKw1Mrip-lkp@intel.com/ +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + include/linux/verification.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/linux/verification.h b/include/linux/verification.h +index f34e50ebcf60a..cb2d47f280910 100644 +--- a/include/linux/verification.h ++++ b/include/linux/verification.h +@@ -8,6 +8,7 @@ + #ifndef _LINUX_VERIFICATION_H + #define _LINUX_VERIFICATION_H + ++#include + #include + + /* +-- +2.42.0 + diff --git a/queue-6.6/kselftest-vm-fix-mdwe-s-mmap_fixed-test-case.patch b/queue-6.6/kselftest-vm-fix-mdwe-s-mmap_fixed-test-case.patch new file mode 100644 index 00000000000..9eda6ceaea2 --- /dev/null +++ b/queue-6.6/kselftest-vm-fix-mdwe-s-mmap_fixed-test-case.patch @@ -0,0 +1,72 @@ +From 5c0ca2d39a5a86c1379b043db3090f7279aa6284 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Aug 2023 17:08:54 +0200 +Subject: kselftest: vm: fix mdwe's mmap_FIXED test case + +From: Florent Revest + +[ Upstream commit a27e2e2d465e4ed73371974040689ac3e78fe3ee ] + +I checked with the original author, the mmap_FIXED test case wasn't +properly tested and fails. Currently, it maps two consecutive (non +overlapping) pages and expects the second mapping to be denied by MDWE but +these two pages have nothing to do with each other so MDWE is actually out +of the picture here. + +What the test actually intended to do was to remap a virtual address using +MAP_FIXED. However, this operation unmaps the existing mapping and +creates a new one so the va is backed by a new page and MDWE is again out +of the picture, all remappings should succeed. + +This patch keeps the test case to make it clear that this situation is +expected to work: MDWE shouldn't block a MAP_FIXED replacement. + +Link: https://lkml.kernel.org/r/20230828150858.393570-3-revest@chromium.org +Fixes: 4cf1fe34fd18 ("kselftest: vm: add tests for memory-deny-write-execute") +Signed-off-by: Florent Revest +Reviewed-by: David Hildenbrand +Reviewed-by: Kees Cook +Reviewed-by: Catalin Marinas +Reviewed-by: Ryan Roberts +Tested-by: Ryan Roberts +Tested-by: Ayush Jain +Cc: Alexey Izbyshev +Cc: Anshuman Khandual +Cc: Greg Thelen +Cc: Joey Gouly +Cc: KP Singh +Cc: Mark Brown +Cc: Michal Hocko +Cc: Peter Xu +Cc: Szabolcs Nagy +Cc: Topi Miettinen +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/mm/mdwe_test.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/tools/testing/selftests/mm/mdwe_test.c b/tools/testing/selftests/mm/mdwe_test.c +index bc91bef5d254e..0c5e469ae38fa 100644 +--- a/tools/testing/selftests/mm/mdwe_test.c ++++ b/tools/testing/selftests/mm/mdwe_test.c +@@ -168,13 +168,10 @@ TEST_F(mdwe, mmap_FIXED) + self->p = mmap(NULL, self->size, PROT_READ, self->flags, 0, 0); + ASSERT_NE(self->p, MAP_FAILED); + +- p = mmap(self->p + self->size, self->size, PROT_READ | PROT_EXEC, ++ /* MAP_FIXED unmaps the existing page before mapping which is allowed */ ++ p = mmap(self->p, self->size, PROT_READ | PROT_EXEC, + self->flags | MAP_FIXED, 0, 0); +- if (variant->enabled) { +- EXPECT_EQ(p, MAP_FAILED); +- } else { +- EXPECT_EQ(p, self->p); +- } ++ EXPECT_EQ(p, self->p); + } + + TEST_F(mdwe, arm64_BTI) +-- +2.42.0 + diff --git a/queue-6.6/kunit-fix-missed-memory-release-in-kunit_free_suite_.patch b/queue-6.6/kunit-fix-missed-memory-release-in-kunit_free_suite_.patch new file mode 100644 index 00000000000..2c4d5b80aef --- /dev/null +++ b/queue-6.6/kunit-fix-missed-memory-release-in-kunit_free_suite_.patch @@ -0,0 +1,69 @@ +From b9e7ff76287751833f80154aa4a91f47ffa576d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 17:03:47 +0800 +Subject: kunit: Fix missed memory release in kunit_free_suite_set() + +From: Jinjie Ruan + +[ Upstream commit a6074cf0126b0bee51ab77a15930dc24a4d5db90 ] + +modprobe cpumask_kunit and rmmod cpumask_kunit, kmemleak detect +a suspected memory leak as below. + +If kunit_filter_suites() in kunit_module_init() succeeds, the +suite_set.start will not be NULL and the kunit_free_suite_set() in +kunit_module_exit() should free all the memory which has not +been freed. However the test_cases in suites is left out. + +unreferenced object 0xffff54ac47e83200 (size 512): + comm "modprobe", pid 592, jiffies 4294913238 (age 1367.612s) + hex dump (first 32 bytes): + 84 13 1a f0 d3 b6 ff ff 30 68 1a f0 d3 b6 ff ff ........0h...... + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [<000000008dec63a2>] slab_post_alloc_hook+0xb8/0x368 + [<00000000ec280d8e>] __kmem_cache_alloc_node+0x174/0x290 + [<00000000896c7740>] __kmalloc+0x60/0x2c0 + [<000000007a50fa06>] kunit_filter_suites+0x254/0x5b8 + [<0000000078cc98e2>] kunit_module_notify+0xf4/0x240 + [<0000000033cea952>] notifier_call_chain+0x98/0x17c + [<00000000973d05cc>] notifier_call_chain_robust+0x4c/0xa4 + [<000000005f95895f>] blocking_notifier_call_chain_robust+0x4c/0x74 + [<0000000048e36fa7>] load_module+0x1a2c/0x1c40 + [<0000000004eb8a91>] init_module_from_file+0x94/0xcc + [<0000000037dbba28>] idempotent_init_module+0x184/0x278 + [<00000000161b75cb>] __arm64_sys_finit_module+0x68/0xa8 + [<000000006dc1669b>] invoke_syscall+0x44/0x100 + [<00000000fa87e304>] el0_svc_common.constprop.1+0x68/0xe0 + [<000000009d8ad866>] do_el0_svc+0x1c/0x28 + [<000000005b83c607>] el0_svc+0x3c/0xc4 + +Fixes: a127b154a8f2 ("kunit: tool: allow filtering test cases via glob") +Signed-off-by: Jinjie Ruan +Reviewed-by: Rae Moar +Reviewed-by: David Gow +Signed-off-by: Shuah Khan +Signed-off-by: Sasha Levin +--- + lib/kunit/executor.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c +index a6348489d45fe..a037a46fae5ea 100644 +--- a/lib/kunit/executor.c ++++ b/lib/kunit/executor.c +@@ -137,8 +137,10 @@ void kunit_free_suite_set(struct kunit_suite_set suite_set) + { + struct kunit_suite * const *suites; + +- for (suites = suite_set.start; suites < suite_set.end; suites++) ++ for (suites = suite_set.start; suites < suite_set.end; suites++) { ++ kfree((*suites)->test_cases); + kfree(*suites); ++ } + kfree(suite_set.start); + } + +-- +2.42.0 + diff --git a/queue-6.6/kunit-fix-possible-memory-leak-in-kunit_filter_suite.patch b/queue-6.6/kunit-fix-possible-memory-leak-in-kunit_filter_suite.patch new file mode 100644 index 00000000000..70a0493ab9c --- /dev/null +++ b/queue-6.6/kunit-fix-possible-memory-leak-in-kunit_filter_suite.patch @@ -0,0 +1,86 @@ +From c61531cc11137a6d9c394baf1a3c279dabd9ff9e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 17:03:49 +0800 +Subject: kunit: Fix possible memory leak in kunit_filter_suites() + +From: Jinjie Ruan + +[ Upstream commit 24de14c98b37ea40a7e493dfd0d93b400b6efbca ] + +If the outer layer for loop is iterated more than once and it fails not +in the first iteration, the filtered_suite and filtered_suite->test_cases +allocated in the last kunit_filter_attr_tests() in last inner for loop +is leaked. + +So add a new free_filtered_suite err label and free the filtered_suite +and filtered_suite->test_cases so far. And change kmalloc_array of copy +to kcalloc to Clear the copy to make the kfree safe. + +Fixes: 529534e8cba3 ("kunit: Add ability to filter attributes") +Signed-off-by: Jinjie Ruan +Reviewed-by: Rae Moar +Reviewed-by: David Gow +Signed-off-by: Shuah Khan +Signed-off-by: Sasha Levin +--- + lib/kunit/executor.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c +index 9358ed2df8395..1236b3cd2fbb2 100644 +--- a/lib/kunit/executor.c ++++ b/lib/kunit/executor.c +@@ -157,10 +157,11 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set, + struct kunit_suite_set filtered = {NULL, NULL}; + struct kunit_glob_filter parsed_glob; + struct kunit_attr_filter *parsed_filters = NULL; ++ struct kunit_suite * const *suites; + + const size_t max = suite_set->end - suite_set->start; + +- copy = kmalloc_array(max, sizeof(*filtered.start), GFP_KERNEL); ++ copy = kcalloc(max, sizeof(*filtered.start), GFP_KERNEL); + if (!copy) { /* won't be able to run anything, return an empty set */ + return filtered; + } +@@ -195,7 +196,7 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set, + parsed_glob.test_glob); + if (IS_ERR(filtered_suite)) { + *err = PTR_ERR(filtered_suite); +- goto free_parsed_filters; ++ goto free_filtered_suite; + } + } + if (filter_count > 0 && parsed_filters != NULL) { +@@ -212,11 +213,11 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set, + filtered_suite = new_filtered_suite; + + if (*err) +- goto free_parsed_filters; ++ goto free_filtered_suite; + + if (IS_ERR(filtered_suite)) { + *err = PTR_ERR(filtered_suite); +- goto free_parsed_filters; ++ goto free_filtered_suite; + } + if (!filtered_suite) + break; +@@ -231,6 +232,14 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set, + filtered.start = copy_start; + filtered.end = copy; + ++free_filtered_suite: ++ if (*err) { ++ for (suites = copy_start; suites < copy; suites++) { ++ kfree((*suites)->test_cases); ++ kfree(*suites); ++ } ++ } ++ + free_parsed_filters: + if (filter_count) + kfree(parsed_filters); +-- +2.42.0 + diff --git a/queue-6.6/kunit-fix-the-wrong-kfree-of-copy-for-kunit_filter_s.patch b/queue-6.6/kunit-fix-the-wrong-kfree-of-copy-for-kunit_filter_s.patch new file mode 100644 index 00000000000..2e99e7fea07 --- /dev/null +++ b/queue-6.6/kunit-fix-the-wrong-kfree-of-copy-for-kunit_filter_s.patch @@ -0,0 +1,39 @@ +From 0bc28898122d9f272c468dbcbb5bcde9f5b373da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 17:03:48 +0800 +Subject: kunit: Fix the wrong kfree of copy for kunit_filter_suites() + +From: Jinjie Ruan + +[ Upstream commit e44679515a7b803cf0143dc9de3d2ecbe907f939 ] + +If the outer layer for loop is iterated more than once and it fails not +in the first iteration, the copy pointer has been moved. So it should free +the original copy's backup copy_start. + +Fixes: abbf73816b6f ("kunit: fix possible memory leak in kunit_filter_suites()") +Signed-off-by: Jinjie Ruan +Reviewed-by: Rae Moar +Reviewed-by: David Gow +Signed-off-by: Shuah Khan +Signed-off-by: Sasha Levin +--- + lib/kunit/executor.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c +index a037a46fae5ea..9358ed2df8395 100644 +--- a/lib/kunit/executor.c ++++ b/lib/kunit/executor.c +@@ -243,7 +243,7 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set, + + free_copy: + if (*err) +- kfree(copy); ++ kfree(copy_start); + + return filtered; + } +-- +2.42.0 + diff --git a/queue-6.6/kunit-test-fix-the-possible-memory-leak-in-executor_.patch b/queue-6.6/kunit-test-fix-the-possible-memory-leak-in-executor_.patch new file mode 100644 index 00000000000..090a6234e0a --- /dev/null +++ b/queue-6.6/kunit-test-fix-the-possible-memory-leak-in-executor_.patch @@ -0,0 +1,257 @@ +From bc923d6f7fbde2b56ebf6b569a585cd3159eb481 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 17:03:50 +0800 +Subject: kunit: test: Fix the possible memory leak in executor_test + +From: Jinjie Ruan + +[ Upstream commit 8040345fdae4cb256c5d981f91ae0f22bea8adcc ] + +When CONFIG_KUNIT_ALL_TESTS=y, making CONFIG_DEBUG_KMEMLEAK=y and +CONFIG_DEBUG_KMEMLEAK_AUTO_SCAN=y, the below memory leak is detected. + +If kunit_filter_suites() succeeds, not only copy but also filtered_suite +and filtered_suite->test_cases should be freed. + +So as Rae suggested, to avoid the suite set never be freed when +KUNIT_ASSERT_EQ() fails and exits after kunit_filter_suites() succeeds, +update kfree_at_end() func to free_suite_set_at_end() to use +kunit_free_suite_set() to free them as kunit_module_exit() and +kunit_run_all_tests() do it. As the second arg got of +free_suite_set_at_end() is a local variable, copy it for free to avoid +wild-memory-access. After applying this patch, the following memory leak +is never detected. + +unreferenced object 0xffff8881001de400 (size 1024): + comm "kunit_try_catch", pid 1396, jiffies 4294720452 (age 932.801s) + hex dump (first 32 bytes): + 73 75 69 74 65 32 00 00 00 00 00 00 00 00 00 00 suite2.......... + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [] __kmalloc_node_track_caller+0x53/0x150 + [] kmemdup+0x22/0x50 + [] kunit_filter_suites+0x44d/0xcc0 + [] filter_suites_test+0x12f/0x360 + [] kunit_generic_run_threadfn_adapter+0x4a/0x90 + [] kthread+0x2b6/0x380 + [] ret_from_fork+0x2d/0x70 + [] ret_from_fork_asm+0x11/0x20 +unreferenced object 0xffff8881052cd388 (size 192): + comm "kunit_try_catch", pid 1396, jiffies 4294720452 (age 932.801s) + hex dump (first 32 bytes): + a0 85 9e 82 ff ff ff ff 80 cd 7c 84 ff ff ff ff ..........|..... + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [] __kmalloc+0x52/0x150 + [] kunit_filter_suites+0x481/0xcc0 + [] filter_suites_test+0x12f/0x360 + [] kunit_generic_run_threadfn_adapter+0x4a/0x90 + [] kthread+0x2b6/0x380 + [] ret_from_fork+0x2d/0x70 + [] ret_from_fork_asm+0x11/0x20 + +unreferenced object 0xffff888100da8400 (size 1024): + comm "kunit_try_catch", pid 1398, jiffies 4294720454 (age 781.945s) + hex dump (first 32 bytes): + 73 75 69 74 65 32 00 00 00 00 00 00 00 00 00 00 suite2.......... + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [] __kmalloc_node_track_caller+0x53/0x150 + [] kmemdup+0x22/0x50 + [] kunit_filter_suites+0x44d/0xcc0 + [] filter_suites_test_glob_test+0x12f/0x560 + [] kunit_generic_run_threadfn_adapter+0x4a/0x90 + [] kthread+0x2b6/0x380 + [] ret_from_fork+0x2d/0x70 + [] ret_from_fork_asm+0x11/0x20 +unreferenced object 0xffff888105117878 (size 96): + comm "kunit_try_catch", pid 1398, jiffies 4294720454 (age 781.945s) + hex dump (first 32 bytes): + a0 85 9e 82 ff ff ff ff a0 ac 7c 84 ff ff ff ff ..........|..... + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [] __kmalloc+0x52/0x150 + [] kunit_filter_suites+0x481/0xcc0 + [] filter_suites_test_glob_test+0x12f/0x560 + [] kunit_generic_run_threadfn_adapter+0x4a/0x90 + [] kthread+0x2b6/0x380 + [] ret_from_fork+0x2d/0x70 + [] ret_from_fork_asm+0x11/0x20 +unreferenced object 0xffff888102c31c00 (size 1024): + comm "kunit_try_catch", pid 1404, jiffies 4294720460 (age 781.948s) + hex dump (first 32 bytes): + 6e 6f 72 6d 61 6c 5f 73 75 69 74 65 00 00 00 00 normal_suite.... + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [] __kmalloc_node_track_caller+0x53/0x150 + [] kmemdup+0x22/0x50 + [] kunit_filter_attr_tests+0xf7/0x860 + [] kunit_filter_suites+0x82f/0xcc0 + [] filter_attr_test+0x195/0x5f0 + [] kunit_generic_run_threadfn_adapter+0x4a/0x90 + [] kthread+0x2b6/0x380 + [] ret_from_fork+0x2d/0x70 + [] ret_from_fork_asm+0x11/0x20 +unreferenced object 0xffff8881052cd250 (size 192): + comm "kunit_try_catch", pid 1404, jiffies 4294720460 (age 781.948s) + hex dump (first 32 bytes): + a0 85 9e 82 ff ff ff ff 00 a9 7c 84 ff ff ff ff ..........|..... + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [] __kmalloc+0x52/0x150 + [] kunit_filter_attr_tests+0x1a1/0x860 + [] kunit_filter_suites+0x82f/0xcc0 + [] filter_attr_test+0x195/0x5f0 + [] kunit_generic_run_threadfn_adapter+0x4a/0x90 + [] kthread+0x2b6/0x380 + [] ret_from_fork+0x2d/0x70 + [] ret_from_fork_asm+0x11/0x20 +unreferenced object 0xffff888104f4e400 (size 1024): + comm "kunit_try_catch", pid 1408, jiffies 4294720464 (age 781.944s) + hex dump (first 32 bytes): + 73 75 69 74 65 00 00 00 00 00 00 00 00 00 00 00 suite........... + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [] __kmalloc_node_track_caller+0x53/0x150 + [] kmemdup+0x22/0x50 + [] kunit_filter_attr_tests+0xf7/0x860 + [] kunit_filter_suites+0x82f/0xcc0 + [] filter_attr_skip_test+0x133/0x6e0 + [] kunit_generic_run_threadfn_adapter+0x4a/0x90 + [] kthread+0x2b6/0x380 + [] ret_from_fork+0x2d/0x70 + [] ret_from_fork_asm+0x11/0x20 +unreferenced object 0xffff8881052cc620 (size 192): + comm "kunit_try_catch", pid 1408, jiffies 4294720464 (age 781.944s) + hex dump (first 32 bytes): + a0 85 9e 82 ff ff ff ff c0 a8 7c 84 ff ff ff ff ..........|..... + 00 00 00 00 00 00 00 00 02 00 00 00 02 00 00 00 ................ + backtrace: + [] __kmalloc+0x52/0x150 + [] kunit_filter_attr_tests+0x1a1/0x860 + [] kunit_filter_suites+0x82f/0xcc0 + [] filter_attr_skip_test+0x133/0x6e0 + [] kunit_generic_run_threadfn_adapter+0x4a/0x90 + [] kthread+0x2b6/0x380 + [] ret_from_fork+0x2d/0x70 + [] ret_from_fork_asm+0x11/0x20 + +Fixes: e5857d396f35 ("kunit: flatten kunit_suite*** to kunit_suite** in .kunit_test_suites") +Fixes: 76066f93f1df ("kunit: add tests for filtering attributes") +Signed-off-by: Jinjie Ruan +Suggested-by: Rae Moar +Reviewed-by: David Gow +Suggested-by: David Gow +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202309142251.uJ8saAZv-lkp@intel.com/ +Closes: https://lore.kernel.org/oe-kbuild-all/202309270433.wGmFRGjd-lkp@intel.com/ +Signed-off-by: Shuah Khan +Signed-off-by: Sasha Levin +--- + lib/kunit/executor_test.c | 36 ++++++++++++++++++++++-------------- + 1 file changed, 22 insertions(+), 14 deletions(-) + +diff --git a/lib/kunit/executor_test.c b/lib/kunit/executor_test.c +index b4f6f96b28445..22d4ee86dbedd 100644 +--- a/lib/kunit/executor_test.c ++++ b/lib/kunit/executor_test.c +@@ -9,7 +9,7 @@ + #include + #include + +-static void kfree_at_end(struct kunit *test, const void *to_free); ++static void free_suite_set_at_end(struct kunit *test, const void *to_free); + static struct kunit_suite *alloc_fake_suite(struct kunit *test, + const char *suite_name, + struct kunit_case *test_cases); +@@ -56,7 +56,7 @@ static void filter_suites_test(struct kunit *test) + got = kunit_filter_suites(&suite_set, "suite2", NULL, NULL, &err); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start); + KUNIT_ASSERT_EQ(test, err, 0); +- kfree_at_end(test, got.start); ++ free_suite_set_at_end(test, &got); + + /* Validate we just have suite2 */ + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]); +@@ -82,7 +82,7 @@ static void filter_suites_test_glob_test(struct kunit *test) + got = kunit_filter_suites(&suite_set, "suite2.test2", NULL, NULL, &err); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start); + KUNIT_ASSERT_EQ(test, err, 0); +- kfree_at_end(test, got.start); ++ free_suite_set_at_end(test, &got); + + /* Validate we just have suite2 */ + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]); +@@ -109,7 +109,7 @@ static void filter_suites_to_empty_test(struct kunit *test) + + got = kunit_filter_suites(&suite_set, "not_found", NULL, NULL, &err); + KUNIT_ASSERT_EQ(test, err, 0); +- kfree_at_end(test, got.start); /* just in case */ ++ free_suite_set_at_end(test, &got); /* just in case */ + + KUNIT_EXPECT_PTR_EQ_MSG(test, got.start, got.end, + "should be empty to indicate no match"); +@@ -172,7 +172,7 @@ static void filter_attr_test(struct kunit *test) + got = kunit_filter_suites(&suite_set, NULL, filter, NULL, &err); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start); + KUNIT_ASSERT_EQ(test, err, 0); +- kfree_at_end(test, got.start); ++ free_suite_set_at_end(test, &got); + + /* Validate we just have normal_suite */ + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]); +@@ -200,7 +200,7 @@ static void filter_attr_empty_test(struct kunit *test) + + got = kunit_filter_suites(&suite_set, NULL, filter, NULL, &err); + KUNIT_ASSERT_EQ(test, err, 0); +- kfree_at_end(test, got.start); /* just in case */ ++ free_suite_set_at_end(test, &got); /* just in case */ + + KUNIT_EXPECT_PTR_EQ_MSG(test, got.start, got.end, + "should be empty to indicate no match"); +@@ -222,7 +222,7 @@ static void filter_attr_skip_test(struct kunit *test) + got = kunit_filter_suites(&suite_set, NULL, filter, "skip", &err); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start); + KUNIT_ASSERT_EQ(test, err, 0); +- kfree_at_end(test, got.start); ++ free_suite_set_at_end(test, &got); + + /* Validate we have both the slow and normal test */ + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]->test_cases); +@@ -256,18 +256,26 @@ kunit_test_suites(&executor_test_suite); + + /* Test helpers */ + +-/* Use the resource API to register a call to kfree(to_free). ++static void free_suite_set(void *suite_set) ++{ ++ kunit_free_suite_set(*(struct kunit_suite_set *)suite_set); ++ kfree(suite_set); ++} ++ ++/* Use the resource API to register a call to free_suite_set. + * Since we never actually use the resource, it's safe to use on const data. + */ +-static void kfree_at_end(struct kunit *test, const void *to_free) ++static void free_suite_set_at_end(struct kunit *test, const void *to_free) + { +- /* kfree() handles NULL already, but avoid allocating a no-op cleanup. */ +- if (IS_ERR_OR_NULL(to_free)) ++ struct kunit_suite_set *free; ++ ++ if (!((struct kunit_suite_set *)to_free)->start) + return; + +- kunit_add_action(test, +- (kunit_action_t *)kfree, +- (void *)to_free); ++ free = kzalloc(sizeof(struct kunit_suite_set), GFP_KERNEL); ++ *free = *(struct kunit_suite_set *)to_free; ++ ++ kunit_add_action(test, free_suite_set, (void *)free); + } + + static struct kunit_suite *alloc_fake_suite(struct kunit *test, +-- +2.42.0 + diff --git a/queue-6.6/leds-pwm-don-t-disable-the-pwm-when-the-led-should-b.patch b/queue-6.6/leds-pwm-don-t-disable-the-pwm-when-the-led-should-b.patch new file mode 100644 index 00000000000..ac0088f8777 --- /dev/null +++ b/queue-6.6/leds-pwm-don-t-disable-the-pwm-when-the-led-should-b.patch @@ -0,0 +1,53 @@ +From f065a88c39bae4cce4df0c4e16504f95b348f32f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 21:28:34 +0200 +Subject: leds: pwm: Don't disable the PWM when the LED should be off +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit 76fe464c8e64e71b2e4af11edeef0e5d85eeb6aa ] + +Disabling a PWM (i.e. calling pwm_apply_state with .enabled = false) +gives no guarantees what the PWM output does. It might freeze where it +currently is, or go in a High-Z state or drive the active or inactive +state, it might even continue to toggle. + +To ensure that the LED gets really disabled, don't disable the PWM even +when .duty_cycle is zero. + +This fixes disabling a leds-pwm LED on i.MX28. The PWM on this SoC is +one of those that freezes its output on disable, so if you disable an +LED that is full on, it stays on. If you disable a LED with half +brightness it goes off in 50% of the cases and full on in the other 50%. + +Fixes: 41c42ff5dbe2 ("leds: simple driver for pwm driven LEDs") +Reported-by: Rogan Dawes +Reported-by: Fabio Estevam +Signed-off-by: Uwe Kleine-König +Reviewed-by: Fabio Estevam +Link: https://lore.kernel.org/r/20230922192834.1695727-1-u.kleine-koenig@pengutronix.de +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/leds-pwm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c +index 419b710984ab6..2b3bf1353b707 100644 +--- a/drivers/leds/leds-pwm.c ++++ b/drivers/leds/leds-pwm.c +@@ -53,7 +53,7 @@ static int led_pwm_set(struct led_classdev *led_cdev, + duty = led_dat->pwmstate.period - duty; + + led_dat->pwmstate.duty_cycle = duty; +- led_dat->pwmstate.enabled = duty > 0; ++ led_dat->pwmstate.enabled = true; + return pwm_apply_state(led_dat->pwm, &led_dat->pwmstate); + } + +-- +2.42.0 + diff --git a/queue-6.6/leds-trigger-ledtrig-cpu-fix-output-may-be-truncated.patch b/queue-6.6/leds-trigger-ledtrig-cpu-fix-output-may-be-truncated.patch new file mode 100644 index 00000000000..65f8e415c11 --- /dev/null +++ b/queue-6.6/leds-trigger-ledtrig-cpu-fix-output-may-be-truncated.patch @@ -0,0 +1,63 @@ +From 27ba3f30cc72320f405d816a713e5eade5f5189e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 23 Sep 2023 09:15:38 +0200 +Subject: leds: trigger: ledtrig-cpu:: Fix 'output may be truncated' issue for + 'cpu' +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Christophe JAILLET + +[ Upstream commit ff50f53276131a3059e8307d11293af388ed2bcd ] + +In order to teach the compiler that 'trig->name' will never be truncated, +we need to tell it that 'cpu' is not negative. + +When building with W=1, this fixes the following warnings: + + drivers/leds/trigger/ledtrig-cpu.c: In function ‘ledtrig_cpu_init’: + drivers/leds/trigger/ledtrig-cpu.c:155:56: error: ‘%d’ directive output may be truncated writing between 1 and 11 bytes into a region of size 5 [-Werror=format-truncation=] + 155 | snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); + | ^~ + drivers/leds/trigger/ledtrig-cpu.c:155:52: note: directive argument in the range [-2147483648, 7] + 155 | snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); + | ^~~~~~~ + drivers/leds/trigger/ledtrig-cpu.c:155:17: note: ‘snprintf’ output between 5 and 15 bytes into a destination of size 8 + 155 | snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Fixes: 8f88731d052d ("led-triggers: create a trigger for CPU activity") +Signed-off-by: Christophe JAILLET +Link: https://lore.kernel.org/r/3f4be7a99933cf8566e630da54f6ab913caac432.1695453322.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/trigger/ledtrig-cpu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/leds/trigger/ledtrig-cpu.c b/drivers/leds/trigger/ledtrig-cpu.c +index 8af4f9bb9cde8..05848a2fecff6 100644 +--- a/drivers/leds/trigger/ledtrig-cpu.c ++++ b/drivers/leds/trigger/ledtrig-cpu.c +@@ -130,7 +130,7 @@ static int ledtrig_prepare_down_cpu(unsigned int cpu) + + static int __init ledtrig_cpu_init(void) + { +- int cpu; ++ unsigned int cpu; + int ret; + + /* Supports up to 9999 cpu cores */ +@@ -152,7 +152,7 @@ static int __init ledtrig_cpu_init(void) + if (cpu >= 8) + continue; + +- snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); ++ snprintf(trig->name, MAX_NAME_LEN, "cpu%u", cpu); + + led_trigger_register_simple(trig->name, &trig->_trig); + } +-- +2.42.0 + diff --git a/queue-6.6/leds-turris-omnia-do-not-use-smbus-calls.patch b/queue-6.6/leds-turris-omnia-do-not-use-smbus-calls.patch new file mode 100644 index 00000000000..7cecd691012 --- /dev/null +++ b/queue-6.6/leds-turris-omnia-do-not-use-smbus-calls.patch @@ -0,0 +1,155 @@ +From 3aa8b7a6face1114824203e0d4e3a9ecfa967d5b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Sep 2023 18:11:01 +0200 +Subject: leds: turris-omnia: Do not use SMBUS calls +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Marek Behún + +[ Upstream commit 6de283b96b31b4890e3ee8c86caca2a3a30d1011 ] + +The leds-turris-omnia driver uses three function for I2C access: +- i2c_smbus_write_byte_data() and i2c_smbus_read_byte_data(), which + cause an emulated SMBUS transfer, +- i2c_master_send(), which causes an ordinary I2C transfer. + +The Turris Omnia MCU LED controller is not semantically SMBUS, it +operates as a simple I2C bus. It does not implement any of the SMBUS +specific features, like PEC, or procedure calls, or anything. Moreover +the I2C controller driver also does not implement SMBUS, and so the +emulated SMBUS procedure from drivers/i2c/i2c-core-smbus.c is used for +the SMBUS calls, which gives an unnecessary overhead. + +When I first wrote the driver, I was unaware of these facts, and I +simply used the first function that worked. + +Drop the I2C SMBUS calls and instead use simple I2C transfers. + +Fixes: 089381b27abe ("leds: initial support for Turris Omnia LEDs") +Signed-off-by: Marek Behún +Link: https://lore.kernel.org/r/20230918161104.20860-2-kabel@kernel.org +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/leds-turris-omnia.c | 54 +++++++++++++++++++++++++------- + 1 file changed, 42 insertions(+), 12 deletions(-) + +diff --git a/drivers/leds/leds-turris-omnia.c b/drivers/leds/leds-turris-omnia.c +index b8a95a917cfa4..b13a547e72c49 100644 +--- a/drivers/leds/leds-turris-omnia.c ++++ b/drivers/leds/leds-turris-omnia.c +@@ -2,7 +2,7 @@ + /* + * CZ.NIC's Turris Omnia LEDs driver + * +- * 2020 by Marek Behún ++ * 2020, 2023 by Marek Behún + */ + + #include +@@ -41,6 +41,37 @@ struct omnia_leds { + struct omnia_led leds[]; + }; + ++static int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd, u8 val) ++{ ++ u8 buf[2] = { cmd, val }; ++ ++ return i2c_master_send(client, buf, sizeof(buf)); ++} ++ ++static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd) ++{ ++ struct i2c_msg msgs[2]; ++ u8 reply; ++ int ret; ++ ++ msgs[0].addr = client->addr; ++ msgs[0].flags = 0; ++ msgs[0].len = 1; ++ msgs[0].buf = &cmd; ++ msgs[1].addr = client->addr; ++ msgs[1].flags = I2C_M_RD; ++ msgs[1].len = 1; ++ msgs[1].buf = &reply; ++ ++ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); ++ if (likely(ret == ARRAY_SIZE(msgs))) ++ return reply; ++ else if (ret < 0) ++ return ret; ++ else ++ return -EIO; ++} ++ + static int omnia_led_brightness_set_blocking(struct led_classdev *cdev, + enum led_brightness brightness) + { +@@ -64,7 +95,7 @@ static int omnia_led_brightness_set_blocking(struct led_classdev *cdev, + if (buf[2] || buf[3] || buf[4]) + state |= CMD_LED_STATE_ON; + +- ret = i2c_smbus_write_byte_data(leds->client, CMD_LED_STATE, state); ++ ret = omnia_cmd_write_u8(leds->client, CMD_LED_STATE, state); + if (ret >= 0 && (state & CMD_LED_STATE_ON)) + ret = i2c_master_send(leds->client, buf, 5); + +@@ -114,9 +145,9 @@ static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, + cdev->brightness_set_blocking = omnia_led_brightness_set_blocking; + + /* put the LED into software mode */ +- ret = i2c_smbus_write_byte_data(client, CMD_LED_MODE, +- CMD_LED_MODE_LED(led->reg) | +- CMD_LED_MODE_USER); ++ ret = omnia_cmd_write_u8(client, CMD_LED_MODE, ++ CMD_LED_MODE_LED(led->reg) | ++ CMD_LED_MODE_USER); + if (ret < 0) { + dev_err(dev, "Cannot set LED %pOF to software mode: %i\n", np, + ret); +@@ -124,8 +155,8 @@ static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, + } + + /* disable the LED */ +- ret = i2c_smbus_write_byte_data(client, CMD_LED_STATE, +- CMD_LED_STATE_LED(led->reg)); ++ ret = omnia_cmd_write_u8(client, CMD_LED_STATE, ++ CMD_LED_STATE_LED(led->reg)); + if (ret < 0) { + dev_err(dev, "Cannot set LED %pOF brightness: %i\n", np, ret); + return ret; +@@ -158,7 +189,7 @@ static ssize_t brightness_show(struct device *dev, struct device_attribute *a, + struct i2c_client *client = to_i2c_client(dev); + int ret; + +- ret = i2c_smbus_read_byte_data(client, CMD_LED_GET_BRIGHTNESS); ++ ret = omnia_cmd_read_u8(client, CMD_LED_GET_BRIGHTNESS); + + if (ret < 0) + return ret; +@@ -179,8 +210,7 @@ static ssize_t brightness_store(struct device *dev, struct device_attribute *a, + if (brightness > 100) + return -EINVAL; + +- ret = i2c_smbus_write_byte_data(client, CMD_LED_SET_BRIGHTNESS, +- (u8)brightness); ++ ret = omnia_cmd_write_u8(client, CMD_LED_SET_BRIGHTNESS, brightness); + + return ret < 0 ? ret : count; + } +@@ -237,8 +267,8 @@ static void omnia_leds_remove(struct i2c_client *client) + u8 buf[5]; + + /* put all LEDs into default (HW triggered) mode */ +- i2c_smbus_write_byte_data(client, CMD_LED_MODE, +- CMD_LED_MODE_LED(OMNIA_BOARD_LEDS)); ++ omnia_cmd_write_u8(client, CMD_LED_MODE, ++ CMD_LED_MODE_LED(OMNIA_BOARD_LEDS)); + + /* set all LEDs color to [255, 255, 255] */ + buf[0] = CMD_LED_COLOR; +-- +2.42.0 + diff --git a/queue-6.6/libbpf-fix-syscall-access-arguments-on-riscv.patch b/queue-6.6/libbpf-fix-syscall-access-arguments-on-riscv.patch new file mode 100644 index 00000000000..50dcc10db15 --- /dev/null +++ b/queue-6.6/libbpf-fix-syscall-access-arguments-on-riscv.patch @@ -0,0 +1,39 @@ +From 28eb924c85d0620ecb9886b4a1f45c4877c46448 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 13:09:03 +0200 +Subject: libbpf: Fix syscall access arguments on riscv + +From: Alexandre Ghiti + +[ Upstream commit 8a412c5c1cd6cc6c55e8b9b84fbb789fc395fe78 ] + +Since commit 08d0ce30e0e4 ("riscv: Implement syscall wrappers"), riscv +selects ARCH_HAS_SYSCALL_WRAPPER so let's use the generic implementation +of PT_REGS_SYSCALL_REGS(). + +Fixes: 08d0ce30e0e4 ("riscv: Implement syscall wrappers") +Signed-off-by: Alexandre Ghiti +Signed-off-by: Andrii Nakryiko +Reviewed-by: Sami Tolvanen +Link: https://lore.kernel.org/bpf/20231004110905.49024-2-bjorn@kernel.org +Signed-off-by: Sasha Levin +--- + tools/lib/bpf/bpf_tracing.h | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/tools/lib/bpf/bpf_tracing.h b/tools/lib/bpf/bpf_tracing.h +index 3803479dbe106..1c13f8e88833b 100644 +--- a/tools/lib/bpf/bpf_tracing.h ++++ b/tools/lib/bpf/bpf_tracing.h +@@ -362,8 +362,6 @@ struct pt_regs___arm64 { + #define __PT_PARM7_REG a6 + #define __PT_PARM8_REG a7 + +-/* riscv does not select ARCH_HAS_SYSCALL_WRAPPER. */ +-#define PT_REGS_SYSCALL_REGS(ctx) ctx + #define __PT_PARM1_SYSCALL_REG __PT_PARM1_REG + #define __PT_PARM2_SYSCALL_REG __PT_PARM2_REG + #define __PT_PARM3_SYSCALL_REG __PT_PARM3_REG +-- +2.42.0 + diff --git a/queue-6.6/libnvdimm-of_pmem-use-devm_kstrdup-instead-of-kstrdu.patch b/queue-6.6/libnvdimm-of_pmem-use-devm_kstrdup-instead-of-kstrdu.patch new file mode 100644 index 00000000000..99e2ed8f6d0 --- /dev/null +++ b/queue-6.6/libnvdimm-of_pmem-use-devm_kstrdup-instead-of-kstrdu.patch @@ -0,0 +1,45 @@ +From ab8027a22bfd4e7bbb59ec88b4a11e3ccb43e5cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 07:03:27 +0000 +Subject: libnvdimm/of_pmem: Use devm_kstrdup instead of kstrdup and check its + return value + +From: Chen Ni + +[ Upstream commit 6fd4ebfc4d61e3097b595ab2725d513e3bbd6739 ] + +Use devm_kstrdup() instead of kstrdup() and check its return value to +avoid memory leak. + +Fixes: 49bddc73d15c ("libnvdimm/of_pmem: Provide a unique name for bus provider") +Signed-off-by: Chen Ni +Reviewed-by: Ira Weiny +Reviewed-by: Dave Jiang +Signed-off-by: Ira Weiny +Signed-off-by: Sasha Levin +--- + drivers/nvdimm/of_pmem.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvdimm/of_pmem.c b/drivers/nvdimm/of_pmem.c +index 1b9f5b8a6167e..d3fca0ab62900 100644 +--- a/drivers/nvdimm/of_pmem.c ++++ b/drivers/nvdimm/of_pmem.c +@@ -30,7 +30,13 @@ static int of_pmem_region_probe(struct platform_device *pdev) + if (!priv) + return -ENOMEM; + +- priv->bus_desc.provider_name = kstrdup(pdev->name, GFP_KERNEL); ++ priv->bus_desc.provider_name = devm_kstrdup(&pdev->dev, pdev->name, ++ GFP_KERNEL); ++ if (!priv->bus_desc.provider_name) { ++ kfree(priv); ++ return -ENOMEM; ++ } ++ + priv->bus_desc.module = THIS_MODULE; + priv->bus_desc.of_node = np; + +-- +2.42.0 + diff --git a/queue-6.6/libperf-rc_check-make-implicit-enabling-work-for-gcc.patch b/queue-6.6/libperf-rc_check-make-implicit-enabling-work-for-gcc.patch new file mode 100644 index 00000000000..583aff4d747 --- /dev/null +++ b/queue-6.6/libperf-rc_check-make-implicit-enabling-work-for-gcc.patch @@ -0,0 +1,63 @@ +From 260a1fd1e3d60011ce3d158a490b20df64f669d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Oct 2023 15:23:06 -0700 +Subject: libperf rc_check: Make implicit enabling work for GCC + +From: Ian Rogers + +[ Upstream commit 75265320d290c5f5891f16967b94883676c46705 ] + +Make the implicit REFCOUNT_CHECKING robust to when building with GCC. + +Fixes: 9be6ab181b7b ("libperf rc_check: Enable implicitly with sanitizers") +Signed-off-by: Ian Rogers +Cc: K Prateek Nayak +Cc: Ravi Bangoria +Cc: Sandipan Das +Cc: Anshuman Khandual +Cc: German Gomez +Cc: James Clark +Cc: Nick Terrell +Cc: Sean Christopherson +Cc: Changbin Du +Cc: liuwenyu +Cc: Yang Jihong +Cc: Masami Hiramatsu +Cc: Miguel Ojeda +Cc: Song Liu +Cc: Leo Yan +Cc: Kajol Jain +Cc: Andi Kleen +Cc: Kan Liang +Cc: Athira Rajeev +Cc: Yanteng Si +Cc: Liam Howlett +Cc: Paolo Bonzini +Link: https://lore.kernel.org/r/20231024222353.3024098-4-irogers@google.com +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/lib/perf/include/internal/rc_check.h | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/tools/lib/perf/include/internal/rc_check.h b/tools/lib/perf/include/internal/rc_check.h +index d5d771ccdc7b4..e88a6d8a0b0f9 100644 +--- a/tools/lib/perf/include/internal/rc_check.h ++++ b/tools/lib/perf/include/internal/rc_check.h +@@ -9,8 +9,12 @@ + * Enable reference count checking implicitly with leak checking, which is + * integrated into address sanitizer. + */ +-#if defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) ++#if defined(__SANITIZE_ADDRESS__) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) + #define REFCNT_CHECKING 1 ++#elif defined(__has_feature) ++#if __has_feature(address_sanitizer) || __has_feature(leak_sanitizer) ++#define REFCNT_CHECKING 1 ++#endif + #endif + + /* +-- +2.42.0 + diff --git a/queue-6.6/livepatch-fix-missing-newline-character-in-klp_resol.patch b/queue-6.6/livepatch-fix-missing-newline-character-in-klp_resol.patch new file mode 100644 index 00000000000..a6ddd926450 --- /dev/null +++ b/queue-6.6/livepatch-fix-missing-newline-character-in-klp_resol.patch @@ -0,0 +1,38 @@ +From a0b7b6e5d5feb6abe586ae3fdb9c552e9cd50898 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 15:26:44 +0800 +Subject: livepatch: Fix missing newline character in klp_resolve_symbols() + +From: Zheng Yejian + +[ Upstream commit 67e18e132f0fd738f8c8cac3aa1420312073f795 ] + +Without the newline character, the log may not be printed immediately +after the error occurs. + +Fixes: ca376a937486 ("livepatch: Prevent module-specific KLP rela sections from referencing vmlinux symbols") +Signed-off-by: Zheng Yejian +Reviewed-by: Petr Mladek +Signed-off-by: Petr Mladek +Link: https://lore.kernel.org/r/20230914072644.4098857-1-zhengyejian1@huawei.com +Signed-off-by: Sasha Levin +--- + kernel/livepatch/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c +index 61328328c474c..ecbc9b6aba3a1 100644 +--- a/kernel/livepatch/core.c ++++ b/kernel/livepatch/core.c +@@ -243,7 +243,7 @@ static int klp_resolve_symbols(Elf_Shdr *sechdrs, const char *strtab, + * symbols are exported and normal relas can be used instead. + */ + if (!sec_vmlinux && sym_vmlinux) { +- pr_err("invalid access to vmlinux symbol '%s' from module-specific livepatch relocation section", ++ pr_err("invalid access to vmlinux symbol '%s' from module-specific livepatch relocation section\n", + sym_name); + return -EINVAL; + } +-- +2.42.0 + diff --git a/queue-6.6/media-amphion-handle-firmware-debug-message.patch b/queue-6.6/media-amphion-handle-firmware-debug-message.patch new file mode 100644 index 00000000000..c66a539a010 --- /dev/null +++ b/queue-6.6/media-amphion-handle-firmware-debug-message.patch @@ -0,0 +1,134 @@ +From 5bd1bc6bd94d8d72007033d37856386104939399 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 09:51:00 +0800 +Subject: media: amphion: handle firmware debug message + +From: Ming Qian + +[ Upstream commit 6496617b2b06d7004a5cbd53d48f19567d6b018c ] + +decoder firmware may notify host some debug message, +it can help analyze the state of the firmware in case of error + +Fixes: 9f599f351e86 ("media: amphion: add vpu core driver") +Signed-off-by: Ming Qian +Reviewed-by: Nicolas Dufresne +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/platform/amphion/vpu_defs.h | 1 + + drivers/media/platform/amphion/vpu_helpers.c | 1 + + drivers/media/platform/amphion/vpu_malone.c | 1 + + drivers/media/platform/amphion/vpu_msgs.c | 31 ++++++++++++++++---- + 4 files changed, 29 insertions(+), 5 deletions(-) + +diff --git a/drivers/media/platform/amphion/vpu_defs.h b/drivers/media/platform/amphion/vpu_defs.h +index 667637eedb5d4..7320852668d64 100644 +--- a/drivers/media/platform/amphion/vpu_defs.h ++++ b/drivers/media/platform/amphion/vpu_defs.h +@@ -71,6 +71,7 @@ enum { + VPU_MSG_ID_TIMESTAMP_INFO, + VPU_MSG_ID_FIRMWARE_XCPT, + VPU_MSG_ID_PIC_SKIPPED, ++ VPU_MSG_ID_DBG_MSG, + }; + + enum VPU_ENC_MEMORY_RESOURSE { +diff --git a/drivers/media/platform/amphion/vpu_helpers.c b/drivers/media/platform/amphion/vpu_helpers.c +index af3b336e5dc32..d12310af9ebce 100644 +--- a/drivers/media/platform/amphion/vpu_helpers.c ++++ b/drivers/media/platform/amphion/vpu_helpers.c +@@ -489,6 +489,7 @@ const char *vpu_id_name(u32 id) + case VPU_MSG_ID_UNSUPPORTED: return "unsupported"; + case VPU_MSG_ID_FIRMWARE_XCPT: return "exception"; + case VPU_MSG_ID_PIC_SKIPPED: return "skipped"; ++ case VPU_MSG_ID_DBG_MSG: return "debug msg"; + } + return ""; + } +diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c +index f771661980c01..d3425de7bccd3 100644 +--- a/drivers/media/platform/amphion/vpu_malone.c ++++ b/drivers/media/platform/amphion/vpu_malone.c +@@ -745,6 +745,7 @@ static struct vpu_pair malone_msgs[] = { + {VPU_MSG_ID_UNSUPPORTED, VID_API_EVENT_UNSUPPORTED_STREAM}, + {VPU_MSG_ID_FIRMWARE_XCPT, VID_API_EVENT_FIRMWARE_XCPT}, + {VPU_MSG_ID_PIC_SKIPPED, VID_API_EVENT_PIC_SKIPPED}, ++ {VPU_MSG_ID_DBG_MSG, VID_API_EVENT_DBG_MSG_DEC}, + }; + + static void vpu_malone_pack_fs_alloc(struct vpu_rpc_event *pkt, +diff --git a/drivers/media/platform/amphion/vpu_msgs.c b/drivers/media/platform/amphion/vpu_msgs.c +index d0ead051f7d18..b74a407a19f22 100644 +--- a/drivers/media/platform/amphion/vpu_msgs.c ++++ b/drivers/media/platform/amphion/vpu_msgs.c +@@ -23,6 +23,7 @@ + struct vpu_msg_handler { + u32 id; + void (*done)(struct vpu_inst *inst, struct vpu_rpc_event *pkt); ++ u32 is_str; + }; + + static void vpu_session_handle_start_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt) +@@ -154,7 +155,7 @@ static void vpu_session_handle_error(struct vpu_inst *inst, struct vpu_rpc_event + { + char *str = (char *)pkt->data; + +- if (strlen(str)) ++ if (*str) + dev_err(inst->dev, "instance %d firmware error : %s\n", inst->id, str); + else + dev_err(inst->dev, "instance %d is unsupported stream\n", inst->id); +@@ -180,6 +181,21 @@ static void vpu_session_handle_pic_skipped(struct vpu_inst *inst, struct vpu_rpc + vpu_inst_unlock(inst); + } + ++static void vpu_session_handle_dbg_msg(struct vpu_inst *inst, struct vpu_rpc_event *pkt) ++{ ++ char *str = (char *)pkt->data; ++ ++ if (*str) ++ dev_info(inst->dev, "instance %d firmware dbg msg : %s\n", inst->id, str); ++} ++ ++static void vpu_terminate_string_msg(struct vpu_rpc_event *pkt) ++{ ++ if (pkt->hdr.num == ARRAY_SIZE(pkt->data)) ++ pkt->hdr.num--; ++ pkt->data[pkt->hdr.num] = 0; ++} ++ + static struct vpu_msg_handler handlers[] = { + {VPU_MSG_ID_START_DONE, vpu_session_handle_start_done}, + {VPU_MSG_ID_STOP_DONE, vpu_session_handle_stop_done}, +@@ -193,9 +209,10 @@ static struct vpu_msg_handler handlers[] = { + {VPU_MSG_ID_PIC_DECODED, vpu_session_handle_pic_decoded}, + {VPU_MSG_ID_DEC_DONE, vpu_session_handle_pic_done}, + {VPU_MSG_ID_PIC_EOS, vpu_session_handle_eos}, +- {VPU_MSG_ID_UNSUPPORTED, vpu_session_handle_error}, +- {VPU_MSG_ID_FIRMWARE_XCPT, vpu_session_handle_firmware_xcpt}, ++ {VPU_MSG_ID_UNSUPPORTED, vpu_session_handle_error, true}, ++ {VPU_MSG_ID_FIRMWARE_XCPT, vpu_session_handle_firmware_xcpt, true}, + {VPU_MSG_ID_PIC_SKIPPED, vpu_session_handle_pic_skipped}, ++ {VPU_MSG_ID_DBG_MSG, vpu_session_handle_dbg_msg, true}, + }; + + static int vpu_session_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *msg) +@@ -219,8 +236,12 @@ static int vpu_session_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *m + } + } + +- if (handler && handler->done) +- handler->done(inst, msg); ++ if (handler) { ++ if (handler->is_str) ++ vpu_terminate_string_msg(msg); ++ if (handler->done) ++ handler->done(inst, msg); ++ } + + vpu_response_cmd(inst, msg_id, 1); + +-- +2.42.0 + diff --git a/queue-6.6/media-bttv-fix-use-after-free-error-due-to-btv-timeo.patch b/queue-6.6/media-bttv-fix-use-after-free-error-due-to-btv-timeo.patch new file mode 100644 index 00000000000..0420f0d401e --- /dev/null +++ b/queue-6.6/media-bttv-fix-use-after-free-error-due-to-btv-timeo.patch @@ -0,0 +1,52 @@ +From cdb47dc875eb312d2de3c5cb0b8b066e514a6826 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Apr 2023 11:49:42 +0800 +Subject: media: bttv: fix use after free error due to btv->timeout timer + +From: Zheng Wang + +[ Upstream commit bd5b50b329e850d467e7bcc07b2b6bde3752fbda ] + +There may be some a race condition between timer function +bttv_irq_timeout and bttv_remove. The timer is setup in +probe and there is no timer_delete operation in remove +function. When it hit kfree btv, the function might still be +invoked, which will cause use after free bug. + +This bug is found by static analysis, it may be false positive. + +Fix it by adding del_timer_sync invoking to the remove function. + +cpu0 cpu1 + bttv_probe + ->timer_setup + ->bttv_set_dma + ->mod_timer; +bttv_remove + ->kfree(btv); + ->bttv_irq_timeout + ->USE btv + +Fixes: 162e6376ac58 ("media: pci: Convert timers to use timer_setup()") +Signed-off-by: Zheng Wang +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/pci/bt8xx/bttv-driver.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c +index aa708a0e5eac6..09a193bb87df3 100644 +--- a/drivers/media/pci/bt8xx/bttv-driver.c ++++ b/drivers/media/pci/bt8xx/bttv-driver.c +@@ -3474,6 +3474,7 @@ static void bttv_remove(struct pci_dev *pci_dev) + + /* free resources */ + free_irq(btv->c.pci->irq,btv); ++ del_timer_sync(&btv->timeout); + iounmap(btv->bt848_mmio); + release_mem_region(pci_resource_start(btv->c.pci,0), + pci_resource_len(btv->c.pci,0)); +-- +2.42.0 + diff --git a/queue-6.6/media-cadence-csi2rx-unregister-v4l2-async-notifier.patch b/queue-6.6/media-cadence-csi2rx-unregister-v4l2-async-notifier.patch new file mode 100644 index 00000000000..3632fee7c69 --- /dev/null +++ b/queue-6.6/media-cadence-csi2rx-unregister-v4l2-async-notifier.patch @@ -0,0 +1,67 @@ +From 7a6f683cc9acbea50125d3123cff947777805f39 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 18:39:29 +0530 +Subject: media: cadence: csi2rx: Unregister v4l2 async notifier + +From: Pratyush Yadav + +[ Upstream commit b2701715301a49b53d05c7d43f3fedc3b8743bfc ] + +The notifier is added to the global notifier list when registered. When +the module is removed, the struct csi2rx_priv in which the notifier is +embedded, is destroyed. As a result the notifier list has a reference to +a notifier that no longer exists. This causes invalid memory accesses +when the list is iterated over. Similar for when the probe fails. +Unregister and clean up the notifier to avoid this. + +Fixes: 1fc3b37f34f6 ("media: v4l: cadence: Add Cadence MIPI-CSI2 RX driver") + +Signed-off-by: Pratyush Yadav +Tested-by: Julien Massot +Reviewed-by: Laurent Pinchart +Reviewed-by: Tomi Valkeinen +Reviewed-by: Maxime Ripard +Signed-off-by: Jai Luthra +Signed-off-by: Sakari Ailus +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/platform/cadence/cdns-csi2rx.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c +index 0d879d71d8185..9231ee7e9b3a9 100644 +--- a/drivers/media/platform/cadence/cdns-csi2rx.c ++++ b/drivers/media/platform/cadence/cdns-csi2rx.c +@@ -479,8 +479,10 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx) + asd = v4l2_async_nf_add_fwnode_remote(&csi2rx->notifier, fwh, + struct v4l2_async_connection); + of_node_put(ep); +- if (IS_ERR(asd)) ++ if (IS_ERR(asd)) { ++ v4l2_async_nf_cleanup(&csi2rx->notifier); + return PTR_ERR(asd); ++ } + + csi2rx->notifier.ops = &csi2rx_notifier_ops; + +@@ -543,6 +545,7 @@ static int csi2rx_probe(struct platform_device *pdev) + return 0; + + err_cleanup: ++ v4l2_async_nf_unregister(&csi2rx->notifier); + v4l2_async_nf_cleanup(&csi2rx->notifier); + err_free_priv: + kfree(csi2rx); +@@ -553,6 +556,8 @@ static void csi2rx_remove(struct platform_device *pdev) + { + struct csi2rx_priv *csi2rx = platform_get_drvdata(pdev); + ++ v4l2_async_nf_unregister(&csi2rx->notifier); ++ v4l2_async_nf_cleanup(&csi2rx->notifier); + v4l2_async_unregister_subdev(&csi2rx->subdev); + kfree(csi2rx); + } +-- +2.42.0 + diff --git a/queue-6.6/media-cec-meson-always-include-meson-sub-directory-i.patch b/queue-6.6/media-cec-meson-always-include-meson-sub-directory-i.patch new file mode 100644 index 00000000000..ee728d9ecf9 --- /dev/null +++ b/queue-6.6/media-cec-meson-always-include-meson-sub-directory-i.patch @@ -0,0 +1,37 @@ +From 8045b968702366a1f66cb90d7b66defdba278bd4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Oct 2023 12:35:25 +0200 +Subject: media: cec: meson: always include meson sub-directory in Makefile + +From: Marek Szyprowski + +[ Upstream commit 94e27fbeca27d8c772fc2bc807730aaee5886055 ] + +'meson' directory contains two separate drivers, so it should be added +to Makefile compilation hierarchy unconditionally, because otherwise the +meson-ao-cec-g12a won't be compiled if meson-ao-cec is not selected. + +Signed-off-by: Marek Szyprowski +Fixes: 4be5e8648b0c ("media: move CEC platform drivers to a separate directory") +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/cec/platform/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/cec/platform/Makefile b/drivers/media/cec/platform/Makefile +index 26d2bc7783944..a51e98ab4958d 100644 +--- a/drivers/media/cec/platform/Makefile ++++ b/drivers/media/cec/platform/Makefile +@@ -6,7 +6,7 @@ + # Please keep it in alphabetic order + obj-$(CONFIG_CEC_CROS_EC) += cros-ec/ + obj-$(CONFIG_CEC_GPIO) += cec-gpio/ +-obj-$(CONFIG_CEC_MESON_AO) += meson/ ++obj-y += meson/ + obj-$(CONFIG_CEC_SAMSUNG_S5P) += s5p/ + obj-$(CONFIG_CEC_SECO) += seco/ + obj-$(CONFIG_CEC_STI) += sti/ +-- +2.42.0 + diff --git a/queue-6.6/media-cedrus-fix-clock-reset-sequence.patch b/queue-6.6/media-cedrus-fix-clock-reset-sequence.patch new file mode 100644 index 00000000000..a3dbe2a7d93 --- /dev/null +++ b/queue-6.6/media-cedrus-fix-clock-reset-sequence.patch @@ -0,0 +1,87 @@ +From 04f935a5d0f6013006a7e8a01f346155d5e644e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Sep 2023 20:46:12 +0200 +Subject: media: cedrus: Fix clock/reset sequence + +From: Jernej Skrabec + +[ Upstream commit 36fe515c1a3cd5eac148e8a591a82108d92d5522 ] + +According to H6 user manual, resets should always be de-asserted before +clocks are enabled. This is also consistent with vendor driver. + +Fixes: d5aecd289bab ("media: cedrus: Implement runtime PM") +Signed-off-by: Jernej Skrabec +Acked-by: Paul Kocialkowski +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + .../staging/media/sunxi/cedrus/cedrus_hw.c | 24 +++++++++---------- + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c +index b696bf884cbd6..32af0e96e762b 100644 +--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c ++++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c +@@ -172,12 +172,12 @@ int cedrus_hw_suspend(struct device *device) + { + struct cedrus_dev *dev = dev_get_drvdata(device); + +- reset_control_assert(dev->rstc); +- + clk_disable_unprepare(dev->ram_clk); + clk_disable_unprepare(dev->mod_clk); + clk_disable_unprepare(dev->ahb_clk); + ++ reset_control_assert(dev->rstc); ++ + return 0; + } + +@@ -186,11 +186,18 @@ int cedrus_hw_resume(struct device *device) + struct cedrus_dev *dev = dev_get_drvdata(device); + int ret; + ++ ret = reset_control_reset(dev->rstc); ++ if (ret) { ++ dev_err(dev->dev, "Failed to apply reset\n"); ++ ++ return ret; ++ } ++ + ret = clk_prepare_enable(dev->ahb_clk); + if (ret) { + dev_err(dev->dev, "Failed to enable AHB clock\n"); + +- return ret; ++ goto err_rst; + } + + ret = clk_prepare_enable(dev->mod_clk); +@@ -207,21 +214,14 @@ int cedrus_hw_resume(struct device *device) + goto err_mod_clk; + } + +- ret = reset_control_reset(dev->rstc); +- if (ret) { +- dev_err(dev->dev, "Failed to apply reset\n"); +- +- goto err_ram_clk; +- } +- + return 0; + +-err_ram_clk: +- clk_disable_unprepare(dev->ram_clk); + err_mod_clk: + clk_disable_unprepare(dev->mod_clk); + err_ahb_clk: + clk_disable_unprepare(dev->ahb_clk); ++err_rst: ++ reset_control_assert(dev->rstc); + + return ret; + } +-- +2.42.0 + diff --git a/queue-6.6/media-dvb-usb-v2-af9035-fix-missing-unlock.patch b/queue-6.6/media-dvb-usb-v2-af9035-fix-missing-unlock.patch new file mode 100644 index 00000000000..8058dc70f74 --- /dev/null +++ b/queue-6.6/media-dvb-usb-v2-af9035-fix-missing-unlock.patch @@ -0,0 +1,67 @@ +From d62393522f4ac94edd4d39c98422ca1b5f659701 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Oct 2023 12:08:45 +0200 +Subject: media: dvb-usb-v2: af9035: fix missing unlock + +From: Hans Verkuil + +[ Upstream commit f31b2cb85f0ee165d78e1c43f6d69f82cc3b2145 ] + +Instead of returning an error, goto the mutex unlock at +the end of the function. + +Fixes smatch warning: + +drivers/media/usb/dvb-usb-v2/af9035.c:467 af9035_i2c_master_xfer() warn: inconsistent returns '&d->i2c_mutex'. + Locked on : 326,387 + Unlocked on: 465,467 + +Signed-off-by: Hans Verkuil +Fixes: 7bf744f2de0a ("media: dvb-usb-v2: af9035: Fix null-ptr-deref in af9035_i2c_master_xfer") +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/usb/dvb-usb-v2/af9035.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c +index 33a2aa8907e65..4eb7dd4599b7e 100644 +--- a/drivers/media/usb/dvb-usb-v2/af9035.c ++++ b/drivers/media/usb/dvb-usb-v2/af9035.c +@@ -322,8 +322,10 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap, + ret = -EOPNOTSUPP; + } else if ((msg[0].addr == state->af9033_i2c_addr[0]) || + (msg[0].addr == state->af9033_i2c_addr[1])) { +- if (msg[0].len < 3 || msg[1].len < 1) +- return -EOPNOTSUPP; ++ if (msg[0].len < 3 || msg[1].len < 1) { ++ ret = -EOPNOTSUPP; ++ goto unlock; ++ } + /* demod access via firmware interface */ + u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | + msg[0].buf[2]; +@@ -383,8 +385,10 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap, + ret = -EOPNOTSUPP; + } else if ((msg[0].addr == state->af9033_i2c_addr[0]) || + (msg[0].addr == state->af9033_i2c_addr[1])) { +- if (msg[0].len < 3) +- return -EOPNOTSUPP; ++ if (msg[0].len < 3) { ++ ret = -EOPNOTSUPP; ++ goto unlock; ++ } + /* demod access via firmware interface */ + u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | + msg[0].buf[2]; +@@ -459,6 +463,7 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap, + ret = -EOPNOTSUPP; + } + ++unlock: + mutex_unlock(&d->i2c_mutex); + + if (ret < 0) +-- +2.42.0 + diff --git a/queue-6.6/media-hantro-check-whether-reset-op-is-defined-befor.patch b/queue-6.6/media-hantro-check-whether-reset-op-is-defined-befor.patch new file mode 100644 index 00000000000..6deb4306ddc --- /dev/null +++ b/queue-6.6/media-hantro-check-whether-reset-op-is-defined-befor.patch @@ -0,0 +1,45 @@ +From 154e6da47d70ca83fd8ce800f55ba6c98acfc4ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Aug 2023 03:38:58 +0200 +Subject: media: hantro: Check whether reset op is defined before use + +From: Marek Vasut + +[ Upstream commit 88d4b23a629ebd34f682f770cb6c2116c851f7b8 ] + +The i.MX8MM/N/P does not define the .reset op since reset of the VPU is +done by genpd. Check whether the .reset op is defined before calling it +to avoid NULL pointer dereference. + +Note that the Fixes tag is set to the commit which removed the reset op +from i.MX8M Hantro G2 implementation, this is because before this commit +all the implementations did define the .reset op. + +Fixes: 6971efb70ac3 ("media: hantro: Allow i.MX8MQ G1 and G2 to run independently") +Signed-off-by: Marek Vasut +Reviewed-by: Chen-Yu Tsai +Tested-by: Chen-Yu Tsai +Reviewed-by: Adam Ford +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/platform/verisilicon/hantro_drv.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c +index 423fc85d79ee3..50ec24c753e9e 100644 +--- a/drivers/media/platform/verisilicon/hantro_drv.c ++++ b/drivers/media/platform/verisilicon/hantro_drv.c +@@ -125,7 +125,8 @@ void hantro_watchdog(struct work_struct *work) + ctx = v4l2_m2m_get_curr_priv(vpu->m2m_dev); + if (ctx) { + vpu_err("frame processing timed out!\n"); +- ctx->codec_ops->reset(ctx); ++ if (ctx->codec_ops->reset) ++ ctx->codec_ops->reset(ctx); + hantro_job_finish(vpu, ctx, VB2_BUF_STATE_ERROR); + } + } +-- +2.42.0 + diff --git a/queue-6.6/media-i2c-imx219-convert-to-cci-register-access-help.patch b/queue-6.6/media-i2c-imx219-convert-to-cci-register-access-help.patch new file mode 100644 index 00000000000..16e097da36b --- /dev/null +++ b/queue-6.6/media-i2c-imx219-convert-to-cci-register-access-help.patch @@ -0,0 +1,797 @@ +From 852e116ed57bb79a9d6d6624a62f40d05fe8b13a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Sep 2023 18:32:50 +0300 +Subject: media: i2c: imx219: Convert to CCI register access helpers + +From: Laurent Pinchart + +[ Upstream commit 852798cc8a45362ea7667c754b8ca0575a680a45 ] + +Use the new common CCI register access helpers to replace the private +register access helpers in the imx219 driver. This simplifies the driver +by reducing the amount of code. + +Signed-off-by: Laurent Pinchart +Reviewed-by: Dave Stevenson +Signed-off-by: Sakari Ailus +Signed-off-by: Hans Verkuil +Stable-dep-of: ec80c606cca5 ("media: i2c: imx219: Drop IMX219_REG_CSI_LANE_MODE from common regs array") +Signed-off-by: Sasha Levin +--- + drivers/media/i2c/Kconfig | 1 + + drivers/media/i2c/imx219.c | 513 ++++++++++++++++--------------------- + 2 files changed, 220 insertions(+), 294 deletions(-) + +diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig +index 74ff833ff48ca..53b443be5a59e 100644 +--- a/drivers/media/i2c/Kconfig ++++ b/drivers/media/i2c/Kconfig +@@ -99,6 +99,7 @@ config VIDEO_IMX214 + + config VIDEO_IMX219 + tristate "Sony IMX219 sensor support" ++ select V4L2_CCI_I2C + help + This is a Video4Linux2 sensor driver for the Sony + IMX219 camera. +diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c +index ec53abe2e84e5..c5aeec50b9e85 100644 +--- a/drivers/media/i2c/imx219.c ++++ b/drivers/media/i2c/imx219.c +@@ -21,40 +21,49 @@ + #include + #include + #include ++ ++#include + #include + #include + #include + #include + #include +-#include + +-#define IMX219_REG_VALUE_08BIT 1 +-#define IMX219_REG_VALUE_16BIT 2 ++/* Chip ID */ ++#define IMX219_REG_CHIP_ID CCI_REG16(0x0000) ++#define IMX219_CHIP_ID 0x0219 + +-#define IMX219_REG_MODE_SELECT 0x0100 ++#define IMX219_REG_MODE_SELECT CCI_REG8(0x0100) + #define IMX219_MODE_STANDBY 0x00 + #define IMX219_MODE_STREAMING 0x01 + +-/* Chip ID */ +-#define IMX219_REG_CHIP_ID 0x0000 +-#define IMX219_CHIP_ID 0x0219 +- +-/* External clock frequency is 24.0M */ +-#define IMX219_XCLK_FREQ 24000000 ++#define IMX219_REG_CSI_LANE_MODE CCI_REG8(0x0114) ++#define IMX219_CSI_2_LANE_MODE 0x01 ++#define IMX219_CSI_4_LANE_MODE 0x03 + +-/* Pixel rate is fixed for all the modes */ +-#define IMX219_PIXEL_RATE 182400000 +-#define IMX219_PIXEL_RATE_4LANE 280800000 ++/* Analog gain control */ ++#define IMX219_REG_ANALOG_GAIN CCI_REG8(0x0157) ++#define IMX219_ANA_GAIN_MIN 0 ++#define IMX219_ANA_GAIN_MAX 232 ++#define IMX219_ANA_GAIN_STEP 1 ++#define IMX219_ANA_GAIN_DEFAULT 0x0 + +-#define IMX219_DEFAULT_LINK_FREQ 456000000 +-#define IMX219_DEFAULT_LINK_FREQ_4LANE 363000000 ++/* Digital gain control */ ++#define IMX219_REG_DIGITAL_GAIN CCI_REG16(0x0158) ++#define IMX219_DGTL_GAIN_MIN 0x0100 ++#define IMX219_DGTL_GAIN_MAX 0x0fff ++#define IMX219_DGTL_GAIN_DEFAULT 0x0100 ++#define IMX219_DGTL_GAIN_STEP 1 + +-#define IMX219_REG_CSI_LANE_MODE 0x0114 +-#define IMX219_CSI_2_LANE_MODE 0x01 +-#define IMX219_CSI_4_LANE_MODE 0x03 ++/* Exposure control */ ++#define IMX219_REG_EXPOSURE CCI_REG16(0x015a) ++#define IMX219_EXPOSURE_MIN 4 ++#define IMX219_EXPOSURE_STEP 1 ++#define IMX219_EXPOSURE_DEFAULT 0x640 ++#define IMX219_EXPOSURE_MAX 65535 + + /* V_TIMING internal */ +-#define IMX219_REG_VTS 0x0160 ++#define IMX219_REG_VTS CCI_REG16(0x0160) + #define IMX219_VTS_15FPS 0x0dc6 + #define IMX219_VTS_30FPS_1080P 0x06e3 + #define IMX219_VTS_30FPS_BINNED 0x06e3 +@@ -72,37 +81,16 @@ + /* HBLANK control - read only */ + #define IMX219_PPL_DEFAULT 3448 + +-/* Exposure control */ +-#define IMX219_REG_EXPOSURE 0x015a +-#define IMX219_EXPOSURE_MIN 4 +-#define IMX219_EXPOSURE_STEP 1 +-#define IMX219_EXPOSURE_DEFAULT 0x640 +-#define IMX219_EXPOSURE_MAX 65535 +- +-/* Analog gain control */ +-#define IMX219_REG_ANALOG_GAIN 0x0157 +-#define IMX219_ANA_GAIN_MIN 0 +-#define IMX219_ANA_GAIN_MAX 232 +-#define IMX219_ANA_GAIN_STEP 1 +-#define IMX219_ANA_GAIN_DEFAULT 0x0 +- +-/* Digital gain control */ +-#define IMX219_REG_DIGITAL_GAIN 0x0158 +-#define IMX219_DGTL_GAIN_MIN 0x0100 +-#define IMX219_DGTL_GAIN_MAX 0x0fff +-#define IMX219_DGTL_GAIN_DEFAULT 0x0100 +-#define IMX219_DGTL_GAIN_STEP 1 +- +-#define IMX219_REG_ORIENTATION 0x0172 ++#define IMX219_REG_ORIENTATION CCI_REG8(0x0172) + + /* Binning Mode */ +-#define IMX219_REG_BINNING_MODE 0x0174 ++#define IMX219_REG_BINNING_MODE CCI_REG16(0x0174) + #define IMX219_BINNING_NONE 0x0000 + #define IMX219_BINNING_2X2 0x0101 + #define IMX219_BINNING_2X2_ANALOG 0x0303 + + /* Test Pattern Control */ +-#define IMX219_REG_TEST_PATTERN 0x0600 ++#define IMX219_REG_TEST_PATTERN CCI_REG16(0x0600) + #define IMX219_TEST_PATTERN_DISABLE 0 + #define IMX219_TEST_PATTERN_SOLID_COLOR 1 + #define IMX219_TEST_PATTERN_COLOR_BARS 2 +@@ -110,10 +98,10 @@ + #define IMX219_TEST_PATTERN_PN9 4 + + /* Test pattern colour components */ +-#define IMX219_REG_TESTP_RED 0x0602 +-#define IMX219_REG_TESTP_GREENR 0x0604 +-#define IMX219_REG_TESTP_BLUE 0x0606 +-#define IMX219_REG_TESTP_GREENB 0x0608 ++#define IMX219_REG_TESTP_RED CCI_REG16(0x0602) ++#define IMX219_REG_TESTP_GREENR CCI_REG16(0x0604) ++#define IMX219_REG_TESTP_BLUE CCI_REG16(0x0606) ++#define IMX219_REG_TESTP_GREENB CCI_REG16(0x0608) + #define IMX219_TESTP_COLOUR_MIN 0 + #define IMX219_TESTP_COLOUR_MAX 0x03ff + #define IMX219_TESTP_COLOUR_STEP 1 +@@ -122,6 +110,16 @@ + #define IMX219_TESTP_BLUE_DEFAULT 0 + #define IMX219_TESTP_GREENB_DEFAULT 0 + ++/* External clock frequency is 24.0M */ ++#define IMX219_XCLK_FREQ 24000000 ++ ++/* Pixel rate is fixed for all the modes */ ++#define IMX219_PIXEL_RATE 182400000 ++#define IMX219_PIXEL_RATE_4LANE 280800000 ++ ++#define IMX219_DEFAULT_LINK_FREQ 456000000 ++#define IMX219_DEFAULT_LINK_FREQ_4LANE 363000000 ++ + /* IMX219 native and active pixel array size. */ + #define IMX219_NATIVE_WIDTH 3296U + #define IMX219_NATIVE_HEIGHT 2480U +@@ -130,14 +128,9 @@ + #define IMX219_PIXEL_ARRAY_WIDTH 3280U + #define IMX219_PIXEL_ARRAY_HEIGHT 2464U + +-struct imx219_reg { +- u16 address; +- u8 val; +-}; +- + struct imx219_reg_list { + unsigned int num_of_regs; +- const struct imx219_reg *regs; ++ const struct cci_reg_sequence *regs; + }; + + /* Mode : resolution and related config&values */ +@@ -160,53 +153,53 @@ struct imx219_mode { + bool binning; + }; + +-static const struct imx219_reg imx219_common_regs[] = { +- {0x0100, 0x00}, /* Mode Select */ ++static const struct cci_reg_sequence imx219_common_regs[] = { ++ { CCI_REG8(0x0100), 0x00 }, /* Mode Select */ + + /* To Access Addresses 3000-5fff, send the following commands */ +- {0x30eb, 0x0c}, +- {0x30eb, 0x05}, +- {0x300a, 0xff}, +- {0x300b, 0xff}, +- {0x30eb, 0x05}, +- {0x30eb, 0x09}, ++ { CCI_REG8(0x30eb), 0x0c }, ++ { CCI_REG8(0x30eb), 0x05 }, ++ { CCI_REG8(0x300a), 0xff }, ++ { CCI_REG8(0x300b), 0xff }, ++ { CCI_REG8(0x30eb), 0x05 }, ++ { CCI_REG8(0x30eb), 0x09 }, + + /* PLL Clock Table */ +- {0x0301, 0x05}, /* VTPXCK_DIV */ +- {0x0303, 0x01}, /* VTSYSCK_DIV */ +- {0x0304, 0x03}, /* PREPLLCK_VT_DIV 0x03 = AUTO set */ +- {0x0305, 0x03}, /* PREPLLCK_OP_DIV 0x03 = AUTO set */ +- {0x0306, 0x00}, /* PLL_VT_MPY */ +- {0x0307, 0x39}, +- {0x030b, 0x01}, /* OP_SYS_CLK_DIV */ +- {0x030c, 0x00}, /* PLL_OP_MPY */ +- {0x030d, 0x72}, ++ { CCI_REG8(0x0301), 0x05 }, /* VTPXCK_DIV */ ++ { CCI_REG8(0x0303), 0x01 }, /* VTSYSCK_DIV */ ++ { CCI_REG8(0x0304), 0x03 }, /* PREPLLCK_VT_DIV 0x03 = AUTO set */ ++ { CCI_REG8(0x0305), 0x03 }, /* PREPLLCK_OP_DIV 0x03 = AUTO set */ ++ { CCI_REG8(0x0306), 0x00 }, /* PLL_VT_MPY */ ++ { CCI_REG8(0x0307), 0x39 }, ++ { CCI_REG8(0x030b), 0x01 }, /* OP_SYS_CLK_DIV */ ++ { CCI_REG8(0x030c), 0x00 }, /* PLL_OP_MPY */ ++ { CCI_REG8(0x030d), 0x72 }, + + /* Undocumented registers */ +- {0x455e, 0x00}, +- {0x471e, 0x4b}, +- {0x4767, 0x0f}, +- {0x4750, 0x14}, +- {0x4540, 0x00}, +- {0x47b4, 0x14}, +- {0x4713, 0x30}, +- {0x478b, 0x10}, +- {0x478f, 0x10}, +- {0x4793, 0x10}, +- {0x4797, 0x0e}, +- {0x479b, 0x0e}, ++ { CCI_REG8(0x455e), 0x00 }, ++ { CCI_REG8(0x471e), 0x4b }, ++ { CCI_REG8(0x4767), 0x0f }, ++ { CCI_REG8(0x4750), 0x14 }, ++ { CCI_REG8(0x4540), 0x00 }, ++ { CCI_REG8(0x47b4), 0x14 }, ++ { CCI_REG8(0x4713), 0x30 }, ++ { CCI_REG8(0x478b), 0x10 }, ++ { CCI_REG8(0x478f), 0x10 }, ++ { CCI_REG8(0x4793), 0x10 }, ++ { CCI_REG8(0x4797), 0x0e }, ++ { CCI_REG8(0x479b), 0x0e }, + + /* Frame Bank Register Group "A" */ +- {0x0162, 0x0d}, /* Line_Length_A */ +- {0x0163, 0x78}, +- {0x0170, 0x01}, /* X_ODD_INC_A */ +- {0x0171, 0x01}, /* Y_ODD_INC_A */ ++ { CCI_REG8(0x0162), 0x0d }, /* Line_Length_A */ ++ { CCI_REG8(0x0163), 0x78 }, ++ { CCI_REG8(0x0170), 0x01 }, /* X_ODD_INC_A */ ++ { CCI_REG8(0x0171), 0x01 }, /* Y_ODD_INC_A */ + + /* Output setup registers */ +- {0x0114, 0x01}, /* CSI 2-Lane Mode */ +- {0x0128, 0x00}, /* DPHY Auto Mode */ +- {0x012a, 0x18}, /* EXCK_Freq */ +- {0x012b, 0x00}, ++ { CCI_REG8(0x0114), 0x01 }, /* CSI 2-Lane Mode */ ++ { CCI_REG8(0x0128), 0x00 }, /* DPHY Auto Mode */ ++ { CCI_REG8(0x012a), 0x18 }, /* EXCK_Freq */ ++ { CCI_REG8(0x012b), 0x00 }, + }; + + /* +@@ -214,92 +207,92 @@ static const struct imx219_reg imx219_common_regs[] = { + * driver. + * 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7. + */ +-static const struct imx219_reg mode_3280x2464_regs[] = { +- {0x0164, 0x00}, +- {0x0165, 0x00}, +- {0x0166, 0x0c}, +- {0x0167, 0xcf}, +- {0x0168, 0x00}, +- {0x0169, 0x00}, +- {0x016a, 0x09}, +- {0x016b, 0x9f}, +- {0x016c, 0x0c}, +- {0x016d, 0xd0}, +- {0x016e, 0x09}, +- {0x016f, 0xa0}, +- {0x0624, 0x0c}, +- {0x0625, 0xd0}, +- {0x0626, 0x09}, +- {0x0627, 0xa0}, ++static const struct cci_reg_sequence mode_3280x2464_regs[] = { ++ { CCI_REG8(0x0164), 0x00 }, ++ { CCI_REG8(0x0165), 0x00 }, ++ { CCI_REG8(0x0166), 0x0c }, ++ { CCI_REG8(0x0167), 0xcf }, ++ { CCI_REG8(0x0168), 0x00 }, ++ { CCI_REG8(0x0169), 0x00 }, ++ { CCI_REG8(0x016a), 0x09 }, ++ { CCI_REG8(0x016b), 0x9f }, ++ { CCI_REG8(0x016c), 0x0c }, ++ { CCI_REG8(0x016d), 0xd0 }, ++ { CCI_REG8(0x016e), 0x09 }, ++ { CCI_REG8(0x016f), 0xa0 }, ++ { CCI_REG8(0x0624), 0x0c }, ++ { CCI_REG8(0x0625), 0xd0 }, ++ { CCI_REG8(0x0626), 0x09 }, ++ { CCI_REG8(0x0627), 0xa0 }, + }; + +-static const struct imx219_reg mode_1920_1080_regs[] = { +- {0x0164, 0x02}, +- {0x0165, 0xa8}, +- {0x0166, 0x0a}, +- {0x0167, 0x27}, +- {0x0168, 0x02}, +- {0x0169, 0xb4}, +- {0x016a, 0x06}, +- {0x016b, 0xeb}, +- {0x016c, 0x07}, +- {0x016d, 0x80}, +- {0x016e, 0x04}, +- {0x016f, 0x38}, +- {0x0624, 0x07}, +- {0x0625, 0x80}, +- {0x0626, 0x04}, +- {0x0627, 0x38}, ++static const struct cci_reg_sequence mode_1920_1080_regs[] = { ++ { CCI_REG8(0x0164), 0x02 }, ++ { CCI_REG8(0x0165), 0xa8 }, ++ { CCI_REG8(0x0166), 0x0a }, ++ { CCI_REG8(0x0167), 0x27 }, ++ { CCI_REG8(0x0168), 0x02 }, ++ { CCI_REG8(0x0169), 0xb4 }, ++ { CCI_REG8(0x016a), 0x06 }, ++ { CCI_REG8(0x016b), 0xeb }, ++ { CCI_REG8(0x016c), 0x07 }, ++ { CCI_REG8(0x016d), 0x80 }, ++ { CCI_REG8(0x016e), 0x04 }, ++ { CCI_REG8(0x016f), 0x38 }, ++ { CCI_REG8(0x0624), 0x07 }, ++ { CCI_REG8(0x0625), 0x80 }, ++ { CCI_REG8(0x0626), 0x04 }, ++ { CCI_REG8(0x0627), 0x38 }, + }; + +-static const struct imx219_reg mode_1640_1232_regs[] = { +- {0x0164, 0x00}, +- {0x0165, 0x00}, +- {0x0166, 0x0c}, +- {0x0167, 0xcf}, +- {0x0168, 0x00}, +- {0x0169, 0x00}, +- {0x016a, 0x09}, +- {0x016b, 0x9f}, +- {0x016c, 0x06}, +- {0x016d, 0x68}, +- {0x016e, 0x04}, +- {0x016f, 0xd0}, +- {0x0624, 0x06}, +- {0x0625, 0x68}, +- {0x0626, 0x04}, +- {0x0627, 0xd0}, ++static const struct cci_reg_sequence mode_1640_1232_regs[] = { ++ { CCI_REG8(0x0164), 0x00 }, ++ { CCI_REG8(0x0165), 0x00 }, ++ { CCI_REG8(0x0166), 0x0c }, ++ { CCI_REG8(0x0167), 0xcf }, ++ { CCI_REG8(0x0168), 0x00 }, ++ { CCI_REG8(0x0169), 0x00 }, ++ { CCI_REG8(0x016a), 0x09 }, ++ { CCI_REG8(0x016b), 0x9f }, ++ { CCI_REG8(0x016c), 0x06 }, ++ { CCI_REG8(0x016d), 0x68 }, ++ { CCI_REG8(0x016e), 0x04 }, ++ { CCI_REG8(0x016f), 0xd0 }, ++ { CCI_REG8(0x0624), 0x06 }, ++ { CCI_REG8(0x0625), 0x68 }, ++ { CCI_REG8(0x0626), 0x04 }, ++ { CCI_REG8(0x0627), 0xd0 }, + }; + +-static const struct imx219_reg mode_640_480_regs[] = { +- {0x0164, 0x03}, +- {0x0165, 0xe8}, +- {0x0166, 0x08}, +- {0x0167, 0xe7}, +- {0x0168, 0x02}, +- {0x0169, 0xf0}, +- {0x016a, 0x06}, +- {0x016b, 0xaf}, +- {0x016c, 0x02}, +- {0x016d, 0x80}, +- {0x016e, 0x01}, +- {0x016f, 0xe0}, +- {0x0624, 0x06}, +- {0x0625, 0x68}, +- {0x0626, 0x04}, +- {0x0627, 0xd0}, ++static const struct cci_reg_sequence mode_640_480_regs[] = { ++ { CCI_REG8(0x0164), 0x03 }, ++ { CCI_REG8(0x0165), 0xe8 }, ++ { CCI_REG8(0x0166), 0x08 }, ++ { CCI_REG8(0x0167), 0xe7 }, ++ { CCI_REG8(0x0168), 0x02 }, ++ { CCI_REG8(0x0169), 0xf0 }, ++ { CCI_REG8(0x016a), 0x06 }, ++ { CCI_REG8(0x016b), 0xaf }, ++ { CCI_REG8(0x016c), 0x02 }, ++ { CCI_REG8(0x016d), 0x80 }, ++ { CCI_REG8(0x016e), 0x01 }, ++ { CCI_REG8(0x016f), 0xe0 }, ++ { CCI_REG8(0x0624), 0x06 }, ++ { CCI_REG8(0x0625), 0x68 }, ++ { CCI_REG8(0x0626), 0x04 }, ++ { CCI_REG8(0x0627), 0xd0 }, + }; + +-static const struct imx219_reg raw8_framefmt_regs[] = { +- {0x018c, 0x08}, +- {0x018d, 0x08}, +- {0x0309, 0x08}, ++static const struct cci_reg_sequence raw8_framefmt_regs[] = { ++ { CCI_REG8(0x018c), 0x08 }, ++ { CCI_REG8(0x018d), 0x08 }, ++ { CCI_REG8(0x0309), 0x08 }, + }; + +-static const struct imx219_reg raw10_framefmt_regs[] = { +- {0x018c, 0x0a}, +- {0x018d, 0x0a}, +- {0x0309, 0x0a}, ++static const struct cci_reg_sequence raw10_framefmt_regs[] = { ++ { CCI_REG8(0x018c), 0x0a }, ++ { CCI_REG8(0x018d), 0x0a }, ++ { CCI_REG8(0x0309), 0x0a }, + }; + + static const s64 imx219_link_freq_menu[] = { +@@ -460,6 +453,7 @@ struct imx219 { + struct v4l2_subdev sd; + struct media_pad pad; + ++ struct regmap *regmap; + struct clk *xclk; /* system clock to IMX219 */ + u32 xclk_freq; + +@@ -491,78 +485,6 @@ static inline struct imx219 *to_imx219(struct v4l2_subdev *_sd) + return container_of(_sd, struct imx219, sd); + } + +-/* Read registers up to 2 at a time */ +-static int imx219_read_reg(struct imx219 *imx219, u16 reg, u32 len, u32 *val) +-{ +- struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); +- struct i2c_msg msgs[2]; +- u8 addr_buf[2] = { reg >> 8, reg & 0xff }; +- u8 data_buf[4] = { 0, }; +- int ret; +- +- if (len > 4) +- return -EINVAL; +- +- /* Write register address */ +- msgs[0].addr = client->addr; +- msgs[0].flags = 0; +- msgs[0].len = ARRAY_SIZE(addr_buf); +- msgs[0].buf = addr_buf; +- +- /* Read data from register */ +- msgs[1].addr = client->addr; +- msgs[1].flags = I2C_M_RD; +- msgs[1].len = len; +- msgs[1].buf = &data_buf[4 - len]; +- +- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); +- if (ret != ARRAY_SIZE(msgs)) +- return -EIO; +- +- *val = get_unaligned_be32(data_buf); +- +- return 0; +-} +- +-/* Write registers up to 2 at a time */ +-static int imx219_write_reg(struct imx219 *imx219, u16 reg, u32 len, u32 val) +-{ +- struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); +- u8 buf[6]; +- +- if (len > 4) +- return -EINVAL; +- +- put_unaligned_be16(reg, buf); +- put_unaligned_be32(val << (8 * (4 - len)), buf + 2); +- if (i2c_master_send(client, buf, len + 2) != len + 2) +- return -EIO; +- +- return 0; +-} +- +-/* Write a list of registers */ +-static int imx219_write_regs(struct imx219 *imx219, +- const struct imx219_reg *regs, u32 len) +-{ +- struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); +- unsigned int i; +- int ret; +- +- for (i = 0; i < len; i++) { +- ret = imx219_write_reg(imx219, regs[i].address, 1, regs[i].val); +- if (ret) { +- dev_err_ratelimited(&client->dev, +- "Failed to write reg 0x%4.4x. error = %d\n", +- regs[i].address, ret); +- +- return ret; +- } +- } +- +- return 0; +-} +- + /* Get bayer order based on flip setting. */ + static u32 imx219_get_format_code(struct imx219 *imx219, u32 code) + { +@@ -586,7 +508,7 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) + struct imx219 *imx219 = + container_of(ctrl->handler, struct imx219, ctrl_handler); + struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); +- int ret; ++ int ret = 0; + + if (ctrl->id == V4L2_CID_VBLANK) { + int exposure_max, exposure_def; +@@ -610,48 +532,45 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) + + switch (ctrl->id) { + case V4L2_CID_ANALOGUE_GAIN: +- ret = imx219_write_reg(imx219, IMX219_REG_ANALOG_GAIN, +- IMX219_REG_VALUE_08BIT, ctrl->val); ++ cci_write(imx219->regmap, IMX219_REG_ANALOG_GAIN, ++ ctrl->val, &ret); + break; + case V4L2_CID_EXPOSURE: +- ret = imx219_write_reg(imx219, IMX219_REG_EXPOSURE, +- IMX219_REG_VALUE_16BIT, ctrl->val); ++ cci_write(imx219->regmap, IMX219_REG_EXPOSURE, ++ ctrl->val, &ret); + break; + case V4L2_CID_DIGITAL_GAIN: +- ret = imx219_write_reg(imx219, IMX219_REG_DIGITAL_GAIN, +- IMX219_REG_VALUE_16BIT, ctrl->val); ++ cci_write(imx219->regmap, IMX219_REG_DIGITAL_GAIN, ++ ctrl->val, &ret); + break; + case V4L2_CID_TEST_PATTERN: +- ret = imx219_write_reg(imx219, IMX219_REG_TEST_PATTERN, +- IMX219_REG_VALUE_16BIT, +- imx219_test_pattern_val[ctrl->val]); ++ cci_write(imx219->regmap, IMX219_REG_TEST_PATTERN, ++ imx219_test_pattern_val[ctrl->val], &ret); + break; + case V4L2_CID_HFLIP: + case V4L2_CID_VFLIP: +- ret = imx219_write_reg(imx219, IMX219_REG_ORIENTATION, 1, +- imx219->hflip->val | +- imx219->vflip->val << 1); ++ cci_write(imx219->regmap, IMX219_REG_ORIENTATION, ++ imx219->hflip->val | imx219->vflip->val << 1, &ret); + break; + case V4L2_CID_VBLANK: +- ret = imx219_write_reg(imx219, IMX219_REG_VTS, +- IMX219_REG_VALUE_16BIT, +- imx219->mode->height + ctrl->val); ++ cci_write(imx219->regmap, IMX219_REG_VTS, ++ imx219->mode->height + ctrl->val, &ret); + break; + case V4L2_CID_TEST_PATTERN_RED: +- ret = imx219_write_reg(imx219, IMX219_REG_TESTP_RED, +- IMX219_REG_VALUE_16BIT, ctrl->val); ++ cci_write(imx219->regmap, IMX219_REG_TESTP_RED, ++ ctrl->val, &ret); + break; + case V4L2_CID_TEST_PATTERN_GREENR: +- ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENR, +- IMX219_REG_VALUE_16BIT, ctrl->val); ++ cci_write(imx219->regmap, IMX219_REG_TESTP_GREENR, ++ ctrl->val, &ret); + break; + case V4L2_CID_TEST_PATTERN_BLUE: +- ret = imx219_write_reg(imx219, IMX219_REG_TESTP_BLUE, +- IMX219_REG_VALUE_16BIT, ctrl->val); ++ cci_write(imx219->regmap, IMX219_REG_TESTP_BLUE, ++ ctrl->val, &ret); + break; + case V4L2_CID_TEST_PATTERN_GREENB: +- ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENB, +- IMX219_REG_VALUE_16BIT, ctrl->val); ++ cci_write(imx219->regmap, IMX219_REG_TESTP_GREENB, ++ ctrl->val, &ret); + break; + default: + dev_info(&client->dev, +@@ -802,15 +721,15 @@ static int imx219_set_framefmt(struct imx219 *imx219, + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: +- return imx219_write_regs(imx219, raw8_framefmt_regs, +- ARRAY_SIZE(raw8_framefmt_regs)); ++ return cci_multi_reg_write(imx219->regmap, raw8_framefmt_regs, ++ ARRAY_SIZE(raw8_framefmt_regs), NULL); + + case MEDIA_BUS_FMT_SRGGB10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: +- return imx219_write_regs(imx219, raw10_framefmt_regs, +- ARRAY_SIZE(raw10_framefmt_regs)); ++ return cci_multi_reg_write(imx219->regmap, raw10_framefmt_regs, ++ ARRAY_SIZE(raw10_framefmt_regs), NULL); + } + + return -EINVAL; +@@ -819,28 +738,24 @@ static int imx219_set_framefmt(struct imx219 *imx219, + static int imx219_set_binning(struct imx219 *imx219, + const struct v4l2_mbus_framefmt *format) + { +- if (!imx219->mode->binning) { +- return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE, +- IMX219_REG_VALUE_16BIT, +- IMX219_BINNING_NONE); +- } ++ if (!imx219->mode->binning) ++ return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, ++ IMX219_BINNING_NONE, NULL); + + switch (format->code) { + case MEDIA_BUS_FMT_SRGGB8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: +- return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE, +- IMX219_REG_VALUE_16BIT, +- IMX219_BINNING_2X2_ANALOG); ++ return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, ++ IMX219_BINNING_2X2_ANALOG, NULL); + + case MEDIA_BUS_FMT_SRGGB10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: +- return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE, +- IMX219_REG_VALUE_16BIT, +- IMX219_BINNING_2X2); ++ return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, ++ IMX219_BINNING_2X2, NULL); + } + + return -EINVAL; +@@ -879,9 +794,9 @@ static int imx219_get_selection(struct v4l2_subdev *sd, + + static int imx219_configure_lanes(struct imx219 *imx219) + { +- return imx219_write_reg(imx219, IMX219_REG_CSI_LANE_MODE, +- IMX219_REG_VALUE_08BIT, (imx219->lanes == 2) ? +- IMX219_CSI_2_LANE_MODE : IMX219_CSI_4_LANE_MODE); ++ return cci_write(imx219->regmap, IMX219_REG_CSI_LANE_MODE, ++ imx219->lanes == 2 ? IMX219_CSI_2_LANE_MODE : ++ IMX219_CSI_4_LANE_MODE, NULL); + }; + + static int imx219_start_streaming(struct imx219 *imx219, +@@ -897,7 +812,8 @@ static int imx219_start_streaming(struct imx219 *imx219, + return ret; + + /* Send all registers that are common to all modes */ +- ret = imx219_write_regs(imx219, imx219_common_regs, ARRAY_SIZE(imx219_common_regs)); ++ ret = cci_multi_reg_write(imx219->regmap, imx219_common_regs, ++ ARRAY_SIZE(imx219_common_regs), NULL); + if (ret) { + dev_err(&client->dev, "%s failed to send mfg header\n", __func__); + goto err_rpm_put; +@@ -912,7 +828,8 @@ static int imx219_start_streaming(struct imx219 *imx219, + + /* Apply default values of current mode */ + reg_list = &imx219->mode->reg_list; +- ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs); ++ ret = cci_multi_reg_write(imx219->regmap, reg_list->regs, ++ reg_list->num_of_regs, NULL); + if (ret) { + dev_err(&client->dev, "%s failed to set mode\n", __func__); + goto err_rpm_put; +@@ -939,8 +856,8 @@ static int imx219_start_streaming(struct imx219 *imx219, + goto err_rpm_put; + + /* set stream on register */ +- ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, +- IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING); ++ ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, ++ IMX219_MODE_STREAMING, NULL); + if (ret) + goto err_rpm_put; + +@@ -961,8 +878,8 @@ static void imx219_stop_streaming(struct imx219 *imx219) + int ret; + + /* set stream off register */ +- ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, +- IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY); ++ ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, ++ IMX219_MODE_STANDBY, NULL); + if (ret) + dev_err(&client->dev, "%s failed to set stream\n", __func__); + +@@ -1101,10 +1018,9 @@ static int imx219_identify_module(struct imx219 *imx219) + { + struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); + int ret; +- u32 val; ++ u64 val; + +- ret = imx219_read_reg(imx219, IMX219_REG_CHIP_ID, +- IMX219_REG_VALUE_16BIT, &val); ++ ret = cci_read(imx219->regmap, IMX219_REG_CHIP_ID, &val, NULL); + if (ret) { + dev_err(&client->dev, "failed to read chip id %x\n", + IMX219_CHIP_ID); +@@ -1112,7 +1028,7 @@ static int imx219_identify_module(struct imx219 *imx219) + } + + if (val != IMX219_CHIP_ID) { +- dev_err(&client->dev, "chip id mismatch: %x!=%x\n", ++ dev_err(&client->dev, "chip id mismatch: %x!=%llx\n", + IMX219_CHIP_ID, val); + return -EIO; + } +@@ -1336,6 +1252,13 @@ static int imx219_probe(struct i2c_client *client) + if (imx219_check_hwcfg(dev, imx219)) + return -EINVAL; + ++ imx219->regmap = devm_cci_regmap_init_i2c(client, 16); ++ if (IS_ERR(imx219->regmap)) { ++ ret = PTR_ERR(imx219->regmap); ++ dev_err(dev, "failed to initialize CCI: %d\n", ret); ++ return ret; ++ } ++ + /* Get system clock (xclk) */ + imx219->xclk = devm_clk_get(dev, NULL); + if (IS_ERR(imx219->xclk)) { +@@ -1379,17 +1302,19 @@ static int imx219_probe(struct i2c_client *client) + * streaming is started, so upon power up switch the modes to: + * streaming -> standby + */ +- ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, +- IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING); ++ ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, ++ IMX219_MODE_STREAMING, NULL); + if (ret < 0) + goto error_power_off; ++ + usleep_range(100, 110); + + /* put sensor back to standby mode */ +- ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, +- IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY); ++ ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, ++ IMX219_MODE_STANDBY, NULL); + if (ret < 0) + goto error_power_off; ++ + usleep_range(100, 110); + + ret = imx219_init_controls(imx219); +-- +2.42.0 + diff --git a/queue-6.6/media-i2c-imx219-drop-imx219_reg_csi_lane_mode-from-.patch b/queue-6.6/media-i2c-imx219-drop-imx219_reg_csi_lane_mode-from-.patch new file mode 100644 index 00000000000..1a3e5698b67 --- /dev/null +++ b/queue-6.6/media-i2c-imx219-drop-imx219_reg_csi_lane_mode-from-.patch @@ -0,0 +1,41 @@ +From ebf19c28d7a2bc8cf922d22a03108281eca0200d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Sep 2023 18:32:53 +0300 +Subject: media: i2c: imx219: Drop IMX219_REG_CSI_LANE_MODE from common regs + array + +From: Laurent Pinchart + +[ Upstream commit ec80c606cca5f7a676febde10d63f5532f57e8e7 ] + +The IMX219_REG_CSI_LANE_MODE is configured twice, once with a hardcoded +value in the imx219_common_regs registers array, and once with the value +appropriate for the system in imx219_configure_lanes(). The latter is +enough, drop the former. + +Fixes: ceddfd4493b3 ("media: i2c: imx219: Support four-lane operation") +Suggested-by: Dave Stevenson +Signed-off-by: Laurent Pinchart +Reviewed-by: Dave Stevenson +Signed-off-by: Sakari Ailus +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/i2c/imx219.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c +index f8d164e69b05f..3afa3f79c8a26 100644 +--- a/drivers/media/i2c/imx219.c ++++ b/drivers/media/i2c/imx219.c +@@ -224,7 +224,6 @@ static const struct cci_reg_sequence imx219_common_regs[] = { + { IMX219_REG_Y_ODD_INC_A, 1 }, + + /* Output setup registers */ +- { IMX219_REG_CSI_LANE_MODE, IMX219_CSI_2_LANE_MODE }, + { IMX219_REG_DPHY_CTRL, IMX219_DPHY_CTRL_TIMING_AUTO }, + { IMX219_REG_EXCK_FREQ, IMX219_EXCK_FREQ(IMX219_XCLK_FREQ / 1000000) }, + }; +-- +2.42.0 + diff --git a/queue-6.6/media-i2c-imx219-replace-register-addresses-with-mac.patch b/queue-6.6/media-i2c-imx219-replace-register-addresses-with-mac.patch new file mode 100644 index 00000000000..f09b8d4dfd9 --- /dev/null +++ b/queue-6.6/media-i2c-imx219-replace-register-addresses-with-mac.patch @@ -0,0 +1,272 @@ +From 06916eba95f255c3741aec3ea3e657dec6c0589e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Sep 2023 18:32:52 +0300 +Subject: media: i2c: imx219: Replace register addresses with macros + +From: Laurent Pinchart + +[ Upstream commit 1c9083565a4698ff072f1209e9450ff6c305e2cc ] + +Define macros for all the known registers used in the register arrays, +and use them to replace the numerical addresses. This improves +readability. + +Signed-off-by: Laurent Pinchart +Reviewed-by: Dave Stevenson +Signed-off-by: Sakari Ailus +Signed-off-by: Hans Verkuil +Stable-dep-of: ec80c606cca5 ("media: i2c: imx219: Drop IMX219_REG_CSI_LANE_MODE from common regs array") +Signed-off-by: Sasha Levin +--- + drivers/media/i2c/imx219.c | 169 ++++++++++++++++++------------------- + 1 file changed, 81 insertions(+), 88 deletions(-) + +diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c +index c5aeec50b9e85..f8d164e69b05f 100644 +--- a/drivers/media/i2c/imx219.c ++++ b/drivers/media/i2c/imx219.c +@@ -41,6 +41,13 @@ + #define IMX219_CSI_2_LANE_MODE 0x01 + #define IMX219_CSI_4_LANE_MODE 0x03 + ++#define IMX219_REG_DPHY_CTRL CCI_REG8(0x0128) ++#define IMX219_DPHY_CTRL_TIMING_AUTO 0 ++#define IMX219_DPHY_CTRL_TIMING_MANUAL 1 ++ ++#define IMX219_REG_EXCK_FREQ CCI_REG16(0x012a) ++#define IMX219_EXCK_FREQ(n) ((n) * 256) /* n expressed in MHz */ ++ + /* Analog gain control */ + #define IMX219_REG_ANALOG_GAIN CCI_REG8(0x0157) + #define IMX219_ANA_GAIN_MIN 0 +@@ -81,6 +88,15 @@ + /* HBLANK control - read only */ + #define IMX219_PPL_DEFAULT 3448 + ++#define IMX219_REG_LINE_LENGTH_A CCI_REG16(0x0162) ++#define IMX219_REG_X_ADD_STA_A CCI_REG16(0x0164) ++#define IMX219_REG_X_ADD_END_A CCI_REG16(0x0166) ++#define IMX219_REG_Y_ADD_STA_A CCI_REG16(0x0168) ++#define IMX219_REG_Y_ADD_END_A CCI_REG16(0x016a) ++#define IMX219_REG_X_OUTPUT_SIZE CCI_REG16(0x016c) ++#define IMX219_REG_Y_OUTPUT_SIZE CCI_REG16(0x016e) ++#define IMX219_REG_X_ODD_INC_A CCI_REG8(0x0170) ++#define IMX219_REG_Y_ODD_INC_A CCI_REG8(0x0171) + #define IMX219_REG_ORIENTATION CCI_REG8(0x0172) + + /* Binning Mode */ +@@ -89,6 +105,18 @@ + #define IMX219_BINNING_2X2 0x0101 + #define IMX219_BINNING_2X2_ANALOG 0x0303 + ++#define IMX219_REG_CSI_DATA_FORMAT_A CCI_REG16(0x018c) ++ ++/* PLL Settings */ ++#define IMX219_REG_VTPXCK_DIV CCI_REG8(0x0301) ++#define IMX219_REG_VTSYCK_DIV CCI_REG8(0x0303) ++#define IMX219_REG_PREPLLCK_VT_DIV CCI_REG8(0x0304) ++#define IMX219_REG_PREPLLCK_OP_DIV CCI_REG8(0x0305) ++#define IMX219_REG_PLL_VT_MPY CCI_REG16(0x0306) ++#define IMX219_REG_OPPXCK_DIV CCI_REG8(0x0309) ++#define IMX219_REG_OPSYCK_DIV CCI_REG8(0x030b) ++#define IMX219_REG_PLL_OP_MPY CCI_REG16(0x030c) ++ + /* Test Pattern Control */ + #define IMX219_REG_TEST_PATTERN CCI_REG16(0x0600) + #define IMX219_TEST_PATTERN_DISABLE 0 +@@ -110,6 +138,9 @@ + #define IMX219_TESTP_BLUE_DEFAULT 0 + #define IMX219_TESTP_GREENB_DEFAULT 0 + ++#define IMX219_REG_TP_WINDOW_WIDTH CCI_REG16(0x0624) ++#define IMX219_REG_TP_WINDOW_HEIGHT CCI_REG16(0x0626) ++ + /* External clock frequency is 24.0M */ + #define IMX219_XCLK_FREQ 24000000 + +@@ -154,7 +185,7 @@ struct imx219_mode { + }; + + static const struct cci_reg_sequence imx219_common_regs[] = { +- { CCI_REG8(0x0100), 0x00 }, /* Mode Select */ ++ { IMX219_REG_MODE_SELECT, 0x00 }, /* Mode Select */ + + /* To Access Addresses 3000-5fff, send the following commands */ + { CCI_REG8(0x30eb), 0x0c }, +@@ -165,15 +196,13 @@ static const struct cci_reg_sequence imx219_common_regs[] = { + { CCI_REG8(0x30eb), 0x09 }, + + /* PLL Clock Table */ +- { CCI_REG8(0x0301), 0x05 }, /* VTPXCK_DIV */ +- { CCI_REG8(0x0303), 0x01 }, /* VTSYSCK_DIV */ +- { CCI_REG8(0x0304), 0x03 }, /* PREPLLCK_VT_DIV 0x03 = AUTO set */ +- { CCI_REG8(0x0305), 0x03 }, /* PREPLLCK_OP_DIV 0x03 = AUTO set */ +- { CCI_REG8(0x0306), 0x00 }, /* PLL_VT_MPY */ +- { CCI_REG8(0x0307), 0x39 }, +- { CCI_REG8(0x030b), 0x01 }, /* OP_SYS_CLK_DIV */ +- { CCI_REG8(0x030c), 0x00 }, /* PLL_OP_MPY */ +- { CCI_REG8(0x030d), 0x72 }, ++ { IMX219_REG_VTPXCK_DIV, 5 }, ++ { IMX219_REG_VTSYCK_DIV, 1 }, ++ { IMX219_REG_PREPLLCK_VT_DIV, 3 }, /* 0x03 = AUTO set */ ++ { IMX219_REG_PREPLLCK_OP_DIV, 3 }, /* 0x03 = AUTO set */ ++ { IMX219_REG_PLL_VT_MPY, 57 }, ++ { IMX219_REG_OPSYCK_DIV, 1 }, ++ { IMX219_REG_PLL_OP_MPY, 114 }, + + /* Undocumented registers */ + { CCI_REG8(0x455e), 0x00 }, +@@ -190,16 +219,14 @@ static const struct cci_reg_sequence imx219_common_regs[] = { + { CCI_REG8(0x479b), 0x0e }, + + /* Frame Bank Register Group "A" */ +- { CCI_REG8(0x0162), 0x0d }, /* Line_Length_A */ +- { CCI_REG8(0x0163), 0x78 }, +- { CCI_REG8(0x0170), 0x01 }, /* X_ODD_INC_A */ +- { CCI_REG8(0x0171), 0x01 }, /* Y_ODD_INC_A */ ++ { IMX219_REG_LINE_LENGTH_A, 3448 }, ++ { IMX219_REG_X_ODD_INC_A, 1 }, ++ { IMX219_REG_Y_ODD_INC_A, 1 }, + + /* Output setup registers */ +- { CCI_REG8(0x0114), 0x01 }, /* CSI 2-Lane Mode */ +- { CCI_REG8(0x0128), 0x00 }, /* DPHY Auto Mode */ +- { CCI_REG8(0x012a), 0x18 }, /* EXCK_Freq */ +- { CCI_REG8(0x012b), 0x00 }, ++ { IMX219_REG_CSI_LANE_MODE, IMX219_CSI_2_LANE_MODE }, ++ { IMX219_REG_DPHY_CTRL, IMX219_DPHY_CTRL_TIMING_AUTO }, ++ { IMX219_REG_EXCK_FREQ, IMX219_EXCK_FREQ(IMX219_XCLK_FREQ / 1000000) }, + }; + + /* +@@ -208,91 +235,57 @@ static const struct cci_reg_sequence imx219_common_regs[] = { + * 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7. + */ + static const struct cci_reg_sequence mode_3280x2464_regs[] = { +- { CCI_REG8(0x0164), 0x00 }, +- { CCI_REG8(0x0165), 0x00 }, +- { CCI_REG8(0x0166), 0x0c }, +- { CCI_REG8(0x0167), 0xcf }, +- { CCI_REG8(0x0168), 0x00 }, +- { CCI_REG8(0x0169), 0x00 }, +- { CCI_REG8(0x016a), 0x09 }, +- { CCI_REG8(0x016b), 0x9f }, +- { CCI_REG8(0x016c), 0x0c }, +- { CCI_REG8(0x016d), 0xd0 }, +- { CCI_REG8(0x016e), 0x09 }, +- { CCI_REG8(0x016f), 0xa0 }, +- { CCI_REG8(0x0624), 0x0c }, +- { CCI_REG8(0x0625), 0xd0 }, +- { CCI_REG8(0x0626), 0x09 }, +- { CCI_REG8(0x0627), 0xa0 }, ++ { IMX219_REG_X_ADD_STA_A, 0 }, ++ { IMX219_REG_X_ADD_END_A, 3279 }, ++ { IMX219_REG_Y_ADD_STA_A, 0 }, ++ { IMX219_REG_Y_ADD_END_A, 2463 }, ++ { IMX219_REG_X_OUTPUT_SIZE, 3280 }, ++ { IMX219_REG_Y_OUTPUT_SIZE, 2464 }, ++ { IMX219_REG_TP_WINDOW_WIDTH, 3280 }, ++ { IMX219_REG_TP_WINDOW_HEIGHT, 2464 }, + }; + + static const struct cci_reg_sequence mode_1920_1080_regs[] = { +- { CCI_REG8(0x0164), 0x02 }, +- { CCI_REG8(0x0165), 0xa8 }, +- { CCI_REG8(0x0166), 0x0a }, +- { CCI_REG8(0x0167), 0x27 }, +- { CCI_REG8(0x0168), 0x02 }, +- { CCI_REG8(0x0169), 0xb4 }, +- { CCI_REG8(0x016a), 0x06 }, +- { CCI_REG8(0x016b), 0xeb }, +- { CCI_REG8(0x016c), 0x07 }, +- { CCI_REG8(0x016d), 0x80 }, +- { CCI_REG8(0x016e), 0x04 }, +- { CCI_REG8(0x016f), 0x38 }, +- { CCI_REG8(0x0624), 0x07 }, +- { CCI_REG8(0x0625), 0x80 }, +- { CCI_REG8(0x0626), 0x04 }, +- { CCI_REG8(0x0627), 0x38 }, ++ { IMX219_REG_X_ADD_STA_A, 680 }, ++ { IMX219_REG_X_ADD_END_A, 2599 }, ++ { IMX219_REG_Y_ADD_STA_A, 692 }, ++ { IMX219_REG_Y_ADD_END_A, 1771 }, ++ { IMX219_REG_X_OUTPUT_SIZE, 1920 }, ++ { IMX219_REG_Y_OUTPUT_SIZE, 1080 }, ++ { IMX219_REG_TP_WINDOW_WIDTH, 1920 }, ++ { IMX219_REG_TP_WINDOW_HEIGHT, 1080 }, + }; + + static const struct cci_reg_sequence mode_1640_1232_regs[] = { +- { CCI_REG8(0x0164), 0x00 }, +- { CCI_REG8(0x0165), 0x00 }, +- { CCI_REG8(0x0166), 0x0c }, +- { CCI_REG8(0x0167), 0xcf }, +- { CCI_REG8(0x0168), 0x00 }, +- { CCI_REG8(0x0169), 0x00 }, +- { CCI_REG8(0x016a), 0x09 }, +- { CCI_REG8(0x016b), 0x9f }, +- { CCI_REG8(0x016c), 0x06 }, +- { CCI_REG8(0x016d), 0x68 }, +- { CCI_REG8(0x016e), 0x04 }, +- { CCI_REG8(0x016f), 0xd0 }, +- { CCI_REG8(0x0624), 0x06 }, +- { CCI_REG8(0x0625), 0x68 }, +- { CCI_REG8(0x0626), 0x04 }, +- { CCI_REG8(0x0627), 0xd0 }, ++ { IMX219_REG_X_ADD_STA_A, 0 }, ++ { IMX219_REG_X_ADD_END_A, 3279 }, ++ { IMX219_REG_Y_ADD_STA_A, 0 }, ++ { IMX219_REG_Y_ADD_END_A, 2463 }, ++ { IMX219_REG_X_OUTPUT_SIZE, 1640 }, ++ { IMX219_REG_Y_OUTPUT_SIZE, 1232 }, ++ { IMX219_REG_TP_WINDOW_WIDTH, 1640 }, ++ { IMX219_REG_TP_WINDOW_HEIGHT, 1232 }, + }; + + static const struct cci_reg_sequence mode_640_480_regs[] = { +- { CCI_REG8(0x0164), 0x03 }, +- { CCI_REG8(0x0165), 0xe8 }, +- { CCI_REG8(0x0166), 0x08 }, +- { CCI_REG8(0x0167), 0xe7 }, +- { CCI_REG8(0x0168), 0x02 }, +- { CCI_REG8(0x0169), 0xf0 }, +- { CCI_REG8(0x016a), 0x06 }, +- { CCI_REG8(0x016b), 0xaf }, +- { CCI_REG8(0x016c), 0x02 }, +- { CCI_REG8(0x016d), 0x80 }, +- { CCI_REG8(0x016e), 0x01 }, +- { CCI_REG8(0x016f), 0xe0 }, +- { CCI_REG8(0x0624), 0x06 }, +- { CCI_REG8(0x0625), 0x68 }, +- { CCI_REG8(0x0626), 0x04 }, +- { CCI_REG8(0x0627), 0xd0 }, ++ { IMX219_REG_X_ADD_STA_A, 1000 }, ++ { IMX219_REG_X_ADD_END_A, 2279 }, ++ { IMX219_REG_Y_ADD_STA_A, 752 }, ++ { IMX219_REG_Y_ADD_END_A, 1711 }, ++ { IMX219_REG_X_OUTPUT_SIZE, 640 }, ++ { IMX219_REG_Y_OUTPUT_SIZE, 480 }, ++ { IMX219_REG_TP_WINDOW_WIDTH, 1640 }, ++ { IMX219_REG_TP_WINDOW_HEIGHT, 1232 }, + }; + + static const struct cci_reg_sequence raw8_framefmt_regs[] = { +- { CCI_REG8(0x018c), 0x08 }, +- { CCI_REG8(0x018d), 0x08 }, +- { CCI_REG8(0x0309), 0x08 }, ++ { IMX219_REG_CSI_DATA_FORMAT_A, 0x0808 }, ++ { IMX219_REG_OPPXCK_DIV, 8 }, + }; + + static const struct cci_reg_sequence raw10_framefmt_regs[] = { +- { CCI_REG8(0x018c), 0x0a }, +- { CCI_REG8(0x018d), 0x0a }, +- { CCI_REG8(0x0309), 0x0a }, ++ { IMX219_REG_CSI_DATA_FORMAT_A, 0x0a0a }, ++ { IMX219_REG_OPPXCK_DIV, 10 }, + }; + + static const s64 imx219_link_freq_menu[] = { +-- +2.42.0 + diff --git a/queue-6.6/media-i2c-max9286-fix-some-redundant-of_node_put-cal.patch b/queue-6.6/media-i2c-max9286-fix-some-redundant-of_node_put-cal.patch new file mode 100644 index 00000000000..641a9b4a82f --- /dev/null +++ b/queue-6.6/media-i2c-max9286-fix-some-redundant-of_node_put-cal.patch @@ -0,0 +1,50 @@ +From 310f4b7b46e03d96f9afb8f03e4715d55612e7d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Aug 2023 00:13:40 +0200 +Subject: media: i2c: max9286: Fix some redundant of_node_put() calls + +From: Christophe JAILLET + +[ Upstream commit 0822315e46b400f611cba1193456ee6a5dc3e41d ] + +This is odd to have a of_node_put() just after a for_each_child_of_node() +or a for_each_endpoint_of_node() loop. It should already be called +during the last iteration. + +Remove these calls. + +Fixes: 66d8c9d2422d ("media: i2c: Add MAX9286 driver") +Signed-off-by: Christophe JAILLET +Reviewed-by: Jacopo Mondi +Reviewed-by: Laurent Pinchart +Reviewed-by: Kieran Bingham +Signed-off-by: Sakari Ailus +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/i2c/max9286.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c +index be84ff1e2b170..fc1cf196ef015 100644 +--- a/drivers/media/i2c/max9286.c ++++ b/drivers/media/i2c/max9286.c +@@ -1449,7 +1449,6 @@ static int max9286_parse_dt(struct max9286_priv *priv) + + i2c_mux_mask |= BIT(id); + } +- of_node_put(node); + of_node_put(i2c_mux); + + /* Parse the endpoints */ +@@ -1513,7 +1512,6 @@ static int max9286_parse_dt(struct max9286_priv *priv) + priv->source_mask |= BIT(ep.port); + priv->nsources++; + } +- of_node_put(node); + + of_property_read_u32(dev->of_node, "maxim,bus-width", &priv->bus_width); + switch (priv->bus_width) { +-- +2.42.0 + diff --git a/queue-6.6/media-imx-jpeg-initiate-a-drain-of-the-capture-queue.patch b/queue-6.6/media-imx-jpeg-initiate-a-drain-of-the-capture-queue.patch new file mode 100644 index 00000000000..80c96e00bdf --- /dev/null +++ b/queue-6.6/media-imx-jpeg-initiate-a-drain-of-the-capture-queue.patch @@ -0,0 +1,90 @@ +From 77a226fbbb538a583be6a9ef1aeabc4d7e2fd8c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Aug 2023 09:45:06 +0800 +Subject: media: imx-jpeg: initiate a drain of the capture queue in dynamic + resolution change + +From: Ming Qian + +[ Upstream commit 1c2786632e20c8f0fd4004fae3b3490276e5e5da ] + +The last buffer from before the change must be marked, +with the V4L2_BUF_FLAG_LAST flag, +similarly to the Drain sequence above. + +Meanwhile if V4L2_DEC_CMD_STOP is sent before +the source change triggered, +we need to restore the is_draing flag after +the draining in dynamic resolution change. + +Fixes: b4e1fb8643da ("media: imx-jpeg: Support dynamic resolution change") +Signed-off-by: Ming Qian +Reviewed-by: Nicolas Dufresne +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + .../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 27 ++++++++++++++++--- + 1 file changed, 24 insertions(+), 3 deletions(-) + +diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +index b7a720198ce57..e74b0ed8ec5ba 100644 +--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c ++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +@@ -1322,6 +1322,20 @@ static bool mxc_jpeg_compare_format(const struct mxc_jpeg_fmt *fmt1, + return false; + } + ++static void mxc_jpeg_set_last_buffer(struct mxc_jpeg_ctx *ctx) ++{ ++ struct vb2_v4l2_buffer *next_dst_buf; ++ ++ next_dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); ++ if (!next_dst_buf) { ++ ctx->fh.m2m_ctx->is_draining = true; ++ ctx->fh.m2m_ctx->next_buf_last = true; ++ return; ++ } ++ ++ v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, next_dst_buf); ++} ++ + static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx, + struct mxc_jpeg_src_buf *jpeg_src_buf) + { +@@ -1378,6 +1392,8 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx, + mxc_jpeg_sizeimage(q_data_cap); + notify_src_chg(ctx); + ctx->source_change = 1; ++ if (vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx))) ++ mxc_jpeg_set_last_buffer(ctx); + } + + return ctx->source_change ? true : false; +@@ -1638,8 +1654,13 @@ static void mxc_jpeg_stop_streaming(struct vb2_queue *q) + v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); + } + +- if (V4L2_TYPE_IS_OUTPUT(q->type) || !ctx->source_change) +- v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q); ++ v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q); ++ /* if V4L2_DEC_CMD_STOP is sent before the source change triggered, ++ * restore the is_draining flag ++ */ ++ if (V4L2_TYPE_IS_CAPTURE(q->type) && ctx->source_change && ctx->fh.m2m_ctx->last_src_buf) ++ ctx->fh.m2m_ctx->is_draining = true; ++ + if (V4L2_TYPE_IS_OUTPUT(q->type) && + v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) { + notify_eos(ctx); +@@ -1916,7 +1937,7 @@ static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb) + return -EINVAL; + for (i = 0; i < q_data->fmt->mem_planes; i++) { + sizeimage = mxc_jpeg_get_plane_size(q_data, i); +- if (vb2_plane_size(vb, i) < sizeimage) { ++ if (!ctx->source_change && vb2_plane_size(vb, i) < sizeimage) { + dev_err(dev, "plane %d too small (%lu < %lu)", + i, vb2_plane_size(vb, i), sizeimage); + return -EINVAL; +-- +2.42.0 + diff --git a/queue-6.6/media-imx-jpeg-notify-source-chagne-event-when-the-f.patch b/queue-6.6/media-imx-jpeg-notify-source-chagne-event-when-the-f.patch new file mode 100644 index 00000000000..bdd656646eb --- /dev/null +++ b/queue-6.6/media-imx-jpeg-notify-source-chagne-event-when-the-f.patch @@ -0,0 +1,80 @@ +From 15c92590a08816e47be899cca27c536bb51ae769 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 14:16:57 +0800 +Subject: media: imx-jpeg: notify source chagne event when the first picture + parsed + +From: Ming Qian + +[ Upstream commit b833b178498dafa2156cfb6f4d3ce4581c21f1e5 ] + +After gstreamer rework the dynamic resolution change handling, gstreamer +stop doing capture buffer allocation based on guesses and wait for the +source change event when available. It requires driver always notify +source change event in the initialization, even if the size parsed is +equal to the size set on capture queue. otherwise, the pipeline will be +stalled. + +Currently driver may not notify source change event if the parsed format +and size are equal to those previously established, but it may stall the +gstreamer pipeline. + +The link of gstreamer patch is +https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4437 + +Fixes: b4e1fb8643da ("media: imx-jpeg: Support dynamic resolution change") +Signed-off-by: Ming Qian +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 7 ++++++- + drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h | 1 + + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +index e74b0ed8ec5ba..0c8b204535ffc 100644 +--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c ++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +@@ -1348,7 +1348,8 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx, + q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); + if (mxc_jpeg_compare_format(q_data_cap->fmt, jpeg_src_buf->fmt)) + jpeg_src_buf->fmt = q_data_cap->fmt; +- if (q_data_cap->fmt != jpeg_src_buf->fmt || ++ if (ctx->need_initial_source_change_evt || ++ q_data_cap->fmt != jpeg_src_buf->fmt || + q_data_cap->w != jpeg_src_buf->w || + q_data_cap->h != jpeg_src_buf->h) { + dev_dbg(dev, "Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n", +@@ -1392,6 +1393,7 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx, + mxc_jpeg_sizeimage(q_data_cap); + notify_src_chg(ctx); + ctx->source_change = 1; ++ ctx->need_initial_source_change_evt = false; + if (vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx))) + mxc_jpeg_set_last_buffer(ctx); + } +@@ -1611,6 +1613,9 @@ static int mxc_jpeg_queue_setup(struct vb2_queue *q, + for (i = 0; i < *nplanes; i++) + sizes[i] = mxc_jpeg_get_plane_size(q_data, i); + ++ if (V4L2_TYPE_IS_OUTPUT(q->type)) ++ ctx->need_initial_source_change_evt = true; ++ + return 0; + } + +diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h +index d80e94cc9d992..dc4afeeff5b65 100644 +--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h ++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h +@@ -99,6 +99,7 @@ struct mxc_jpeg_ctx { + enum mxc_jpeg_enc_state enc_state; + int slot; + unsigned int source_change; ++ bool need_initial_source_change_evt; + bool header_parsed; + struct v4l2_ctrl_handler ctrl_handler; + u8 jpeg_quality; +-- +2.42.0 + diff --git a/queue-6.6/media-mediatek-vcodec-handle-invalid-encoder-vsi.patch b/queue-6.6/media-mediatek-vcodec-handle-invalid-encoder-vsi.patch new file mode 100644 index 00000000000..71bf3c8b1a3 --- /dev/null +++ b/queue-6.6/media-mediatek-vcodec-handle-invalid-encoder-vsi.patch @@ -0,0 +1,41 @@ +From 0d1ec079dc1bf73ff338dba8db6374852b16b908 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Oct 2023 19:33:47 +0800 +Subject: media: mediatek: vcodec: Handle invalid encoder vsi + +From: Irui Wang + +[ Upstream commit 19e2e01f30b5d2b448b5db097130486ea95af36f ] + +Handle invalid encoder vsi in vpu_enc_init to ensure the encoder +vsi is valid for future use. + +Fixes: 1972e32431ed ("media: mediatek: vcodec: Fix possible invalid memory access for encoder") + +Signed-off-by: Irui Wang +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c +index ae6290d28f8e9..84ad1cc6ad171 100644 +--- a/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c ++++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c +@@ -154,6 +154,11 @@ int vpu_enc_init(struct venc_vpu_inst *vpu) + return -EINVAL; + } + ++ if (IS_ERR_OR_NULL(vpu->vsi)) { ++ mtk_venc_err(vpu->ctx, "invalid venc vsi"); ++ return -EINVAL; ++ } ++ + return 0; + } + +-- +2.42.0 + diff --git a/queue-6.6/media-mediatek-vcodec-using-encoder-device-to-alloc-.patch b/queue-6.6/media-mediatek-vcodec-using-encoder-device-to-alloc-.patch new file mode 100644 index 00000000000..fb63d2ca718 --- /dev/null +++ b/queue-6.6/media-mediatek-vcodec-using-encoder-device-to-alloc-.patch @@ -0,0 +1,152 @@ +From 37bacc665b72cb5660b15adcd903b4e822f1d2bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 20:20:10 +0800 +Subject: media: mediatek: vcodec: using encoder device to alloc/free encoder + memory + +From: Yunfei Dong + +[ Upstream commit 56c0ac05a31a0bf525fddc300ea997356ad8146f ] + +Need to use encoder device to allocate/free encoder memory when calling +mtk_vcodec_mem_alloc/mtk_vcodec_mem_free, or leading to below crash log +when test encoder with decoder device. + +pc : dma_alloc_attrs+0x44/0xf4 +lr : mtk_vcodec_mem_alloc+0x50/0xa4 [mtk_vcodec_common] +sp : ffffffc0209f3990 +x29: ffffffc0209f39a0 x28: ffffff8024102a18 x27: 0000000000000000 +x26: 0000000000000000 x25: ffffffc00c06e2d8 x24: 0000000000000001 +x23: 0000000000000cc0 x22: 0000000000000010 x21: 0000000000000800 +x20: ffffff8024102a18 x19: 0000000000000000 x18: 0000000000000000 +x17: 0000000000000009 x16: ffffffe389736a98 x15: 0000000000000078 +x14: ffffffe389704434 x13: 0000000000000007 x12: ffffffe38a2b2560 +x11: 0000000000000800 x10: 0000000000000004 x9 : ffffffe331f07484 +x8 : 5400e9aef2395000 x7 : 0000000000000000 x6 : 000000000000003f +x5 : 0000000000000001 x4 : 0000000000000000 x3 : 0000000000000cc0 +x2 : ffffff8024102a18 x1 : 0000000000000800 x0 : 0000000000000010 +Call trace: + dma_alloc_attrs+0x44/0xf4 + mtk_vcodec_mem_alloc+0x50/0xa4 [mtk_vcodec_common 2819d3d601f3cd06c1f2213ac1b9995134441421] + h264_enc_set_param+0x27c/0x378 [mtk_vcodec_enc 772cc3d26c254e8cf54079451ef8d930d2eb4404] + venc_if_set_param+0x4c/0x7c [mtk_vcodec_enc 772cc3d26c254e8cf54079451ef8d930d2eb4404] + vb2ops_venc_start_streaming+0x1bc/0x328 [mtk_vcodec_enc 772cc3d26c254e8cf54079451ef8d930d2eb4404] + vb2_start_streaming+0x64/0x12c + vb2_core_streamon+0x114/0x158 + vb2_streamon+0x38/0x60 + v4l2_m2m_streamon+0x48/0x88 + v4l2_m2m_ioctl_streamon+0x20/0x2c + v4l_streamon+0x2c/0x38 + __video_do_ioctl+0x2c4/0x3dc + video_usercopy+0x404/0x934 + video_ioctl2+0x20/0x2c + v4l2_ioctl+0x54/0x64 + v4l2_compat_ioctl32+0x90/0xa34 + __arm64_compat_sys_ioctl+0x128/0x13c + invoke_syscall+0x4c/0x108 + el0_svc_common+0x98/0x104 + do_el0_svc_compat+0x28/0x34 + el0_svc_compat+0x2c/0x74 + el0t_32_sync_handler+0xa8/0xcc + el0t_32_sync+0x194/0x198 +Code: aa0003f6 aa0203f4 aa0103f5 f900 + +'Fixes: 01abf5fbb081c ("media: mediatek: vcodec: separate struct 'mtk_vcodec_ctx'")' +Signed-off-by: Yunfei Dong +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + .../mediatek/vcodec/common/mtk_vcodec_util.c | 56 +++++++++++++------ + 1 file changed, 40 insertions(+), 16 deletions(-) + +diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c +index 908602031fd0e..9ce34a3b5ee67 100644 +--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c ++++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c +@@ -47,20 +47,32 @@ EXPORT_SYMBOL(mtk_vcodec_write_vdecsys); + + int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) + { ++ enum mtk_instance_type inst_type = *((unsigned int *)priv); ++ struct platform_device *plat_dev; + unsigned long size = mem->size; +- struct mtk_vcodec_dec_ctx *ctx = priv; +- struct device *dev = &ctx->dev->plat_dev->dev; ++ int id; + +- mem->va = dma_alloc_coherent(dev, size, &mem->dma_addr, GFP_KERNEL); ++ if (inst_type == MTK_INST_ENCODER) { ++ struct mtk_vcodec_enc_ctx *enc_ctx = priv; ++ ++ plat_dev = enc_ctx->dev->plat_dev; ++ id = enc_ctx->id; ++ } else { ++ struct mtk_vcodec_dec_ctx *dec_ctx = priv; ++ ++ plat_dev = dec_ctx->dev->plat_dev; ++ id = dec_ctx->id; ++ } ++ ++ mem->va = dma_alloc_coherent(&plat_dev->dev, size, &mem->dma_addr, GFP_KERNEL); + if (!mem->va) { +- mtk_v4l2_vdec_err(ctx, "%s dma_alloc size=%ld failed!", dev_name(dev), size); ++ mtk_v4l2_err(plat_dev, "%s dma_alloc size=%ld failed!", ++ dev_name(&plat_dev->dev), size); + return -ENOMEM; + } + +- mtk_v4l2_vdec_dbg(3, ctx, "[%d] - va = %p", ctx->id, mem->va); +- mtk_v4l2_vdec_dbg(3, ctx, "[%d] - dma = 0x%lx", ctx->id, +- (unsigned long)mem->dma_addr); +- mtk_v4l2_vdec_dbg(3, ctx, "[%d] size = 0x%lx", ctx->id, size); ++ mtk_v4l2_debug(plat_dev, 3, "[%d] - va = %p dma = 0x%lx size = 0x%lx", id, mem->va, ++ (unsigned long)mem->dma_addr, size); + + return 0; + } +@@ -68,21 +80,33 @@ EXPORT_SYMBOL(mtk_vcodec_mem_alloc); + + void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) + { ++ enum mtk_instance_type inst_type = *((unsigned int *)priv); ++ struct platform_device *plat_dev; + unsigned long size = mem->size; +- struct mtk_vcodec_dec_ctx *ctx = priv; +- struct device *dev = &ctx->dev->plat_dev->dev; ++ int id; ++ ++ if (inst_type == MTK_INST_ENCODER) { ++ struct mtk_vcodec_enc_ctx *enc_ctx = priv; ++ ++ plat_dev = enc_ctx->dev->plat_dev; ++ id = enc_ctx->id; ++ } else { ++ struct mtk_vcodec_dec_ctx *dec_ctx = priv; ++ ++ plat_dev = dec_ctx->dev->plat_dev; ++ id = dec_ctx->id; ++ } + + if (!mem->va) { +- mtk_v4l2_vdec_err(ctx, "%s dma_free size=%ld failed!", dev_name(dev), size); ++ mtk_v4l2_err(plat_dev, "%s dma_free size=%ld failed!", ++ dev_name(&plat_dev->dev), size); + return; + } + +- mtk_v4l2_vdec_dbg(3, ctx, "[%d] - va = %p", ctx->id, mem->va); +- mtk_v4l2_vdec_dbg(3, ctx, "[%d] - dma = 0x%lx", ctx->id, +- (unsigned long)mem->dma_addr); +- mtk_v4l2_vdec_dbg(3, ctx, "[%d] size = 0x%lx", ctx->id, size); ++ mtk_v4l2_debug(plat_dev, 3, "[%d] - va = %p dma = 0x%lx size = 0x%lx", id, mem->va, ++ (unsigned long)mem->dma_addr, size); + +- dma_free_coherent(dev, size, mem->va, mem->dma_addr); ++ dma_free_coherent(&plat_dev->dev, size, mem->va, mem->dma_addr); + mem->va = NULL; + mem->dma_addr = 0; + mem->size = 0; +-- +2.42.0 + diff --git a/queue-6.6/media-mtk-jpegenc-fix-bug-in-jpeg-encode-quality-sel.patch b/queue-6.6/media-mtk-jpegenc-fix-bug-in-jpeg-encode-quality-sel.patch new file mode 100644 index 00000000000..d59d03f7121 --- /dev/null +++ b/queue-6.6/media-mtk-jpegenc-fix-bug-in-jpeg-encode-quality-sel.patch @@ -0,0 +1,52 @@ +From 9ccc5458ef8fa8dea97e9c0b8a5b4885b41e2ef4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Sep 2023 21:28:04 +0800 +Subject: media: mtk-jpegenc: Fix bug in JPEG encode quality selection + +From: Fei Shao + +[ Upstream commit 0aeccc63f3bc4cfd49dc4893da1409402ee6b295 ] + +The driver uses the upper-bound approach to decide the target JPEG +encode quality, but there's a logic bug that if the desired quality is +higher than what the driver can support, the driver falls back to using +the worst quality. + +Fix the bug by assuming using the best quality in the beginning, and +with trivial refactor to avoid long lines. + +Fixes: 45f13a57d813 ("media: platform: Add jpeg enc feature") +Signed-off-by: Fei Shao +Reviewed-by: Chen-Yu Tsai +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c +index 2bbc48c7402ca..f8fa3b841ccfb 100644 +--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c ++++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c +@@ -127,6 +127,7 @@ void mtk_jpeg_set_enc_params(struct mtk_jpeg_ctx *ctx, void __iomem *base) + u32 img_stride; + u32 mem_stride; + u32 i, enc_quality; ++ u32 nr_enc_quality = ARRAY_SIZE(mtk_jpeg_enc_quality); + + value = width << 16 | height; + writel(value, base + JPEG_ENC_IMG_SIZE); +@@ -157,8 +158,8 @@ void mtk_jpeg_set_enc_params(struct mtk_jpeg_ctx *ctx, void __iomem *base) + writel(img_stride, base + JPEG_ENC_IMG_STRIDE); + writel(mem_stride, base + JPEG_ENC_STRIDE); + +- enc_quality = mtk_jpeg_enc_quality[0].hardware_value; +- for (i = 0; i < ARRAY_SIZE(mtk_jpeg_enc_quality); i++) { ++ enc_quality = mtk_jpeg_enc_quality[nr_enc_quality - 1].hardware_value; ++ for (i = 0; i < nr_enc_quality; i++) { + if (ctx->enc_quality <= mtk_jpeg_enc_quality[i].quality_param) { + enc_quality = mtk_jpeg_enc_quality[i].hardware_value; + break; +-- +2.42.0 + diff --git a/queue-6.6/media-ov13b10-fix-some-error-checking-in-probe.patch b/queue-6.6/media-ov13b10-fix-some-error-checking-in-probe.patch new file mode 100644 index 00000000000..ab8c4e51fbb --- /dev/null +++ b/queue-6.6/media-ov13b10-fix-some-error-checking-in-probe.patch @@ -0,0 +1,38 @@ +From 4c3b7573452ac1137a7787563d167cace6d71329 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Jul 2023 13:16:10 +0300 +Subject: media: ov13b10: Fix some error checking in probe + +From: Dan Carpenter + +[ Upstream commit d66b45e1b082462c3e14528b83e18ee92362e456 ] + +The "ret = " assignment was missing, so ov13b10_power_on() is not +checked for errors. Add the assignment. + +Fixes: 6e28afd15228 ("media: ov13b10: add PM control support based on power resources") +Signed-off-by: Dan Carpenter +Reviewed-by: Bingbu Cao +Signed-off-by: Sakari Ailus +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/i2c/ov13b10.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/i2c/ov13b10.c b/drivers/media/i2c/ov13b10.c +index dbc642c5995b6..8ebdb32dd3dbc 100644 +--- a/drivers/media/i2c/ov13b10.c ++++ b/drivers/media/i2c/ov13b10.c +@@ -1501,7 +1501,7 @@ static int ov13b10_probe(struct i2c_client *client) + + full_power = acpi_dev_state_d0(&client->dev); + if (full_power) { +- ov13b10_power_on(&client->dev); ++ ret = ov13b10_power_on(&client->dev); + if (ret) { + dev_err(&client->dev, "failed to power on\n"); + return ret; +-- +2.42.0 + diff --git a/queue-6.6/media-ov5640-fix-a-memory-leak-when-ov5640_probe-fai.patch b/queue-6.6/media-ov5640-fix-a-memory-leak-when-ov5640_probe-fai.patch new file mode 100644 index 00000000000..5a1aeb89854 --- /dev/null +++ b/queue-6.6/media-ov5640-fix-a-memory-leak-when-ov5640_probe-fai.patch @@ -0,0 +1,56 @@ +From 18d2223dc0cd481898991b4835e6690263956ed1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Aug 2023 17:05:35 +0800 +Subject: media: ov5640: Fix a memory leak when ov5640_probe fails + +From: Xiaolei Wang + +[ Upstream commit 20290feaaeb76cc719921aad275ccb18662a7c3a ] + +sensor->ctrls.handler is initialized in ov5640_init_controls(), +so when the sensor is not connected and ov5640_sensor_resume() +fails, sensor->ctrls.handler should be released, otherwise a +memory leak will be detected: + +unreferenced object 0xc674ca80 (size 64): + comm "swapper/0", pid 1, jiffies 4294938337 (age 204.880s) + hex dump (first 32 bytes): + 80 55 75 c6 80 54 75 c6 00 55 75 c6 80 52 75 c6 .Uu..Tu..Uu..Ru. + 00 53 75 c6 00 00 00 00 00 00 00 00 00 00 00 00 .Su.......... + +Fixes: 85644a9b37ec ("media: ov5640: Use runtime PM") +Signed-off-by: Xiaolei Wang +Signed-off-by: Sakari Ailus +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/i2c/ov5640.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c +index 1c9cda1e7df5c..40532f7bcabea 100644 +--- a/drivers/media/i2c/ov5640.c ++++ b/drivers/media/i2c/ov5640.c +@@ -3928,7 +3928,7 @@ static int ov5640_probe(struct i2c_client *client) + ret = ov5640_sensor_resume(dev); + if (ret) { + dev_err(dev, "failed to power on\n"); +- goto entity_cleanup; ++ goto free_ctrls; + } + + pm_runtime_set_active(dev); +@@ -3953,8 +3953,9 @@ static int ov5640_probe(struct i2c_client *client) + err_pm_runtime: + pm_runtime_put_noidle(dev); + pm_runtime_disable(dev); +- v4l2_ctrl_handler_free(&sensor->ctrls.handler); + ov5640_sensor_suspend(dev); ++free_ctrls: ++ v4l2_ctrl_handler_free(&sensor->ctrls.handler); + entity_cleanup: + media_entity_cleanup(&sensor->sd.entity); + mutex_destroy(&sensor->lock); +-- +2.42.0 + diff --git a/queue-6.6/media-ov5640-fix-vblank-unchange-issue-when-work-at-.patch b/queue-6.6/media-ov5640-fix-vblank-unchange-issue-when-work-at-.patch new file mode 100644 index 00000000000..690344303e4 --- /dev/null +++ b/queue-6.6/media-ov5640-fix-vblank-unchange-issue-when-work-at-.patch @@ -0,0 +1,81 @@ +From 72a533c574e76b57104b7d74e8b197248f4db959 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Jul 2023 15:30:12 +0800 +Subject: media: ov5640: fix vblank unchange issue when work at dvp mode + +From: Guoniu.zhou + +[ Upstream commit 8fc29e3c9f682d4ad9b0764d44ecc6c19b000051 ] + +The value of V4L2_CID_VBLANK control is initialized to default vblank +value of 640x480 when driver probe. When OV5640 work at DVP mode, the +control value won't update and lead to sensor can't output data if the +resolution remain the same as last time since incorrect total vertical +size. So update it when there is a new value applied. + +Fixes: bce93b827de6 ("media: ov5640: Add VBLANK control") +Signed-off-by: Guoniu.zhou +Signed-off-by: Sakari Ailus +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/i2c/ov5640.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c +index 5fe85aa2d2ec4..1c9cda1e7df5c 100644 +--- a/drivers/media/i2c/ov5640.c ++++ b/drivers/media/i2c/ov5640.c +@@ -2850,12 +2850,22 @@ static int ov5640_try_fmt_internal(struct v4l2_subdev *sd, + return 0; + } + ++static void __v4l2_ctrl_vblank_update(struct ov5640_dev *sensor, u32 vblank) ++{ ++ const struct ov5640_mode_info *mode = sensor->current_mode; ++ ++ __v4l2_ctrl_modify_range(sensor->ctrls.vblank, OV5640_MIN_VBLANK, ++ OV5640_MAX_VTS - mode->height, 1, vblank); ++ ++ __v4l2_ctrl_s_ctrl(sensor->ctrls.vblank, vblank); ++} ++ + static int ov5640_update_pixel_rate(struct ov5640_dev *sensor) + { + const struct ov5640_mode_info *mode = sensor->current_mode; + enum ov5640_pixel_rate_id pixel_rate_id = mode->pixel_rate; + struct v4l2_mbus_framefmt *fmt = &sensor->fmt; +- const struct ov5640_timings *timings; ++ const struct ov5640_timings *timings = ov5640_timings(sensor, mode); + s32 exposure_val, exposure_max; + unsigned int hblank; + unsigned int i = 0; +@@ -2874,6 +2884,8 @@ static int ov5640_update_pixel_rate(struct ov5640_dev *sensor) + __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate, + ov5640_calc_pixel_rate(sensor)); + ++ __v4l2_ctrl_vblank_update(sensor, timings->vblank_def); ++ + return 0; + } + +@@ -2916,15 +2928,12 @@ static int ov5640_update_pixel_rate(struct ov5640_dev *sensor) + __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate, pixel_rate); + __v4l2_ctrl_s_ctrl(sensor->ctrls.link_freq, i); + +- timings = ov5640_timings(sensor, mode); + hblank = timings->htot - mode->width; + __v4l2_ctrl_modify_range(sensor->ctrls.hblank, + hblank, hblank, 1, hblank); + + vblank = timings->vblank_def; +- __v4l2_ctrl_modify_range(sensor->ctrls.vblank, OV5640_MIN_VBLANK, +- OV5640_MAX_VTS - mode->height, 1, vblank); +- __v4l2_ctrl_s_ctrl(sensor->ctrls.vblank, vblank); ++ __v4l2_ctrl_vblank_update(sensor, vblank); + + exposure_max = timings->crop.height + vblank - 4; + exposure_val = clamp_t(s32, sensor->ctrls.exposure->val, +-- +2.42.0 + diff --git a/queue-6.6/media-platform-mtk-mdp3-fix-uninitialized-variable-i.patch b/queue-6.6/media-platform-mtk-mdp3-fix-uninitialized-variable-i.patch new file mode 100644 index 00000000000..12e9c460d48 --- /dev/null +++ b/queue-6.6/media-platform-mtk-mdp3-fix-uninitialized-variable-i.patch @@ -0,0 +1,57 @@ +From 1153cd82ba84d68863e552a3294b48d72ce9de95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 11:00:37 +0800 +Subject: media: platform: mtk-mdp3: fix uninitialized variable in + mdp_path_config() + +From: Moudy Ho + +[ Upstream commit 2a76e7679b594ea3e1b3b7fb6c3d67158114020d ] + +Fix the build warnings that were detected by the linux-media +build scripts tool: + +drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c: + In function 'mdp_path_config.isra': +drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c: + warning: 'ctx' may be used uninitialized [-Wmaybe-uninitialized] + | out = CFG_COMP(MT8195, ctx->param, outputs[0]); + | ~~~^~~~~~~ +drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h: note: + in definition of macro 'CFG_COMP' + | (IS_ERR_OR_NULL(comp) ? 0 : _CFG_COMP(plat, comp, mem)) + | ^~~~ +drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c: + note: 'ctx' was declared here + | struct mdp_comp_ctx *ctx; + | + +Fixes: 61890ccaefaf ("media: platform: mtk-mdp3: add MediaTek MDP3 driver") +Signed-off-by: Moudy Ho +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c +index 3177592490bee..6adac857a4779 100644 +--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c ++++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c +@@ -261,11 +261,11 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd, + const struct v4l2_rect *compose; + u32 out = 0; + ++ ctx = &path->comps[index]; + if (CFG_CHECK(MT8183, p_id)) + out = CFG_COMP(MT8183, ctx->param, outputs[0]); + + compose = path->composes[out]; +- ctx = &path->comps[index]; + ret = call_op(ctx, config_frame, cmd, compose); + if (ret) + return ret; +-- +2.42.0 + diff --git a/queue-6.6/media-s3c-camif-avoid-inappropriate-kfree.patch b/queue-6.6/media-s3c-camif-avoid-inappropriate-kfree.patch new file mode 100644 index 00000000000..d9e8925fe59 --- /dev/null +++ b/queue-6.6/media-s3c-camif-avoid-inappropriate-kfree.patch @@ -0,0 +1,54 @@ +From 18cedc3c8ac296b96c3e94a550861c82ae77f797 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 14:55:06 +0300 +Subject: media: s3c-camif: Avoid inappropriate kfree() + +From: Katya Orlova + +[ Upstream commit 61334819aca018c3416ee6c330a08a49c1524fc3 ] + +s3c_camif_register_video_node() works with video_device structure stored +as a field of camif_vp, so it should not be kfreed. +But there is video_device_release() on error path that do it. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: babde1c243b2 ("[media] V4L: Add driver for S3C24XX/S3C64XX SoC series camera interface") +Signed-off-by: Katya Orlova +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/platform/samsung/s3c-camif/camif-capture.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/media/platform/samsung/s3c-camif/camif-capture.c b/drivers/media/platform/samsung/s3c-camif/camif-capture.c +index 76634d242b103..0f5b3845d7b94 100644 +--- a/drivers/media/platform/samsung/s3c-camif/camif-capture.c ++++ b/drivers/media/platform/samsung/s3c-camif/camif-capture.c +@@ -1133,12 +1133,12 @@ int s3c_camif_register_video_node(struct camif_dev *camif, int idx) + + ret = vb2_queue_init(q); + if (ret) +- goto err_vd_rel; ++ return ret; + + vp->pad.flags = MEDIA_PAD_FL_SINK; + ret = media_entity_pads_init(&vfd->entity, 1, &vp->pad); + if (ret) +- goto err_vd_rel; ++ return ret; + + video_set_drvdata(vfd, vp); + +@@ -1171,8 +1171,6 @@ int s3c_camif_register_video_node(struct camif_dev *camif, int idx) + v4l2_ctrl_handler_free(&vp->ctrl_handler); + err_me_cleanup: + media_entity_cleanup(&vfd->entity); +-err_vd_rel: +- video_device_release(vfd); + return ret; + } + +-- +2.42.0 + diff --git a/queue-6.6/media-verisilicon-do-not-enable-g2-postproc-downscal.patch b/queue-6.6/media-verisilicon-do-not-enable-g2-postproc-downscal.patch new file mode 100644 index 00000000000..96bef81c2eb --- /dev/null +++ b/queue-6.6/media-verisilicon-do-not-enable-g2-postproc-downscal.patch @@ -0,0 +1,58 @@ +From 49c72d29b3093b5c6d3d0ce46d17550324881d3e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Aug 2023 03:39:35 +0200 +Subject: media: verisilicon: Do not enable G2 postproc downscale if source is + narrower than destination + +From: Marek Vasut + +[ Upstream commit 6e481d52d363218a3e6feb31694da74b38b30fad ] + +In case of encoded input VP9 data width that is not multiple of macroblock +size, which is 16 (e.g. 1080x1920 frames, where 1080 is multiple of 8), the +width is padded to be a multiple of macroblock size (for 1080x1920 frames, +that is 1088x1920). + +The hantro_postproc_g2_enable() checks whether the encoded data width is +equal to decoded frame width, and if not, enables down-scale mode. For a +frame where input is 1080x1920 and output is 1088x1920, this is incorrect +as no down-scale happens, the frame is only padded. Enabling the down-scale +mode in this case results in corrupted frames. + +Fix this by adjusting the check to test whether encoded data width is +greater than decoded frame width, and only in that case enable the +down-scale mode. + +To generate input test data to trigger this bug, use e.g.: +$ gst-launch-1.0 videotestsrc ! video/x-raw,width=272,height=256,format=I420 ! \ + vp9enc ! matroskamux ! filesink location=/tmp/test.vp9 +To trigger the bug upon decoding (note that the NV12 must be forced, as +that assures the output data would pass the G2 postproc): +$ gst-launch-1.0 filesrc location=/tmp/test.vp9 ! matroskademux ! vp9parse ! \ + v4l2slvp9dec ! video/x-raw,format=NV12 ! videoconvert ! fbdevsink + +Fixes: 79c987de8b35 ("media: hantro: Use post processor scaling capacities") +Signed-off-by: Marek Vasut +Reviewed-by: Benjamin Gaignard +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/platform/verisilicon/hantro_postproc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/platform/verisilicon/hantro_postproc.c b/drivers/media/platform/verisilicon/hantro_postproc.c +index 0224ff68ab3fc..64d6fb852ae9b 100644 +--- a/drivers/media/platform/verisilicon/hantro_postproc.c ++++ b/drivers/media/platform/verisilicon/hantro_postproc.c +@@ -107,7 +107,7 @@ static void hantro_postproc_g1_enable(struct hantro_ctx *ctx) + + static int down_scale_factor(struct hantro_ctx *ctx) + { +- if (ctx->src_fmt.width == ctx->dst_fmt.width) ++ if (ctx->src_fmt.width <= ctx->dst_fmt.width) + return 0; + + return DIV_ROUND_CLOSEST(ctx->src_fmt.width, ctx->dst_fmt.width); +-- +2.42.0 + diff --git a/queue-6.6/media-verisilicon-fixes-clock-list-for-rk3588-av1-de.patch b/queue-6.6/media-verisilicon-fixes-clock-list-for-rk3588-av1-de.patch new file mode 100644 index 00000000000..4149c9f565a --- /dev/null +++ b/queue-6.6/media-verisilicon-fixes-clock-list-for-rk3588-av1-de.patch @@ -0,0 +1,38 @@ +From 9eefeff9f292c1010eb674ce114c6ce473a1b54b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Oct 2023 16:51:16 +0200 +Subject: media: verisilicon: Fixes clock list for rk3588 av1 decoder + +From: Benjamin Gaignard + +[ Upstream commit 39377f84fb98561b86b645f0b7c33512eba7afaf ] + +Mainlined RK3588 clock driver manage by itself the dependency between +aclk/hclk and their root clocks (aclk_vdpu_root/hclk_vdpu_root). +RK3588 av1 video decoder do not have to take care of it anymore so +remove them from the list and be compliant with yaml bindings description. + +Fixes: 003afda97c65 ("media: verisilicon: Enable AV1 decoder on rk3588") +Signed-off-by: Benjamin Gaignard +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/platform/verisilicon/rockchip_vpu_hw.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/platform/verisilicon/rockchip_vpu_hw.c b/drivers/media/platform/verisilicon/rockchip_vpu_hw.c +index 816ffa905a4bb..f975276707835 100644 +--- a/drivers/media/platform/verisilicon/rockchip_vpu_hw.c ++++ b/drivers/media/platform/verisilicon/rockchip_vpu_hw.c +@@ -648,7 +648,7 @@ static const char * const rockchip_vpu_clk_names[] = { + }; + + static const char * const rk3588_vpu981_vpu_clk_names[] = { +- "aclk", "hclk", "aclk_vdpu_root", "hclk_vdpu_root" ++ "aclk", "hclk", + }; + + /* VDPU1/VEPU1 */ +-- +2.42.0 + diff --git a/queue-6.6/media-vidtv-mux-add-check-and-kfree-for-kstrdup.patch b/queue-6.6/media-vidtv-mux-add-check-and-kfree-for-kstrdup.patch new file mode 100644 index 00000000000..43857295fb0 --- /dev/null +++ b/queue-6.6/media-vidtv-mux-add-check-and-kfree-for-kstrdup.patch @@ -0,0 +1,56 @@ +From dc19da55298a6f8541976c11663b510c9ebbf4fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Jun 2023 16:12:02 +0800 +Subject: media: vidtv: mux: Add check and kfree for kstrdup + +From: Jiasheng Jiang + +[ Upstream commit 1fd6eb12642e0c32692924ff359c07de4b781d78 ] + +Add check for the return value of kstrdup() and return the error +if it fails in order to avoid NULL pointer dereference. +Moreover, use kfree() in the later error handling in order to avoid +memory leak. + +Fixes: c2f78f0cb294 ("media: vidtv: psi: add a Network Information Table (NIT)") +Signed-off-by: Jiasheng Jiang +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/test-drivers/vidtv/vidtv_mux.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c +index b51e6a3b8cbeb..f99878eff7ace 100644 +--- a/drivers/media/test-drivers/vidtv/vidtv_mux.c ++++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c +@@ -504,13 +504,16 @@ struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe, + m->priv = args->priv; + m->network_id = args->network_id; + m->network_name = kstrdup(args->network_name, GFP_KERNEL); ++ if (!m->network_name) ++ goto free_mux_buf; ++ + m->timing.current_jiffies = get_jiffies_64(); + + if (args->channels) + m->channels = args->channels; + else + if (vidtv_channels_init(m) < 0) +- goto free_mux_buf; ++ goto free_mux_network_name; + + /* will alloc data for pmt_sections after initializing pat */ + if (vidtv_channel_si_init(m) < 0) +@@ -527,6 +530,8 @@ struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe, + vidtv_channel_si_destroy(m); + free_channels: + vidtv_channels_destroy(m); ++free_mux_network_name: ++ kfree(m->network_name); + free_mux_buf: + vfree(m->mux_buf); + free_mux: +-- +2.42.0 + diff --git a/queue-6.6/media-vidtv-psi-add-check-for-kstrdup.patch b/queue-6.6/media-vidtv-psi-add-check-for-kstrdup.patch new file mode 100644 index 00000000000..269fb2e499f --- /dev/null +++ b/queue-6.6/media-vidtv-psi-add-check-for-kstrdup.patch @@ -0,0 +1,111 @@ +From a2c97cd11aa42de920afb81272969d75bbb61ec5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Jun 2023 16:12:01 +0800 +Subject: media: vidtv: psi: Add check for kstrdup + +From: Jiasheng Jiang + +[ Upstream commit 76a2c5df6ca8bd8ada45e953b8c72b746f42918d ] + +Add check for the return value of kstrdup() and return the error +if it fails in order to avoid NULL pointer dereference. + +Fixes: 7a7899f6f58e ("media: vidtv: psi: Implement an Event Information Table (EIT)") +Fixes: c2f78f0cb294 ("media: vidtv: psi: add a Network Information Table (NIT)") +Fixes: f90cf6079bf6 ("media: vidtv: add a bridge driver") +Signed-off-by: Jiasheng Jiang +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/test-drivers/vidtv/vidtv_psi.c | 45 +++++++++++++++++--- + 1 file changed, 40 insertions(+), 5 deletions(-) + +diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c +index ce0b7a6e92dc3..2a51c898c11eb 100644 +--- a/drivers/media/test-drivers/vidtv/vidtv_psi.c ++++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c +@@ -301,16 +301,29 @@ struct vidtv_psi_desc_service *vidtv_psi_service_desc_init(struct vidtv_psi_desc + + desc->service_name_len = service_name_len; + +- if (service_name && service_name_len) ++ if (service_name && service_name_len) { + desc->service_name = kstrdup(service_name, GFP_KERNEL); ++ if (!desc->service_name) ++ goto free_desc; ++ } + + desc->provider_name_len = provider_name_len; + +- if (provider_name && provider_name_len) ++ if (provider_name && provider_name_len) { + desc->provider_name = kstrdup(provider_name, GFP_KERNEL); ++ if (!desc->provider_name) ++ goto free_desc_service_name; ++ } + + vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc); + return desc; ++ ++free_desc_service_name: ++ if (service_name && service_name_len) ++ kfree(desc->service_name); ++free_desc: ++ kfree(desc); ++ return NULL; + } + + struct vidtv_psi_desc_registration +@@ -355,8 +368,13 @@ struct vidtv_psi_desc_network_name + + desc->length = network_name_len; + +- if (network_name && network_name_len) ++ if (network_name && network_name_len) { + desc->network_name = kstrdup(network_name, GFP_KERNEL); ++ if (!desc->network_name) { ++ kfree(desc); ++ return NULL; ++ } ++ } + + vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc); + return desc; +@@ -442,15 +460,32 @@ struct vidtv_psi_desc_short_event + iso_language_code = "eng"; + + desc->iso_language_code = kstrdup(iso_language_code, GFP_KERNEL); ++ if (!desc->iso_language_code) ++ goto free_desc; + +- if (event_name && event_name_len) ++ if (event_name && event_name_len) { + desc->event_name = kstrdup(event_name, GFP_KERNEL); ++ if (!desc->event_name) ++ goto free_desc_language_code; ++ } + +- if (text && text_len) ++ if (text && text_len) { + desc->text = kstrdup(text, GFP_KERNEL); ++ if (!desc->text) ++ goto free_desc_event_name; ++ } + + vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc); + return desc; ++ ++free_desc_event_name: ++ if (event_name && event_name_len) ++ kfree(desc->event_name); ++free_desc_language_code: ++ kfree(desc->iso_language_code); ++free_desc: ++ kfree(desc); ++ return NULL; + } + + struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc) +-- +2.42.0 + diff --git a/queue-6.6/memory-tegra-set-bpmp-msg-flags-to-reset-ipc-channel.patch b/queue-6.6/memory-tegra-set-bpmp-msg-flags-to-reset-ipc-channel.patch new file mode 100644 index 00000000000..8f407b15dab --- /dev/null +++ b/queue-6.6/memory-tegra-set-bpmp-msg-flags-to-reset-ipc-channel.patch @@ -0,0 +1,43 @@ +From 2685308b69c8c71be1efd5a6b7e2ff676807042b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 15:35:57 +0530 +Subject: memory: tegra: Set BPMP msg flags to reset IPC channels + +From: Thierry Reding + +[ Upstream commit f344675a34383ae26a8230f4b1cd99cbd0defebd ] + +Set the 'TEGRA_BPMP_MESSAGE_RESET' bit in newly added 'flags' field +of 'struct tegra_bpmp_message' to request for the reset of BPMP IPC +channels. This is used along with the 'suspended' check in BPMP driver +for handling early bandwidth requests due to the hotplug of CPU's +during system resume before the driver gets resumed. + +Fixes: f41e1442ac5b ("cpufreq: tegra194: add OPP support and set bandwidth") +Co-developed-by: Sumit Gupta +Signed-off-by: Sumit Gupta +Acked-by: Krzysztof Kozlowski +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + drivers/memory/tegra/tegra234.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/memory/tegra/tegra234.c b/drivers/memory/tegra/tegra234.c +index 9e5b5dbd9c8df..2845041f32d69 100644 +--- a/drivers/memory/tegra/tegra234.c ++++ b/drivers/memory/tegra/tegra234.c +@@ -986,6 +986,10 @@ static int tegra234_mc_icc_set(struct icc_node *src, struct icc_node *dst) + msg.rx.data = &bwmgr_resp; + msg.rx.size = sizeof(bwmgr_resp); + ++ if (pclient->bpmp_id >= TEGRA_ICC_BPMP_CPU_CLUSTER0 && ++ pclient->bpmp_id <= TEGRA_ICC_BPMP_CPU_CLUSTER2) ++ msg.flags = TEGRA_BPMP_MESSAGE_RESET; ++ + ret = tegra_bpmp_transfer(mc->bpmp, &msg); + if (ret < 0) { + dev_err(mc->dev, "BPMP transfer failed: %d\n", ret); +-- +2.42.0 + diff --git a/queue-6.6/mfd-arizona-spi-set-pdata.hpdet_channel-for-acpi-enu.patch b/queue-6.6/mfd-arizona-spi-set-pdata.hpdet_channel-for-acpi-enu.patch new file mode 100644 index 00000000000..7d1c491f10e --- /dev/null +++ b/queue-6.6/mfd-arizona-spi-set-pdata.hpdet_channel-for-acpi-enu.patch @@ -0,0 +1,50 @@ +From 3d4be6f3324b1edd9759409520e19ef9640da9c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Oct 2023 22:54:14 +0200 +Subject: mfd: arizona-spi: Set pdata.hpdet_channel for ACPI enumerated devs + +From: Hans de Goede + +[ Upstream commit 831d1af85133e1763d41e20414912d9a1058ea72 ] + +Commit 9e86b2ad4c11 changed the channel used for HPDET detection +(headphones vs lineout detection) from being hardcoded to +ARIZONA_ACCDET_MODE_HPL (HP left channel) to it being configurable +through arizona_pdata.hpdet_channel the DT/OF parsing added for +filling arizona_pdata on devicetree platforms ensures that +arizona_pdata.hpdet_channel gets set to ARIZONA_ACCDET_MODE_HPL +when not specified in the devicetree-node. + +But on ACPI platforms where arizona_pdata is filled by +arizona_spi_acpi_probe() arizona_pdata.hpdet_channel was not +getting set, causing it to default to 0 aka ARIZONA_ACCDET_MODE_MIC. + +This causes headphones to get misdetected as line-out on some models. +Fix this by setting hpdet_channel = ARIZONA_ACCDET_MODE_HPL. + +Fixes: e933836744a2 ("mfd: arizona: Add support for ACPI enumeration of WM5102 connected over SPI") +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20231014205414.59415-1-hdegoede@redhat.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/arizona-spi.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c +index 02cf4f3e91d76..de5d894ac04af 100644 +--- a/drivers/mfd/arizona-spi.c ++++ b/drivers/mfd/arizona-spi.c +@@ -159,6 +159,9 @@ static int arizona_spi_acpi_probe(struct arizona *arizona) + arizona->pdata.micd_ranges = arizona_micd_aosp_ranges; + arizona->pdata.num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges); + ++ /* Use left headphone speaker for HP vs line-out detection */ ++ arizona->pdata.hpdet_channel = ARIZONA_ACCDET_MODE_HPL; ++ + return 0; + } + +-- +2.42.0 + diff --git a/queue-6.6/mfd-core-ensure-disabled-devices-are-skipped-without.patch b/queue-6.6/mfd-core-ensure-disabled-devices-are-skipped-without.patch new file mode 100644 index 00000000000..bb8f41480c5 --- /dev/null +++ b/queue-6.6/mfd-core-ensure-disabled-devices-are-skipped-without.patch @@ -0,0 +1,77 @@ +From a409597687e888ef32ba1f4f2a1d9dc5931eadb3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Aug 2023 18:39:17 +0200 +Subject: mfd: core: Ensure disabled devices are skipped without aborting + +From: Herve Codina + +[ Upstream commit 7ba7bdef4d14e3722e2842da3b48cbadb73e52d6 ] + +The loop searching for a matching device based on its compatible +string is aborted when a matching disabled device is found. +This abort prevents to add devices as soon as one disabled device +is found. + +Continue searching for an other device instead of aborting on the +first disabled one fixes the issue. + +Fixes: 22380b65dc70 ("mfd: mfd-core: Ensure disabled devices are ignored without error") +Signed-off-by: Herve Codina +Reviewed-by: Christophe Leroy +Signed-off-by: Christophe Leroy +Link: https://lore.kernel.org/r/528425d6472176bb1d02d79596b51f8c28a551cc.1692376361.git.christophe.leroy@csgroup.eu +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/mfd-core.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c +index 0ed7c0d7784e1..2b85509a90fc2 100644 +--- a/drivers/mfd/mfd-core.c ++++ b/drivers/mfd/mfd-core.c +@@ -146,6 +146,7 @@ static int mfd_add_device(struct device *parent, int id, + struct platform_device *pdev; + struct device_node *np = NULL; + struct mfd_of_node_entry *of_entry, *tmp; ++ bool disabled = false; + int ret = -ENOMEM; + int platform_id; + int r; +@@ -183,11 +184,10 @@ static int mfd_add_device(struct device *parent, int id, + if (IS_ENABLED(CONFIG_OF) && parent->of_node && cell->of_compatible) { + for_each_child_of_node(parent->of_node, np) { + if (of_device_is_compatible(np, cell->of_compatible)) { +- /* Ignore 'disabled' devices error free */ ++ /* Skip 'disabled' devices */ + if (!of_device_is_available(np)) { +- of_node_put(np); +- ret = 0; +- goto fail_alias; ++ disabled = true; ++ continue; + } + + ret = mfd_match_of_node_to_dev(pdev, np, cell); +@@ -197,10 +197,17 @@ static int mfd_add_device(struct device *parent, int id, + if (ret) + goto fail_alias; + +- break; ++ goto match; + } + } + ++ if (disabled) { ++ /* Ignore 'disabled' devices error free */ ++ ret = 0; ++ goto fail_alias; ++ } ++ ++match: + if (!pdev->dev.of_node) + pr_warn("%s: Failed to locate of_node [id: %d]\n", + cell->name, platform_id); +-- +2.42.0 + diff --git a/queue-6.6/mfd-core-un-constify-mfd_cell.of_reg.patch b/queue-6.6/mfd-core-un-constify-mfd_cell.of_reg.patch new file mode 100644 index 00000000000..040a9c8c1ba --- /dev/null +++ b/queue-6.6/mfd-core-un-constify-mfd_cell.of_reg.patch @@ -0,0 +1,40 @@ +From 11f8690afb8d959dd7eaf0b6dff7ccdf2b49b9e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Aug 2023 22:16:11 +0200 +Subject: mfd: core: Un-constify mfd_cell.of_reg +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michał Mirosław + +[ Upstream commit 3c70342f1f0045dc827bb2f02d814ce31e0e0d05 ] + +Enable dynamically filling in the whole mfd_cell structure. All other +fields already allow that. + +Fixes: 466a62d7642f ("mfd: core: Make a best effort attempt to match devices with the correct of_nodes") +Signed-off-by: Michał Mirosław +Link: https://lore.kernel.org/r/b73fe4bc4bd6ba1af90940a640ed65fe254c0408.1693253717.git.mirq-linux@rere.qmqm.pl +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + include/linux/mfd/core.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h +index 47e7a3a61ce69..e8bcad641d8c2 100644 +--- a/include/linux/mfd/core.h ++++ b/include/linux/mfd/core.h +@@ -92,7 +92,7 @@ struct mfd_cell { + * (above) when matching OF nodes with devices that have identical + * compatible strings + */ +- const u64 of_reg; ++ u64 of_reg; + + /* Set to 'true' to use 'of_reg' (above) - allows for of_reg=0 */ + bool use_of_reg; +-- +2.42.0 + diff --git a/queue-6.6/mfd-dln2-fix-double-put-in-dln2_probe.patch b/queue-6.6/mfd-dln2-fix-double-put-in-dln2_probe.patch new file mode 100644 index 00000000000..a6bb05f2d03 --- /dev/null +++ b/queue-6.6/mfd-dln2-fix-double-put-in-dln2_probe.patch @@ -0,0 +1,37 @@ +From 79b8c91da2aeed913a2bae8c67c4a4c8e2c72b7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Sep 2023 10:41:33 +0800 +Subject: mfd: dln2: Fix double put in dln2_probe + +From: Dinghao Liu + +[ Upstream commit 759c409bc5fc496cbc22cd0b392d3cbb0c0e23eb ] + +The dln2_free() already contains usb_put_dev(). Therefore, +the redundant usb_put_dev() before dln2_free() may lead to +a double free. + +Fixes: 96da8f148396 ("mfd: dln2: Fix memory leak in dln2_probe()") +Signed-off-by: Dinghao Liu +Link: https://lore.kernel.org/r/20230925024134.9683-1-dinghao.liu@zju.edu.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/dln2.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c +index c7510434380a4..fbbe82c6e75b5 100644 +--- a/drivers/mfd/dln2.c ++++ b/drivers/mfd/dln2.c +@@ -826,7 +826,6 @@ static int dln2_probe(struct usb_interface *interface, + dln2_stop_rx_urbs(dln2); + + out_free: +- usb_put_dev(dln2->usb_dev); + dln2_free(dln2); + + return ret; +-- +2.42.0 + diff --git a/queue-6.6/misc-st_core-do-not-call-kfree_skb-under-spin_lock_i.patch b/queue-6.6/misc-st_core-do-not-call-kfree_skb-under-spin_lock_i.patch new file mode 100644 index 00000000000..cffd2d1e2ab --- /dev/null +++ b/queue-6.6/misc-st_core-do-not-call-kfree_skb-under-spin_lock_i.patch @@ -0,0 +1,65 @@ +From 51929fe1d411e76c2dd58678d00313c43d35e2ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Aug 2023 11:50:20 +0800 +Subject: misc: st_core: Do not call kfree_skb() under spin_lock_irqsave() + +From: Jinjie Ruan + +[ Upstream commit 4d08c3d12b61022501989f9f071514d2d6f77c47 ] + +It is not allowed to call kfree_skb() from hardware interrupt +context or with hardware interrupts being disabled. +So replace kfree_skb() with dev_kfree_skb_irq() under +spin_lock_irqsave(). Compile tested only. + +Fixes: 53618cc1e51e ("Staging: sources for ST core") +Signed-off-by: Jinjie Ruan +Link: https://lore.kernel.org/r/20230823035020.1281892-1-ruanjinjie@huawei.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/misc/ti-st/st_core.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c +index c1a134bd8ba7b..b878431553abc 100644 +--- a/drivers/misc/ti-st/st_core.c ++++ b/drivers/misc/ti-st/st_core.c +@@ -15,6 +15,7 @@ + #include + + #include ++#include + + /* + * function pointer pointing to either, +@@ -429,7 +430,7 @@ static void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb) + case ST_LL_AWAKE_TO_ASLEEP: + pr_err("ST LL is illegal state(%ld)," + "purging received skb.", st_ll_getstate(st_gdata)); +- kfree_skb(skb); ++ dev_kfree_skb_irq(skb); + break; + case ST_LL_ASLEEP: + skb_queue_tail(&st_gdata->tx_waitq, skb); +@@ -438,7 +439,7 @@ static void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb) + default: + pr_err("ST LL is illegal state(%ld)," + "purging received skb.", st_ll_getstate(st_gdata)); +- kfree_skb(skb); ++ dev_kfree_skb_irq(skb); + break; + } + +@@ -492,7 +493,7 @@ void st_tx_wakeup(struct st_data_s *st_data) + spin_unlock_irqrestore(&st_data->lock, flags); + break; + } +- kfree_skb(skb); ++ dev_kfree_skb_irq(skb); + spin_unlock_irqrestore(&st_data->lock, flags); + } + /* if wake-up is set in another context- restart sending */ +-- +2.42.0 + diff --git a/queue-6.6/mlxsw-use-size_mul-in-call-to-struct_size.patch b/queue-6.6/mlxsw-use-size_mul-in-call-to-struct_size.patch new file mode 100644 index 00000000000..f3e2f2f5019 --- /dev/null +++ b/queue-6.6/mlxsw-use-size_mul-in-call-to-struct_size.patch @@ -0,0 +1,39 @@ +From 6757493883079340e28fa2d0fc547b570d84feeb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 13:01:23 -0600 +Subject: mlxsw: Use size_mul() in call to struct_size() + +From: Gustavo A. R. Silva + +[ Upstream commit e22c6ea025013ae447fe269269753ffec763dde5 ] + +If, for any reason, the open-coded arithmetic causes a wraparound, the +protection that `struct_size()` adds against potential integer overflows +is defeated. Fix this by hardening call to `struct_size()` with `size_mul()`. + +Fixes: 2285ec872d9d ("mlxsw: spectrum_acl_bloom_filter: use struct_size() in kzalloc()") +Signed-off-by: Gustavo A. R. Silva +Reviewed-by: Kees Cook +Reviewed-by: Ido Schimmel +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c +index e2aced7ab4547..95f63fcf4ba1f 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c +@@ -496,7 +496,7 @@ mlxsw_sp_acl_bf_init(struct mlxsw_sp *mlxsw_sp, unsigned int num_erp_banks) + * is 2^ACL_MAX_BF_LOG + */ + bf_bank_size = 1 << MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_BF_LOG); +- bf = kzalloc(struct_size(bf, refcnt, bf_bank_size * num_erp_banks), ++ bf = kzalloc(struct_size(bf, refcnt, size_mul(bf_bank_size, num_erp_banks)), + GFP_KERNEL); + if (!bf) + return ERR_PTR(-ENOMEM); +-- +2.42.0 + diff --git a/queue-6.6/modpost-fix-ishtp-module_device_table-built-on-big-e.patch b/queue-6.6/modpost-fix-ishtp-module_device_table-built-on-big-e.patch new file mode 100644 index 00000000000..abd56fb60f1 --- /dev/null +++ b/queue-6.6/modpost-fix-ishtp-module_device_table-built-on-big-e.patch @@ -0,0 +1,66 @@ +From 619719a176295ef8c47c0511cd8351da7c4bec6f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Oct 2023 02:04:45 +0900 +Subject: modpost: fix ishtp MODULE_DEVICE_TABLE built on big-endian host +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Masahiro Yamada + +[ Upstream commit ac96a15a0f0c8812a3aaa587b871cd5527f6d736 ] + +When MODULE_DEVICE_TABLE(ishtp, ) is built on a host with a different +endianness from the target architecture, it results in an incorrect +MODULE_ALIAS(). + +For example, see a case where drivers/platform/x86/intel/ishtp_eclite.c +is built as a module for x86. + +If you build it on a little-endian host, you will get the correct +MODULE_ALIAS: + + $ grep MODULE_ALIAS drivers/platform/x86/intel/ishtp_eclite.mod.c + MODULE_ALIAS("ishtp:{6A19CC4B-D760-4DE3-B14D-F25EBD0FBCD9}"); + +However, if you build it on a big-endian host, you will get a wrong +MODULE_ALIAS: + + $ grep MODULE_ALIAS drivers/platform/x86/intel/ishtp_eclite.mod.c + MODULE_ALIAS("ishtp:{BD0FBCD9-F25E-B14D-4DE3-D7606A19CC4B}"); + +This issue has been unnoticed because the x86 kernel is most likely built +natively on an x86 host. + +The guid field must not be reversed because guid_t is an array of __u8. + +Fixes: fa443bc3c1e4 ("HID: intel-ish-hid: add support for MODULE_DEVICE_TABLE()") +Signed-off-by: Masahiro Yamada +Reviewed-by: Thomas Weißschuh +Tested-by: Srinivas Pandruvada +Acked-by: Srinivas Pandruvada +Signed-off-by: Sasha Levin +--- + scripts/mod/file2alias.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c +index 70bf6a2f585ce..6583b36dbe694 100644 +--- a/scripts/mod/file2alias.c ++++ b/scripts/mod/file2alias.c +@@ -1401,10 +1401,10 @@ static int do_mhi_ep_entry(const char *filename, void *symval, char *alias) + /* Looks like: ishtp:{guid} */ + static int do_ishtp_entry(const char *filename, void *symval, char *alias) + { +- DEF_FIELD(symval, ishtp_device_id, guid); ++ DEF_FIELD_ADDR(symval, ishtp_device_id, guid); + + strcpy(alias, ISHTP_MODULE_PREFIX "{"); +- add_guid(alias, guid); ++ add_guid(alias, *guid); + strcat(alias, "}"); + + return 1; +-- +2.42.0 + diff --git a/queue-6.6/modpost-fix-tee-module_device_table-built-on-big-end.patch b/queue-6.6/modpost-fix-tee-module_device_table-built-on-big-end.patch new file mode 100644 index 00000000000..bb2d95edae1 --- /dev/null +++ b/queue-6.6/modpost-fix-tee-module_device_table-built-on-big-end.patch @@ -0,0 +1,71 @@ +From 5f921dbb49732b7b6f8b2703c912e101ff09ec1f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Oct 2023 02:04:44 +0900 +Subject: modpost: fix tee MODULE_DEVICE_TABLE built on big-endian host + +From: Masahiro Yamada + +[ Upstream commit 7f54e00e5842663c2cea501bbbdfa572c94348a3 ] + +When MODULE_DEVICE_TABLE(tee, ) is built on a host with a different +endianness from the target architecture, it results in an incorrect +MODULE_ALIAS(). + +For example, see a case where drivers/char/hw_random/optee-rng.c +is built as a module for ARM little-endian. + +If you build it on a little-endian host, you will get the correct +MODULE_ALIAS: + + $ grep MODULE_ALIAS drivers/char/hw_random/optee-rng.mod.c + MODULE_ALIAS("tee:ab7a617c-b8e7-4d8f-8301-d09b61036b64*"); + +However, if you build it on a big-endian host, you will get a wrong +MODULE_ALIAS: + + $ grep MODULE_ALIAS drivers/char/hw_random/optee-rng.mod.c + MODULE_ALIAS("tee:646b0361-9bd0-0183-8f4d-e7b87c617aab*"); + +The same problem also occurs when you enable CONFIG_CPU_BIG_ENDIAN, +and build it on a little-endian host. + +This issue has been unnoticed because the ARM kernel is configured for +little-endian by default, and most likely built on a little-endian host +(cross-build on x86 or native-build on ARM). + +The uuid field must not be reversed because uuid_t is an array of __u8. + +Fixes: 0fc1db9d1059 ("tee: add bus driver framework for TEE based devices") +Signed-off-by: Masahiro Yamada +Reviewed-by: Sumit Garg +Signed-off-by: Sasha Levin +--- + scripts/mod/file2alias.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c +index 7056751c29b1f..70bf6a2f585ce 100644 +--- a/scripts/mod/file2alias.c ++++ b/scripts/mod/file2alias.c +@@ -1348,13 +1348,13 @@ static int do_typec_entry(const char *filename, void *symval, char *alias) + /* Looks like: tee:uuid */ + static int do_tee_entry(const char *filename, void *symval, char *alias) + { +- DEF_FIELD(symval, tee_client_device_id, uuid); ++ DEF_FIELD_ADDR(symval, tee_client_device_id, uuid); + + sprintf(alias, "tee:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", +- uuid.b[0], uuid.b[1], uuid.b[2], uuid.b[3], uuid.b[4], +- uuid.b[5], uuid.b[6], uuid.b[7], uuid.b[8], uuid.b[9], +- uuid.b[10], uuid.b[11], uuid.b[12], uuid.b[13], uuid.b[14], +- uuid.b[15]); ++ uuid->b[0], uuid->b[1], uuid->b[2], uuid->b[3], uuid->b[4], ++ uuid->b[5], uuid->b[6], uuid->b[7], uuid->b[8], uuid->b[9], ++ uuid->b[10], uuid->b[11], uuid->b[12], uuid->b[13], uuid->b[14], ++ uuid->b[15]); + + add_wildcard(alias); + return 1; +-- +2.42.0 + diff --git a/queue-6.6/module-decompress-use-vmalloc-for-gzip-decompression.patch b/queue-6.6/module-decompress-use-vmalloc-for-gzip-decompression.patch new file mode 100644 index 00000000000..ec4ca6d720f --- /dev/null +++ b/queue-6.6/module-decompress-use-vmalloc-for-gzip-decompression.patch @@ -0,0 +1,64 @@ +From 823985712279298b57254450f5534d6b8dde1808 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Aug 2023 17:58:20 +0200 +Subject: module/decompress: use vmalloc() for gzip decompression workspace + +From: Andrea Righi + +[ Upstream commit 3737df782c740b944912ed93420c57344b1cf864 ] + +Use a similar approach as commit a419beac4a07 ("module/decompress: use +vmalloc() for zstd decompression workspace") and replace kmalloc() with +vmalloc() also for the gzip module decompression workspace. + +In this case the workspace is represented by struct inflate_workspace +that can be fairly large for kmalloc() and it can potentially lead to +allocation errors on certain systems: + +$ pahole inflate_workspace +struct inflate_workspace { + struct inflate_state inflate_state; /* 0 9544 */ + /* --- cacheline 149 boundary (9536 bytes) was 8 bytes ago --- */ + unsigned char working_window[32768]; /* 9544 32768 */ + + /* size: 42312, cachelines: 662, members: 2 */ + /* last cacheline: 8 bytes */ +}; + +Considering that there is no need to use continuous physical memory, +simply switch to vmalloc() to provide a more reliable in-kernel module +decompression. + +Fixes: b1ae6dc41eaa ("module: add in-kernel support for decompressing") +Signed-off-by: Andrea Righi +Signed-off-by: Luis Chamberlain +Signed-off-by: Sasha Levin +--- + kernel/module/decompress.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/kernel/module/decompress.c b/kernel/module/decompress.c +index 87440f714c0ca..4156d59be4408 100644 +--- a/kernel/module/decompress.c ++++ b/kernel/module/decompress.c +@@ -100,7 +100,7 @@ static ssize_t module_gzip_decompress(struct load_info *info, + s.next_in = buf + gzip_hdr_len; + s.avail_in = size - gzip_hdr_len; + +- s.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); ++ s.workspace = vmalloc(zlib_inflate_workspacesize()); + if (!s.workspace) + return -ENOMEM; + +@@ -138,7 +138,7 @@ static ssize_t module_gzip_decompress(struct load_info *info, + out_inflate_end: + zlib_inflateEnd(&s); + out: +- kfree(s.workspace); ++ vfree(s.workspace); + return retval; + } + #elif defined(CONFIG_MODULE_COMPRESS_XZ) +-- +2.42.0 + diff --git a/queue-6.6/mptcp-properly-account-fastopen-data.patch b/queue-6.6/mptcp-properly-account-fastopen-data.patch new file mode 100644 index 00000000000..f7522cb9aa5 --- /dev/null +++ b/queue-6.6/mptcp-properly-account-fastopen-data.patch @@ -0,0 +1,40 @@ +From 58a4059f777e3d68a4767cebcc6637de7cce7474 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Oct 2023 13:44:35 -0700 +Subject: mptcp: properly account fastopen data + +From: Paolo Abeni + +[ Upstream commit bf0e96108fb6707613dd055aff5e98b02b99bb14 ] + +Currently the socket level counter aggregating the received data +does not take in account the data received via fastopen. + +Address the issue updating the counter as required. + +Fixes: 38967f424b5b ("mptcp: track some aggregate data counters") +Reviewed-by: Mat Martineau +Signed-off-by: Paolo Abeni +Signed-off-by: Mat Martineau +Link: https://lore.kernel.org/r/20231023-send-net-next-20231023-2-v1-2-9dc60939d371@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/mptcp/fastopen.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/mptcp/fastopen.c b/net/mptcp/fastopen.c +index bceaab8dd8e46..74698582a2859 100644 +--- a/net/mptcp/fastopen.c ++++ b/net/mptcp/fastopen.c +@@ -52,6 +52,7 @@ void mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context *subf + + mptcp_set_owner_r(skb, sk); + __skb_queue_tail(&sk->sk_receive_queue, skb); ++ mptcp_sk(sk)->bytes_received += skb->len; + + sk->sk_data_ready(sk); + +-- +2.42.0 + diff --git a/queue-6.6/nd_btt-make-btt-lanes-preemptible.patch b/queue-6.6/nd_btt-make-btt-lanes-preemptible.patch new file mode 100644 index 00000000000..363760e6943 --- /dev/null +++ b/queue-6.6/nd_btt-make-btt-lanes-preemptible.patch @@ -0,0 +1,94 @@ +From a491d9705448f7b35eb5b10ef5f94d462b6a4e28 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Sep 2023 07:37:12 +0200 +Subject: nd_btt: Make BTT lanes preemptible + +From: Tomas Glozar + +[ Upstream commit 36c75ce3bd299878fd9b238e9803d3817ddafbf3 ] + +nd_region_acquire_lane uses get_cpu, which disables preemption. This is +an issue on PREEMPT_RT kernels, since btt_write_pg and also +nd_region_acquire_lane itself take a spin lock, resulting in BUG: +sleeping function called from invalid context. + +Fix the issue by replacing get_cpu with smp_process_id and +migrate_disable when needed. This makes BTT operations preemptible, thus +permitting the use of spin_lock. + +BUG example occurring when running ndctl tests on PREEMPT_RT kernel: + +BUG: sleeping function called from invalid context at +kernel/locking/spinlock_rt.c:48 +in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 4903, name: +libndctl +preempt_count: 1, expected: 0 +RCU nest depth: 0, expected: 0 +Preemption disabled at: +[] nd_region_acquire_lane+0x15/0x90 [libnvdimm] +Call Trace: + + dump_stack_lvl+0x8e/0xb0 + __might_resched+0x19b/0x250 + rt_spin_lock+0x4c/0x100 + ? btt_write_pg+0x2d7/0x500 [nd_btt] + btt_write_pg+0x2d7/0x500 [nd_btt] + ? local_clock_noinstr+0x9/0xc0 + btt_submit_bio+0x16d/0x270 [nd_btt] + __submit_bio+0x48/0x80 + __submit_bio_noacct+0x7e/0x1e0 + submit_bio_wait+0x58/0xb0 + __blkdev_direct_IO_simple+0x107/0x240 + ? inode_set_ctime_current+0x51/0x110 + ? __pfx_submit_bio_wait_endio+0x10/0x10 + blkdev_write_iter+0x1d8/0x290 + vfs_write+0x237/0x330 + ... + + +Fixes: 5212e11fde4d ("nd_btt: atomic sector updates") +Signed-off-by: Tomas Glozar +Reviewed-by: Ira Weiny +Reviewed-by: Vishal Verma +Signed-off-by: Ira Weiny +Signed-off-by: Sasha Levin +--- + drivers/nvdimm/region_devs.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c +index 0a81f87f6f6c0..e2f1fb99707fc 100644 +--- a/drivers/nvdimm/region_devs.c ++++ b/drivers/nvdimm/region_devs.c +@@ -939,7 +939,8 @@ unsigned int nd_region_acquire_lane(struct nd_region *nd_region) + { + unsigned int cpu, lane; + +- cpu = get_cpu(); ++ migrate_disable(); ++ cpu = smp_processor_id(); + if (nd_region->num_lanes < nr_cpu_ids) { + struct nd_percpu_lane *ndl_lock, *ndl_count; + +@@ -958,16 +959,15 @@ EXPORT_SYMBOL(nd_region_acquire_lane); + void nd_region_release_lane(struct nd_region *nd_region, unsigned int lane) + { + if (nd_region->num_lanes < nr_cpu_ids) { +- unsigned int cpu = get_cpu(); ++ unsigned int cpu = smp_processor_id(); + struct nd_percpu_lane *ndl_lock, *ndl_count; + + ndl_count = per_cpu_ptr(nd_region->lane, cpu); + ndl_lock = per_cpu_ptr(nd_region->lane, lane); + if (--ndl_count->count == 0) + spin_unlock(&ndl_lock->lock); +- put_cpu(); + } +- put_cpu(); ++ migrate_enable(); + } + EXPORT_SYMBOL(nd_region_release_lane); + +-- +2.42.0 + diff --git a/queue-6.6/net-add-dev_stats_read-helper.patch b/queue-6.6/net-add-dev_stats_read-helper.patch new file mode 100644 index 00000000000..ee8faefa43a --- /dev/null +++ b/queue-6.6/net-add-dev_stats_read-helper.patch @@ -0,0 +1,55 @@ +From 22e1e17f530599cbeaf57d19916c8457b3ac52ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 08:52:16 +0000 +Subject: net: add DEV_STATS_READ() helper + +From: Eric Dumazet + +[ Upstream commit 0b068c714ca9479d2783cc333fff5bc2d4a6d45c ] + +Companion of DEV_STATS_INC() & DEV_STATS_ADD(). + +This is going to be used in the series. + +Use it in macsec_get_stats64(). + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Stable-dep-of: ff672b9ffeb3 ("ipvlan: properly track tx_errors") +Signed-off-by: Sasha Levin +--- + drivers/net/macsec.c | 6 +++--- + include/linux/netdevice.h | 1 + + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c +index c5cd4551c67ca..9663050a852d8 100644 +--- a/drivers/net/macsec.c ++++ b/drivers/net/macsec.c +@@ -3657,9 +3657,9 @@ static void macsec_get_stats64(struct net_device *dev, + + dev_fetch_sw_netstats(s, dev->tstats); + +- s->rx_dropped = atomic_long_read(&dev->stats.__rx_dropped); +- s->tx_dropped = atomic_long_read(&dev->stats.__tx_dropped); +- s->rx_errors = atomic_long_read(&dev->stats.__rx_errors); ++ s->rx_dropped = DEV_STATS_READ(dev, rx_dropped); ++ s->tx_dropped = DEV_STATS_READ(dev, tx_dropped); ++ s->rx_errors = DEV_STATS_READ(dev, rx_errors); + } + + static int macsec_get_iflink(const struct net_device *dev) +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index 0896aaa91dd7b..b646609f09c05 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -5214,5 +5214,6 @@ extern struct net_device *blackhole_netdev; + #define DEV_STATS_INC(DEV, FIELD) atomic_long_inc(&(DEV)->stats.__##FIELD) + #define DEV_STATS_ADD(DEV, FIELD, VAL) \ + atomic_long_add((VAL), &(DEV)->stats.__##FIELD) ++#define DEV_STATS_READ(DEV, FIELD) atomic_long_read(&(DEV)->stats.__##FIELD) + + #endif /* _LINUX_NETDEVICE_H */ +-- +2.42.0 + diff --git a/queue-6.6/net-ethernet-mtk_wed-fix-ext_int_status_rx_fbuf-defi.patch b/queue-6.6/net-ethernet-mtk_wed-fix-ext_int_status_rx_fbuf-defi.patch new file mode 100644 index 00000000000..8dfc5c1d6b1 --- /dev/null +++ b/queue-6.6/net-ethernet-mtk_wed-fix-ext_int_status_rx_fbuf-defi.patch @@ -0,0 +1,40 @@ +From f4998aa40734969b79f34da829b3a8c95cfc00ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Sep 2023 12:29:11 +0200 +Subject: net: ethernet: mtk_wed: fix EXT_INT_STATUS_RX_FBUF definitions for + MT7986 SoC + +From: Lorenzo Bianconi + +[ Upstream commit c80471ba74b7f332ac19b985ccb76d852d507acf ] + +Fix MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH and +MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH definitions for MT7986 (MT7986 is +the only SoC to use them). + +Fixes: de84a090d99a ("net: ethernet: mtk_eth_wed: add wed support for mt7986 chipset") +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mediatek/mtk_wed_regs.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h +index 47ea69feb3b24..f87ab9b8a5901 100644 +--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h +@@ -64,8 +64,8 @@ struct mtk_wdma_desc { + #define MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID BIT(4) + #define MTK_WED_EXT_INT_STATUS_TX_FBUF_LO_TH BIT(8) + #define MTK_WED_EXT_INT_STATUS_TX_FBUF_HI_TH BIT(9) +-#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH BIT(12) +-#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH BIT(13) ++#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH BIT(10) /* wed v2 */ ++#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH BIT(11) /* wed v2 */ + #define MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR BIT(16) + #define MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR BIT(17) + #define MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT BIT(18) +-- +2.42.0 + diff --git a/queue-6.6/net-skb_find_text-ignore-patterns-extending-past-to.patch b/queue-6.6/net-skb_find_text-ignore-patterns-extending-past-to.patch new file mode 100644 index 00000000000..83c0d065dcf --- /dev/null +++ b/queue-6.6/net-skb_find_text-ignore-patterns-extending-past-to.patch @@ -0,0 +1,205 @@ +From 350c995efa4cc609289c3afb12d2f84e3cd4558a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 11:39:06 +0200 +Subject: net: skb_find_text: Ignore patterns extending past 'to' + +From: Phil Sutter + +[ Upstream commit c4eee56e14fe001e1cff54f0b438a5e2d0dd7454 ] + +Assume that caller's 'to' offset really represents an upper boundary for +the pattern search, so patterns extending past this offset are to be +rejected. + +The old behaviour also was kind of inconsistent when it comes to +fragmentation (or otherwise non-linear skbs): If the pattern started in +between 'to' and 'from' offsets but extended to the next fragment, it +was not found if 'to' offset was still within the current fragment. + +Test the new behaviour in a kselftest using iptables' string match. + +Suggested-by: Pablo Neira Ayuso +Fixes: f72b948dcbb8 ("[NET]: skb_find_text ignores to argument") +Signed-off-by: Phil Sutter +Reviewed-by: Florian Westphal +Reviewed-by: Pablo Neira Ayuso +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/core/skbuff.c | 3 +- + tools/testing/selftests/netfilter/Makefile | 2 +- + .../testing/selftests/netfilter/xt_string.sh | 128 ++++++++++++++++++ + 3 files changed, 131 insertions(+), 2 deletions(-) + create mode 100755 tools/testing/selftests/netfilter/xt_string.sh + +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 4eaf7ed0d1f44..97b4a42e6e347 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -4254,6 +4254,7 @@ static void skb_ts_finish(struct ts_config *conf, struct ts_state *state) + unsigned int skb_find_text(struct sk_buff *skb, unsigned int from, + unsigned int to, struct ts_config *config) + { ++ unsigned int patlen = config->ops->get_pattern_len(config); + struct ts_state state; + unsigned int ret; + +@@ -4265,7 +4266,7 @@ unsigned int skb_find_text(struct sk_buff *skb, unsigned int from, + skb_prepare_seq_read(skb, from, to, TS_SKB_CB(&state)); + + ret = textsearch_find(config, &state); +- return (ret <= to - from ? ret : UINT_MAX); ++ return (ret + patlen <= to - from ? ret : UINT_MAX); + } + EXPORT_SYMBOL(skb_find_text); + +diff --git a/tools/testing/selftests/netfilter/Makefile b/tools/testing/selftests/netfilter/Makefile +index ef90aca4cc96a..bced422b78f72 100644 +--- a/tools/testing/selftests/netfilter/Makefile ++++ b/tools/testing/selftests/netfilter/Makefile +@@ -7,7 +7,7 @@ TEST_PROGS := nft_trans_stress.sh nft_fib.sh nft_nat.sh bridge_brouter.sh \ + nft_queue.sh nft_meta.sh nf_nat_edemux.sh \ + ipip-conntrack-mtu.sh conntrack_tcp_unreplied.sh \ + conntrack_vrf.sh nft_synproxy.sh rpath.sh nft_audit.sh \ +- conntrack_sctp_collision.sh ++ conntrack_sctp_collision.sh xt_string.sh + + HOSTPKG_CONFIG := pkg-config + +diff --git a/tools/testing/selftests/netfilter/xt_string.sh b/tools/testing/selftests/netfilter/xt_string.sh +new file mode 100755 +index 0000000000000..1802653a47287 +--- /dev/null ++++ b/tools/testing/selftests/netfilter/xt_string.sh +@@ -0,0 +1,128 @@ ++#!/bin/bash ++# SPDX-License-Identifier: GPL-2.0 ++ ++# return code to signal skipped test ++ksft_skip=4 ++rc=0 ++ ++if ! iptables --version >/dev/null 2>&1; then ++ echo "SKIP: Test needs iptables" ++ exit $ksft_skip ++fi ++if ! ip -V >/dev/null 2>&1; then ++ echo "SKIP: Test needs iproute2" ++ exit $ksft_skip ++fi ++if ! nc -h >/dev/null 2>&1; then ++ echo "SKIP: Test needs netcat" ++ exit $ksft_skip ++fi ++ ++pattern="foo bar baz" ++patlen=11 ++hdrlen=$((20 + 8)) # IPv4 + UDP ++ns="ns-$(mktemp -u XXXXXXXX)" ++trap 'ip netns del $ns' EXIT ++ip netns add "$ns" ++ip -net "$ns" link add d0 type dummy ++ip -net "$ns" link set d0 up ++ip -net "$ns" addr add 10.1.2.1/24 dev d0 ++ ++#ip netns exec "$ns" tcpdump -npXi d0 & ++#tcpdump_pid=$! ++#trap 'kill $tcpdump_pid; ip netns del $ns' EXIT ++ ++add_rule() { # (alg, from, to) ++ ip netns exec "$ns" \ ++ iptables -A OUTPUT -o d0 -m string \ ++ --string "$pattern" --algo $1 --from $2 --to $3 ++} ++showrules() { # () ++ ip netns exec "$ns" iptables -v -S OUTPUT | grep '^-A' ++} ++zerorules() { ++ ip netns exec "$ns" iptables -Z OUTPUT ++} ++countrule() { # (pattern) ++ showrules | grep -c -- "$*" ++} ++send() { # (offset) ++ ( for ((i = 0; i < $1 - $hdrlen; i++)); do ++ printf " " ++ done ++ printf "$pattern" ++ ) | ip netns exec "$ns" nc -w 1 -u 10.1.2.2 27374 ++} ++ ++add_rule bm 1000 1500 ++add_rule bm 1400 1600 ++add_rule kmp 1000 1500 ++add_rule kmp 1400 1600 ++ ++zerorules ++send 0 ++send $((1000 - $patlen)) ++if [ $(countrule -c 0 0) -ne 4 ]; then ++ echo "FAIL: rules match data before --from" ++ showrules ++ ((rc--)) ++fi ++ ++zerorules ++send 1000 ++send $((1400 - $patlen)) ++if [ $(countrule -c 2) -ne 2 ]; then ++ echo "FAIL: only two rules should match at low offset" ++ showrules ++ ((rc--)) ++fi ++ ++zerorules ++send $((1500 - $patlen)) ++if [ $(countrule -c 1) -ne 4 ]; then ++ echo "FAIL: all rules should match at end of packet" ++ showrules ++ ((rc--)) ++fi ++ ++zerorules ++send 1495 ++if [ $(countrule -c 1) -ne 1 ]; then ++ echo "FAIL: only kmp with proper --to should match pattern spanning fragments" ++ showrules ++ ((rc--)) ++fi ++ ++zerorules ++send 1500 ++if [ $(countrule -c 1) -ne 2 ]; then ++ echo "FAIL: two rules should match pattern at start of second fragment" ++ showrules ++ ((rc--)) ++fi ++ ++zerorules ++send $((1600 - $patlen)) ++if [ $(countrule -c 1) -ne 2 ]; then ++ echo "FAIL: two rules should match pattern at end of largest --to" ++ showrules ++ ((rc--)) ++fi ++ ++zerorules ++send $((1600 - $patlen + 1)) ++if [ $(countrule -c 1) -ne 0 ]; then ++ echo "FAIL: no rules should match pattern extending largest --to" ++ showrules ++ ((rc--)) ++fi ++ ++zerorules ++send 1600 ++if [ $(countrule -c 1) -ne 0 ]; then ++ echo "FAIL: no rule should match pattern past largest --to" ++ showrules ++ ((rc--)) ++fi ++ ++exit $rc +-- +2.42.0 + diff --git a/queue-6.6/net-spider_net-use-size_add-in-call-to-struct_size.patch b/queue-6.6/net-spider_net-use-size_add-in-call-to-struct_size.patch new file mode 100644 index 00000000000..850520c29b4 --- /dev/null +++ b/queue-6.6/net-spider_net-use-size_add-in-call-to-struct_size.patch @@ -0,0 +1,40 @@ +From 757314e3fdc7cffdc932f8eb3faa2e0ab83cdd3c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 13:25:36 -0600 +Subject: net: spider_net: Use size_add() in call to struct_size() + +From: Gustavo A. R. Silva + +[ Upstream commit 0201409079b975e46cc40e8bdff4bd61329ee10f ] + +If, for any reason, the open-coded arithmetic causes a wraparound, +the protection that `struct_size()` adds against potential integer +overflows is defeated. Fix this by hardening call to `struct_size()` +with `size_add()`. + +Fixes: 3f1071ec39f7 ("net: spider_net: Use struct_size() helper") +Signed-off-by: Gustavo A. R. Silva +Reviewed-by: Kees Cook +Signed-off-by: Geoff Levand +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/toshiba/spider_net.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/toshiba/spider_net.c b/drivers/net/ethernet/toshiba/spider_net.c +index 50d7eacfec582..87e67121477cb 100644 +--- a/drivers/net/ethernet/toshiba/spider_net.c ++++ b/drivers/net/ethernet/toshiba/spider_net.c +@@ -2332,7 +2332,7 @@ spider_net_alloc_card(void) + struct spider_net_card *card; + + netdev = alloc_etherdev(struct_size(card, darray, +- tx_descriptors + rx_descriptors)); ++ size_add(tx_descriptors, rx_descriptors))); + if (!netdev) + return NULL; + +-- +2.42.0 + diff --git a/queue-6.6/netfilter-nf_tables-drop-pointless-memset-when-dumpi.patch b/queue-6.6/netfilter-nf_tables-drop-pointless-memset-when-dumpi.patch new file mode 100644 index 00000000000..cb1866e7c45 --- /dev/null +++ b/queue-6.6/netfilter-nf_tables-drop-pointless-memset-when-dumpi.patch @@ -0,0 +1,38 @@ +From cc6a71b56069a3afb609ebdd56e177b28d167489 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 21:19:19 +0200 +Subject: netfilter: nf_tables: Drop pointless memset when dumping rules + +From: Phil Sutter + +[ Upstream commit 30fa41a0f6df4c85790cc6499ddc4a926a113bfa ] + +None of the dump callbacks uses netlink_callback::args beyond the first +element, no need to zero the data. + +Fixes: 96518518cc41 ("netfilter: add nftables") +Signed-off-by: Phil Sutter +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 29c651804cb22..3bf428a188ccf 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -3465,10 +3465,6 @@ static int __nf_tables_dump_rules(struct sk_buff *skb, + goto cont_skip; + if (*idx < s_idx) + goto cont; +- if (*idx > s_idx) { +- memset(&cb->args[1], 0, +- sizeof(cb->args) - sizeof(cb->args[0])); +- } + if (prule) + handle = prule->handle; + else +-- +2.42.0 + diff --git a/queue-6.6/nfsd-handle-eopenstale-correctly-in-the-filecache.patch b/queue-6.6/nfsd-handle-eopenstale-correctly-in-the-filecache.patch new file mode 100644 index 00000000000..aa910e0c1d8 --- /dev/null +++ b/queue-6.6/nfsd-handle-eopenstale-correctly-in-the-filecache.patch @@ -0,0 +1,231 @@ +From d5be5e307f0975d2685a29ebd4054b87dfc1b46f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Sep 2023 14:30:27 -0400 +Subject: nfsd: Handle EOPENSTALE correctly in the filecache + +From: Trond Myklebust + +[ Upstream commit d59b3515ab021e010fdc58a8f445ea62dd2f7f4c ] + +The nfsd_open code handles EOPENSTALE correctly, by retrying the call to +fh_verify() and __nfsd_open(). However the filecache just drops the +error on the floor, and immediately returns nfserr_stale to the caller. + +This patch ensures that we propagate the EOPENSTALE code back to +nfsd_file_do_acquire, and that we handle it correctly. + +Fixes: 65294c1f2c5e ("nfsd: add a new struct file caching facility to nfsd") +Signed-off-by: Trond Myklebust +Reviewed-by: Jeff Layton +Message-Id: <20230911183027.11372-1-trond.myklebust@hammerspace.com> +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfsd/filecache.c | 27 +++++++++++++++++++-------- + fs/nfsd/vfs.c | 28 +++++++++++++--------------- + fs/nfsd/vfs.h | 4 ++-- + 3 files changed, 34 insertions(+), 25 deletions(-) + +diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c +index ee9c923192e08..07bf219f9ae48 100644 +--- a/fs/nfsd/filecache.c ++++ b/fs/nfsd/filecache.c +@@ -989,22 +989,21 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + unsigned char need = may_flags & NFSD_FILE_MAY_MASK; + struct net *net = SVC_NET(rqstp); + struct nfsd_file *new, *nf; +- const struct cred *cred; ++ bool stale_retry = true; + bool open_retry = true; + struct inode *inode; + __be32 status; + int ret; + ++retry: + status = fh_verify(rqstp, fhp, S_IFREG, + may_flags|NFSD_MAY_OWNER_OVERRIDE); + if (status != nfs_ok) + return status; + inode = d_inode(fhp->fh_dentry); +- cred = get_current_cred(); + +-retry: + rcu_read_lock(); +- nf = nfsd_file_lookup_locked(net, cred, inode, need, want_gc); ++ nf = nfsd_file_lookup_locked(net, current_cred(), inode, need, want_gc); + rcu_read_unlock(); + + if (nf) { +@@ -1026,7 +1025,7 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + + rcu_read_lock(); + spin_lock(&inode->i_lock); +- nf = nfsd_file_lookup_locked(net, cred, inode, need, want_gc); ++ nf = nfsd_file_lookup_locked(net, current_cred(), inode, need, want_gc); + if (unlikely(nf)) { + spin_unlock(&inode->i_lock); + rcu_read_unlock(); +@@ -1058,6 +1057,7 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + goto construction_err; + } + open_retry = false; ++ fh_put(fhp); + goto retry; + } + this_cpu_inc(nfsd_file_cache_hits); +@@ -1074,7 +1074,6 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + nfsd_file_check_write_error(nf); + *pnf = nf; + } +- put_cred(cred); + trace_nfsd_file_acquire(rqstp, inode, may_flags, nf, status); + return status; + +@@ -1088,8 +1087,20 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, + status = nfs_ok; + trace_nfsd_file_opened(nf, status); + } else { +- status = nfsd_open_verified(rqstp, fhp, may_flags, +- &nf->nf_file); ++ ret = nfsd_open_verified(rqstp, fhp, may_flags, ++ &nf->nf_file); ++ if (ret == -EOPENSTALE && stale_retry) { ++ stale_retry = false; ++ nfsd_file_unhash(nf); ++ clear_and_wake_up_bit(NFSD_FILE_PENDING, ++ &nf->nf_flags); ++ if (refcount_dec_and_test(&nf->nf_ref)) ++ nfsd_file_free(nf); ++ nf = NULL; ++ fh_put(fhp); ++ goto retry; ++ } ++ status = nfserrno(ret); + trace_nfsd_file_open(nf, status); + } + } else +diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c +index 02f5fcaad03f3..b24462efa1781 100644 +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -823,7 +823,7 @@ int nfsd_open_break_lease(struct inode *inode, int access) + * and additional flags. + * N.B. After this call fhp needs an fh_put + */ +-static __be32 ++static int + __nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, + int may_flags, struct file **filp) + { +@@ -831,14 +831,12 @@ __nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, + struct inode *inode; + struct file *file; + int flags = O_RDONLY|O_LARGEFILE; +- __be32 err; +- int host_err = 0; ++ int host_err = -EPERM; + + path.mnt = fhp->fh_export->ex_path.mnt; + path.dentry = fhp->fh_dentry; + inode = d_inode(path.dentry); + +- err = nfserr_perm; + if (IS_APPEND(inode) && (may_flags & NFSD_MAY_WRITE)) + goto out; + +@@ -847,7 +845,7 @@ __nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, + + host_err = nfsd_open_break_lease(inode, may_flags); + if (host_err) /* NOMEM or WOULDBLOCK */ +- goto out_nfserr; ++ goto out; + + if (may_flags & NFSD_MAY_WRITE) { + if (may_flags & NFSD_MAY_READ) +@@ -859,13 +857,13 @@ __nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, + file = dentry_open(&path, flags, current_cred()); + if (IS_ERR(file)) { + host_err = PTR_ERR(file); +- goto out_nfserr; ++ goto out; + } + + host_err = ima_file_check(file, may_flags); + if (host_err) { + fput(file); +- goto out_nfserr; ++ goto out; + } + + if (may_flags & NFSD_MAY_64BIT_COOKIE) +@@ -874,10 +872,8 @@ __nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, + file->f_mode |= FMODE_32BITHASH; + + *filp = file; +-out_nfserr: +- err = nfserrno(host_err); + out: +- return err; ++ return host_err; + } + + __be32 +@@ -885,6 +881,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, + int may_flags, struct file **filp) + { + __be32 err; ++ int host_err; + bool retried = false; + + validate_process_creds(); +@@ -904,12 +901,13 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, + retry: + err = fh_verify(rqstp, fhp, type, may_flags); + if (!err) { +- err = __nfsd_open(rqstp, fhp, type, may_flags, filp); +- if (err == nfserr_stale && !retried) { ++ host_err = __nfsd_open(rqstp, fhp, type, may_flags, filp); ++ if (host_err == -EOPENSTALE && !retried) { + retried = true; + fh_put(fhp); + goto retry; + } ++ err = nfserrno(host_err); + } + validate_process_creds(); + return err; +@@ -922,13 +920,13 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, + * @may_flags: internal permission flags + * @filp: OUT: open "struct file *" + * +- * Returns an nfsstat value in network byte order. ++ * Returns zero on success, or a negative errno value. + */ +-__be32 ++int + nfsd_open_verified(struct svc_rqst *rqstp, struct svc_fh *fhp, int may_flags, + struct file **filp) + { +- __be32 err; ++ int err; + + validate_process_creds(); + err = __nfsd_open(rqstp, fhp, S_IFREG, may_flags, filp); +diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h +index a6890ea7b765b..e3c29596f4df1 100644 +--- a/fs/nfsd/vfs.h ++++ b/fs/nfsd/vfs.h +@@ -104,8 +104,8 @@ __be32 nfsd_setxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, + int nfsd_open_break_lease(struct inode *, int); + __be32 nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t, + int, struct file **); +-__be32 nfsd_open_verified(struct svc_rqst *, struct svc_fh *, +- int, struct file **); ++int nfsd_open_verified(struct svc_rqst *rqstp, struct svc_fh *fhp, ++ int may_flags, struct file **filp); + __be32 nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp, + struct file *file, loff_t offset, + unsigned long *count, +-- +2.42.0 + diff --git a/queue-6.6/numa-generalize-numa_map_to_online_node.patch b/queue-6.6/numa-generalize-numa_map_to_online_node.patch new file mode 100644 index 00000000000..e5d11f3d300 --- /dev/null +++ b/queue-6.6/numa-generalize-numa_map_to_online_node.patch @@ -0,0 +1,111 @@ +From 89946fe842e673407ad1b9230aacfa3786ada326 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 19 Aug 2023 07:12:33 -0700 +Subject: numa: Generalize numa_map_to_online_node() + +From: Yury Norov + +[ Upstream commit b1f099b1cf51d553c510c6c8141c27d9ba7ea1fe ] + +The function in fact searches the nearest node for a given one, +based on a N_ONLINE state. This is a common pattern to search +for a nearest node. + +This patch converts numa_map_to_online_node() to numa_nearest_node() +so that others won't need to opencode the logic. + +Signed-off-by: Yury Norov +Signed-off-by: Ingo Molnar +Cc: Mel Gorman +Link: https://lore.kernel.org/r/20230819141239.287290-2-yury.norov@gmail.com +Stable-dep-of: 617f2c38cb5c ("sched/topology: Fix sched_numa_find_nth_cpu() in CPU-less case") +Signed-off-by: Sasha Levin +--- + include/linux/numa.h | 7 +++++-- + mm/mempolicy.c | 18 +++++++++++------- + 2 files changed, 16 insertions(+), 9 deletions(-) + +diff --git a/include/linux/numa.h b/include/linux/numa.h +index 59df211d051fa..fb30a42f0700d 100644 +--- a/include/linux/numa.h ++++ b/include/linux/numa.h +@@ -25,7 +25,7 @@ + #include + + /* Generic implementation available */ +-int numa_map_to_online_node(int node); ++int numa_nearest_node(int node, unsigned int state); + + #ifndef memory_add_physaddr_to_nid + static inline int memory_add_physaddr_to_nid(u64 start) +@@ -44,10 +44,11 @@ static inline int phys_to_target_node(u64 start) + } + #endif + #else /* !CONFIG_NUMA */ +-static inline int numa_map_to_online_node(int node) ++static inline int numa_nearest_node(int node, unsigned int state) + { + return NUMA_NO_NODE; + } ++ + static inline int memory_add_physaddr_to_nid(u64 start) + { + return 0; +@@ -58,6 +59,8 @@ static inline int phys_to_target_node(u64 start) + } + #endif + ++#define numa_map_to_online_node(node) numa_nearest_node(node, N_ONLINE) ++ + #ifdef CONFIG_HAVE_ARCH_NODE_DEV_GROUP + extern const struct attribute_group arch_node_dev_group; + #endif +diff --git a/mm/mempolicy.c b/mm/mempolicy.c +index 29ebf1e7898cf..e52e3a0b8f2e6 100644 +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -131,22 +131,26 @@ static struct mempolicy default_policy = { + static struct mempolicy preferred_node_policy[MAX_NUMNODES]; + + /** +- * numa_map_to_online_node - Find closest online node ++ * numa_nearest_node - Find nearest node by state + * @node: Node id to start the search ++ * @state: State to filter the search + * +- * Lookup the next closest node by distance if @nid is not online. ++ * Lookup the closest node by distance if @nid is not in state. + * +- * Return: this @node if it is online, otherwise the closest node by distance ++ * Return: this @node if it is in state, otherwise the closest node by distance + */ +-int numa_map_to_online_node(int node) ++int numa_nearest_node(int node, unsigned int state) + { + int min_dist = INT_MAX, dist, n, min_node; + +- if (node == NUMA_NO_NODE || node_online(node)) ++ if (state >= NR_NODE_STATES) ++ return -EINVAL; ++ ++ if (node == NUMA_NO_NODE || node_state(node, state)) + return node; + + min_node = node; +- for_each_online_node(n) { ++ for_each_node_state(n, state) { + dist = node_distance(node, n); + if (dist < min_dist) { + min_dist = dist; +@@ -156,7 +160,7 @@ int numa_map_to_online_node(int node) + + return min_node; + } +-EXPORT_SYMBOL_GPL(numa_map_to_online_node); ++EXPORT_SYMBOL_GPL(numa_nearest_node); + + struct mempolicy *get_task_policy(struct task_struct *p) + { +-- +2.42.0 + diff --git a/queue-6.6/objtool-propagate-early-errors.patch b/queue-6.6/objtool-propagate-early-errors.patch new file mode 100644 index 00000000000..e646f60cdb8 --- /dev/null +++ b/queue-6.6/objtool-propagate-early-errors.patch @@ -0,0 +1,41 @@ +From d810d0762c86963c18e4e6d7463482c647c36a6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 17:08:18 -0700 +Subject: objtool: Propagate early errors + +From: Aaron Plattner + +[ Upstream commit e959c279d391c10b35ce300fb4b0fe3b98e86bd2 ] + +If objtool runs into a problem that causes it to exit early, the overall +tool still returns a status code of 0, which causes the build to +continue as if nothing went wrong. + +Note this only affects early errors, as later errors are still ignored +by check(). + +Fixes: b51277eb9775 ("objtool: Ditch subcommands") +Signed-off-by: Aaron Plattner +Link: https://lore.kernel.org/r/cb6a28832d24b2ebfafd26da9abb95f874c83045.1696355111.git.aplattner@nvidia.com +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/objtool.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c +index c54f7235c5d94..f40febdd6e36a 100644 +--- a/tools/objtool/objtool.c ++++ b/tools/objtool/objtool.c +@@ -146,7 +146,5 @@ int main(int argc, const char **argv) + exec_cmd_init("objtool", UNUSED, UNUSED, UNUSED); + pager_init(UNUSED); + +- objtool_run(argc, argv); +- +- return 0; ++ return objtool_run(argc, argv); + } +-- +2.42.0 + diff --git a/queue-6.6/padata-fix-refcnt-handling-in-padata_free_shell.patch b/queue-6.6/padata-fix-refcnt-handling-in-padata_free_shell.patch new file mode 100644 index 00000000000..9e24843f8e6 --- /dev/null +++ b/queue-6.6/padata-fix-refcnt-handling-in-padata_free_shell.patch @@ -0,0 +1,110 @@ +From c1f9bd54131b754cf3d7b25ef204c4a82add994b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Oct 2023 09:15:21 +0800 +Subject: padata: Fix refcnt handling in padata_free_shell() + +From: WangJinchao + +[ Upstream commit 7ddc21e317b360c3444de3023bcc83b85fabae2f ] + +In a high-load arm64 environment, the pcrypt_aead01 test in LTP can lead +to system UAF (Use-After-Free) issues. Due to the lengthy analysis of +the pcrypt_aead01 function call, I'll describe the problem scenario +using a simplified model: + +Suppose there's a user of padata named `user_function` that adheres to +the padata requirement of calling `padata_free_shell` after `serial()` +has been invoked, as demonstrated in the following code: + +```c +struct request { + struct padata_priv padata; + struct completion *done; +}; + +void parallel(struct padata_priv *padata) { + do_something(); +} + +void serial(struct padata_priv *padata) { + struct request *request = container_of(padata, + struct request, + padata); + complete(request->done); +} + +void user_function() { + DECLARE_COMPLETION(done) + padata->parallel = parallel; + padata->serial = serial; + padata_do_parallel(); + wait_for_completion(&done); + padata_free_shell(); +} +``` + +In the corresponding padata.c file, there's the following code: + +```c +static void padata_serial_worker(struct work_struct *serial_work) { + ... + cnt = 0; + + while (!list_empty(&local_list)) { + ... + padata->serial(padata); + cnt++; + } + + local_bh_enable(); + + if (refcount_sub_and_test(cnt, &pd->refcnt)) + padata_free_pd(pd); +} +``` + +Because of the high system load and the accumulation of unexecuted +softirq at this moment, `local_bh_enable()` in padata takes longer +to execute than usual. Subsequently, when accessing `pd->refcnt`, +`pd` has already been released by `padata_free_shell()`, resulting +in a UAF issue with `pd->refcnt`. + +The fix is straightforward: add `refcount_dec_and_test` before calling +`padata_free_pd` in `padata_free_shell`. + +Fixes: 07928d9bfc81 ("padata: Remove broken queue flushing") + +Signed-off-by: WangJinchao +Acked-by: Daniel Jordan +Acked-by: Daniel Jordan +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + kernel/padata.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/kernel/padata.c b/kernel/padata.c +index 222d60195de66..ff349e1084c1d 100644 +--- a/kernel/padata.c ++++ b/kernel/padata.c +@@ -1102,12 +1102,16 @@ EXPORT_SYMBOL(padata_alloc_shell); + */ + void padata_free_shell(struct padata_shell *ps) + { ++ struct parallel_data *pd; ++ + if (!ps) + return; + + mutex_lock(&ps->pinst->lock); + list_del(&ps->list); +- padata_free_pd(rcu_dereference_protected(ps->pd, 1)); ++ pd = rcu_dereference_protected(ps->pd, 1); ++ if (refcount_dec_and_test(&pd->refcnt)) ++ padata_free_pd(pd); + mutex_unlock(&ps->pinst->lock); + + kfree(ps); +-- +2.42.0 + diff --git a/queue-6.6/pci-endpoint-fix-double-free-in-__pci_epc_create.patch b/queue-6.6/pci-endpoint-fix-double-free-in-__pci_epc_create.patch new file mode 100644 index 00000000000..ea025b20462 --- /dev/null +++ b/queue-6.6/pci-endpoint-fix-double-free-in-__pci_epc_create.patch @@ -0,0 +1,37 @@ +From 3f3e3061b8941d3e5ff6713875dde725372619f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 14:57:23 +0300 +Subject: PCI: endpoint: Fix double free in __pci_epc_create() + +From: Dan Carpenter + +[ Upstream commit c9501d268944d6c0475ecb3e740a084a7da9cbfe ] + +The pci_epc_release() function frees "epc" so the kfree() on the next line +is a double free. Drop the redundant free. + +Fixes: 7711cbb4862a ("PCI: endpoint: Fix WARN() when an endpoint driver is removed") +Link: https://lore.kernel.org/r/2ce68694-87a7-4c06-b8a4-9870c891b580@moroto.mountain +Signed-off-by: Dan Carpenter +Signed-off-by: Bjorn Helgaas +Reviewed-by: Manivannan Sadhasivam +Signed-off-by: Sasha Levin +--- + drivers/pci/endpoint/pci-epc-core.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c +index 5a4a8b0be6262..a7d3a92391a41 100644 +--- a/drivers/pci/endpoint/pci-epc-core.c ++++ b/drivers/pci/endpoint/pci-epc-core.c +@@ -869,7 +869,6 @@ __pci_epc_create(struct device *dev, const struct pci_epc_ops *ops, + + put_dev: + put_device(&epc->dev); +- kfree(epc); + + err_ret: + return ERR_PTR(ret); +-- +2.42.0 + diff --git a/queue-6.6/pci-msi-provide-stubs-for-ims-functions.patch b/queue-6.6/pci-msi-provide-stubs-for-ims-functions.patch new file mode 100644 index 00000000000..7b54d19f101 --- /dev/null +++ b/queue-6.6/pci-msi-provide-stubs-for-ims-functions.patch @@ -0,0 +1,94 @@ +From 7230f571c98ea4db87117d59883a05eae7cb3e8e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 10:56:38 -0700 +Subject: PCI/MSI: Provide stubs for IMS functions + +From: Reinette Chatre + +[ Upstream commit 41efa431244f6498833ff8ee8dde28c4924c5479 ] + +The IMS related functions (pci_create_ims_domain(), pci_ims_alloc_irq(), +and pci_ims_free_irq()) are not declared when CONFIG_PCI_MSI is disabled. + +Provide definitions of these functions for use when callers are compiled +with CONFIG_PCI_MSI disabled. + +Fixes: 0194425af0c8 ("PCI/MSI: Provide IMS (Interrupt Message Store) support") +Fixes: c9e5bea27383 ("PCI/MSI: Provide pci_ims_alloc/free_irq()") +Signed-off-by: Reinette Chatre +Signed-off-by: Thomas Gleixner +Link: https://lore.kernel.org/r/14ff656899a3757453f8584c1109d7a9b98fa258.1697564731.git.reinette.chatre@intel.com +Signed-off-by: Sasha Levin +--- + include/linux/pci.h | 34 ++++++++++++++++++++++++++-------- + 1 file changed, 26 insertions(+), 8 deletions(-) + +diff --git a/include/linux/pci.h b/include/linux/pci.h +index 8c7c2c3c6c652..b56417276042d 100644 +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -1624,6 +1624,8 @@ struct msix_entry { + u16 entry; /* Driver uses to specify entry, OS writes */ + }; + ++struct msi_domain_template; ++ + #ifdef CONFIG_PCI_MSI + int pci_msi_vec_count(struct pci_dev *dev); + void pci_disable_msi(struct pci_dev *dev); +@@ -1656,6 +1658,11 @@ void pci_msix_free_irq(struct pci_dev *pdev, struct msi_map map); + void pci_free_irq_vectors(struct pci_dev *dev); + int pci_irq_vector(struct pci_dev *dev, unsigned int nr); + const struct cpumask *pci_irq_get_affinity(struct pci_dev *pdev, int vec); ++bool pci_create_ims_domain(struct pci_dev *pdev, const struct msi_domain_template *template, ++ unsigned int hwsize, void *data); ++struct msi_map pci_ims_alloc_irq(struct pci_dev *pdev, union msi_instance_cookie *icookie, ++ const struct irq_affinity_desc *affdesc); ++void pci_ims_free_irq(struct pci_dev *pdev, struct msi_map map); + + #else + static inline int pci_msi_vec_count(struct pci_dev *dev) { return -ENOSYS; } +@@ -1719,6 +1726,25 @@ static inline const struct cpumask *pci_irq_get_affinity(struct pci_dev *pdev, + { + return cpu_possible_mask; + } ++ ++static inline bool pci_create_ims_domain(struct pci_dev *pdev, ++ const struct msi_domain_template *template, ++ unsigned int hwsize, void *data) ++{ return false; } ++ ++static inline struct msi_map pci_ims_alloc_irq(struct pci_dev *pdev, ++ union msi_instance_cookie *icookie, ++ const struct irq_affinity_desc *affdesc) ++{ ++ struct msi_map map = { .index = -ENOSYS, }; ++ ++ return map; ++} ++ ++static inline void pci_ims_free_irq(struct pci_dev *pdev, struct msi_map map) ++{ ++} ++ + #endif + + /** +@@ -2616,14 +2642,6 @@ static inline bool pci_is_thunderbolt_attached(struct pci_dev *pdev) + void pci_uevent_ers(struct pci_dev *pdev, enum pci_ers_result err_type); + #endif + +-struct msi_domain_template; +- +-bool pci_create_ims_domain(struct pci_dev *pdev, const struct msi_domain_template *template, +- unsigned int hwsize, void *data); +-struct msi_map pci_ims_alloc_irq(struct pci_dev *pdev, union msi_instance_cookie *icookie, +- const struct irq_affinity_desc *affdesc); +-void pci_ims_free_irq(struct pci_dev *pdev, struct msi_map map); +- + #include + + #define pci_printk(level, pdev, fmt, arg...) \ +-- +2.42.0 + diff --git a/queue-6.6/pci-vmd-correct-pci-header-type-register-s-multi-fun.patch b/queue-6.6/pci-vmd-correct-pci-header-type-register-s-multi-fun.patch new file mode 100644 index 00000000000..3bfbc83d737 --- /dev/null +++ b/queue-6.6/pci-vmd-correct-pci-header-type-register-s-multi-fun.patch @@ -0,0 +1,46 @@ +From c9eae9ade53c1be17707278f21149ece663ecd04 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Oct 2023 15:52:58 +0300 +Subject: PCI: vmd: Correct PCI Header Type Register's multi-function check +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit 5827e17d0555b566c32044b0632b46f9f95054fa ] + +vmd_domain_reset() attempts to find whether the device may contain multiple +functions by checking 0x80 (Multi-Function Device), however, the hdr_type +variable has already been masked with PCI_HEADER_TYPE_MASK so the check can +never true. + +To fix the issue, don't mask the read with PCI_HEADER_TYPE_MASK. + +Fixes: 6aab5622296b ("PCI: vmd: Clean up domain before enumeration") +Link: https://lore.kernel.org/r/20231003125300.5541-2-ilpo.jarvinen@linux.intel.com +Signed-off-by: Ilpo Järvinen +Signed-off-by: Bjorn Helgaas +Cc: Nirmal Patel +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/vmd.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c +index ad56df98b8e63..1c1c1aa940a51 100644 +--- a/drivers/pci/controller/vmd.c ++++ b/drivers/pci/controller/vmd.c +@@ -525,8 +525,7 @@ static void vmd_domain_reset(struct vmd_dev *vmd) + base = vmd->cfgbar + PCIE_ECAM_OFFSET(bus, + PCI_DEVFN(dev, 0), 0); + +- hdr_type = readb(base + PCI_HEADER_TYPE) & +- PCI_HEADER_TYPE_MASK; ++ hdr_type = readb(base + PCI_HEADER_TYPE); + + functions = (hdr_type & 0x80) ? 8 : 1; + for (fn = 0; fn < functions; fn++) { +-- +2.42.0 + diff --git a/queue-6.6/pcmcia-cs-fix-possible-hung-task-and-memory-leak-pcc.patch b/queue-6.6/pcmcia-cs-fix-possible-hung-task-and-memory-leak-pcc.patch new file mode 100644 index 00000000000..61f36a3a530 --- /dev/null +++ b/queue-6.6/pcmcia-cs-fix-possible-hung-task-and-memory-leak-pcc.patch @@ -0,0 +1,43 @@ +From d91c0b269dd703b8de836bd84d229b2c1f065aee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Nov 2022 17:25:41 +0800 +Subject: pcmcia: cs: fix possible hung task and memory leak pccardd() + +From: Yang Yingliang + +[ Upstream commit e3ea1b4847e49234e691c0d66bf030bd65bb7f2b ] + +If device_register() returns error in pccardd(), it leads two issues: + +1. The socket_released has never been completed, it will block + pcmcia_unregister_socket(), because of waiting for completion + of socket_released. +2. The device name allocated by dev_set_name() is leaked. + +Fix this two issues by calling put_device() when device_register() fails. +socket_released can be completed in pcmcia_release_socket(), the name can +be freed in kobject_cleanup(). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Yang Yingliang +Signed-off-by: Dominik Brodowski +Signed-off-by: Sasha Levin +--- + drivers/pcmcia/cs.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c +index 5658745c398f5..b33be1e63c98f 100644 +--- a/drivers/pcmcia/cs.c ++++ b/drivers/pcmcia/cs.c +@@ -605,6 +605,7 @@ static int pccardd(void *__skt) + dev_warn(&skt->dev, "PCMCIA: unable to register socket\n"); + skt->thread = NULL; + complete(&skt->thread_done); ++ put_device(&skt->dev); + return 0; + } + ret = pccard_sysfs_add_socket(&skt->dev); +-- +2.42.0 + diff --git a/queue-6.6/pcmcia-ds-fix-possible-name-leak-in-error-path-in-pc.patch b/queue-6.6/pcmcia-ds-fix-possible-name-leak-in-error-path-in-pc.patch new file mode 100644 index 00000000000..559292385ba --- /dev/null +++ b/queue-6.6/pcmcia-ds-fix-possible-name-leak-in-error-path-in-pc.patch @@ -0,0 +1,53 @@ +From 7e89408d53a279a319bfddecae6159c4b08efc8e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Nov 2022 17:29:24 +0800 +Subject: pcmcia: ds: fix possible name leak in error path in + pcmcia_device_add() + +From: Yang Yingliang + +[ Upstream commit 99e1241049a92dd3e9a90a0f91e32ce390133278 ] + +Afer commit 1fa5ae857bb1 ("driver core: get rid of struct device's +bus_id string array"), the name of device is allocated dynamically. +Therefore, it needs to be freed, which is done by the driver core for +us once all references to the device are gone. Therefore, move the +dev_set_name() call immediately before the call device_register(), which +either succeeds (then the freeing will be done upon subsequent remvoal), +or puts the reference in the error call. Also, it is not unusual that the +return value of dev_set_name is not checked. + +Fixes: 1fa5ae857bb1 ("driver core: get rid of struct device's bus_id string array") +Signed-off-by: Yang Yingliang +[linux@dominikbrodowski.net: simplification, commit message modified] +Signed-off-by: Dominik Brodowski +Signed-off-by: Sasha Levin +--- + drivers/pcmcia/ds.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c +index c90c68dee1e45..b4b8363d1de21 100644 +--- a/drivers/pcmcia/ds.c ++++ b/drivers/pcmcia/ds.c +@@ -513,9 +513,6 @@ static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, + /* by default don't allow DMA */ + p_dev->dma_mask = 0; + p_dev->dev.dma_mask = &p_dev->dma_mask; +- dev_set_name(&p_dev->dev, "%d.%d", p_dev->socket->sock, p_dev->device_no); +- if (!dev_name(&p_dev->dev)) +- goto err_free; + p_dev->devname = kasprintf(GFP_KERNEL, "pcmcia%s", dev_name(&p_dev->dev)); + if (!p_dev->devname) + goto err_free; +@@ -573,6 +570,7 @@ static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, + + pcmcia_device_query(p_dev); + ++ dev_set_name(&p_dev->dev, "%d.%d", p_dev->socket->sock, p_dev->device_no); + if (device_register(&p_dev->dev)) { + mutex_lock(&s->ops_mutex); + list_del(&p_dev->socket_device_list); +-- +2.42.0 + diff --git a/queue-6.6/pcmcia-ds-fix-refcount-leak-in-pcmcia_device_add.patch b/queue-6.6/pcmcia-ds-fix-refcount-leak-in-pcmcia_device_add.patch new file mode 100644 index 00000000000..666775f32ad --- /dev/null +++ b/queue-6.6/pcmcia-ds-fix-refcount-leak-in-pcmcia_device_add.patch @@ -0,0 +1,49 @@ +From e018a473af3a62eca7421165f5b49555252659b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Nov 2022 17:29:23 +0800 +Subject: pcmcia: ds: fix refcount leak in pcmcia_device_add() + +From: Yang Yingliang + +[ Upstream commit 402ab979b29126068e0b596b641422ff7490214c ] + +As the comment of device_register() says, it should use put_device() +to give up the reference in the error path. Then, insofar resources +will be freed in pcmcia_release_dev(), the error path is no longer +needed. In particular, this means that the (previously missing) dropping +of the reference to &p_dev->function_config->ref is now handled by +pcmcia_release_dev(). + +Fixes: 360b65b95bae ("[PATCH] pcmcia: make config_t independent, add reference counting") +Signed-off-by: Yang Yingliang +[linux@dominikbrodowski.net: simplification, commit message rewrite] +Signed-off-by: Dominik Brodowski +Signed-off-by: Sasha Levin +--- + drivers/pcmcia/ds.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c +index d500e5dbbc3f5..c90c68dee1e45 100644 +--- a/drivers/pcmcia/ds.c ++++ b/drivers/pcmcia/ds.c +@@ -573,8 +573,14 @@ static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, + + pcmcia_device_query(p_dev); + +- if (device_register(&p_dev->dev)) +- goto err_unreg; ++ if (device_register(&p_dev->dev)) { ++ mutex_lock(&s->ops_mutex); ++ list_del(&p_dev->socket_device_list); ++ s->device_count--; ++ mutex_unlock(&s->ops_mutex); ++ put_device(&p_dev->dev); ++ return NULL; ++ } + + return p_dev; + +-- +2.42.0 + diff --git a/queue-6.6/perf-arm-cmn-fix-dtc-domain-detection.patch b/queue-6.6/perf-arm-cmn-fix-dtc-domain-detection.patch new file mode 100644 index 00000000000..1cc3d75d626 --- /dev/null +++ b/queue-6.6/perf-arm-cmn-fix-dtc-domain-detection.patch @@ -0,0 +1,68 @@ +From fd5601211c170de8ae4aa49e1e4d272b6026ef65 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 18:51:25 +0100 +Subject: perf/arm-cmn: Fix DTC domain detection + +From: Robin Murphy + +[ Upstream commit e3e73f511c49c741f6309862c2248958ad77bbaa ] + +It transpires that dtm_unit_info is another register which got shuffled +in CMN-700 without me noticing. Fix that in a way which also proactively +fixes the fragile laziness of its consumer, just in case any further +fields ever get added alongside dtc_domain. + +Fixes: 23760a014417 ("perf/arm-cmn: Add CMN-700 support") +Signed-off-by: Robin Murphy +Reviewed-by: Ilkka Koskinen +Link: https://lore.kernel.org/r/3076ee83d0554f6939fbb6ee49ab2bdb28d8c7ee.1697824215.git.robin.murphy@arm.com +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + drivers/perf/arm-cmn.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c +index 6b50bc5519846..caae2d3e9d3ea 100644 +--- a/drivers/perf/arm-cmn.c ++++ b/drivers/perf/arm-cmn.c +@@ -112,7 +112,9 @@ + + #define CMN_DTM_PMEVCNTSR 0x240 + +-#define CMN_DTM_UNIT_INFO 0x0910 ++#define CMN650_DTM_UNIT_INFO 0x0910 ++#define CMN_DTM_UNIT_INFO 0x0960 ++#define CMN_DTM_UNIT_INFO_DTC_DOMAIN GENMASK_ULL(1, 0) + + #define CMN_DTM_NUM_COUNTERS 4 + /* Want more local counters? Why not replicate the whole DTM! Ugh... */ +@@ -2117,6 +2119,16 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn) + return 0; + } + ++static unsigned int arm_cmn_dtc_domain(struct arm_cmn *cmn, void __iomem *xp_region) ++{ ++ int offset = CMN_DTM_UNIT_INFO; ++ ++ if (cmn->part == PART_CMN650 || cmn->part == PART_CI700) ++ offset = CMN650_DTM_UNIT_INFO; ++ ++ return FIELD_GET(CMN_DTM_UNIT_INFO_DTC_DOMAIN, readl_relaxed(xp_region + offset)); ++} ++ + static void arm_cmn_init_node_info(struct arm_cmn *cmn, u32 offset, struct arm_cmn_node *node) + { + int level; +@@ -2248,7 +2260,7 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) + if (cmn->part == PART_CMN600) + xp->dtc = 0xf; + else +- xp->dtc = 1 << readl_relaxed(xp_region + CMN_DTM_UNIT_INFO); ++ xp->dtc = 1 << arm_cmn_dtc_domain(cmn, xp_region); + + xp->dtm = dtm - cmn->dtms; + arm_cmn_init_dtm(dtm++, xp, 0); +-- +2.42.0 + diff --git a/queue-6.6/perf-build-add-missing-comment-about-no_libtraceeven.patch b/queue-6.6/perf-build-add-missing-comment-about-no_libtraceeven.patch new file mode 100644 index 00000000000..e348082fb35 --- /dev/null +++ b/queue-6.6/perf-build-add-missing-comment-about-no_libtraceeven.patch @@ -0,0 +1,47 @@ +From 2ca4fd9f8794f44d3e48974606508c35a9709a79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Oct 2023 10:46:26 -0300 +Subject: perf build: Add missing comment about NO_LIBTRACEEVENT=1 + +From: Arnaldo Carvalho de Melo + +[ Upstream commit c1783ddfb62420c44cdf4672dad2046f056c624b ] + +By default perf will fail the build if the development files for +libtraceevent are not available. + +To build perf without libtraceevent support, disabling several features +such as 'perf trace', one needs to add NO_LIBTRACEVENT=1 to the make +command line. + +Add the missing comments about that to the tools/perf/Makefile.perf +file, just like all the other such command line toggles. + +Fixes: 378ef0f5d9d7f465 ("perf build: Use libtraceevent from the system") +Signed-off-by: Arnaldo Carvalho de Melo +Reviewed-by: Ian Rogers +Link: https://lore.kernel.org/r/ZR6+MhXtLnv6ow6E@kernel.org +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/Makefile.perf | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf +index 37af6df7b978d..86569f230e60d 100644 +--- a/tools/perf/Makefile.perf ++++ b/tools/perf/Makefile.perf +@@ -69,6 +69,10 @@ include ../scripts/utilities.mak + # Define NO_LIBDW_DWARF_UNWIND if you do not want libdw support + # for dwarf backtrace post unwind. + # ++# Define NO_LIBTRACEEVENT=1 if you don't want libtraceevent to be linked, ++# this will remove multiple features and tools, such as 'perf trace', ++# that need it to read tracefs event format files, etc. ++# + # Define NO_PERF_READ_VDSO32 if you do not want to build perf-read-vdso32 + # for reading the 32-bit compatibility VDSO in 64-bit mode + # +-- +2.42.0 + diff --git a/queue-6.6/perf-hisi-fix-use-after-free-when-register-pmu-fails.patch b/queue-6.6/perf-hisi-fix-use-after-free-when-register-pmu-fails.patch new file mode 100644 index 00000000000..7b9d0070ca5 --- /dev/null +++ b/queue-6.6/perf-hisi-fix-use-after-free-when-register-pmu-fails.patch @@ -0,0 +1,62 @@ +From bb4ccdd9f33a5021b733a6f534d26283542f5846 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Oct 2023 19:36:30 +0800 +Subject: perf: hisi: Fix use-after-free when register pmu fails + +From: Junhao He + +[ Upstream commit b805cafc604bfdb671fae7347a57f51154afa735 ] + +When we fail to register the uncore pmu, the pmu context may not been +allocated. The error handing will call cpuhp_state_remove_instance() +to call uncore pmu offline callback, which migrate the pmu context. +Since that's liable to lead to some kind of use-after-free. + +Use cpuhp_state_remove_instance_nocalls() instead of +cpuhp_state_remove_instance() so that the notifiers don't execute after +the PMU device has been failed to register. + +Fixes: a0ab25cd82ee ("drivers/perf: hisi: Add support for HiSilicon PA PMU driver") +FIxes: 3bf30882c3c7 ("drivers/perf: hisi: Add support for HiSilicon SLLC PMU driver") +Signed-off-by: Junhao He +Link: https://lore.kernel.org/r/20231024113630.13472-1-hejunhao3@huawei.com +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + drivers/perf/hisilicon/hisi_uncore_pa_pmu.c | 4 ++-- + drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c +index d941e746b4248..797cf201996a9 100644 +--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c ++++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c +@@ -505,8 +505,8 @@ static int hisi_pa_pmu_probe(struct platform_device *pdev) + ret = perf_pmu_register(&pa_pmu->pmu, name, -1); + if (ret) { + dev_err(pa_pmu->dev, "PMU register failed, ret = %d\n", ret); +- cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE, +- &pa_pmu->node); ++ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE, ++ &pa_pmu->node); + return ret; + } + +diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c +index 6fe534a665eda..e706ca5676764 100644 +--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c ++++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c +@@ -450,8 +450,8 @@ static int hisi_sllc_pmu_probe(struct platform_device *pdev) + ret = perf_pmu_register(&sllc_pmu->pmu, name, -1); + if (ret) { + dev_err(sllc_pmu->dev, "PMU register failed, ret = %d\n", ret); +- cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE, +- &sllc_pmu->node); ++ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE, ++ &sllc_pmu->node); + return ret; + } + +-- +2.42.0 + diff --git a/queue-6.6/perf-hist-add-missing-puts-to-hist__account_cycles.patch b/queue-6.6/perf-hist-add-missing-puts-to-hist__account_cycles.patch new file mode 100644 index 00000000000..7c8238768c1 --- /dev/null +++ b/queue-6.6/perf-hist-add-missing-puts-to-hist__account_cycles.patch @@ -0,0 +1,81 @@ +From 289410ba1a3a5f0c260c2886ca68901a4cc77395 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Oct 2023 15:23:08 -0700 +Subject: perf hist: Add missing puts to hist__account_cycles + +From: Ian Rogers + +[ Upstream commit c1149037f65bcf0334886180ebe3d5efcf214912 ] + +Caught using reference count checking on perf top with +"--call-graph=lbr". After this no memory leaks were detected. + +Fixes: 57849998e2cd ("perf report: Add processing for cycle histograms") +Signed-off-by: Ian Rogers +Cc: K Prateek Nayak +Cc: Ravi Bangoria +Cc: Sandipan Das +Cc: Anshuman Khandual +Cc: German Gomez +Cc: James Clark +Cc: Nick Terrell +Cc: Sean Christopherson +Cc: Changbin Du +Cc: liuwenyu +Cc: Yang Jihong +Cc: Masami Hiramatsu +Cc: Miguel Ojeda +Cc: Song Liu +Cc: Leo Yan +Cc: Kajol Jain +Cc: Andi Kleen +Cc: Kan Liang +Cc: Athira Rajeev +Cc: Yanteng Si +Cc: Liam Howlett +Cc: Paolo Bonzini +Link: https://lore.kernel.org/r/20231024222353.3024098-6-irogers@google.com +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/hist.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c +index 3dc8a4968beb9..ac8c0ef48a7f3 100644 +--- a/tools/perf/util/hist.c ++++ b/tools/perf/util/hist.c +@@ -2676,8 +2676,6 @@ void hist__account_cycles(struct branch_stack *bs, struct addr_location *al, + + /* If we have branch cycles always annotate them. */ + if (bs && bs->nr && entries[0].flags.cycles) { +- int i; +- + bi = sample__resolve_bstack(sample, al); + if (bi) { + struct addr_map_symbol *prev = NULL; +@@ -2692,7 +2690,7 @@ void hist__account_cycles(struct branch_stack *bs, struct addr_location *al, + * Note that perf stores branches reversed from + * program order! + */ +- for (i = bs->nr - 1; i >= 0; i--) { ++ for (int i = bs->nr - 1; i >= 0; i--) { + addr_map_symbol__account_cycles(&bi[i].from, + nonany_branch_mode ? NULL : prev, + bi[i].flags.cycles); +@@ -2701,6 +2699,12 @@ void hist__account_cycles(struct branch_stack *bs, struct addr_location *al, + if (total_cycles) + *total_cycles += bi[i].flags.cycles; + } ++ for (unsigned int i = 0; i < bs->nr; i++) { ++ map__put(bi[i].to.ms.map); ++ maps__put(bi[i].to.ms.maps); ++ map__put(bi[i].from.ms.map); ++ maps__put(bi[i].from.ms.maps); ++ } + free(bi); + } + } +-- +2.42.0 + diff --git a/queue-6.6/perf-kwork-add-the-supported-subcommands-to-the-docu.patch b/queue-6.6/perf-kwork-add-the-supported-subcommands-to-the-docu.patch new file mode 100644 index 00000000000..616620d3c7f --- /dev/null +++ b/queue-6.6/perf-kwork-add-the-supported-subcommands-to-the-docu.patch @@ -0,0 +1,49 @@ +From 06efc3e51a4a793ae929547580532bd01ccceda3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Aug 2023 08:49:03 +0000 +Subject: perf kwork: Add the supported subcommands to the document + +From: Yang Jihong + +[ Upstream commit 76e0d8c821bbd952730799cc7af841f9de67b7f7 ] + +Add missing report, latency and timehist subcommands to the document. + +Fixes: f98919ec4fccdacf ("perf kwork: Implement 'report' subcommand") +Fixes: ad3d9f7a929ab2df ("perf kwork: Implement perf kwork latency") +Fixes: bcc8b3e88d6fa1a3 ("perf kwork: Implement perf kwork timehist") +Reviewed-by: Ian Rogers +Signed-off-by: Yang Jihong +Cc: Adrian Hunter +Cc: Alexander Shishkin +Cc: Ingo Molnar +Cc: Jiri Olsa +Cc: Kan Liang +Cc: Mark Rutland +Cc: Namhyung Kim +Cc: Peter Zijlstra +Cc: Ravi Bangoria +Cc: Sandipan Das +Link: https://lore.kernel.org/r/20230812084917.169338-3-yangjihong1@huawei.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/Documentation/perf-kwork.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/Documentation/perf-kwork.txt b/tools/perf/Documentation/perf-kwork.txt +index 3c36324712b6e..482d6c52e2edf 100644 +--- a/tools/perf/Documentation/perf-kwork.txt ++++ b/tools/perf/Documentation/perf-kwork.txt +@@ -8,7 +8,7 @@ perf-kwork - Tool to trace/measure kernel work properties (latencies) + SYNOPSIS + -------- + [verse] +-'perf kwork' {record} ++'perf kwork' {record|report|latency|timehist} + + DESCRIPTION + ----------- +-- +2.42.0 + diff --git a/queue-6.6/perf-kwork-fix-incorrect-and-missing-free-atom-in-wo.patch b/queue-6.6/perf-kwork-fix-incorrect-and-missing-free-atom-in-wo.patch new file mode 100644 index 00000000000..5d47b22db68 --- /dev/null +++ b/queue-6.6/perf-kwork-fix-incorrect-and-missing-free-atom-in-wo.patch @@ -0,0 +1,58 @@ +From 5e16058640ffb9dd9a6a30dc370028ebcebda6a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Aug 2023 08:49:02 +0000 +Subject: perf kwork: Fix incorrect and missing free atom in work_push_atom() + +From: Yang Jihong + +[ Upstream commit d39710088d82ef100b33cdf4a9de3546fb0bb5df ] + +1. Atoms are managed in page mode and should be released using atom_free() + instead of free(). +2. When the event does not match, the atom needs to free. + +Fixes: f98919ec4fccdacf ("perf kwork: Implement 'report' subcommand") +Reviewed-by: Ian Rogers +Signed-off-by: Yang Jihong +Cc: Adrian Hunter +Cc: Alexander Shishkin +Cc: Ingo Molnar +Cc: Jiri Olsa +Cc: Kan Liang +Cc: Mark Rutland +Cc: Namhyung Kim +Cc: Peter Zijlstra +Cc: Ravi Bangoria +Cc: Sandipan Das +Cc: Yang Jihong +Link: https://lore.kernel.org/r/20230812084917.169338-2-yangjihong1@huawei.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-kwork.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/builtin-kwork.c b/tools/perf/builtin-kwork.c +index 14bf7a8429e76..73b5dc099a8ae 100644 +--- a/tools/perf/builtin-kwork.c ++++ b/tools/perf/builtin-kwork.c +@@ -406,12 +406,14 @@ static int work_push_atom(struct perf_kwork *kwork, + + work = work_findnew(&class->work_root, &key, &kwork->cmp_id); + if (work == NULL) { +- free(atom); ++ atom_free(atom); + return -1; + } + +- if (!profile_event_match(kwork, work, sample)) ++ if (!profile_event_match(kwork, work, sample)) { ++ atom_free(atom); + return 0; ++ } + + if (dst_type < KWORK_TRACE_MAX) { + dst_atom = list_last_entry_or_null(&work->atom_list[dst_type], +-- +2.42.0 + diff --git a/queue-6.6/perf-kwork-set-ordered_events-to-true-in-struct-perf.patch b/queue-6.6/perf-kwork-set-ordered_events-to-true-in-struct-perf.patch new file mode 100644 index 00000000000..f76a02e5667 --- /dev/null +++ b/queue-6.6/perf-kwork-set-ordered_events-to-true-in-struct-perf.patch @@ -0,0 +1,53 @@ +From 1de0c8ea2241b1b6fc961a594bb8ac9a58092d17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Aug 2023 08:49:04 +0000 +Subject: perf kwork: Set ordered_events to true in 'struct perf_tool' + +From: Yang Jihong + +[ Upstream commit 0c526579a4b2b6ecd540472f2e34c2850cf70f76 ] + +'perf kwork' processes data based on timestamps and needs to sort events. + +Fixes: f98919ec4fccdacf ("perf kwork: Implement 'report' subcommand") +Reviewed-by: Ian Rogers +Signed-off-by: Yang Jihong +Cc: Adrian Hunter +Cc: Alexander Shishkin +Cc: Ingo Molnar +Cc: Jiri Olsa +Cc: Kan Liang +Cc: Mark Rutland +Cc: Namhyung Kim +Cc: Peter Zijlstra +Cc: Ravi Bangoria +Cc: Sandipan Das +Cc: Yang Jihong +Link: https://lore.kernel.org/r/20230812084917.169338-4-yangjihong1@huawei.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-kwork.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/tools/perf/builtin-kwork.c b/tools/perf/builtin-kwork.c +index 73b5dc099a8ae..de2fbb7c56c32 100644 +--- a/tools/perf/builtin-kwork.c ++++ b/tools/perf/builtin-kwork.c +@@ -1694,9 +1694,10 @@ int cmd_kwork(int argc, const char **argv) + static struct perf_kwork kwork = { + .class_list = LIST_HEAD_INIT(kwork.class_list), + .tool = { +- .mmap = perf_event__process_mmap, +- .mmap2 = perf_event__process_mmap2, +- .sample = perf_kwork__process_tracepoint_sample, ++ .mmap = perf_event__process_mmap, ++ .mmap2 = perf_event__process_mmap2, ++ .sample = perf_kwork__process_tracepoint_sample, ++ .ordered_events = true, + }, + .atom_page_list = LIST_HEAD_INIT(kwork.atom_page_list), + .sort_list = LIST_HEAD_INIT(kwork.sort_list), +-- +2.42.0 + diff --git a/queue-6.6/perf-machine-avoid-out-of-bounds-lbr-memory-read.patch b/queue-6.6/perf-machine-avoid-out-of-bounds-lbr-memory-read.patch new file mode 100644 index 00000000000..01e1bf2cccb --- /dev/null +++ b/queue-6.6/perf-machine-avoid-out-of-bounds-lbr-memory-read.patch @@ -0,0 +1,80 @@ +From bb269fae402812c24abf53e9514e2938059a350d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Oct 2023 15:23:05 -0700 +Subject: perf machine: Avoid out of bounds LBR memory read + +From: Ian Rogers + +[ Upstream commit ab8ce150781d326c6bfbe1e09f175ffde1186f80 ] + +Running perf top with address sanitizer and "--call-graph=lbr" fails +due to reading sample 0 when no samples exist. Add a guard to prevent +this. + +Fixes: e2b23483eb1d ("perf machine: Factor out lbr_callchain_add_lbr_ip()") +Signed-off-by: Ian Rogers +Cc: K Prateek Nayak +Cc: Ravi Bangoria +Cc: Sandipan Das +Cc: Anshuman Khandual +Cc: German Gomez +Cc: James Clark +Cc: Nick Terrell +Cc: Sean Christopherson +Cc: Changbin Du +Cc: liuwenyu +Cc: Yang Jihong +Cc: Masami Hiramatsu +Cc: Miguel Ojeda +Cc: Song Liu +Cc: Leo Yan +Cc: Kajol Jain +Cc: Andi Kleen +Cc: Kan Liang +Cc: Athira Rajeev +Cc: Yanteng Si +Cc: Liam Howlett +Cc: Paolo Bonzini +Link: https://lore.kernel.org/r/20231024222353.3024098-3-irogers@google.com +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/machine.c | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c +index 88f31b3a63acb..e6a8d758f6fe4 100644 +--- a/tools/perf/util/machine.c ++++ b/tools/perf/util/machine.c +@@ -2624,16 +2624,18 @@ static int lbr_callchain_add_lbr_ip(struct thread *thread, + save_lbr_cursor_node(thread, cursor, i); + } + +- /* Add LBR ip from first entries.to */ +- ip = entries[0].to; +- flags = &entries[0].flags; +- *branch_from = entries[0].from; +- err = add_callchain_ip(thread, cursor, parent, +- root_al, &cpumode, ip, +- true, flags, NULL, +- *branch_from); +- if (err) +- return err; ++ if (lbr_nr > 0) { ++ /* Add LBR ip from first entries.to */ ++ ip = entries[0].to; ++ flags = &entries[0].flags; ++ *branch_from = entries[0].from; ++ err = add_callchain_ip(thread, cursor, parent, ++ root_al, &cpumode, ip, ++ true, flags, NULL, ++ *branch_from); ++ if (err) ++ return err; ++ } + + return 0; + } +-- +2.42.0 + diff --git a/queue-6.6/perf-mem-events-avoid-uninitialized-read.patch b/queue-6.6/perf-mem-events-avoid-uninitialized-read.patch new file mode 100644 index 00000000000..14106584da3 --- /dev/null +++ b/queue-6.6/perf-mem-events-avoid-uninitialized-read.patch @@ -0,0 +1,56 @@ +From 70eda74f020c1235a3a0d719d39333ed5ac7e084 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 11:39:10 -0700 +Subject: perf mem-events: Avoid uninitialized read + +From: Ian Rogers + +[ Upstream commit 85f73c377b2ac9988a204b119aebb33ca5c60083 ] + +pmu should be initialized to NULL before perf_pmus__scan loop. Fix and +shrink the scope of pmu at the same time. Issue detected by clang-tidy. + +Fixes: 5752c20f3787 ("perf mem: Scan all PMUs instead of just core ones") +Signed-off-by: Ian Rogers +Acked-by: Namhyung Kim +Cc: Ravi Bangoria +Cc: Nick Desaulniers +Cc: Yang Jihong +Cc: Huacai Chen +Cc: Nathan Chancellor +Cc: Kan Liang +Cc: llvm@lists.linux.dev +Cc: Ming Wang +Cc: Tom Rix +Cc: bpf@vger.kernel.org +Link: https://lore.kernel.org/r/20231009183920.200859-10-irogers@google.com +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/mem-events.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/perf/util/mem-events.c b/tools/perf/util/mem-events.c +index 39ffe8ceb3809..954b235e12e51 100644 +--- a/tools/perf/util/mem-events.c ++++ b/tools/perf/util/mem-events.c +@@ -185,7 +185,6 @@ int perf_mem_events__record_args(const char **rec_argv, int *argv_nr, + { + int i = *argv_nr, k = 0; + struct perf_mem_event *e; +- struct perf_pmu *pmu; + + for (int j = 0; j < PERF_MEM_EVENTS__MAX; j++) { + e = perf_mem_events__ptr(j); +@@ -202,6 +201,8 @@ int perf_mem_events__record_args(const char **rec_argv, int *argv_nr, + rec_argv[i++] = "-e"; + rec_argv[i++] = perf_mem_events__name(j, NULL); + } else { ++ struct perf_pmu *pmu = NULL; ++ + if (!e->supported) { + perf_mem_events__print_unsupport_hybrid(e, j); + return -1; +-- +2.42.0 + diff --git a/queue-6.6/perf-optimize-perf_cgroup_switch.patch b/queue-6.6/perf-optimize-perf_cgroup_switch.patch new file mode 100644 index 00000000000..cae09930edc --- /dev/null +++ b/queue-6.6/perf-optimize-perf_cgroup_switch.patch @@ -0,0 +1,370 @@ +From a3793c5c6b3d14139ff375f95591afe5bcdfce77 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 23:04:25 +0200 +Subject: perf: Optimize perf_cgroup_switch() + +From: Peter Zijlstra + +[ Upstream commit f06cc667f79909e9175460b167c277b7c64d3df0 ] + +Namhyung reported that bd2756811766 ("perf: Rewrite core context handling") +regresses context switch overhead when perf-cgroup is in use together +with 'slow' PMUs like uncore. + +Specifically, perf_cgroup_switch()'s perf_ctx_disable() / +ctx_sched_out() etc.. all iterate the full list of active PMUs for +that CPU, even if they don't have cgroup events. + +Previously there was cgrp_cpuctx_list which linked the relevant PMUs +together, but that got lost in the rework. Instead of re-instruducing +a similar list, let the perf_event_pmu_context iteration skip those +that do not have cgroup events. This avoids growing multiple versions +of the perf_event_pmu_context iteration. + +Measured performance (on a slightly different patch): + +Before) + + $ taskset -c 0 ./perf bench sched pipe -l 10000 -G AAA,BBB + # Running 'sched/pipe' benchmark: + # Executed 10000 pipe operations between two processes + + Total time: 0.901 [sec] + + 90.128700 usecs/op + 11095 ops/sec + +After) + + $ taskset -c 0 ./perf bench sched pipe -l 10000 -G AAA,BBB + # Running 'sched/pipe' benchmark: + # Executed 10000 pipe operations between two processes + + Total time: 0.065 [sec] + + 6.560100 usecs/op + 152436 ops/sec + +Fixes: bd2756811766 ("perf: Rewrite core context handling") +Reported-by: Namhyung Kim +Debugged-by: Namhyung Kim +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20231009210425.GC6307@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + include/linux/perf_event.h | 1 + + kernel/events/core.c | 115 +++++++++++++++++++------------------ + 2 files changed, 61 insertions(+), 55 deletions(-) + +diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h +index 7b5406e3288d9..16913318af930 100644 +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -879,6 +879,7 @@ struct perf_event_pmu_context { + unsigned int embedded : 1; + + unsigned int nr_events; ++ unsigned int nr_cgroups; + + atomic_t refcount; /* event <-> epc */ + struct rcu_head rcu_head; +diff --git a/kernel/events/core.c b/kernel/events/core.c +index a2f2a9525d72e..452c15d747328 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -375,6 +375,7 @@ enum event_type_t { + EVENT_TIME = 0x4, + /* see ctx_resched() for details */ + EVENT_CPU = 0x8, ++ EVENT_CGROUP = 0x10, + EVENT_ALL = EVENT_FLEXIBLE | EVENT_PINNED, + }; + +@@ -684,20 +685,26 @@ do { \ + ___p; \ + }) + +-static void perf_ctx_disable(struct perf_event_context *ctx) ++static void perf_ctx_disable(struct perf_event_context *ctx, bool cgroup) + { + struct perf_event_pmu_context *pmu_ctx; + +- list_for_each_entry(pmu_ctx, &ctx->pmu_ctx_list, pmu_ctx_entry) ++ list_for_each_entry(pmu_ctx, &ctx->pmu_ctx_list, pmu_ctx_entry) { ++ if (cgroup && !pmu_ctx->nr_cgroups) ++ continue; + perf_pmu_disable(pmu_ctx->pmu); ++ } + } + +-static void perf_ctx_enable(struct perf_event_context *ctx) ++static void perf_ctx_enable(struct perf_event_context *ctx, bool cgroup) + { + struct perf_event_pmu_context *pmu_ctx; + +- list_for_each_entry(pmu_ctx, &ctx->pmu_ctx_list, pmu_ctx_entry) ++ list_for_each_entry(pmu_ctx, &ctx->pmu_ctx_list, pmu_ctx_entry) { ++ if (cgroup && !pmu_ctx->nr_cgroups) ++ continue; + perf_pmu_enable(pmu_ctx->pmu); ++ } + } + + static void ctx_sched_out(struct perf_event_context *ctx, enum event_type_t event_type); +@@ -856,9 +863,9 @@ static void perf_cgroup_switch(struct task_struct *task) + return; + + perf_ctx_lock(cpuctx, cpuctx->task_ctx); +- perf_ctx_disable(&cpuctx->ctx); ++ perf_ctx_disable(&cpuctx->ctx, true); + +- ctx_sched_out(&cpuctx->ctx, EVENT_ALL); ++ ctx_sched_out(&cpuctx->ctx, EVENT_ALL|EVENT_CGROUP); + /* + * must not be done before ctxswout due + * to update_cgrp_time_from_cpuctx() in +@@ -870,9 +877,9 @@ static void perf_cgroup_switch(struct task_struct *task) + * perf_cgroup_set_timestamp() in ctx_sched_in() + * to not have to pass task around + */ +- ctx_sched_in(&cpuctx->ctx, EVENT_ALL); ++ ctx_sched_in(&cpuctx->ctx, EVENT_ALL|EVENT_CGROUP); + +- perf_ctx_enable(&cpuctx->ctx); ++ perf_ctx_enable(&cpuctx->ctx, true); + perf_ctx_unlock(cpuctx, cpuctx->task_ctx); + } + +@@ -965,6 +972,8 @@ perf_cgroup_event_enable(struct perf_event *event, struct perf_event_context *ct + if (!is_cgroup_event(event)) + return; + ++ event->pmu_ctx->nr_cgroups++; ++ + /* + * Because cgroup events are always per-cpu events, + * @ctx == &cpuctx->ctx. +@@ -985,6 +994,8 @@ perf_cgroup_event_disable(struct perf_event *event, struct perf_event_context *c + if (!is_cgroup_event(event)) + return; + ++ event->pmu_ctx->nr_cgroups--; ++ + /* + * Because cgroup events are always per-cpu events, + * @ctx == &cpuctx->ctx. +@@ -2679,9 +2690,9 @@ static void ctx_resched(struct perf_cpu_context *cpuctx, + + event_type &= EVENT_ALL; + +- perf_ctx_disable(&cpuctx->ctx); ++ perf_ctx_disable(&cpuctx->ctx, false); + if (task_ctx) { +- perf_ctx_disable(task_ctx); ++ perf_ctx_disable(task_ctx, false); + task_ctx_sched_out(task_ctx, event_type); + } + +@@ -2699,9 +2710,9 @@ static void ctx_resched(struct perf_cpu_context *cpuctx, + + perf_event_sched_in(cpuctx, task_ctx); + +- perf_ctx_enable(&cpuctx->ctx); ++ perf_ctx_enable(&cpuctx->ctx, false); + if (task_ctx) +- perf_ctx_enable(task_ctx); ++ perf_ctx_enable(task_ctx, false); + } + + void perf_pmu_resched(struct pmu *pmu) +@@ -3246,6 +3257,9 @@ ctx_sched_out(struct perf_event_context *ctx, enum event_type_t event_type) + struct perf_cpu_context *cpuctx = this_cpu_ptr(&perf_cpu_context); + struct perf_event_pmu_context *pmu_ctx; + int is_active = ctx->is_active; ++ bool cgroup = event_type & EVENT_CGROUP; ++ ++ event_type &= ~EVENT_CGROUP; + + lockdep_assert_held(&ctx->lock); + +@@ -3292,8 +3306,11 @@ ctx_sched_out(struct perf_event_context *ctx, enum event_type_t event_type) + + is_active ^= ctx->is_active; /* changed bits */ + +- list_for_each_entry(pmu_ctx, &ctx->pmu_ctx_list, pmu_ctx_entry) ++ list_for_each_entry(pmu_ctx, &ctx->pmu_ctx_list, pmu_ctx_entry) { ++ if (cgroup && !pmu_ctx->nr_cgroups) ++ continue; + __pmu_ctx_sched_out(pmu_ctx, is_active); ++ } + } + + /* +@@ -3484,7 +3501,7 @@ perf_event_context_sched_out(struct task_struct *task, struct task_struct *next) + raw_spin_lock_nested(&next_ctx->lock, SINGLE_DEPTH_NESTING); + if (context_equiv(ctx, next_ctx)) { + +- perf_ctx_disable(ctx); ++ perf_ctx_disable(ctx, false); + + /* PMIs are disabled; ctx->nr_pending is stable. */ + if (local_read(&ctx->nr_pending) || +@@ -3504,7 +3521,7 @@ perf_event_context_sched_out(struct task_struct *task, struct task_struct *next) + perf_ctx_sched_task_cb(ctx, false); + perf_event_swap_task_ctx_data(ctx, next_ctx); + +- perf_ctx_enable(ctx); ++ perf_ctx_enable(ctx, false); + + /* + * RCU_INIT_POINTER here is safe because we've not +@@ -3528,13 +3545,13 @@ perf_event_context_sched_out(struct task_struct *task, struct task_struct *next) + + if (do_switch) { + raw_spin_lock(&ctx->lock); +- perf_ctx_disable(ctx); ++ perf_ctx_disable(ctx, false); + + inside_switch: + perf_ctx_sched_task_cb(ctx, false); + task_ctx_sched_out(ctx, EVENT_ALL); + +- perf_ctx_enable(ctx); ++ perf_ctx_enable(ctx, false); + raw_spin_unlock(&ctx->lock); + } + } +@@ -3820,47 +3837,32 @@ static int merge_sched_in(struct perf_event *event, void *data) + return 0; + } + +-static void ctx_pinned_sched_in(struct perf_event_context *ctx, struct pmu *pmu) ++static void pmu_groups_sched_in(struct perf_event_context *ctx, ++ struct perf_event_groups *groups, ++ struct pmu *pmu) + { +- struct perf_event_pmu_context *pmu_ctx; + int can_add_hw = 1; +- +- if (pmu) { +- visit_groups_merge(ctx, &ctx->pinned_groups, +- smp_processor_id(), pmu, +- merge_sched_in, &can_add_hw); +- } else { +- list_for_each_entry(pmu_ctx, &ctx->pmu_ctx_list, pmu_ctx_entry) { +- can_add_hw = 1; +- visit_groups_merge(ctx, &ctx->pinned_groups, +- smp_processor_id(), pmu_ctx->pmu, +- merge_sched_in, &can_add_hw); +- } +- } ++ visit_groups_merge(ctx, groups, smp_processor_id(), pmu, ++ merge_sched_in, &can_add_hw); + } + +-static void ctx_flexible_sched_in(struct perf_event_context *ctx, struct pmu *pmu) ++static void ctx_groups_sched_in(struct perf_event_context *ctx, ++ struct perf_event_groups *groups, ++ bool cgroup) + { + struct perf_event_pmu_context *pmu_ctx; +- int can_add_hw = 1; + +- if (pmu) { +- visit_groups_merge(ctx, &ctx->flexible_groups, +- smp_processor_id(), pmu, +- merge_sched_in, &can_add_hw); +- } else { +- list_for_each_entry(pmu_ctx, &ctx->pmu_ctx_list, pmu_ctx_entry) { +- can_add_hw = 1; +- visit_groups_merge(ctx, &ctx->flexible_groups, +- smp_processor_id(), pmu_ctx->pmu, +- merge_sched_in, &can_add_hw); +- } ++ list_for_each_entry(pmu_ctx, &ctx->pmu_ctx_list, pmu_ctx_entry) { ++ if (cgroup && !pmu_ctx->nr_cgroups) ++ continue; ++ pmu_groups_sched_in(ctx, groups, pmu_ctx->pmu); + } + } + +-static void __pmu_ctx_sched_in(struct perf_event_context *ctx, struct pmu *pmu) ++static void __pmu_ctx_sched_in(struct perf_event_context *ctx, ++ struct pmu *pmu) + { +- ctx_flexible_sched_in(ctx, pmu); ++ pmu_groups_sched_in(ctx, &ctx->flexible_groups, pmu); + } + + static void +@@ -3868,6 +3870,9 @@ ctx_sched_in(struct perf_event_context *ctx, enum event_type_t event_type) + { + struct perf_cpu_context *cpuctx = this_cpu_ptr(&perf_cpu_context); + int is_active = ctx->is_active; ++ bool cgroup = event_type & EVENT_CGROUP; ++ ++ event_type &= ~EVENT_CGROUP; + + lockdep_assert_held(&ctx->lock); + +@@ -3900,11 +3905,11 @@ ctx_sched_in(struct perf_event_context *ctx, enum event_type_t event_type) + * in order to give them the best chance of going on. + */ + if (is_active & EVENT_PINNED) +- ctx_pinned_sched_in(ctx, NULL); ++ ctx_groups_sched_in(ctx, &ctx->pinned_groups, cgroup); + + /* Then walk through the lower prio flexible groups */ + if (is_active & EVENT_FLEXIBLE) +- ctx_flexible_sched_in(ctx, NULL); ++ ctx_groups_sched_in(ctx, &ctx->flexible_groups, cgroup); + } + + static void perf_event_context_sched_in(struct task_struct *task) +@@ -3919,11 +3924,11 @@ static void perf_event_context_sched_in(struct task_struct *task) + + if (cpuctx->task_ctx == ctx) { + perf_ctx_lock(cpuctx, ctx); +- perf_ctx_disable(ctx); ++ perf_ctx_disable(ctx, false); + + perf_ctx_sched_task_cb(ctx, true); + +- perf_ctx_enable(ctx); ++ perf_ctx_enable(ctx, false); + perf_ctx_unlock(cpuctx, ctx); + goto rcu_unlock; + } +@@ -3936,7 +3941,7 @@ static void perf_event_context_sched_in(struct task_struct *task) + if (!ctx->nr_events) + goto unlock; + +- perf_ctx_disable(ctx); ++ perf_ctx_disable(ctx, false); + /* + * We want to keep the following priority order: + * cpu pinned (that don't need to move), task pinned, +@@ -3946,7 +3951,7 @@ static void perf_event_context_sched_in(struct task_struct *task) + * events, no need to flip the cpuctx's events around. + */ + if (!RB_EMPTY_ROOT(&ctx->pinned_groups.tree)) { +- perf_ctx_disable(&cpuctx->ctx); ++ perf_ctx_disable(&cpuctx->ctx, false); + ctx_sched_out(&cpuctx->ctx, EVENT_FLEXIBLE); + } + +@@ -3955,9 +3960,9 @@ static void perf_event_context_sched_in(struct task_struct *task) + perf_ctx_sched_task_cb(cpuctx->task_ctx, true); + + if (!RB_EMPTY_ROOT(&ctx->pinned_groups.tree)) +- perf_ctx_enable(&cpuctx->ctx); ++ perf_ctx_enable(&cpuctx->ctx, false); + +- perf_ctx_enable(ctx); ++ perf_ctx_enable(ctx, false); + + unlock: + perf_ctx_unlock(cpuctx, ctx); +-- +2.42.0 + diff --git a/queue-6.6/perf-parse-events-fix-for-term-values-that-are-raw-e.patch b/queue-6.6/perf-parse-events-fix-for-term-values-that-are-raw-e.patch new file mode 100644 index 00000000000..788ed74964a --- /dev/null +++ b/queue-6.6/perf-parse-events-fix-for-term-values-that-are-raw-e.patch @@ -0,0 +1,87 @@ +From 3496b526a8a3bb64c0b9d9819448a46a6c78e827 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 17:44:31 -0700 +Subject: perf parse-events: Fix for term values that are raw events + +From: Ian Rogers + +[ Upstream commit b20576fd7fe39554b212095c3c0d7a3dff512515 ] + +Raw events can be strings like 'r0xead' but the 0x is optional so they +can also be 'read'. On IcelakeX uncore_imc_free_running has an event +called 'read' which may be programmed as: +``` +$ perf stat -e 'uncore_imc_free_running/event=read/' -a sleep 1 +``` +However, the PE_RAW type isn't allowed on the right of a term, even +though in this case we just want to interpret it as a string. This +leads to the following error on IcelakeX: +``` +$ perf stat -e 'uncore_imc_free_running/event=read/' -a sleep 1 +event syntax error: '..nning/event=read/' + \___ parser error +Run 'perf list' for a list of valid events + + Usage: perf stat [] [] + + -e, --event event selector. use 'perf list' to list available events +``` +Fix this by allowing raw types on the right of terms and treat them as +strings, just as is already done for PE_LEGACY_CACHE. Make this +consistent by just entirely removing name_or_legacy and always using +name_or_raw that covers all three cases. + +Fixes: 6fd1e5191591 ("perf parse-events: Support PMUs for legacy cache events") +Signed-off-by: Ian Rogers +Cc: James Clark +Cc: Kan Liang +Link: https://lore.kernel.org/r/20230928004431.1926969-1-irogers@google.com +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/parse-events.y | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y +index da9aac47972c1..c3a86ef4b7cf3 100644 +--- a/tools/perf/util/parse-events.y ++++ b/tools/perf/util/parse-events.y +@@ -79,7 +79,7 @@ static void free_list_evsel(struct list_head* list_evsel) + %type PE_MODIFIER_BP + %type PE_EVENT_NAME + %type PE_DRV_CFG_TERM +-%type name_or_raw name_or_legacy ++%type name_or_raw + %destructor { free ($$); } + %type event_term + %destructor { parse_events_term__delete ($$); } +@@ -680,8 +680,6 @@ event_term + + name_or_raw: PE_RAW | PE_NAME | PE_LEGACY_CACHE + +-name_or_legacy: PE_NAME | PE_LEGACY_CACHE +- + event_term: + PE_RAW + { +@@ -696,7 +694,7 @@ PE_RAW + $$ = term; + } + | +-name_or_raw '=' name_or_legacy ++name_or_raw '=' name_or_raw + { + struct parse_events_term *term; + int err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, $1, $3, &@1, &@3); +@@ -776,7 +774,7 @@ PE_TERM_HW + $$ = term; + } + | +-PE_TERM '=' name_or_legacy ++PE_TERM '=' name_or_raw + { + struct parse_events_term *term; + int err = parse_events_term__str(&term, (enum parse_events__term_type)$1, +-- +2.42.0 + diff --git a/queue-6.6/perf-parse-events-fix-tracepoint-name-memory-leak.patch b/queue-6.6/perf-parse-events-fix-tracepoint-name-memory-leak.patch new file mode 100644 index 00000000000..b702cabb11e --- /dev/null +++ b/queue-6.6/perf-parse-events-fix-tracepoint-name-memory-leak.patch @@ -0,0 +1,71 @@ +From 94c12e0ffa52497512397ea2d966115cb7a2f13c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 09:40:28 -0700 +Subject: perf parse-events: Fix tracepoint name memory leak + +From: Ian Rogers + +[ Upstream commit ede72dca45b1893f3e9236b6ad6c4e790db232f6 ] + +Fuzzing found that an invalid tracepoint name would create a memory +leak with an address sanitizer build: +``` +$ perf stat -e '*:o/' true +event syntax error: '*:o/' + \___ parser error +Run 'perf list' for a list of valid events + + Usage: perf stat [] [] + + -e, --event event selector. use 'perf list' to list available events + +================================================================= +==59380==ERROR: LeakSanitizer: detected memory leaks + +Direct leak of 4 byte(s) in 2 object(s) allocated from: + #0 0x7f38ac07077b in __interceptor_strdup ../../../../src/libsanitizer/asan/asan_interceptors.cpp:439 + #1 0x55f2f41be73b in str util/parse-events.l:49 + #2 0x55f2f41d08e8 in parse_events_lex util/parse-events.l:338 + #3 0x55f2f41dc3b1 in parse_events_parse util/parse-events-bison.c:1464 + #4 0x55f2f410b8b3 in parse_events__scanner util/parse-events.c:1822 + #5 0x55f2f410d1b9 in __parse_events util/parse-events.c:2094 + #6 0x55f2f410e57f in parse_events_option util/parse-events.c:2279 + #7 0x55f2f4427b56 in get_value tools/lib/subcmd/parse-options.c:251 + #8 0x55f2f4428d98 in parse_short_opt tools/lib/subcmd/parse-options.c:351 + #9 0x55f2f4429d80 in parse_options_step tools/lib/subcmd/parse-options.c:539 + #10 0x55f2f442acb9 in parse_options_subcommand tools/lib/subcmd/parse-options.c:654 + #11 0x55f2f3ec99fc in cmd_stat tools/perf/builtin-stat.c:2501 + #12 0x55f2f4093289 in run_builtin tools/perf/perf.c:322 + #13 0x55f2f40937f5 in handle_internal_command tools/perf/perf.c:375 + #14 0x55f2f4093bbd in run_argv tools/perf/perf.c:419 + #15 0x55f2f409412b in main tools/perf/perf.c:535 + +SUMMARY: AddressSanitizer: 4 byte(s) leaked in 2 allocation(s). +``` +Fix by adding the missing destructor. + +Fixes: 865582c3f48e ("perf tools: Adds the tracepoint name parsing support") +Signed-off-by: Ian Rogers +Cc: He Kuang +Link: https://lore.kernel.org/r/20230914164028.363220-1-irogers@google.com +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/parse-events.y | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y +index 21bfe7e0d9444..da9aac47972c1 100644 +--- a/tools/perf/util/parse-events.y ++++ b/tools/perf/util/parse-events.y +@@ -104,6 +104,7 @@ static void free_list_evsel(struct list_head* list_evsel) + %type groups + %destructor { free_list_evsel ($$); } + %type tracepoint_name ++%destructor { free ($$.sys); free ($$.event); } + %type PE_TERM_HW + %destructor { free ($$.str); } + +-- +2.42.0 + diff --git a/queue-6.6/perf-record-fix-btf-type-checks-in-the-off-cpu-profi.patch b/queue-6.6/perf-record-fix-btf-type-checks-in-the-off-cpu-profi.patch new file mode 100644 index 00000000000..8b4186c2e7a --- /dev/null +++ b/queue-6.6/perf-record-fix-btf-type-checks-in-the-off-cpu-profi.patch @@ -0,0 +1,59 @@ +From feb525510373e42b791289e52bd8078c206e1255 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 16:44:44 -0700 +Subject: perf record: Fix BTF type checks in the off-cpu profiling + +From: Namhyung Kim + +[ Upstream commit 0e501a65d35bf72414379fed0e31a0b6b81ab57d ] + +The BTF func proto for a tracepoint has one more argument than the +actual tracepoint function since it has a context argument at the +begining. So it should compare to 5 when the tracepoint has 4 +arguments. + + typedef void (*btf_trace_sched_switch)(void *, bool, struct task_struct *, struct task_struct *, unsigned int); + +Also, recent change in the perf tool would use a hand-written minimal +vmlinux.h to generate BTF in the skeleton. So it won't have the info +of the tracepoint. Anyway it should use the kernel's vmlinux BTF to +check the type in the kernel. + +Fixes: b36888f71c85 ("perf record: Handle argument change in sched_switch") +Reviewed-by: Ian Rogers +Acked-by: Song Liu +Cc: Hao Luo +CC: bpf@vger.kernel.org +Link: https://lore.kernel.org/r/20230922234444.3115821-1-namhyung@kernel.org +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/bpf_off_cpu.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/util/bpf_off_cpu.c b/tools/perf/util/bpf_off_cpu.c +index 01f70b8e705a8..21f4d9ba023d9 100644 +--- a/tools/perf/util/bpf_off_cpu.c ++++ b/tools/perf/util/bpf_off_cpu.c +@@ -98,7 +98,7 @@ static void off_cpu_finish(void *arg __maybe_unused) + /* v5.18 kernel added prev_state arg, so it needs to check the signature */ + static void check_sched_switch_args(void) + { +- const struct btf *btf = bpf_object__btf(skel->obj); ++ const struct btf *btf = btf__load_vmlinux_btf(); + const struct btf_type *t1, *t2, *t3; + u32 type_id; + +@@ -116,7 +116,8 @@ static void check_sched_switch_args(void) + return; + + t3 = btf__type_by_id(btf, t2->type); +- if (t3 && btf_is_func_proto(t3) && btf_vlen(t3) == 4) { ++ /* btf_trace func proto has one more argument for the context */ ++ if (t3 && btf_is_func_proto(t3) && btf_vlen(t3) == 5) { + /* new format: pass prev_state as 4th arg */ + skel->rodata->has_prev_state = true; + } +-- +2.42.0 + diff --git a/queue-6.6/perf-stat-fix-aggr-mode-initialization.patch b/queue-6.6/perf-stat-fix-aggr-mode-initialization.patch new file mode 100644 index 00000000000..744ffa9dfcf --- /dev/null +++ b/queue-6.6/perf-stat-fix-aggr-mode-initialization.patch @@ -0,0 +1,76 @@ +From 0231c22b9764c4c5e7b581f2412d1ac4d5a5bd7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Sep 2023 17:39:12 -0700 +Subject: perf stat: Fix aggr mode initialization + +From: Ian Rogers + +[ Upstream commit a84fbf205609313594b86065c67e823f09ebe29b ] + +Generating metrics llc_code_read_mpi_demand_plus_prefetch, +llc_data_read_mpi_demand_plus_prefetch, +llc_miss_local_memory_bandwidth_read, +llc_miss_local_memory_bandwidth_write, +nllc_miss_remote_memory_bandwidth_read, memory_bandwidth_read, +memory_bandwidth_write, uncore_frequency, upi_data_transmit_bw, +C2_Pkg_Residency, C3_Core_Residency, C3_Pkg_Residency, +C6_Core_Residency, C6_Pkg_Residency, C7_Core_Residency, +C7_Pkg_Residency, UNCORE_FREQ and tma_info_system_socket_clks would +trigger an address sanitizer heap-buffer-overflows on a SkylakeX. + +``` +==2567752==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x5020003ed098 at pc 0x5621a816654e bp 0x7fffb55d4da0 sp 0x7fffb55d4d98 +READ of size 4 at 0x5020003eee78 thread T0 + #0 0x558265d6654d in aggr_cpu_id__is_empty tools/perf/util/cpumap.c:694:12 + #1 0x558265c914da in perf_stat__get_aggr tools/perf/builtin-stat.c:1490:6 + #2 0x558265c914da in perf_stat__get_global_cached tools/perf/builtin-stat.c:1530:9 + #3 0x558265e53290 in should_skip_zero_counter tools/perf/util/stat-display.c:947:31 + #4 0x558265e53290 in print_counter_aggrdata tools/perf/util/stat-display.c:985:18 + #5 0x558265e51931 in print_counter tools/perf/util/stat-display.c:1110:3 + #6 0x558265e51931 in evlist__print_counters tools/perf/util/stat-display.c:1571:5 + #7 0x558265c8ec87 in print_counters tools/perf/builtin-stat.c:981:2 + #8 0x558265c8cc71 in cmd_stat tools/perf/builtin-stat.c:2837:3 + #9 0x558265bb9bd4 in run_builtin tools/perf/perf.c:323:11 + #10 0x558265bb98eb in handle_internal_command tools/perf/perf.c:377:8 + #11 0x558265bb9389 in run_argv tools/perf/perf.c:421:2 + #12 0x558265bb9389 in main tools/perf/perf.c:537:3 +``` + +The issue was the use of testing a cpumap with NULL rather than using +empty, as a map containing the dummy value isn't NULL and the -1 +results in an empty aggr map being allocated which legitimately +overflows when any member is accessed. + +Fixes: 8a96f454f5668572 ("perf stat: Avoid SEGV if core.cpus isn't set") +Signed-off-by: Ian Rogers +Acked-by: Namhyung Kim +Cc: Adrian Hunter +Cc: Alexander Shishkin +Cc: Ian Rogers +Cc: Ingo Molnar +Cc: Jiri Olsa +Cc: Mark Rutland +Cc: Peter Zijlstra +Link: https://lore.kernel.org/r/20230906003912.3317462-1-irogers@google.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-stat.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c +index 07b48f6df48eb..a3af805a1d572 100644 +--- a/tools/perf/builtin-stat.c ++++ b/tools/perf/builtin-stat.c +@@ -1622,7 +1622,7 @@ static int perf_stat_init_aggr_mode(void) + * taking the highest cpu number to be the size of + * the aggregation translate cpumap. + */ +- if (evsel_list->core.user_requested_cpus) ++ if (!perf_cpu_map__empty(evsel_list->core.user_requested_cpus)) + nr = perf_cpu_map__max(evsel_list->core.user_requested_cpus).cpu; + else + nr = 0; +-- +2.42.0 + diff --git a/queue-6.6/perf-tools-do-not-ignore-the-default-vmlinux.h.patch b/queue-6.6/perf-tools-do-not-ignore-the-default-vmlinux.h.patch new file mode 100644 index 00000000000..54e8a43cb41 --- /dev/null +++ b/queue-6.6/perf-tools-do-not-ignore-the-default-vmlinux.h.patch @@ -0,0 +1,35 @@ +From c604b03c173149c080d9258fc83b6616e2de2140 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 16:42:47 -0700 +Subject: perf tools: Do not ignore the default vmlinux.h + +From: Namhyung Kim + +[ Upstream commit 1f36b190ad2dea68e3a7e84b7b2f24ce8c4063ea ] + +The recent change made it possible to generate vmlinux.h from BTF and +to ignore the file. But we also have a minimal vmlinux.h that will be +used by default. It should not be ignored by GIT. + +Fixes: b7a2d774c9c5 ("perf build: Add ability to build with a generated vmlinux.h") +Reported-by: kernel test robot +Reviewed-by: Ian Rogers +Closes: https://lore.kernel.org/oe-kbuild-all/202310110451.rvdUZJEY-lkp@intel.com/ +Cc: oe-kbuild-all@lists.linux.dev +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/bpf_skel/vmlinux/.gitignore | 1 + + 1 file changed, 1 insertion(+) + create mode 100644 tools/perf/util/bpf_skel/vmlinux/.gitignore + +diff --git a/tools/perf/util/bpf_skel/vmlinux/.gitignore b/tools/perf/util/bpf_skel/vmlinux/.gitignore +new file mode 100644 +index 0000000000000..49502c04183a2 +--- /dev/null ++++ b/tools/perf/util/bpf_skel/vmlinux/.gitignore +@@ -0,0 +1 @@ ++!vmlinux.h +-- +2.42.0 + diff --git a/queue-6.6/perf-trace-use-the-right-bpf_probe_read-_str-variant.patch b/queue-6.6/perf-trace-use-the-right-bpf_probe_read-_str-variant.patch new file mode 100644 index 00000000000..ca0b9a68f0f --- /dev/null +++ b/queue-6.6/perf-trace-use-the-right-bpf_probe_read-_str-variant.patch @@ -0,0 +1,172 @@ +From aadb00c090fff6949571ff81b8c868ffbc2afcc0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Oct 2023 10:26:42 +0200 +Subject: perf trace: Use the right bpf_probe_read(_str) variant for reading + user data + +From: Thomas Richter + +[ Upstream commit 5069211e2f0b47e75119805e23ae6352d871e263 ] + +Perf test case 111 Check open filename arg using perf trace + vfs_getname +fails on s390. This is caused by a failing function +bpf_probe_read() in file util/bpf_skel/augmented_raw_syscalls.bpf.c. + +The root cause is the lookup by address. Function bpf_probe_read() +is used. This function works only for architectures +with ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE. + +On s390 is not possible to determine from the address to which +address space the address belongs to (user or kernel space). + +Replace bpf_probe_read() by bpf_probe_read_kernel() +and bpf_probe_read_str() by bpf_probe_read_user_str() to +explicity specify the address space the address refers to. + +Output before: + # ./perf trace -eopen,openat -- touch /tmp/111 + libbpf: prog 'sys_enter': BPF program load failed: Invalid argument + libbpf: prog 'sys_enter': -- BEGIN PROG LOAD LOG -- + reg type unsupported for arg#0 function sys_enter#75 + 0: R1=ctx(off=0,imm=0) R10=fp0 + ; int sys_enter(struct syscall_enter_args *args) + 0: (bf) r6 = r1 ; R1=ctx(off=0,imm=0) R6_w=ctx(off=0,imm=0) + ; return bpf_get_current_pid_tgid(); + 1: (85) call bpf_get_current_pid_tgid#14 ; R0_w=scalar() + 2: (63) *(u32 *)(r10 -8) = r0 ; R0_w=scalar() R10=fp0 fp-8=????mmmm + 3: (bf) r2 = r10 ; R2_w=fp0 R10=fp0 + ; + ..... + lines deleted here + ..... + 23: (bf) r3 = r6 ; R3_w=ctx(off=0,imm=0) R6=ctx(off=0,imm=0) + 24: (85) call bpf_probe_read#4 + unknown func bpf_probe_read#4 + processed 23 insns (limit 1000000) max_states_per_insn 0 \ + total_states 2 peak_states 2 mark_read 2 + -- END PROG LOAD LOG -- + libbpf: prog 'sys_enter': failed to load: -22 + libbpf: failed to load object 'augmented_raw_syscalls_bpf' + libbpf: failed to load BPF skeleton 'augmented_raw_syscalls_bpf': -22 + .... + +Output after: + # ./perf test -Fv 111 + 111: Check open filename arg using perf trace + vfs_getname : + --- start --- + 1.085 ( 0.011 ms): touch/320753 openat(dfd: CWD, filename: \ + "/tmp/temporary_file.SWH85", \ + flags: CREAT|NOCTTY|NONBLOCK|WRONLY, mode: IRUGO|IWUGO) = 3 + ---- end ---- + Check open filename arg using perf trace + vfs_getname: Ok + # + +Test with the sleep command shows: +Output before: + # ./perf trace -e *sleep sleep 1.234567890 + 0.000 (1234.681 ms): sleep/63114 clock_nanosleep(rqtp: \ + { .tv_sec: 0, .tv_nsec: 0 }, rmtp: 0x3ffe0979720) = 0 + # + +Output after: + # ./perf trace -e *sleep sleep 1.234567890 + 0.000 (1234.686 ms): sleep/64277 clock_nanosleep(rqtp: \ + { .tv_sec: 1, .tv_nsec: 234567890 }, rmtp: 0x3fff3df9ea0) = 0 + # + +Fixes: 14e4b9f4289a ("perf trace: Raw augmented syscalls fix libbpf 1.0+ compatibility") +Signed-off-by: Thomas Richter +Co-developed-by: Arnaldo Carvalho de Melo +Acked-by: Ilya Leoshkevich +Tested-by: Arnaldo Carvalho de Melo +Cc: Ian Rogers +Cc: gor@linux.ibm.com +Cc: hca@linux.ibm.com +Cc: sumanthk@linux.ibm.com +Cc: svens@linux.ibm.com +Link: https://lore.kernel.org/r/20231019082642.3286650-1-tmricht@linux.ibm.com +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + .../util/bpf_skel/augmented_raw_syscalls.bpf.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c b/tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c +index 939ec769bf4a5..52c270330ae0d 100644 +--- a/tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c ++++ b/tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c +@@ -153,7 +153,7 @@ static inline + unsigned int augmented_arg__read_str(struct augmented_arg *augmented_arg, const void *arg, unsigned int arg_len) + { + unsigned int augmented_len = sizeof(*augmented_arg); +- int string_len = bpf_probe_read_str(&augmented_arg->value, arg_len, arg); ++ int string_len = bpf_probe_read_user_str(&augmented_arg->value, arg_len, arg); + + augmented_arg->size = augmented_arg->err = 0; + /* +@@ -203,7 +203,7 @@ int sys_enter_connect(struct syscall_enter_args *args) + _Static_assert(is_power_of_2(sizeof(augmented_args->saddr)), "sizeof(augmented_args->saddr) needs to be a power of two"); + socklen &= sizeof(augmented_args->saddr) - 1; + +- bpf_probe_read(&augmented_args->saddr, socklen, sockaddr_arg); ++ bpf_probe_read_user(&augmented_args->saddr, socklen, sockaddr_arg); + + return augmented__output(args, augmented_args, len + socklen); + } +@@ -221,7 +221,7 @@ int sys_enter_sendto(struct syscall_enter_args *args) + + socklen &= sizeof(augmented_args->saddr) - 1; + +- bpf_probe_read(&augmented_args->saddr, socklen, sockaddr_arg); ++ bpf_probe_read_user(&augmented_args->saddr, socklen, sockaddr_arg); + + return augmented__output(args, augmented_args, len + socklen); + } +@@ -311,7 +311,7 @@ int sys_enter_perf_event_open(struct syscall_enter_args *args) + if (augmented_args == NULL) + goto failure; + +- if (bpf_probe_read(&augmented_args->__data, sizeof(*attr), attr) < 0) ++ if (bpf_probe_read_user(&augmented_args->__data, sizeof(*attr), attr) < 0) + goto failure; + + attr_read = (const struct perf_event_attr_size *)augmented_args->__data; +@@ -325,7 +325,7 @@ int sys_enter_perf_event_open(struct syscall_enter_args *args) + goto failure; + + // Now that we read attr->size and tested it against the size limits, read it completely +- if (bpf_probe_read(&augmented_args->__data, size, attr) < 0) ++ if (bpf_probe_read_user(&augmented_args->__data, size, attr) < 0) + goto failure; + + return augmented__output(args, augmented_args, len + size); +@@ -347,7 +347,7 @@ int sys_enter_clock_nanosleep(struct syscall_enter_args *args) + if (size > sizeof(augmented_args->__data)) + goto failure; + +- bpf_probe_read(&augmented_args->__data, size, rqtp_arg); ++ bpf_probe_read_user(&augmented_args->__data, size, rqtp_arg); + + return augmented__output(args, augmented_args, len + size); + failure: +@@ -385,7 +385,7 @@ int sys_enter(struct syscall_enter_args *args) + if (augmented_args == NULL) + return 1; + +- bpf_probe_read(&augmented_args->args, sizeof(augmented_args->args), args); ++ bpf_probe_read_kernel(&augmented_args->args, sizeof(augmented_args->args), args); + + /* + * Jump to syscall specific augmenter, even if the default one, +@@ -406,7 +406,7 @@ int sys_exit(struct syscall_exit_args *args) + if (pid_filter__has(&pids_filtered, getpid())) + return 0; + +- bpf_probe_read(&exit_args, sizeof(exit_args), args); ++ bpf_probe_read_kernel(&exit_args, sizeof(exit_args), args); + /* + * Jump to syscall specific return augmenter, even if the default one, + * "!raw_syscalls:unaugmented" that will just return 1 to return the +-- +2.42.0 + diff --git a/queue-6.6/perf-vendor-events-arm64-fix-for-ampereone-metrics.patch b/queue-6.6/perf-vendor-events-arm64-fix-for-ampereone-metrics.patch new file mode 100644 index 00000000000..c0926e420bf --- /dev/null +++ b/queue-6.6/perf-vendor-events-arm64-fix-for-ampereone-metrics.patch @@ -0,0 +1,628 @@ +From 701a520b5fd71a9a232750fe48b4175abd6eeda0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 23:18:39 -0700 +Subject: perf vendor events arm64: Fix for AmpereOne metrics + +From: Ilkka Koskinen + +[ Upstream commit 59faeaf80d0239412056c4495cc49097e9cea4da ] + +This patch addresses review comments that were given for +705ed549148f ("perf vendor events arm64: Add AmpereOne metrics") +but didn't make it to the original patch [1][2] + +Changes include: A fix for backend_memory formula, use of standard metrics +when possible, using #slots, renaming metrics to avoid spaces in the names, +and cleanup. + +[1] https://lore.kernel.org/linux-perf-users/e9bdacb-a231-36af-6a2e-6918ee7effa@os.amperecomputing.com/ +[2] https://lore.kernel.org/linux-perf-users/20230826192352.3043220-1-ilkka@os.amperecomputing.com/ + +Fixes: 705ed549148f ("perf vendor events arm64: Add AmpereOne metrics") +Signed-off-by: Ilkka Koskinen +Reviewed-by: Ian Rogers +Cc: James Clark +Cc: Will Deacon +Cc: Leo Yan +Cc: Mike Leach +Cc: Dave Kleikamp +Cc: John Garry +Cc: D Scott Phillips +Cc: linux-arm-kernel@lists.infradead.org +Link: https://lore.kernel.org/r/20230920061839.2437413-1-ilkka@os.amperecomputing.com +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + .../arch/arm64/ampere/ampereone/metrics.json | 418 +++++++++--------- + 1 file changed, 220 insertions(+), 198 deletions(-) + +diff --git a/tools/perf/pmu-events/arch/arm64/ampere/ampereone/metrics.json b/tools/perf/pmu-events/arch/arm64/ampere/ampereone/metrics.json +index 1e7e8901a4450..e2848a9d48487 100644 +--- a/tools/perf/pmu-events/arch/arm64/ampere/ampereone/metrics.json ++++ b/tools/perf/pmu-events/arch/arm64/ampere/ampereone/metrics.json +@@ -1,362 +1,384 @@ + [ + { ++ "MetricName": "branch_miss_pred_rate", + "MetricExpr": "BR_MIS_PRED / BR_PRED", + "BriefDescription": "Branch predictor misprediction rate. May not count branches that are never resolved because they are in the misprediction shadow of an earlier branch", +- "MetricGroup": "Branch Prediction", +- "MetricName": "Misprediction" ++ "MetricGroup": "branch", ++ "ScaleUnit": "100%" + }, + { +- "MetricExpr": "BR_MIS_PRED_RETIRED / BR_RETIRED", +- "BriefDescription": "Branch predictor misprediction rate", +- "MetricGroup": "Branch Prediction", +- "MetricName": "Misprediction (retired)" +- }, +- { +- "MetricExpr": "BUS_ACCESS / ( BUS_CYCLES * 1)", ++ "MetricName": "bus_utilization", ++ "MetricExpr": "((BUS_ACCESS / (BUS_CYCLES * 1)) * 100)", + "BriefDescription": "Core-to-uncore bus utilization", + "MetricGroup": "Bus", +- "MetricName": "Bus utilization" ++ "ScaleUnit": "1percent of bus cycles" + }, + { +- "MetricExpr": "L1D_CACHE_REFILL / L1D_CACHE", +- "BriefDescription": "L1D cache miss rate", +- "MetricGroup": "Cache", +- "MetricName": "L1D cache miss" ++ "MetricName": "l1d_cache_miss_ratio", ++ "MetricExpr": "(L1D_CACHE_REFILL / L1D_CACHE)", ++ "BriefDescription": "This metric measures the ratio of level 1 data cache accesses missed to the total number of level 1 data cache accesses. This gives an indication of the effectiveness of the level 1 data cache.", ++ "MetricGroup": "Miss_Ratio;L1D_Cache_Effectiveness", ++ "ScaleUnit": "1per cache access" ++ }, ++ { ++ "MetricName": "l1i_cache_miss_ratio", ++ "MetricExpr": "(L1I_CACHE_REFILL / L1I_CACHE)", ++ "BriefDescription": "This metric measures the ratio of level 1 instruction cache accesses missed to the total number of level 1 instruction cache accesses. This gives an indication of the effectiveness of the level 1 instruction cache.", ++ "MetricGroup": "Miss_Ratio;L1I_Cache_Effectiveness", ++ "ScaleUnit": "1per cache access" + }, + { ++ "MetricName": "Miss_Ratio;l1d_cache_read_miss", + "MetricExpr": "L1D_CACHE_LMISS_RD / L1D_CACHE_RD", + "BriefDescription": "L1D cache read miss rate", + "MetricGroup": "Cache", +- "MetricName": "L1D cache read miss" ++ "ScaleUnit": "1per cache read access" + }, + { +- "MetricExpr": "L1I_CACHE_REFILL / L1I_CACHE", +- "BriefDescription": "L1I cache miss rate", +- "MetricGroup": "Cache", +- "MetricName": "L1I cache miss" +- }, +- { +- "MetricExpr": "L2D_CACHE_REFILL / L2D_CACHE", +- "BriefDescription": "L2 cache miss rate", +- "MetricGroup": "Cache", +- "MetricName": "L2 cache miss" ++ "MetricName": "l2_cache_miss_ratio", ++ "MetricExpr": "(L2D_CACHE_REFILL / L2D_CACHE)", ++ "BriefDescription": "This metric measures the ratio of level 2 cache accesses missed to the total number of level 2 cache accesses. This gives an indication of the effectiveness of the level 2 cache, which is a unified cache that stores both data and instruction. Note that cache accesses in this cache are either data memory access or instruction fetch as this is a unified cache.", ++ "MetricGroup": "Miss_Ratio;L2_Cache_Effectiveness", ++ "ScaleUnit": "1per cache access" + }, + { ++ "MetricName": "l1i_cache_read_miss_rate", + "MetricExpr": "L1I_CACHE_LMISS / L1I_CACHE", + "BriefDescription": "L1I cache read miss rate", + "MetricGroup": "Cache", +- "MetricName": "L1I cache read miss" ++ "ScaleUnit": "1per cache access" + }, + { ++ "MetricName": "l2d_cache_read_miss_rate", + "MetricExpr": "L2D_CACHE_LMISS_RD / L2D_CACHE_RD", + "BriefDescription": "L2 cache read miss rate", + "MetricGroup": "Cache", +- "MetricName": "L2 cache read miss" ++ "ScaleUnit": "1per cache read access" + }, + { +- "MetricExpr": "(L1D_CACHE_LMISS_RD * 1000) / INST_RETIRED", ++ "MetricName": "l1d_cache_miss_mpki", ++ "MetricExpr": "(L1D_CACHE_LMISS_RD * 1e3) / INST_RETIRED", + "BriefDescription": "Misses per thousand instructions (data)", + "MetricGroup": "Cache", +- "MetricName": "MPKI data" ++ "ScaleUnit": "1MPKI" + }, + { +- "MetricExpr": "(L1I_CACHE_LMISS * 1000) / INST_RETIRED", ++ "MetricName": "l1i_cache_miss_mpki", ++ "MetricExpr": "(L1I_CACHE_LMISS * 1e3) / INST_RETIRED", + "BriefDescription": "Misses per thousand instructions (instruction)", + "MetricGroup": "Cache", +- "MetricName": "MPKI instruction" ++ "ScaleUnit": "1MPKI" + }, + { +- "MetricExpr": "ASE_SPEC / OP_SPEC", +- "BriefDescription": "Proportion of advanced SIMD data processing operations (excluding DP_SPEC/LD_SPEC) operations", +- "MetricGroup": "Instruction", +- "MetricName": "ASE mix" ++ "MetricName": "simd_percentage", ++ "MetricExpr": "((ASE_SPEC / INST_SPEC) * 100)", ++ "BriefDescription": "This metric measures advanced SIMD operations as a percentage of total operations speculatively executed.", ++ "MetricGroup": "Operation_Mix", ++ "ScaleUnit": "1percent of operations" + }, + { +- "MetricExpr": "CRYPTO_SPEC / OP_SPEC", +- "BriefDescription": "Proportion of crypto data processing operations", +- "MetricGroup": "Instruction", +- "MetricName": "Crypto mix" ++ "MetricName": "crypto_percentage", ++ "MetricExpr": "((CRYPTO_SPEC / INST_SPEC) * 100)", ++ "BriefDescription": "This metric measures crypto operations as a percentage of operations speculatively executed.", ++ "MetricGroup": "Operation_Mix", ++ "ScaleUnit": "1percent of operations" + }, + { +- "MetricExpr": "VFP_SPEC / (duration_time *1000000000)", ++ "MetricName": "gflops", ++ "MetricExpr": "VFP_SPEC / (duration_time * 1e9)", + "BriefDescription": "Giga-floating point operations per second", +- "MetricGroup": "Instruction", +- "MetricName": "GFLOPS_ISSUED" ++ "MetricGroup": "InstructionMix" + }, + { +- "MetricExpr": "DP_SPEC / OP_SPEC", +- "BriefDescription": "Proportion of integer data processing operations", +- "MetricGroup": "Instruction", +- "MetricName": "Integer mix" ++ "MetricName": "integer_dp_percentage", ++ "MetricExpr": "((DP_SPEC / INST_SPEC) * 100)", ++ "BriefDescription": "This metric measures scalar integer operations as a percentage of operations speculatively executed.", ++ "MetricGroup": "Operation_Mix", ++ "ScaleUnit": "1percent of operations" + }, + { +- "MetricExpr": "INST_RETIRED / CPU_CYCLES", +- "BriefDescription": "Instructions per cycle", +- "MetricGroup": "Instruction", +- "MetricName": "IPC" ++ "MetricName": "ipc", ++ "MetricExpr": "(INST_RETIRED / CPU_CYCLES)", ++ "BriefDescription": "This metric measures the number of instructions retired per cycle.", ++ "MetricGroup": "General", ++ "ScaleUnit": "1per cycle" + }, + { +- "MetricExpr": "LD_SPEC / OP_SPEC", +- "BriefDescription": "Proportion of load operations", +- "MetricGroup": "Instruction", +- "MetricName": "Load mix" ++ "MetricName": "load_percentage", ++ "MetricExpr": "((LD_SPEC / INST_SPEC) * 100)", ++ "BriefDescription": "This metric measures load operations as a percentage of operations speculatively executed.", ++ "MetricGroup": "Operation_Mix", ++ "ScaleUnit": "1percent of operations" + }, + { +- "MetricExpr": "LDST_SPEC/ OP_SPEC", +- "BriefDescription": "Proportion of load & store operations", +- "MetricGroup": "Instruction", +- "MetricName": "Load-store mix" ++ "MetricName": "load_store_spec_rate", ++ "MetricExpr": "((LDST_SPEC / INST_SPEC) * 100)", ++ "BriefDescription": "The rate of load or store instructions speculatively executed to overall instructions speclatively executed", ++ "MetricGroup": "Operation_Mix", ++ "ScaleUnit": "1percent of operations" + }, + { +- "MetricExpr": "INST_RETIRED / (duration_time * 1000000)", ++ "MetricName": "retired_mips", ++ "MetricExpr": "INST_RETIRED / (duration_time * 1e6)", + "BriefDescription": "Millions of instructions per second", +- "MetricGroup": "Instruction", +- "MetricName": "MIPS_RETIRED" ++ "MetricGroup": "InstructionMix" + }, + { +- "MetricExpr": "INST_SPEC / (duration_time * 1000000)", ++ "MetricName": "spec_utilization_mips", ++ "MetricExpr": "INST_SPEC / (duration_time * 1e6)", + "BriefDescription": "Millions of instructions per second", +- "MetricGroup": "Instruction", +- "MetricName": "MIPS_UTILIZATION" +- }, +- { +- "MetricExpr": "PC_WRITE_SPEC / OP_SPEC", +- "BriefDescription": "Proportion of software change of PC operations", +- "MetricGroup": "Instruction", +- "MetricName": "PC write mix" ++ "MetricGroup": "PEutilization" + }, + { +- "MetricExpr": "ST_SPEC / OP_SPEC", +- "BriefDescription": "Proportion of store operations", +- "MetricGroup": "Instruction", +- "MetricName": "Store mix" ++ "MetricName": "pc_write_spec_rate", ++ "MetricExpr": "((PC_WRITE_SPEC / INST_SPEC) * 100)", ++ "BriefDescription": "The rate of software change of the PC speculatively executed to overall instructions speclatively executed", ++ "MetricGroup": "Operation_Mix", ++ "ScaleUnit": "1percent of operations" + }, + { +- "MetricExpr": "VFP_SPEC / OP_SPEC", +- "BriefDescription": "Proportion of FP operations", +- "MetricGroup": "Instruction", +- "MetricName": "VFP mix" ++ "MetricName": "store_percentage", ++ "MetricExpr": "((ST_SPEC / INST_SPEC) * 100)", ++ "BriefDescription": "This metric measures store operations as a percentage of operations speculatively executed.", ++ "MetricGroup": "Operation_Mix", ++ "ScaleUnit": "1percent of operations" + }, + { +- "MetricExpr": "1 - (OP_RETIRED/ (CPU_CYCLES * 4))", +- "BriefDescription": "Proportion of slots lost", +- "MetricGroup": "Speculation / TDA", +- "MetricName": "CPU lost" ++ "MetricName": "scalar_fp_percentage", ++ "MetricExpr": "((VFP_SPEC / INST_SPEC) * 100)", ++ "BriefDescription": "This metric measures scalar floating point operations as a percentage of operations speculatively executed.", ++ "MetricGroup": "Operation_Mix", ++ "ScaleUnit": "1percent of operations" + }, + { +- "MetricExpr": "OP_RETIRED/ (CPU_CYCLES * 4)", +- "BriefDescription": "Proportion of slots retiring", +- "MetricGroup": "Speculation / TDA", +- "MetricName": "CPU utilization" ++ "MetricName": "retired_rate", ++ "MetricExpr": "OP_RETIRED / OP_SPEC", ++ "BriefDescription": "Of all the micro-operations issued, what percentage are retired(committed)", ++ "MetricGroup": "General", ++ "ScaleUnit": "100%" + }, + { +- "MetricExpr": "OP_RETIRED - OP_SPEC", +- "BriefDescription": "Operations lost due to misspeculation", +- "MetricGroup": "Speculation / TDA", +- "MetricName": "Operations lost" ++ "MetricName": "wasted", ++ "MetricExpr": "1 - (OP_RETIRED / (CPU_CYCLES * #slots))", ++ "BriefDescription": "Of all the micro-operations issued, what proportion are lost", ++ "MetricGroup": "General", ++ "ScaleUnit": "100%" + }, + { +- "MetricExpr": "1 - (OP_RETIRED / OP_SPEC)", +- "BriefDescription": "Proportion of operations lost", +- "MetricGroup": "Speculation / TDA", +- "MetricName": "Operations lost (ratio)" ++ "MetricName": "wasted_rate", ++ "MetricExpr": "1 - OP_RETIRED / OP_SPEC", ++ "BriefDescription": "Of all the micro-operations issued, what percentage are not retired(committed)", ++ "MetricGroup": "General", ++ "ScaleUnit": "100%" + }, + { +- "MetricExpr": "OP_RETIRED / OP_SPEC", +- "BriefDescription": "Proportion of operations retired", +- "MetricGroup": "Speculation / TDA", +- "MetricName": "Operations retired" +- }, +- { +- "MetricExpr": "STALL_BACKEND_CACHE / CPU_CYCLES", ++ "MetricName": "stall_backend_cache_rate", ++ "MetricExpr": "((STALL_BACKEND_CACHE / CPU_CYCLES) * 100)", + "BriefDescription": "Proportion of cycles stalled and no operations issued to backend and cache miss", + "MetricGroup": "Stall", +- "MetricName": "Stall backend cache cycles" ++ "ScaleUnit": "1percent of cycles" + }, + { +- "MetricExpr": "STALL_BACKEND_RESOURCE / CPU_CYCLES", ++ "MetricName": "stall_backend_resource_rate", ++ "MetricExpr": "((STALL_BACKEND_RESOURCE / CPU_CYCLES) * 100)", + "BriefDescription": "Proportion of cycles stalled and no operations issued to backend and resource full", + "MetricGroup": "Stall", +- "MetricName": "Stall backend resource cycles" ++ "ScaleUnit": "1percent of cycles" + }, + { +- "MetricExpr": "STALL_BACKEND_TLB / CPU_CYCLES", ++ "MetricName": "stall_backend_tlb_rate", ++ "MetricExpr": "((STALL_BACKEND_TLB / CPU_CYCLES) * 100)", + "BriefDescription": "Proportion of cycles stalled and no operations issued to backend and TLB miss", + "MetricGroup": "Stall", +- "MetricName": "Stall backend tlb cycles" ++ "ScaleUnit": "1percent of cycles" + }, + { +- "MetricExpr": "STALL_FRONTEND_CACHE / CPU_CYCLES", ++ "MetricName": "stall_frontend_cache_rate", ++ "MetricExpr": "((STALL_FRONTEND_CACHE / CPU_CYCLES) * 100)", + "BriefDescription": "Proportion of cycles stalled and no ops delivered from frontend and cache miss", + "MetricGroup": "Stall", +- "MetricName": "Stall frontend cache cycles" ++ "ScaleUnit": "1percent of cycles" + }, + { +- "MetricExpr": "STALL_FRONTEND_TLB / CPU_CYCLES", ++ "MetricName": "stall_frontend_tlb_rate", ++ "MetricExpr": "((STALL_FRONTEND_TLB / CPU_CYCLES) * 100)", + "BriefDescription": "Proportion of cycles stalled and no ops delivered from frontend and TLB miss", + "MetricGroup": "Stall", +- "MetricName": "Stall frontend tlb cycles" ++ "ScaleUnit": "1percent of cycles" + }, + { +- "MetricExpr": "DTLB_WALK / L1D_TLB", +- "BriefDescription": "D-side walk per d-side translation request", +- "MetricGroup": "TLB", +- "MetricName": "DTLB walks" ++ "MetricName": "dtlb_walk_ratio", ++ "MetricExpr": "(DTLB_WALK / L1D_TLB)", ++ "BriefDescription": "This metric measures the ratio of data TLB Walks to the total number of data TLB accesses. This gives an indication of the effectiveness of the data TLB accesses.", ++ "MetricGroup": "Miss_Ratio;DTLB_Effectiveness", ++ "ScaleUnit": "1per TLB access" + }, + { +- "MetricExpr": "ITLB_WALK / L1I_TLB", +- "BriefDescription": "I-side walk per i-side translation request", +- "MetricGroup": "TLB", +- "MetricName": "ITLB walks" ++ "MetricName": "itlb_walk_ratio", ++ "MetricExpr": "(ITLB_WALK / L1I_TLB)", ++ "BriefDescription": "This metric measures the ratio of instruction TLB Walks to the total number of instruction TLB accesses. This gives an indication of the effectiveness of the instruction TLB accesses.", ++ "MetricGroup": "Miss_Ratio;ITLB_Effectiveness", ++ "ScaleUnit": "1per TLB access" + }, + { +- "MetricExpr": "STALL_SLOT_BACKEND / (CPU_CYCLES * 4)", +- "BriefDescription": "Fraction of slots backend bound", +- "MetricGroup": "TopDownL1", +- "MetricName": "backend" ++ "ArchStdEvent": "backend_bound" + }, + { +- "MetricExpr": "1 - (retiring + lost + backend)", +- "BriefDescription": "Fraction of slots frontend bound", +- "MetricGroup": "TopDownL1", +- "MetricName": "frontend" ++ "ArchStdEvent": "frontend_bound", ++ "MetricExpr": "100 - (retired_fraction + slots_lost_misspeculation_fraction + backend_bound)" + }, + { +- "MetricExpr": "((OP_SPEC - OP_RETIRED) / (CPU_CYCLES * 4))", ++ "MetricName": "slots_lost_misspeculation_fraction", ++ "MetricExpr": "100 * ((OP_SPEC - OP_RETIRED) / (CPU_CYCLES * #slots))", + "BriefDescription": "Fraction of slots lost due to misspeculation", +- "MetricGroup": "TopDownL1", +- "MetricName": "lost" ++ "MetricGroup": "Default;TopdownL1", ++ "ScaleUnit": "1percent of slots" + }, + { +- "MetricExpr": "(OP_RETIRED / (CPU_CYCLES * 4))", ++ "MetricName": "retired_fraction", ++ "MetricExpr": "100 * (OP_RETIRED / (CPU_CYCLES * #slots))", + "BriefDescription": "Fraction of slots retiring, useful work", +- "MetricGroup": "TopDownL1", +- "MetricName": "retiring" ++ "MetricGroup": "Default;TopdownL1", ++ "ScaleUnit": "1percent of slots" + }, + { +- "MetricExpr": "backend - backend_memory", ++ "MetricName": "backend_core", ++ "MetricExpr": "(backend_bound / 100) - backend_memory", + "BriefDescription": "Fraction of slots the CPU was stalled due to backend non-memory subsystem issues", +- "MetricGroup": "TopDownL2", +- "MetricName": "backend_core" ++ "MetricGroup": "TopdownL2", ++ "ScaleUnit": "100%" + }, + { +- "MetricExpr": "(STALL_BACKEND_TLB + STALL_BACKEND_CACHE + STALL_BACKEND_MEM) / CPU_CYCLES ", ++ "MetricName": "backend_memory", ++ "MetricExpr": "(STALL_BACKEND_TLB + STALL_BACKEND_CACHE) / CPU_CYCLES", + "BriefDescription": "Fraction of slots the CPU was stalled due to backend memory subsystem issues (cache/tlb miss)", +- "MetricGroup": "TopDownL2", +- "MetricName": "backend_memory" ++ "MetricGroup": "TopdownL2", ++ "ScaleUnit": "100%" + }, + { +- "MetricExpr": " (BR_MIS_PRED_RETIRED / GPC_FLUSH) * lost", ++ "MetricName": "branch_mispredict", ++ "MetricExpr": "(BR_MIS_PRED_RETIRED / GPC_FLUSH) * slots_lost_misspeculation_fraction", + "BriefDescription": "Fraction of slots lost due to branch misprediciton", +- "MetricGroup": "TopDownL2", +- "MetricName": "branch_mispredict" ++ "MetricGroup": "TopdownL2", ++ "ScaleUnit": "1percent of slots" + }, + { +- "MetricExpr": "frontend - frontend_latency", ++ "MetricName": "frontend_bandwidth", ++ "MetricExpr": "frontend_bound - frontend_latency", + "BriefDescription": "Fraction of slots the CPU did not dispatch at full bandwidth - able to dispatch partial slots only (1, 2, or 3 uops)", +- "MetricGroup": "TopDownL2", +- "MetricName": "frontend_bandwidth" ++ "MetricGroup": "TopdownL2", ++ "ScaleUnit": "1percent of slots" + }, + { +- "MetricExpr": "(STALL_FRONTEND - ((STALL_SLOT_FRONTEND - (frontend * CPU_CYCLES * 4)) / 4)) / CPU_CYCLES", ++ "MetricName": "frontend_latency", ++ "MetricExpr": "((STALL_FRONTEND - ((STALL_SLOT_FRONTEND - ((frontend_bound / 100) * CPU_CYCLES * #slots)) / #slots)) / CPU_CYCLES) * 100", + "BriefDescription": "Fraction of slots the CPU was stalled due to frontend latency issues (cache/tlb miss); nothing to dispatch", +- "MetricGroup": "TopDownL2", +- "MetricName": "frontend_latency" ++ "MetricGroup": "TopdownL2", ++ "ScaleUnit": "1percent of slots" + }, + { +- "MetricExpr": "lost - branch_mispredict", ++ "MetricName": "other_miss_pred", ++ "MetricExpr": "slots_lost_misspeculation_fraction - branch_mispredict", + "BriefDescription": "Fraction of slots lost due to other/non-branch misprediction misspeculation", +- "MetricGroup": "TopDownL2", +- "MetricName": "other_clears" ++ "MetricGroup": "TopdownL2", ++ "ScaleUnit": "1percent of slots" + }, + { +- "MetricExpr": "(IXU_NUM_UOPS_ISSUED + FSU_ISSUED) / (CPU_CYCLES * 6)", ++ "MetricName": "pipe_utilization", ++ "MetricExpr": "100 * ((IXU_NUM_UOPS_ISSUED + FSU_ISSUED) / (CPU_CYCLES * 6))", + "BriefDescription": "Fraction of execute slots utilized", +- "MetricGroup": "TopDownL2", +- "MetricName": "pipe_utilization" ++ "MetricGroup": "TopdownL2", ++ "ScaleUnit": "1percent of slots" + }, + { +- "MetricExpr": "STALL_BACKEND_MEM / CPU_CYCLES", ++ "MetricName": "d_cache_l2_miss_rate", ++ "MetricExpr": "((STALL_BACKEND_MEM / CPU_CYCLES) * 100)", + "BriefDescription": "Fraction of cycles the CPU was stalled due to data L2 cache miss", +- "MetricGroup": "TopDownL3", +- "MetricName": "d_cache_l2_miss" ++ "MetricGroup": "TopdownL3", ++ "ScaleUnit": "1percent of cycles" + }, + { +- "MetricExpr": "STALL_BACKEND_CACHE / CPU_CYCLES", ++ "MetricName": "d_cache_miss_rate", ++ "MetricExpr": "((STALL_BACKEND_CACHE / CPU_CYCLES) * 100)", + "BriefDescription": "Fraction of cycles the CPU was stalled due to data cache miss", +- "MetricGroup": "TopDownL3", +- "MetricName": "d_cache_miss" ++ "MetricGroup": "TopdownL3", ++ "ScaleUnit": "1percent of cycles" + }, + { +- "MetricExpr": "STALL_BACKEND_TLB / CPU_CYCLES", ++ "MetricName": "d_tlb_miss_rate", ++ "MetricExpr": "((STALL_BACKEND_TLB / CPU_CYCLES) * 100)", + "BriefDescription": "Fraction of cycles the CPU was stalled due to data TLB miss", +- "MetricGroup": "TopDownL3", +- "MetricName": "d_tlb_miss" ++ "MetricGroup": "TopdownL3", ++ "ScaleUnit": "1percent of cycles" + }, + { +- "MetricExpr": "FSU_ISSUED / (CPU_CYCLES * 2)", ++ "MetricName": "fsu_pipe_utilization", ++ "MetricExpr": "((FSU_ISSUED / (CPU_CYCLES * 2)) * 100)", + "BriefDescription": "Fraction of FSU execute slots utilized", +- "MetricGroup": "TopDownL3", +- "MetricName": "fsu_pipe_utilization" ++ "MetricGroup": "TopdownL3", ++ "ScaleUnit": "1percent of slots" + }, + { +- "MetricExpr": "STALL_FRONTEND_CACHE / CPU_CYCLES", ++ "MetricName": "i_cache_miss_rate", ++ "MetricExpr": "((STALL_FRONTEND_CACHE / CPU_CYCLES) * 100)", + "BriefDescription": "Fraction of cycles the CPU was stalled due to instruction cache miss", +- "MetricGroup": "TopDownL3", +- "MetricName": "i_cache_miss" ++ "MetricGroup": "TopdownL3", ++ "ScaleUnit": "1percent of slots" + }, + { +- "MetricExpr": " STALL_FRONTEND_TLB / CPU_CYCLES ", ++ "MetricName": "i_tlb_miss_rate", ++ "MetricExpr": "((STALL_FRONTEND_TLB / CPU_CYCLES) * 100)", + "BriefDescription": "Fraction of cycles the CPU was stalled due to instruction TLB miss", +- "MetricGroup": "TopDownL3", +- "MetricName": "i_tlb_miss" ++ "MetricGroup": "TopdownL3", ++ "ScaleUnit": "1percent of slots" + }, + { +- "MetricExpr": "IXU_NUM_UOPS_ISSUED / (CPU_CYCLES / 4)", ++ "MetricName": "ixu_pipe_utilization", ++ "MetricExpr": "((IXU_NUM_UOPS_ISSUED / (CPU_CYCLES * #slots)) * 100)", + "BriefDescription": "Fraction of IXU execute slots utilized", +- "MetricGroup": "TopDownL3", +- "MetricName": "ixu_pipe_utilization" ++ "MetricGroup": "TopdownL3", ++ "ScaleUnit": "1percent of slots" + }, + { +- "MetricExpr": "IDR_STALL_FLUSH / CPU_CYCLES", ++ "MetricName": "stall_recovery_rate", ++ "MetricExpr": "((IDR_STALL_FLUSH / CPU_CYCLES) * 100)", + "BriefDescription": "Fraction of cycles the CPU was stalled due to flush recovery", +- "MetricGroup": "TopDownL3", +- "MetricName": "recovery" +- }, +- { +- "MetricExpr": "STALL_BACKEND_RESOURCE / CPU_CYCLES", +- "BriefDescription": "Fraction of cycles the CPU was stalled due to core resource shortage", +- "MetricGroup": "TopDownL3", +- "MetricName": "resource" ++ "MetricGroup": "TopdownL3", ++ "ScaleUnit": "1percent of slots" + }, + { +- "MetricExpr": "IDR_STALL_FSU_SCHED / CPU_CYCLES ", ++ "MetricName": "stall_fsu_sched_rate", ++ "MetricExpr": "((IDR_STALL_FSU_SCHED / CPU_CYCLES) * 100)", + "BriefDescription": "Fraction of cycles the CPU was stalled and FSU was full", +- "MetricGroup": "TopDownL4", +- "MetricName": "stall_fsu_sched" ++ "MetricGroup": "TopdownL4", ++ "ScaleUnit": "1percent of cycles" + }, + { +- "MetricExpr": "IDR_STALL_IXU_SCHED / CPU_CYCLES ", ++ "MetricName": "stall_ixu_sched_rate", ++ "MetricExpr": "((IDR_STALL_IXU_SCHED / CPU_CYCLES) * 100)", + "BriefDescription": "Fraction of cycles the CPU was stalled and IXU was full", +- "MetricGroup": "TopDownL4", +- "MetricName": "stall_ixu_sched" ++ "MetricGroup": "TopdownL4", ++ "ScaleUnit": "1percent of cycles" + }, + { +- "MetricExpr": "IDR_STALL_LOB_ID / CPU_CYCLES ", ++ "MetricName": "stall_lob_id_rate", ++ "MetricExpr": "((IDR_STALL_LOB_ID / CPU_CYCLES) * 100)", + "BriefDescription": "Fraction of cycles the CPU was stalled and LOB was full", +- "MetricGroup": "TopDownL4", +- "MetricName": "stall_lob_id" ++ "MetricGroup": "TopdownL4", ++ "ScaleUnit": "1percent of cycles" + }, + { +- "MetricExpr": "IDR_STALL_ROB_ID / CPU_CYCLES", ++ "MetricName": "stall_rob_id_rate", ++ "MetricExpr": "((IDR_STALL_ROB_ID / CPU_CYCLES) * 100)", + "BriefDescription": "Fraction of cycles the CPU was stalled and ROB was full", +- "MetricGroup": "TopDownL4", +- "MetricName": "stall_rob_id" ++ "MetricGroup": "TopdownL4", ++ "ScaleUnit": "1percent of cycles" + }, + { +- "MetricExpr": "IDR_STALL_SOB_ID / CPU_CYCLES ", ++ "MetricName": "stall_sob_id_rate", ++ "MetricExpr": "((IDR_STALL_SOB_ID / CPU_CYCLES) * 100)", + "BriefDescription": "Fraction of cycles the CPU was stalled and SOB was full", +- "MetricGroup": "TopDownL4", +- "MetricName": "stall_sob_id" ++ "MetricGroup": "TopdownL4", ++ "ScaleUnit": "1percent of cycles" + } + ] +-- +2.42.0 + diff --git a/queue-6.6/perf-vendor-events-intel-add-broadwellde-two-metrics.patch b/queue-6.6/perf-vendor-events-intel-add-broadwellde-two-metrics.patch new file mode 100644 index 00000000000..3dfe7ec248e --- /dev/null +++ b/queue-6.6/perf-vendor-events-intel-add-broadwellde-two-metrics.patch @@ -0,0 +1,60 @@ +From 959517a5298753c6a1bd3be83a51cd066f97583d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Sep 2023 13:59:47 -0700 +Subject: perf vendor events intel: Add broadwellde two metrics + +From: Ian Rogers + +[ Upstream commit 19a214bffdf7abb8d472895bb944d9c269ab1699 ] + +Add tma_info_system_socket_clks and uncore_freq metrics that require a +broadwellx style uncore event for UNC_CLOCK. + +The associated converter script fix is in: +https://github.com/intel/perfmon/pull/112 + +Fixes: 7d124303d620 ("perf vendor events intel: Update broadwell variant events/metrics") +Signed-off-by: Ian Rogers +Reviewed-by: Kan Liang +Cc: Caleb Biggers +Cc: Perry Taylor +Link: https://lore.kernel.org/r/20230926205948.1399594-2-irogers@google.com +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + .../arch/x86/broadwellde/bdwde-metrics.json | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/tools/perf/pmu-events/arch/x86/broadwellde/bdwde-metrics.json b/tools/perf/pmu-events/arch/x86/broadwellde/bdwde-metrics.json +index d0ef46c9bb612..e1f55fcfa0d02 100644 +--- a/tools/perf/pmu-events/arch/x86/broadwellde/bdwde-metrics.json ++++ b/tools/perf/pmu-events/arch/x86/broadwellde/bdwde-metrics.json +@@ -48,6 +48,12 @@ + "MetricName": "C7_Pkg_Residency", + "ScaleUnit": "100%" + }, ++ { ++ "BriefDescription": "Uncore frequency per die [GHZ]", ++ "MetricExpr": "tma_info_system_socket_clks / #num_dies / duration_time / 1e9", ++ "MetricGroup": "SoC", ++ "MetricName": "UNCORE_FREQ" ++ }, + { + "BriefDescription": "Percentage of cycles spent in System Management Interrupts.", + "MetricExpr": "((msr@aperf@ - cycles) / msr@aperf@ if msr@smi@ > 0 else 0)", +@@ -690,6 +696,12 @@ + "MetricGroup": "SMT", + "MetricName": "tma_info_system_smt_2t_utilization" + }, ++ { ++ "BriefDescription": "Socket actual clocks when any core is active on that socket", ++ "MetricExpr": "cbox_0@event\\=0x0@", ++ "MetricGroup": "SoC", ++ "MetricName": "tma_info_system_socket_clks" ++ }, + { + "BriefDescription": "Average Frequency Utilization relative nominal frequency", + "MetricExpr": "tma_info_thread_clks / CPU_CLK_UNHALTED.REF_TSC", +-- +2.42.0 + diff --git a/queue-6.6/perf-vendor-events-intel-fix-broadwellde-tma_info_sy.patch b/queue-6.6/perf-vendor-events-intel-fix-broadwellde-tma_info_sy.patch new file mode 100644 index 00000000000..37b9a2fd525 --- /dev/null +++ b/queue-6.6/perf-vendor-events-intel-fix-broadwellde-tma_info_sy.patch @@ -0,0 +1,46 @@ +From bf195140360268ab43def2ee34bc7d0d619af602 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Sep 2023 20:10:34 -0700 +Subject: perf vendor events intel: Fix broadwellde tma_info_system_dram_bw_use + metric + +From: Ian Rogers + +[ Upstream commit 3779416eed25a843364b940decee452620a1de4b ] + +Broadwell-de has a consumer core and server uncore. The uncore_arb PMU +isn't present and the broadwellx style cbox PMU should be used +instead. Fix the tma_info_system_dram_bw_use metric to use the server +metric rather than client. + +The associated converter script fix is in: +https://github.com/intel/perfmon/pull/111 + +Fixes: 7d124303d620 ("perf vendor events intel: Update broadwell variant events/metrics") +Signed-off-by: Ian Rogers +Reviewed-by: Kan Liang +Cc: Caleb Biggers +Cc: Perry Taylor +Link: https://lore.kernel.org/r/20230926031034.1201145-1-irogers@google.com +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/pmu-events/arch/x86/broadwellde/bdwde-metrics.json | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/pmu-events/arch/x86/broadwellde/bdwde-metrics.json b/tools/perf/pmu-events/arch/x86/broadwellde/bdwde-metrics.json +index 8fc62b8f667d8..d0ef46c9bb612 100644 +--- a/tools/perf/pmu-events/arch/x86/broadwellde/bdwde-metrics.json ++++ b/tools/perf/pmu-events/arch/x86/broadwellde/bdwde-metrics.json +@@ -652,7 +652,7 @@ + }, + { + "BriefDescription": "Average external Memory Bandwidth Use for reads and writes [GB / sec]", +- "MetricExpr": "64 * (arb@event\\=0x81\\,umask\\=0x1@ + arb@event\\=0x84\\,umask\\=0x1@) / 1e6 / duration_time / 1e3", ++ "MetricExpr": "64 * (UNC_M_CAS_COUNT.RD + UNC_M_CAS_COUNT.WR) / 1e9 / duration_time", + "MetricGroup": "HPC;Mem;MemoryBW;SoC;tma_issueBW", + "MetricName": "tma_info_system_dram_bw_use", + "PublicDescription": "Average external Memory Bandwidth Use for reads and writes [GB / sec]. Related metrics: tma_fb_full, tma_mem_bandwidth, tma_sq_full" +-- +2.42.0 + diff --git a/queue-6.6/perf-vendor-events-update-pmc-used-in-pm_run_inst_cm.patch b/queue-6.6/perf-vendor-events-update-pmc-used-in-pm_run_inst_cm.patch new file mode 100644 index 00000000000..f360641850a --- /dev/null +++ b/queue-6.6/perf-vendor-events-update-pmc-used-in-pm_run_inst_cm.patch @@ -0,0 +1,73 @@ +From 5d2029e3db96d9a585b6ddd25f1a7f8f9001c6e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Oct 2023 20:01:10 +0530 +Subject: perf vendor events: Update PMC used in PM_RUN_INST_CMPL event for + power10 platform + +From: Kajol Jain + +[ Upstream commit 3f8b6e5b11192dacb721d2d28ea4589917f5e822 ] + +The CPI_STALL_RATIO metric group can be used to present the high +level CPI stall breakdown metrics in powerpc, which will show: + +- DISPATCH_STALL_CPI ( Dispatch stall cycles per insn ) +- ISSUE_STALL_CPI ( Issue stall cycles per insn ) +- EXECUTION_STALL_CPI ( Execution stall cycles per insn ) +- COMPLETION_STALL_CPI ( Completion stall cycles per insn ) + +Commit cf26e043c2a9 ("perf vendor events power10: Add JSON +metric events to present CPI stall cycles in powerpc)" which added +the CPI_STALL_RATIO metric group, also modified +the PMC value used in PM_RUN_INST_CMPL event from PMC4 to PMC5, +to avoid multiplexing of events. +But that got revert in recent changes. Fix this issue by changing +back the PMC value used in PM_RUN_INST_CMPL to PMC5. + +Result with the fix: + + ./perf stat --metric-no-group -M CPI_STALL_RATIO + + Performance counter stats for 'workload': + + 68,745,426 PM_CMPL_STALL # 0.21 COMPLETION_STALL_CPI + 7,692,827 PM_ISSUE_STALL # 0.02 ISSUE_STALL_CPI + 322,638,223 PM_RUN_INST_CMPL # 0.05 DISPATCH_STALL_CPI + # 0.48 EXECUTION_STALL_CPI + 16,858,553 PM_DISP_STALL_CYC + 153,880,133 PM_EXEC_STALL + + 0.089774592 seconds time elapsed + +"--metric-no-group" is used for forcing PM_RUN_INST_CMPL to be scheduled +in all group for more accuracy. + +Fixes: 7d473f475b2a ("perf vendor events: Move JSON/events to appropriate files for power10 platform") +Reported-by: Disha Goel +Signed-off-by: Kajol Jain +Reviewed-by: Athira Rajeev +Tested-by: Disha Goel +Cc: maddy@linux.ibm.com +Link: https://lore.kernel.org/r/20231016143110.244255-1-kjain@linux.ibm.com +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/pmu-events/arch/powerpc/power10/pmc.json | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/pmu-events/arch/powerpc/power10/pmc.json b/tools/perf/pmu-events/arch/powerpc/power10/pmc.json +index c606ae03cd27d..0e0253d0e7577 100644 +--- a/tools/perf/pmu-events/arch/powerpc/power10/pmc.json ++++ b/tools/perf/pmu-events/arch/powerpc/power10/pmc.json +@@ -195,7 +195,7 @@ + "BriefDescription": "Threshold counter exceeded a value of 128." + }, + { +- "EventCode": "0x400FA", ++ "EventCode": "0x500FA", + "EventName": "PM_RUN_INST_CMPL", + "BriefDescription": "PowerPC instruction completed while the run latch is set." + } +-- +2.42.0 + diff --git a/queue-6.6/pinctrl-baytrail-fix-debounce-disable-case.patch b/queue-6.6/pinctrl-baytrail-fix-debounce-disable-case.patch new file mode 100644 index 00000000000..a3175603d27 --- /dev/null +++ b/queue-6.6/pinctrl-baytrail-fix-debounce-disable-case.patch @@ -0,0 +1,51 @@ +From 4eef992ef82b748b8cfe3f1d5e753d9c194124e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 21:18:15 +0530 +Subject: pinctrl: baytrail: fix debounce disable case + +From: Raag Jadav + +[ Upstream commit 2d325e54d9e2e4ae247c9fd03f810208ce958c51 ] + +We don't need to update debounce pulse value in case debounce is to be +disabled. Break such a case where arg value is zero. + +Fixes: 4cfff5b7af8b ("pinctrl: baytrail: consolidate common mask operation") +Reported-by: Dan Carpenter +Closes: https://lore.kernel.org/linux-gpio/d164d471-5432-4c3c-afdb-33dc8f53d043@moroto.mountain/ +Signed-off-by: Raag Jadav +Acked-by: Mika Westerberg +Signed-off-by: Andy Shevchenko +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/intel/pinctrl-baytrail.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c +index faa8b7ff5bcf3..ec76e43527c5c 100644 +--- a/drivers/pinctrl/intel/pinctrl-baytrail.c ++++ b/drivers/pinctrl/intel/pinctrl-baytrail.c +@@ -983,11 +983,18 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, + + break; + case PIN_CONFIG_INPUT_DEBOUNCE: +- if (arg) ++ if (arg) { + conf |= BYT_DEBOUNCE_EN; +- else ++ } else { + conf &= ~BYT_DEBOUNCE_EN; + ++ /* ++ * No need to update the pulse value. ++ * Debounce is going to be disabled. ++ */ ++ break; ++ } ++ + switch (arg) { + case 375: + db_pulse = BYT_DEBOUNCE_PULSE_375US; +-- +2.42.0 + diff --git a/queue-6.6/pinctrl-renesas-rzg2l-make-reverse-order-of-enable-f.patch b/queue-6.6/pinctrl-renesas-rzg2l-make-reverse-order-of-enable-f.patch new file mode 100644 index 00000000000..a9007c86a2b --- /dev/null +++ b/queue-6.6/pinctrl-renesas-rzg2l-make-reverse-order-of-enable-f.patch @@ -0,0 +1,48 @@ +From b290467cc7d48f85568611d42ec18db25b0ed8d4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Sep 2023 13:33:54 +0100 +Subject: pinctrl: renesas: rzg2l: Make reverse order of enable() for disable() + +From: Biju Das + +[ Upstream commit dd462cf53e4dff0f4eba5e6650e31ceddec74c6f ] + +We usually do reverse order of enable() for disable(). Currently, the +ordering of irq_chip_disable_parent() is not correct in +rzg2l_gpio_irq_disable(). Fix the incorrect order. + +Fixes: db2e5f21a48e ("pinctrl: renesas: pinctrl-rzg2l: Add IRQ domain to handle GPIO interrupt") +Signed-off-by: Biju Das +Tested-by: Claudiu Beznea +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20230918123355.262115-2-biju.das.jz@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/renesas/pinctrl-rzg2l.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c +index 37cdfe4b04f9a..2ea6ef99cc70b 100644 +--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c ++++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c +@@ -1175,6 +1175,8 @@ static void rzg2l_gpio_irq_disable(struct irq_data *d) + u32 port; + u8 bit; + ++ irq_chip_disable_parent(d); ++ + port = RZG2L_PIN_ID_TO_PORT(hwirq); + bit = RZG2L_PIN_ID_TO_PIN(hwirq); + +@@ -1189,7 +1191,6 @@ static void rzg2l_gpio_irq_disable(struct irq_data *d) + spin_unlock_irqrestore(&pctrl->lock, flags); + + gpiochip_disable_irq(gc, hwirq); +- irq_chip_disable_parent(d); + } + + static void rzg2l_gpio_irq_enable(struct irq_data *d) +-- +2.42.0 + diff --git a/queue-6.6/platform-chrome-cros_ec_lpc-separate-host-command-an.patch b/queue-6.6/platform-chrome-cros_ec_lpc-separate-host-command-an.patch new file mode 100644 index 00000000000..f814413b2d4 --- /dev/null +++ b/queue-6.6/platform-chrome-cros_ec_lpc-separate-host-command-an.patch @@ -0,0 +1,264 @@ +From 2d977b6d01934bbde3bbbe61f7d1a796b21efa74 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Oct 2023 16:02:22 -0500 +Subject: platform/chrome: cros_ec_lpc: Separate host command and irq disable + +From: Lalith Rajendran + +[ Upstream commit 47ea0ddb1f5604ba3496baa19110aec6a3151f2e ] + +Both cros host command and irq disable were moved to suspend +prepare stage from late suspend recently. This is causing EC +to report MKBP event timeouts during suspend stress testing. +When the MKBP event timeouts happen during suspend, subsequent +wakeup of AP by EC using MKBP doesn't happen properly. Move the +irq disabling part back to late suspend stage which is a general +suggestion from the suspend kernel documentaiton to do irq +disable as late as possible. + +Fixes: 4b9abbc132b8 ("platform/chrome: cros_ec_lpc: Move host command to prepare/complete") +Signed-off-by: Lalith Rajendran +Link: https://lore.kernel.org/r/20231027160221.v4.1.I1725c3ed27eb7cd9836904e49e8bfa9fb0200a97@changeid +Signed-off-by: Tzung-Bi Shih +Signed-off-by: Sasha Levin +--- + drivers/platform/chrome/cros_ec.c | 116 +++++++++++++++++++++----- + drivers/platform/chrome/cros_ec.h | 4 + + drivers/platform/chrome/cros_ec_lpc.c | 22 ++++- + 3 files changed, 116 insertions(+), 26 deletions(-) + +diff --git a/drivers/platform/chrome/cros_ec.c b/drivers/platform/chrome/cros_ec.c +index 5d36fbc75e1bb..badc68bbae8cc 100644 +--- a/drivers/platform/chrome/cros_ec.c ++++ b/drivers/platform/chrome/cros_ec.c +@@ -321,17 +321,8 @@ void cros_ec_unregister(struct cros_ec_device *ec_dev) + EXPORT_SYMBOL(cros_ec_unregister); + + #ifdef CONFIG_PM_SLEEP +-/** +- * cros_ec_suspend() - Handle a suspend operation for the ChromeOS EC device. +- * @ec_dev: Device to suspend. +- * +- * This can be called by drivers to handle a suspend event. +- * +- * Return: 0 on success or negative error code. +- */ +-int cros_ec_suspend(struct cros_ec_device *ec_dev) ++static void cros_ec_send_suspend_event(struct cros_ec_device *ec_dev) + { +- struct device *dev = ec_dev->dev; + int ret; + u8 sleep_event; + +@@ -343,7 +334,26 @@ int cros_ec_suspend(struct cros_ec_device *ec_dev) + if (ret < 0) + dev_dbg(ec_dev->dev, "Error %d sending suspend event to ec\n", + ret); ++} + ++/** ++ * cros_ec_suspend_prepare() - Handle a suspend prepare operation for the ChromeOS EC device. ++ * @ec_dev: Device to suspend. ++ * ++ * This can be called by drivers to handle a suspend prepare stage of suspend. ++ * ++ * Return: 0 always. ++ */ ++int cros_ec_suspend_prepare(struct cros_ec_device *ec_dev) ++{ ++ cros_ec_send_suspend_event(ec_dev); ++ return 0; ++} ++EXPORT_SYMBOL(cros_ec_suspend_prepare); ++ ++static void cros_ec_disable_irq(struct cros_ec_device *ec_dev) ++{ ++ struct device *dev = ec_dev->dev; + if (device_may_wakeup(dev)) + ec_dev->wake_enabled = !enable_irq_wake(ec_dev->irq); + else +@@ -351,7 +361,35 @@ int cros_ec_suspend(struct cros_ec_device *ec_dev) + + disable_irq(ec_dev->irq); + ec_dev->suspended = true; ++} + ++/** ++ * cros_ec_suspend_late() - Handle a suspend late operation for the ChromeOS EC device. ++ * @ec_dev: Device to suspend. ++ * ++ * This can be called by drivers to handle a suspend late stage of suspend. ++ * ++ * Return: 0 always. ++ */ ++int cros_ec_suspend_late(struct cros_ec_device *ec_dev) ++{ ++ cros_ec_disable_irq(ec_dev); ++ return 0; ++} ++EXPORT_SYMBOL(cros_ec_suspend_late); ++ ++/** ++ * cros_ec_suspend() - Handle a suspend operation for the ChromeOS EC device. ++ * @ec_dev: Device to suspend. ++ * ++ * This can be called by drivers to handle a suspend event. ++ * ++ * Return: 0 always. ++ */ ++int cros_ec_suspend(struct cros_ec_device *ec_dev) ++{ ++ cros_ec_send_suspend_event(ec_dev); ++ cros_ec_disable_irq(ec_dev); + return 0; + } + EXPORT_SYMBOL(cros_ec_suspend); +@@ -370,22 +408,11 @@ static void cros_ec_report_events_during_suspend(struct cros_ec_device *ec_dev) + } + } + +-/** +- * cros_ec_resume() - Handle a resume operation for the ChromeOS EC device. +- * @ec_dev: Device to resume. +- * +- * This can be called by drivers to handle a resume event. +- * +- * Return: 0 on success or negative error code. +- */ +-int cros_ec_resume(struct cros_ec_device *ec_dev) ++static void cros_ec_send_resume_event(struct cros_ec_device *ec_dev) + { + int ret; + u8 sleep_event; + +- ec_dev->suspended = false; +- enable_irq(ec_dev->irq); +- + sleep_event = (!IS_ENABLED(CONFIG_ACPI) || pm_suspend_via_firmware()) ? + HOST_SLEEP_EVENT_S3_RESUME : + HOST_SLEEP_EVENT_S0IX_RESUME; +@@ -394,6 +421,24 @@ int cros_ec_resume(struct cros_ec_device *ec_dev) + if (ret < 0) + dev_dbg(ec_dev->dev, "Error %d sending resume event to ec\n", + ret); ++} ++ ++/** ++ * cros_ec_resume_complete() - Handle a resume complete operation for the ChromeOS EC device. ++ * @ec_dev: Device to resume. ++ * ++ * This can be called by drivers to handle a resume complete stage of resume. ++ */ ++void cros_ec_resume_complete(struct cros_ec_device *ec_dev) ++{ ++ cros_ec_send_resume_event(ec_dev); ++} ++EXPORT_SYMBOL(cros_ec_resume_complete); ++ ++static void cros_ec_enable_irq(struct cros_ec_device *ec_dev) ++{ ++ ec_dev->suspended = false; ++ enable_irq(ec_dev->irq); + + if (ec_dev->wake_enabled) + disable_irq_wake(ec_dev->irq); +@@ -403,8 +448,35 @@ int cros_ec_resume(struct cros_ec_device *ec_dev) + * suspend. This way the clients know what to do with them. + */ + cros_ec_report_events_during_suspend(ec_dev); ++} + ++/** ++ * cros_ec_resume_early() - Handle a resume early operation for the ChromeOS EC device. ++ * @ec_dev: Device to resume. ++ * ++ * This can be called by drivers to handle a resume early stage of resume. ++ * ++ * Return: 0 always. ++ */ ++int cros_ec_resume_early(struct cros_ec_device *ec_dev) ++{ ++ cros_ec_enable_irq(ec_dev); ++ return 0; ++} ++EXPORT_SYMBOL(cros_ec_resume_early); + ++/** ++ * cros_ec_resume() - Handle a resume operation for the ChromeOS EC device. ++ * @ec_dev: Device to resume. ++ * ++ * This can be called by drivers to handle a resume event. ++ * ++ * Return: 0 always. ++ */ ++int cros_ec_resume(struct cros_ec_device *ec_dev) ++{ ++ cros_ec_enable_irq(ec_dev); ++ cros_ec_send_resume_event(ec_dev); + return 0; + } + EXPORT_SYMBOL(cros_ec_resume); +diff --git a/drivers/platform/chrome/cros_ec.h b/drivers/platform/chrome/cros_ec.h +index bbca0096868ac..566332f487892 100644 +--- a/drivers/platform/chrome/cros_ec.h ++++ b/drivers/platform/chrome/cros_ec.h +@@ -14,7 +14,11 @@ int cros_ec_register(struct cros_ec_device *ec_dev); + void cros_ec_unregister(struct cros_ec_device *ec_dev); + + int cros_ec_suspend(struct cros_ec_device *ec_dev); ++int cros_ec_suspend_late(struct cros_ec_device *ec_dev); ++int cros_ec_suspend_prepare(struct cros_ec_device *ec_dev); + int cros_ec_resume(struct cros_ec_device *ec_dev); ++int cros_ec_resume_early(struct cros_ec_device *ec_dev); ++void cros_ec_resume_complete(struct cros_ec_device *ec_dev); + + irqreturn_t cros_ec_irq_thread(int irq, void *data); + +diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c +index 356572452898d..42e1770887fb0 100644 +--- a/drivers/platform/chrome/cros_ec_lpc.c ++++ b/drivers/platform/chrome/cros_ec_lpc.c +@@ -549,22 +549,36 @@ MODULE_DEVICE_TABLE(dmi, cros_ec_lpc_dmi_table); + static int cros_ec_lpc_prepare(struct device *dev) + { + struct cros_ec_device *ec_dev = dev_get_drvdata(dev); +- +- return cros_ec_suspend(ec_dev); ++ return cros_ec_suspend_prepare(ec_dev); + } + + static void cros_ec_lpc_complete(struct device *dev) + { + struct cros_ec_device *ec_dev = dev_get_drvdata(dev); +- cros_ec_resume(ec_dev); ++ cros_ec_resume_complete(ec_dev); ++} ++ ++static int cros_ec_lpc_suspend_late(struct device *dev) ++{ ++ struct cros_ec_device *ec_dev = dev_get_drvdata(dev); ++ ++ return cros_ec_suspend_late(ec_dev); ++} ++ ++static int cros_ec_lpc_resume_early(struct device *dev) ++{ ++ struct cros_ec_device *ec_dev = dev_get_drvdata(dev); ++ ++ return cros_ec_resume_early(ec_dev); + } + #endif + + static const struct dev_pm_ops cros_ec_lpc_pm_ops = { + #ifdef CONFIG_PM_SLEEP + .prepare = cros_ec_lpc_prepare, +- .complete = cros_ec_lpc_complete ++ .complete = cros_ec_lpc_complete, + #endif ++ SET_LATE_SYSTEM_SLEEP_PM_OPS(cros_ec_lpc_suspend_late, cros_ec_lpc_resume_early) + }; + + static struct platform_driver cros_ec_lpc_driver = { +-- +2.42.0 + diff --git a/queue-6.6/platform-x86-wmi-fix-opening-of-char-device.patch b/queue-6.6/platform-x86-wmi-fix-opening-of-char-device.patch new file mode 100644 index 00000000000..9d61c86ada6 --- /dev/null +++ b/queue-6.6/platform-x86-wmi-fix-opening-of-char-device.patch @@ -0,0 +1,69 @@ +From 44610cec864c7cd0f944c176d1b5da643091d0b2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 23:10:04 +0200 +Subject: platform/x86: wmi: Fix opening of char device +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Armin Wolf + +[ Upstream commit eba9ac7abab91c8f6d351460239108bef5e7a0b6 ] + +Since commit fa1f68db6ca7 ("drivers: misc: pass miscdevice pointer via +file private data"), the miscdevice stores a pointer to itself inside +filp->private_data, which means that private_data will not be NULL when +wmi_char_open() is called. This might cause memory corruption should +wmi_char_open() be unable to find its driver, something which can +happen when the associated WMI device is deleted in wmi_free_devices(). + +Fix the problem by using the miscdevice pointer to retrieve the WMI +device data associated with a char device using container_of(). This +also avoids wmi_char_open() picking a wrong WMI device bound to a +driver with the same name as the original driver. + +Fixes: 44b6b7661132 ("platform/x86: wmi: create userspace interface for drivers") +Signed-off-by: Armin Wolf +Link: https://lore.kernel.org/r/20231020211005.38216-5-W_Armin@gmx.de +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/wmi.c | 20 ++++++-------------- + 1 file changed, 6 insertions(+), 14 deletions(-) + +diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c +index 7d11ff5bc856c..317c907304149 100644 +--- a/drivers/platform/x86/wmi.c ++++ b/drivers/platform/x86/wmi.c +@@ -911,21 +911,13 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver) + } + static int wmi_char_open(struct inode *inode, struct file *filp) + { +- const char *driver_name = filp->f_path.dentry->d_iname; +- struct wmi_block *wblock; +- struct wmi_block *next; +- +- list_for_each_entry_safe(wblock, next, &wmi_block_list, list) { +- if (!wblock->dev.dev.driver) +- continue; +- if (strcmp(driver_name, wblock->dev.dev.driver->name) == 0) { +- filp->private_data = wblock; +- break; +- } +- } ++ /* ++ * The miscdevice already stores a pointer to itself ++ * inside filp->private_data ++ */ ++ struct wmi_block *wblock = container_of(filp->private_data, struct wmi_block, char_dev); + +- if (!filp->private_data) +- return -ENODEV; ++ filp->private_data = wblock; + + return nonseekable_open(inode, filp); + } +-- +2.42.0 + diff --git a/queue-6.6/platform-x86-wmi-fix-probe-failure-when-failing-to-r.patch b/queue-6.6/platform-x86-wmi-fix-probe-failure-when-failing-to-r.patch new file mode 100644 index 00000000000..c24bc15bc0e --- /dev/null +++ b/queue-6.6/platform-x86-wmi-fix-probe-failure-when-failing-to-r.patch @@ -0,0 +1,84 @@ +From ccc3df1f300c0fb1119e087d1bfddf2166982285 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 23:10:03 +0200 +Subject: platform/x86: wmi: Fix probe failure when failing to register WMI + devices +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Armin Wolf + +[ Upstream commit ed85891a276edaf7a867de0e9acd0837bc3008f2 ] + +When a WMI device besides the first one somehow fails to register, +retval is returned while still containing a negative error code. This +causes the ACPI device fail to probe, leaving behind zombie WMI devices +leading to various errors later. + +Handle the single error path separately and return 0 unconditionally +after trying to register all WMI devices to solve the issue. Also +continue to register WMI devices even if some fail to allocate memory. + +Fixes: 6ee50aaa9a20 ("platform/x86: wmi: Instantiate all devices before adding them") +Signed-off-by: Armin Wolf +Link: https://lore.kernel.org/r/20231020211005.38216-4-W_Armin@gmx.de +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/wmi.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c +index a78ddd83cda02..7d11ff5bc856c 100644 +--- a/drivers/platform/x86/wmi.c ++++ b/drivers/platform/x86/wmi.c +@@ -1270,8 +1270,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device) + struct wmi_block *wblock, *next; + union acpi_object *obj; + acpi_status status; +- int retval = 0; + u32 i, total; ++ int retval; + + status = acpi_evaluate_object(device->handle, "_WDG", NULL, &out); + if (ACPI_FAILURE(status)) +@@ -1282,8 +1282,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device) + return -ENXIO; + + if (obj->type != ACPI_TYPE_BUFFER) { +- retval = -ENXIO; +- goto out_free_pointer; ++ kfree(obj); ++ return -ENXIO; + } + + gblock = (const struct guid_block *)obj->buffer.pointer; +@@ -1298,8 +1298,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device) + + wblock = kzalloc(sizeof(*wblock), GFP_KERNEL); + if (!wblock) { +- retval = -ENOMEM; +- break; ++ dev_err(wmi_bus_dev, "Failed to allocate %pUL\n", &gblock[i].guid); ++ continue; + } + + wblock->acpi_device = device; +@@ -1338,9 +1338,9 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device) + } + } + +-out_free_pointer: +- kfree(out.pointer); +- return retval; ++ kfree(obj); ++ ++ return 0; + } + + /* +-- +2.42.0 + diff --git a/queue-6.6/pm-devfreq-rockchip-dfi-make-pmu-regmap-mandatory.patch b/queue-6.6/pm-devfreq-rockchip-dfi-make-pmu-regmap-mandatory.patch new file mode 100644 index 00000000000..8dd30572f21 --- /dev/null +++ b/queue-6.6/pm-devfreq-rockchip-dfi-make-pmu-regmap-mandatory.patch @@ -0,0 +1,53 @@ +From f17a0b773178339ff17c6b9e297e4109646518a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jul 2023 11:32:17 +0200 +Subject: PM / devfreq: rockchip-dfi: Make pmu regmap mandatory + +From: Sascha Hauer + +[ Upstream commit 1e0731c05c985deb68a97fa44c1adcd3305dda90 ] + +As a matter of fact the regmap_pmu already is mandatory because +it is used unconditionally in the driver. Bail out gracefully in +probe() rather than crashing later. + +Link: https://lore.kernel.org/lkml/20230704093242.583575-2-s.hauer@pengutronix.de/ +Fixes: b9d1262bca0af ("PM / devfreq: event: support rockchip dfi controller") +Reviewed-by: Sebastian Reichel +Signed-off-by: Sascha Hauer +Signed-off-by: Chanwoo Choi +Signed-off-by: Sasha Levin +--- + drivers/devfreq/event/rockchip-dfi.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c +index 39ac069cabc75..74893c06aa087 100644 +--- a/drivers/devfreq/event/rockchip-dfi.c ++++ b/drivers/devfreq/event/rockchip-dfi.c +@@ -193,14 +193,15 @@ static int rockchip_dfi_probe(struct platform_device *pdev) + return dev_err_probe(dev, PTR_ERR(data->clk), + "Cannot get the clk pclk_ddr_mon\n"); + +- /* try to find the optional reference to the pmu syscon */ + node = of_parse_phandle(np, "rockchip,pmu", 0); +- if (node) { +- data->regmap_pmu = syscon_node_to_regmap(node); +- of_node_put(node); +- if (IS_ERR(data->regmap_pmu)) +- return PTR_ERR(data->regmap_pmu); +- } ++ if (!node) ++ return dev_err_probe(&pdev->dev, -ENODEV, "Can't find pmu_grf registers\n"); ++ ++ data->regmap_pmu = syscon_node_to_regmap(node); ++ of_node_put(node); ++ if (IS_ERR(data->regmap_pmu)) ++ return PTR_ERR(data->regmap_pmu); ++ + data->dev = dev; + + desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); +-- +2.42.0 + diff --git a/queue-6.6/pm-sleep-fix-symbol-export-for-_simple_-variants-of-.patch b/queue-6.6/pm-sleep-fix-symbol-export-for-_simple_-variants-of-.patch new file mode 100644 index 00000000000..0f0486e16da --- /dev/null +++ b/queue-6.6/pm-sleep-fix-symbol-export-for-_simple_-variants-of-.patch @@ -0,0 +1,116 @@ +From a45cb1fc7f7d8363be1b9d003bc43fcf9940e782 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 11:15:52 +0530 +Subject: PM: sleep: Fix symbol export for _SIMPLE_ variants of _PM_OPS() + +From: Raag Jadav + +[ Upstream commit 8d74f1da776da9b0306630b13a3025214fa44618 ] + +Currently EXPORT_*_SIMPLE_DEV_PM_OPS() use EXPORT_*_DEV_PM_OPS() set +of macros to export dev_pm_ops symbol, which export the symbol in case +CONFIG_PM=y but don't take CONFIG_PM_SLEEP into consideration. + +Since _SIMPLE_ variants of _PM_OPS() do not include runtime PM handles +and are only used in case CONFIG_PM_SLEEP=y, we should not be exporting +dev_pm_ops symbol for them in case CONFIG_PM_SLEEP=n. + +This can be fixed by having two distinct set of export macros for both +_RUNTIME_ and _SIMPLE_ variants of _PM_OPS(), such that the export of +dev_pm_ops symbol used in each variant depends on CONFIG_PM and +CONFIG_PM_SLEEP respectively. + +Introduce _DEV_SLEEP_PM_OPS() set of export macros for _SIMPLE_ variants +of _PM_OPS(), which export dev_pm_ops symbol only in case CONFIG_PM_SLEEP=y +and discard it otherwise. + +Fixes: 34e1ed189fab ("PM: Improve EXPORT_*_DEV_PM_OPS macros") +Signed-off-by: Raag Jadav +Reviewed-by: Paul Cercueil +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + include/linux/pm.h | 43 +++++++++++++++++++++++++++++-------------- + 1 file changed, 29 insertions(+), 14 deletions(-) + +diff --git a/include/linux/pm.h b/include/linux/pm.h +index 1400c37b29c75..629c1633bbd00 100644 +--- a/include/linux/pm.h ++++ b/include/linux/pm.h +@@ -374,24 +374,39 @@ const struct dev_pm_ops name = { \ + RUNTIME_PM_OPS(runtime_suspend_fn, runtime_resume_fn, idle_fn) \ + } + +-#ifdef CONFIG_PM +-#define _EXPORT_DEV_PM_OPS(name, license, ns) \ ++#define _EXPORT_PM_OPS(name, license, ns) \ + const struct dev_pm_ops name; \ + __EXPORT_SYMBOL(name, license, ns); \ + const struct dev_pm_ops name +-#define EXPORT_PM_FN_GPL(name) EXPORT_SYMBOL_GPL(name) +-#define EXPORT_PM_FN_NS_GPL(name, ns) EXPORT_SYMBOL_NS_GPL(name, ns) +-#else +-#define _EXPORT_DEV_PM_OPS(name, license, ns) \ ++ ++#define _DISCARD_PM_OPS(name, license, ns) \ + static __maybe_unused const struct dev_pm_ops __static_##name ++ ++#ifdef CONFIG_PM ++#define _EXPORT_DEV_PM_OPS(name, license, ns) _EXPORT_PM_OPS(name, license, ns) ++#define EXPORT_PM_FN_GPL(name) EXPORT_SYMBOL_GPL(name) ++#define EXPORT_PM_FN_NS_GPL(name, ns) EXPORT_SYMBOL_NS_GPL(name, ns) ++#else ++#define _EXPORT_DEV_PM_OPS(name, license, ns) _DISCARD_PM_OPS(name, license, ns) + #define EXPORT_PM_FN_GPL(name) + #define EXPORT_PM_FN_NS_GPL(name, ns) + #endif + +-#define EXPORT_DEV_PM_OPS(name) _EXPORT_DEV_PM_OPS(name, "", "") +-#define EXPORT_GPL_DEV_PM_OPS(name) _EXPORT_DEV_PM_OPS(name, "GPL", "") +-#define EXPORT_NS_DEV_PM_OPS(name, ns) _EXPORT_DEV_PM_OPS(name, "", #ns) +-#define EXPORT_NS_GPL_DEV_PM_OPS(name, ns) _EXPORT_DEV_PM_OPS(name, "GPL", #ns) ++#ifdef CONFIG_PM_SLEEP ++#define _EXPORT_DEV_SLEEP_PM_OPS(name, license, ns) _EXPORT_PM_OPS(name, license, ns) ++#else ++#define _EXPORT_DEV_SLEEP_PM_OPS(name, license, ns) _DISCARD_PM_OPS(name, license, ns) ++#endif ++ ++#define EXPORT_DEV_PM_OPS(name) _EXPORT_DEV_PM_OPS(name, "", "") ++#define EXPORT_GPL_DEV_PM_OPS(name) _EXPORT_DEV_PM_OPS(name, "GPL", "") ++#define EXPORT_NS_DEV_PM_OPS(name, ns) _EXPORT_DEV_PM_OPS(name, "", #ns) ++#define EXPORT_NS_GPL_DEV_PM_OPS(name, ns) _EXPORT_DEV_PM_OPS(name, "GPL", #ns) ++ ++#define EXPORT_DEV_SLEEP_PM_OPS(name) _EXPORT_DEV_SLEEP_PM_OPS(name, "", "") ++#define EXPORT_GPL_DEV_SLEEP_PM_OPS(name) _EXPORT_DEV_SLEEP_PM_OPS(name, "GPL", "") ++#define EXPORT_NS_DEV_SLEEP_PM_OPS(name, ns) _EXPORT_DEV_SLEEP_PM_OPS(name, "", #ns) ++#define EXPORT_NS_GPL_DEV_SLEEP_PM_OPS(name, ns) _EXPORT_DEV_SLEEP_PM_OPS(name, "GPL", #ns) + + /* + * Use this if you want to use the same suspend and resume callbacks for suspend +@@ -404,19 +419,19 @@ const struct dev_pm_ops name = { \ + _DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL) + + #define EXPORT_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ +- EXPORT_DEV_PM_OPS(name) = { \ ++ EXPORT_DEV_SLEEP_PM_OPS(name) = { \ + SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ + } + #define EXPORT_GPL_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ +- EXPORT_GPL_DEV_PM_OPS(name) = { \ ++ EXPORT_GPL_DEV_SLEEP_PM_OPS(name) = { \ + SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ + } + #define EXPORT_NS_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn, ns) \ +- EXPORT_NS_DEV_PM_OPS(name, ns) = { \ ++ EXPORT_NS_DEV_SLEEP_PM_OPS(name, ns) = { \ + SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ + } + #define EXPORT_NS_GPL_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn, ns) \ +- EXPORT_NS_GPL_DEV_PM_OPS(name, ns) = { \ ++ EXPORT_NS_GPL_DEV_SLEEP_PM_OPS(name, ns) = { \ + SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ + } + +-- +2.42.0 + diff --git a/queue-6.6/powerpc-40x-remove-stale-pte_atomic_updates-macro.patch b/queue-6.6/powerpc-40x-remove-stale-pte_atomic_updates-macro.patch new file mode 100644 index 00000000000..0b962856e1b --- /dev/null +++ b/queue-6.6/powerpc-40x-remove-stale-pte_atomic_updates-macro.patch @@ -0,0 +1,44 @@ +From 16ebd3b12cd113aa5c6b1c4ec304e61b6b83ce6d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Sep 2023 20:31:17 +0200 +Subject: powerpc/40x: Remove stale PTE_ATOMIC_UPDATES macro + +From: Christophe Leroy + +[ Upstream commit cc8ee288f484a2a59c01ccd4d8a417d6ed3466e3 ] + +40x TLB handlers were reworked by commit 2c74e2586bb9 ("powerpc/40x: +Rework 40x PTE access and TLB miss") to not require PTE_ATOMIC_UPDATES +anymore. + +Then commit 4e1df545e2fa ("powerpc/pgtable: Drop PTE_ATOMIC_UPDATES") +removed all code related to PTE_ATOMIC_UPDATES. + +Remove left over PTE_ATOMIC_UPDATES macro. + +Fixes: 2c74e2586bb9 ("powerpc/40x: Rework 40x PTE access and TLB miss") +Signed-off-by: Christophe Leroy +Signed-off-by: Michael Ellerman +Link: https://msgid.link/f061db5857fcd748f84a6707aad01754686ce97e.1695659959.git.christophe.leroy@csgroup.eu +Signed-off-by: Sasha Levin +--- + arch/powerpc/include/asm/nohash/32/pte-40x.h | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/arch/powerpc/include/asm/nohash/32/pte-40x.h b/arch/powerpc/include/asm/nohash/32/pte-40x.h +index 6fe46e7545566..0b4e5f8ce3e8a 100644 +--- a/arch/powerpc/include/asm/nohash/32/pte-40x.h ++++ b/arch/powerpc/include/asm/nohash/32/pte-40x.h +@@ -69,9 +69,6 @@ + + #define _PTE_NONE_MASK 0 + +-/* Until my rework is finished, 40x still needs atomic PTE updates */ +-#define PTE_ATOMIC_UPDATES 1 +- + #define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED) + #define _PAGE_BASE (_PAGE_BASE_NC) + +-- +2.42.0 + diff --git a/queue-6.6/powerpc-hide-empty-pt_regs-at-base-of-the-stack.patch b/queue-6.6/powerpc-hide-empty-pt_regs-at-base-of-the-stack.patch new file mode 100644 index 00000000000..8f5d0b4d591 --- /dev/null +++ b/queue-6.6/powerpc-hide-empty-pt_regs-at-base-of-the-stack.patch @@ -0,0 +1,123 @@ +From 942f3d6d5d23de86e73c9a789fdd0ba4a8a7b569 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Aug 2023 16:42:10 +1000 +Subject: powerpc: Hide empty pt_regs at base of the stack + +From: Michael Ellerman + +[ Upstream commit d45c4b48dafb5820e5cc267ff9a6d7784d13a43c ] + +A thread started via eg. user_mode_thread() runs in the kernel to begin +with and then may later return to userspace. While it's running in the +kernel it has a pt_regs at the base of its kernel stack, but that +pt_regs is all zeroes. + +If the thread oopses in that state, it leads to an ugly stack trace with +a big block of zero GPRs, as reported by Joel: + + Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) + CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.5.0-rc7-00004-gf7757129e3de-dirty #3 + Hardware name: IBM PowerNV (emulated by qemu) POWER9 0x4e1200 opal:v7.0 PowerNV + Call Trace: + [c0000000036afb00] [c0000000010dd058] dump_stack_lvl+0x6c/0x9c (unreliable) + [c0000000036afb30] [c00000000013c524] panic+0x178/0x424 + [c0000000036afbd0] [c000000002005100] mount_root_generic+0x250/0x324 + [c0000000036afca0] [c0000000020057d0] prepare_namespace+0x2d4/0x344 + [c0000000036afd20] [c0000000020049c0] kernel_init_freeable+0x358/0x3ac + [c0000000036afdf0] [c0000000000111b0] kernel_init+0x30/0x1a0 + [c0000000036afe50] [c00000000000debc] ret_from_kernel_user_thread+0x14/0x1c + --- interrupt: 0 at 0x0 + NIP: 0000000000000000 LR: 0000000000000000 CTR: 0000000000000000 + REGS: c0000000036afe80 TRAP: 0000 Not tainted (6.5.0-rc7-00004-gf7757129e3de-dirty) + MSR: 0000000000000000 <> CR: 00000000 XER: 00000000 + CFAR: 0000000000000000 IRQMASK: 0 + GPR00: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 + GPR04: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 + GPR08: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 + GPR12: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 + GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 + GPR20: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 + GPR24: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 + GPR28: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 + NIP [0000000000000000] 0x0 + LR [0000000000000000] 0x0 + --- interrupt: 0 + +The all-zero pt_regs looks ugly and conveys no useful information, other +than its presence. So detect that case and just show the presence of the +frame by printing the interrupt marker, eg: + + Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) + CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.5.0-rc3-00126-g18e9506562a0-dirty #301 + Hardware name: IBM pSeries (emulated by qemu) POWER9 (raw) 0x4e1202 0xf000005 of:SLOF,HEAD hv:linux,kvm pSeries + Call Trace: + [c000000003aabb00] [c000000001143db8] dump_stack_lvl+0x6c/0x9c (unreliable) + [c000000003aabb30] [c00000000014c624] panic+0x178/0x424 + [c000000003aabbd0] [c0000000020050fc] mount_root_generic+0x250/0x324 + [c000000003aabca0] [c0000000020057cc] prepare_namespace+0x2d4/0x344 + [c000000003aabd20] [c0000000020049bc] kernel_init_freeable+0x358/0x3ac + [c000000003aabdf0] [c0000000000111b0] kernel_init+0x30/0x1a0 + [c000000003aabe50] [c00000000000debc] ret_from_kernel_user_thread+0x14/0x1c + --- interrupt: 0 at 0x0 + +To avoid ever suppressing a valid pt_regs make sure the pt_regs has a +zero MSR and TRAP value, and is located at the very base of the stack. + +Fixes: 6895dfc04741 ("powerpc: copy_thread fill in interrupt frame marker and back chain") +Reported-by: Joel Stanley +Reported-by: Nicholas Piggin +Reviewed-by: Joel Stanley +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20230824064210.907266-1-mpe@ellerman.id.au +Signed-off-by: Sasha Levin +--- + arch/powerpc/kernel/process.c | 26 +++++++++++++++++++++++--- + 1 file changed, 23 insertions(+), 3 deletions(-) + +diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c +index b68898ac07e19..392404688cec3 100644 +--- a/arch/powerpc/kernel/process.c ++++ b/arch/powerpc/kernel/process.c +@@ -2258,6 +2258,22 @@ unsigned long __get_wchan(struct task_struct *p) + return ret; + } + ++static bool empty_user_regs(struct pt_regs *regs, struct task_struct *tsk) ++{ ++ unsigned long stack_page; ++ ++ // A non-empty pt_regs should never have a zero MSR or TRAP value. ++ if (regs->msr || regs->trap) ++ return false; ++ ++ // Check it sits at the very base of the stack ++ stack_page = (unsigned long)task_stack_page(tsk); ++ if ((unsigned long)(regs + 1) != stack_page + THREAD_SIZE) ++ return false; ++ ++ return true; ++} ++ + static int kstack_depth_to_print = CONFIG_PRINT_STACK_DEPTH; + + void __no_sanitize_address show_stack(struct task_struct *tsk, +@@ -2322,9 +2338,13 @@ void __no_sanitize_address show_stack(struct task_struct *tsk, + lr = regs->link; + printk("%s--- interrupt: %lx at %pS\n", + loglvl, regs->trap, (void *)regs->nip); +- __show_regs(regs); +- printk("%s--- interrupt: %lx\n", +- loglvl, regs->trap); ++ ++ // Detect the case of an empty pt_regs at the very base ++ // of the stack and suppress showing it in full. ++ if (!empty_user_regs(regs, tsk)) { ++ __show_regs(regs); ++ printk("%s--- interrupt: %lx\n", loglvl, regs->trap); ++ } + + firstframe = 1; + } +-- +2.42.0 + diff --git a/queue-6.6/powerpc-imc-pmu-use-the-correct-spinlock-initializer.patch b/queue-6.6/powerpc-imc-pmu-use-the-correct-spinlock-initializer.patch new file mode 100644 index 00000000000..9de53184b51 --- /dev/null +++ b/queue-6.6/powerpc-imc-pmu-use-the-correct-spinlock-initializer.patch @@ -0,0 +1,40 @@ +From 6035ad972e75451261c8a997413dd6fd75a9f99e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Mar 2023 14:48:31 +0100 +Subject: powerpc/imc-pmu: Use the correct spinlock initializer. + +From: Sebastian Andrzej Siewior + +[ Upstream commit 007240d59c11f87ac4f6cfc6a1d116630b6b634c ] + +The macro __SPIN_LOCK_INITIALIZER() is implementation specific. Users +that desire to initialize a spinlock in a struct must use +__SPIN_LOCK_UNLOCKED(). + +Use __SPIN_LOCK_UNLOCKED() for the spinlock_t in imc_global_refc. + +Fixes: 76d588dddc459 ("powerpc/imc-pmu: Fix use of mutex in IRQs disabled section") +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20230309134831.Nz12nqsU@linutronix.de +Signed-off-by: Sasha Levin +--- + arch/powerpc/perf/imc-pmu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c +index 9d229ef7f86ef..ada817c49b722 100644 +--- a/arch/powerpc/perf/imc-pmu.c ++++ b/arch/powerpc/perf/imc-pmu.c +@@ -51,7 +51,7 @@ static int trace_imc_mem_size; + * core and trace-imc + */ + static struct imc_pmu_ref imc_global_refc = { +- .lock = __SPIN_LOCK_INITIALIZER(imc_global_refc.lock), ++ .lock = __SPIN_LOCK_UNLOCKED(imc_global_refc.lock), + .id = 0, + .refc = 0, + }; +-- +2.42.0 + diff --git a/queue-6.6/powerpc-only-define-__parse_fpscr-when-required.patch b/queue-6.6/powerpc-only-define-__parse_fpscr-when-required.patch new file mode 100644 index 00000000000..36c69fe68d7 --- /dev/null +++ b/queue-6.6/powerpc-only-define-__parse_fpscr-when-required.patch @@ -0,0 +1,55 @@ +From 8646db4827e4f07947cf5d8df2bd74f6c0709f09 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 14:33:13 +0200 +Subject: powerpc: Only define __parse_fpscr() when required + +From: Christophe Leroy + +[ Upstream commit c7e0d9bb9154c6e6b2ac8746faba27b53393f25e ] + +Clang 17 reports: + +arch/powerpc/kernel/traps.c:1167:19: error: unused function '__parse_fpscr' [-Werror,-Wunused-function] + +__parse_fpscr() is called from two sites. First call is guarded +by #ifdef CONFIG_PPC_FPU_REGS + +Second call is guarded by CONFIG_MATH_EMULATION which selects +CONFIG_PPC_FPU_REGS. + +So only define __parse_fpscr() when CONFIG_PPC_FPU_REGS is defined. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202309210327.WkqSd5Bq-lkp@intel.com/ +Fixes: b6254ced4da6 ("powerpc/signal: Don't manage floating point regs when no FPU") +Signed-off-by: Christophe Leroy +Signed-off-by: Michael Ellerman +Link: https://msgid.link/5de2998c57f3983563b27b39228ea9a7229d4110.1695385984.git.christophe.leroy@csgroup.eu +Signed-off-by: Sasha Levin +--- + arch/powerpc/kernel/traps.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c +index 64ff37721fd06..fe3f720c9cd61 100644 +--- a/arch/powerpc/kernel/traps.c ++++ b/arch/powerpc/kernel/traps.c +@@ -1164,6 +1164,7 @@ void emulate_single_step(struct pt_regs *regs) + __single_step_exception(regs); + } + ++#ifdef CONFIG_PPC_FPU_REGS + static inline int __parse_fpscr(unsigned long fpscr) + { + int ret = FPE_FLTUNK; +@@ -1190,6 +1191,7 @@ static inline int __parse_fpscr(unsigned long fpscr) + + return ret; + } ++#endif + + static void parse_fpe(struct pt_regs *regs) + { +-- +2.42.0 + diff --git a/queue-6.6/powerpc-pseries-fix-potential-memory-leak-in-init_cp.patch b/queue-6.6/powerpc-pseries-fix-potential-memory-leak-in-init_cp.patch new file mode 100644 index 00000000000..ebc615d57e8 --- /dev/null +++ b/queue-6.6/powerpc-pseries-fix-potential-memory-leak-in-init_cp.patch @@ -0,0 +1,43 @@ +From 273a818d308fcb4abc9198ac1e05f538e7eb560d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Dec 2022 15:46:23 +0800 +Subject: powerpc/pseries: fix potential memory leak in + init_cpu_associativity() + +From: Wang Yufen + +[ Upstream commit 95f1a128cd728a7257d78e868f1f5a145fc43736 ] + +If the vcpu_associativity alloc memory successfully but the +pcpu_associativity fails to alloc memory, the vcpu_associativity +memory leaks. + +Fixes: d62c8deeb6e6 ("powerpc/pseries: Provide vcpu dispatch statistics") +Signed-off-by: Wang Yufen +Reviewed-by: "Naveen N. Rao" +Signed-off-by: Michael Ellerman +Link: https://msgid.link/1671003983-10794-1-git-send-email-wangyufen@huawei.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/platforms/pseries/lpar.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c +index f2cb62148f36f..d4d6de0628b05 100644 +--- a/arch/powerpc/platforms/pseries/lpar.c ++++ b/arch/powerpc/platforms/pseries/lpar.c +@@ -526,8 +526,10 @@ static ssize_t vcpudispatch_stats_write(struct file *file, const char __user *p, + + if (cmd) { + rc = init_cpu_associativity(); +- if (rc) ++ if (rc) { ++ destroy_cpu_associativity(); + goto out; ++ } + + for_each_possible_cpu(cpu) { + disp = per_cpu_ptr(&vcpu_disp_data, cpu); +-- +2.42.0 + diff --git a/queue-6.6/powerpc-vas-limit-open-window-failure-messages-in-lo.patch b/queue-6.6/powerpc-vas-limit-open-window-failure-messages-in-lo.patch new file mode 100644 index 00000000000..aff98a1e77f --- /dev/null +++ b/queue-6.6/powerpc-vas-limit-open-window-failure-messages-in-lo.patch @@ -0,0 +1,191 @@ +From bbaa4b26b98b4fc53a7dbbbe96b7ea7f0075540f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Oct 2023 14:50:33 -0700 +Subject: powerpc/vas: Limit open window failure messages in log bufffer + +From: Haren Myneni + +[ Upstream commit 73b25505ce043b561028e5571d84dc82aa53c2b4 ] + +The VAS open window call prints error message and returns -EBUSY +after the migration suspend event initiated and until the resume +event completed on the destination system. It can cause the log +buffer filled with these error messages if the user space issues +continuous open window calls. Similar case even for DLPAR CPU +remove event when no credits are available until the credits are +freed or with the other DLPAR CPU add event. + +So changes in the patch to use pr_err_ratelimited() instead of +pr_err() to display open window failure and not-available credits +error messages. + +Use pr_fmt() and make the corresponding changes to have the +consistencein prefix all pr_*() messages (vas-api.c). + +Fixes: 37e6764895ef ("powerpc/pseries/vas: Add VAS migration handler") +Signed-off-by: Haren Myneni +[mpe: Use "vas-api" as the prefix to match the file name.] +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20231019215033.1335251-1-haren@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/platforms/book3s/vas-api.c | 34 ++++++++++++------------- + arch/powerpc/platforms/pseries/vas.c | 4 +-- + 2 files changed, 18 insertions(+), 20 deletions(-) + +diff --git a/arch/powerpc/platforms/book3s/vas-api.c b/arch/powerpc/platforms/book3s/vas-api.c +index 77ea9335fd049..f381b177ea06a 100644 +--- a/arch/powerpc/platforms/book3s/vas-api.c ++++ b/arch/powerpc/platforms/book3s/vas-api.c +@@ -4,6 +4,8 @@ + * Copyright (C) 2019 Haren Myneni, IBM Corp + */ + ++#define pr_fmt(fmt) "vas-api: " fmt ++ + #include + #include + #include +@@ -78,7 +80,7 @@ int get_vas_user_win_ref(struct vas_user_win_ref *task_ref) + task_ref->mm = get_task_mm(current); + if (!task_ref->mm) { + put_pid(task_ref->pid); +- pr_err("VAS: pid(%d): mm_struct is not found\n", ++ pr_err("pid(%d): mm_struct is not found\n", + current->pid); + return -EPERM; + } +@@ -235,8 +237,7 @@ void vas_update_csb(struct coprocessor_request_block *crb, + rc = kill_pid_info(SIGSEGV, &info, pid); + rcu_read_unlock(); + +- pr_devel("%s(): pid %d kill_proc_info() rc %d\n", __func__, +- pid_vnr(pid), rc); ++ pr_devel("pid %d kill_proc_info() rc %d\n", pid_vnr(pid), rc); + } + + void vas_dump_crb(struct coprocessor_request_block *crb) +@@ -294,7 +295,7 @@ static int coproc_ioc_tx_win_open(struct file *fp, unsigned long arg) + + rc = copy_from_user(&uattr, uptr, sizeof(uattr)); + if (rc) { +- pr_err("%s(): copy_from_user() returns %d\n", __func__, rc); ++ pr_err("copy_from_user() returns %d\n", rc); + return -EFAULT; + } + +@@ -311,7 +312,7 @@ static int coproc_ioc_tx_win_open(struct file *fp, unsigned long arg) + txwin = cp_inst->coproc->vops->open_win(uattr.vas_id, uattr.flags, + cp_inst->coproc->cop_type); + if (IS_ERR(txwin)) { +- pr_err("%s() VAS window open failed, %ld\n", __func__, ++ pr_err_ratelimited("VAS window open failed rc=%ld\n", + PTR_ERR(txwin)); + return PTR_ERR(txwin); + } +@@ -405,8 +406,7 @@ static vm_fault_t vas_mmap_fault(struct vm_fault *vmf) + * window is not opened. Shouldn't expect this error. + */ + if (!cp_inst || !cp_inst->txwin) { +- pr_err("%s(): Unexpected fault on paste address with TX window closed\n", +- __func__); ++ pr_err("Unexpected fault on paste address with TX window closed\n"); + return VM_FAULT_SIGBUS; + } + +@@ -421,8 +421,7 @@ static vm_fault_t vas_mmap_fault(struct vm_fault *vmf) + * issue NX request. + */ + if (txwin->task_ref.vma != vmf->vma) { +- pr_err("%s(): No previous mapping with paste address\n", +- __func__); ++ pr_err("No previous mapping with paste address\n"); + return VM_FAULT_SIGBUS; + } + +@@ -481,19 +480,19 @@ static int coproc_mmap(struct file *fp, struct vm_area_struct *vma) + txwin = cp_inst->txwin; + + if ((vma->vm_end - vma->vm_start) > PAGE_SIZE) { +- pr_debug("%s(): size 0x%zx, PAGE_SIZE 0x%zx\n", __func__, ++ pr_debug("size 0x%zx, PAGE_SIZE 0x%zx\n", + (vma->vm_end - vma->vm_start), PAGE_SIZE); + return -EINVAL; + } + + /* Ensure instance has an open send window */ + if (!txwin) { +- pr_err("%s(): No send window open?\n", __func__); ++ pr_err("No send window open?\n"); + return -EINVAL; + } + + if (!cp_inst->coproc->vops || !cp_inst->coproc->vops->paste_addr) { +- pr_err("%s(): VAS API is not registered\n", __func__); ++ pr_err("VAS API is not registered\n"); + return -EACCES; + } + +@@ -510,14 +509,14 @@ static int coproc_mmap(struct file *fp, struct vm_area_struct *vma) + */ + mutex_lock(&txwin->task_ref.mmap_mutex); + if (txwin->status != VAS_WIN_ACTIVE) { +- pr_err("%s(): Window is not active\n", __func__); ++ pr_err("Window is not active\n"); + rc = -EACCES; + goto out; + } + + paste_addr = cp_inst->coproc->vops->paste_addr(txwin); + if (!paste_addr) { +- pr_err("%s(): Window paste address failed\n", __func__); ++ pr_err("Window paste address failed\n"); + rc = -EINVAL; + goto out; + } +@@ -533,8 +532,8 @@ static int coproc_mmap(struct file *fp, struct vm_area_struct *vma) + rc = remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff, + vma->vm_end - vma->vm_start, prot); + +- pr_devel("%s(): paste addr %llx at %lx, rc %d\n", __func__, +- paste_addr, vma->vm_start, rc); ++ pr_devel("paste addr %llx at %lx, rc %d\n", paste_addr, ++ vma->vm_start, rc); + + txwin->task_ref.vma = vma; + vma->vm_ops = &vas_vm_ops; +@@ -609,8 +608,7 @@ int vas_register_coproc_api(struct module *mod, enum vas_cop_type cop_type, + goto err; + } + +- pr_devel("%s: Added dev [%d,%d]\n", __func__, MAJOR(devno), +- MINOR(devno)); ++ pr_devel("Added dev [%d,%d]\n", MAJOR(devno), MINOR(devno)); + + return 0; + +diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c +index e25ac52acf507..b1f25bac280b4 100644 +--- a/arch/powerpc/platforms/pseries/vas.c ++++ b/arch/powerpc/platforms/pseries/vas.c +@@ -341,7 +341,7 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags, + + if (atomic_inc_return(&cop_feat_caps->nr_used_credits) > + atomic_read(&cop_feat_caps->nr_total_credits)) { +- pr_err("Credits are not available to allocate window\n"); ++ pr_err_ratelimited("Credits are not available to allocate window\n"); + rc = -EINVAL; + goto out; + } +@@ -424,7 +424,7 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags, + + put_vas_user_win_ref(&txwin->vas_win.task_ref); + rc = -EBUSY; +- pr_err("No credit is available to allocate window\n"); ++ pr_err_ratelimited("No credit is available to allocate window\n"); + + out_free: + /* +-- +2.42.0 + diff --git a/queue-6.6/powerpc-vmcore-add-mmu-information-to-vmcoreinfo.patch b/queue-6.6/powerpc-vmcore-add-mmu-information-to-vmcoreinfo.patch new file mode 100644 index 00000000000..acdbb1892b1 --- /dev/null +++ b/queue-6.6/powerpc-vmcore-add-mmu-information-to-vmcoreinfo.patch @@ -0,0 +1,73 @@ +From ff9e972d542604f0ccda33a407a133426928912a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Oct 2023 12:56:12 +0530 +Subject: powerpc/vmcore: Add MMU information to vmcoreinfo + +From: Aditya Gupta + +[ Upstream commit 36e826b568e412f61d68fedc02a67b4d8b7583cc ] + +Since below commit, address mapping for vmemmap has changed for Radix +MMU, where address mapping is stored in kernel page table itself, +instead of earlier used 'vmemmap_list'. + + commit 368a0590d954 ("powerpc/book3s64/vmemmap: switch radix to use + a different vmemmap handling function") + +Hence with upstream kernel, in case of Radix MMU, makedumpfile fails +to do address translation for vmemmap addresses, as it depended on +vmemmap_list, which can now be empty. + +While fixing the address translation in makedumpfile, it was identified +that currently makedumpfile cannot distinguish between Hash MMU and +Radix MMU, unless VMLINUX is passed with -x flag to makedumpfile. And +hence fails to assign offsets and shifts correctly (such as in L4 to +PGDIR offset calculation in makedumpfile). + +For getting the MMU, makedumpfile uses `cur_cpu_spec.mmu_features`. + +Add `cur_cpu_spec` symbol and offset of `mmu_features` in the `cpu_spec` +struct, to VMCOREINFO, so that makedumpfile can assign the offsets +correctly, without needing a VMLINUX. + +Also, even along with `cur_cpu_spec->mmu_features` makedumpfile has to +depend on the 'MMU_FTR_TYPE_RADIX' flag in mmu_features, implying kernel +developers need to be cautious of changes to 'MMU_FTR_*' defines. + +A more stable approach was suggested in the below thread by contributors: + https://lore.kernel.org/linuxppc-dev/20230920105706.853626-1-adityag@linux.ibm.com/ + +The suggestion was to add whether 'RADIX_MMU' is enabled in vmcoreinfo + +This patch also implements the suggestion, by adding 'RADIX_MMU' in +vmcoreinfo, which makedumpfile can use to get whether the crashed system +had RADIX MMU (in which case 'NUMBER(RADIX_MMU)=1') or not (in which +case 'NUMBER(RADIX_MMU)=0') + +Fixes: 368a0590d954 ("powerpc/book3s64/vmemmap: switch radix to use a different vmemmap handling function") +Reported-by: Sachin Sant +Signed-off-by: Aditya Gupta +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20231023072612.50874-1-adityag@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/kexec/core.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/powerpc/kexec/core.c b/arch/powerpc/kexec/core.c +index de64c79629912..005269ac3244c 100644 +--- a/arch/powerpc/kexec/core.c ++++ b/arch/powerpc/kexec/core.c +@@ -74,6 +74,9 @@ void arch_crash_save_vmcoreinfo(void) + VMCOREINFO_STRUCT_SIZE(mmu_psize_def); + VMCOREINFO_OFFSET(mmu_psize_def, shift); + #endif ++ VMCOREINFO_SYMBOL(cur_cpu_spec); ++ VMCOREINFO_OFFSET(cpu_spec, mmu_features); ++ vmcoreinfo_append_str("NUMBER(RADIX_MMU)=%d\n", early_radix_enabled()); + vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset()); + } + +-- +2.42.0 + diff --git a/queue-6.6/powerpc-xive-fix-endian-conversion-size.patch b/queue-6.6/powerpc-xive-fix-endian-conversion-size.patch new file mode 100644 index 00000000000..a01ba23d92a --- /dev/null +++ b/queue-6.6/powerpc-xive-fix-endian-conversion-size.patch @@ -0,0 +1,41 @@ +From 03ef94bea71ad881743f0fb31a95a710c24bcf53 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 16:37:00 +1100 +Subject: powerpc/xive: Fix endian conversion size + +From: Benjamin Gray + +[ Upstream commit ff7a60ab1e065257a0e467c13b519f4debcd7fcf ] + +Sparse reports a size mismatch in the endian swap. The Opal +implementation[1] passes the value as a __be64, and the receiving +variable out_qsize is a u64, so the use of be32_to_cpu() appears to be +an error. + +[1]: https://github.com/open-power/skiboot/blob/80e2b1dc73/hw/xive.c#L3854 + +Fixes: 88ec6b93c8e7 ("powerpc/xive: add OPAL extensions for the XIVE native exploitation support") +Signed-off-by: Benjamin Gray +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20231011053711.93427-2-bgray@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/sysdev/xive/native.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c +index 9f0af4d795d88..f1c0fa6ece21d 100644 +--- a/arch/powerpc/sysdev/xive/native.c ++++ b/arch/powerpc/sysdev/xive/native.c +@@ -802,7 +802,7 @@ int xive_native_get_queue_info(u32 vp_id, u32 prio, + if (out_qpage) + *out_qpage = be64_to_cpu(qpage); + if (out_qsize) +- *out_qsize = be32_to_cpu(qsize); ++ *out_qsize = be64_to_cpu(qsize); + if (out_qeoi_page) + *out_qeoi_page = be64_to_cpu(qeoi_page); + if (out_escalate_irq) +-- +2.42.0 + diff --git a/queue-6.6/pstore-platform-add-check-for-kstrdup.patch b/queue-6.6/pstore-platform-add-check-for-kstrdup.patch new file mode 100644 index 00000000000..edc9d2c94cb --- /dev/null +++ b/queue-6.6/pstore-platform-add-check-for-kstrdup.patch @@ -0,0 +1,63 @@ +From 2c5b359114e1ce89f1bc7f9c7edc607d77bf3290 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Jun 2023 10:27:06 +0800 +Subject: pstore/platform: Add check for kstrdup + +From: Jiasheng Jiang + +[ Upstream commit a19d48f7c5d57c0f0405a7d4334d1d38fe9d3c1c ] + +Add check for the return value of kstrdup() and return the error +if it fails in order to avoid NULL pointer dereference. + +Fixes: 563ca40ddf40 ("pstore/platform: Switch pstore_info::name to const") +Signed-off-by: Jiasheng Jiang +Link: https://lore.kernel.org/r/20230623022706.32125-1-jiasheng@iscas.ac.cn +Signed-off-by: Kees Cook +Signed-off-by: Sasha Levin +--- + fs/pstore/platform.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c +index e5bca9a004ccc..03425928d2fb3 100644 +--- a/fs/pstore/platform.c ++++ b/fs/pstore/platform.c +@@ -464,6 +464,8 @@ static int pstore_write_user_compat(struct pstore_record *record, + */ + int pstore_register(struct pstore_info *psi) + { ++ char *new_backend; ++ + if (backend && strcmp(backend, psi->name)) { + pr_warn("backend '%s' already in use: ignoring '%s'\n", + backend, psi->name); +@@ -484,11 +486,16 @@ int pstore_register(struct pstore_info *psi) + return -EINVAL; + } + ++ new_backend = kstrdup(psi->name, GFP_KERNEL); ++ if (!new_backend) ++ return -ENOMEM; ++ + mutex_lock(&psinfo_lock); + if (psinfo) { + pr_warn("backend '%s' already loaded: ignoring '%s'\n", + psinfo->name, psi->name); + mutex_unlock(&psinfo_lock); ++ kfree(new_backend); + return -EBUSY; + } + +@@ -521,7 +528,7 @@ int pstore_register(struct pstore_info *psi) + * Update the module parameter backend, so it is visible + * through /sys/module/pstore/parameters/backend + */ +- backend = kstrdup(psi->name, GFP_KERNEL); ++ backend = new_backend; + + pr_info("Registered %s as persistent store backend\n", psi->name); + +-- +2.42.0 + diff --git a/queue-6.6/r8152-break-the-loop-when-the-budget-is-exhausted.patch b/queue-6.6/r8152-break-the-loop-when-the-budget-is-exhausted.patch new file mode 100644 index 00000000000..3c71e6cdeb2 --- /dev/null +++ b/queue-6.6/r8152-break-the-loop-when-the-budget-is-exhausted.patch @@ -0,0 +1,90 @@ +From a0e946f97f11a8a84c9e284e3f5f3b45a61b9d85 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Sep 2023 19:17:13 +0800 +Subject: r8152: break the loop when the budget is exhausted + +From: Hayes Wang + +[ Upstream commit 2cf51f931797d9a47e75d999d0993a68cbd2a560 ] + +A bulk transfer of the USB may contain many packets. And, the total +number of the packets in the bulk transfer may be more than budget. + +Originally, only budget packets would be handled by napi_gro_receive(), +and the other packets would be queued in the driver for next schedule. + +This patch would break the loop about getting next bulk transfer, when +the budget is exhausted. That is, only the current bulk transfer would +be handled, and the other bulk transfers would be queued for next +schedule. Besides, the packets which are more than the budget in the +current bulk trasnfer would be still queued in the driver, as the +original method. + +In addition, a bulk transfer wouldn't contain more than 400 packets, so +the check of queue length is unnecessary. Therefore, I replace it with +WARN_ON_ONCE(). + +Fixes: cf74eb5a5bc8 ("eth: r8152: try to use a normal budget") +Signed-off-by: Hayes Wang +Link: https://lore.kernel.org/r/20230926111714.9448-433-nic_swsd@realtek.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/usb/r8152.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index afb20c0ed688d..be18d72cefcce 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -2543,7 +2543,7 @@ static int rx_bottom(struct r8152 *tp, int budget) + } + } + +- if (list_empty(&tp->rx_done)) ++ if (list_empty(&tp->rx_done) || work_done >= budget) + goto out1; + + clear_bit(RX_EPROTO, &tp->flags); +@@ -2559,6 +2559,15 @@ static int rx_bottom(struct r8152 *tp, int budget) + struct urb *urb; + u8 *rx_data; + ++ /* A bulk transfer of USB may contain may packets, so the ++ * total packets may more than the budget. Deal with all ++ * packets in current bulk transfer, and stop to handle the ++ * next bulk transfer until next schedule, if budget is ++ * exhausted. ++ */ ++ if (work_done >= budget) ++ break; ++ + list_del_init(cursor); + + agg = list_entry(cursor, struct rx_agg, list); +@@ -2578,9 +2587,7 @@ static int rx_bottom(struct r8152 *tp, int budget) + unsigned int pkt_len, rx_frag_head_sz; + struct sk_buff *skb; + +- /* limit the skb numbers for rx_queue */ +- if (unlikely(skb_queue_len(&tp->rx_queue) >= 1000)) +- break; ++ WARN_ON_ONCE(skb_queue_len(&tp->rx_queue) >= 1000); + + pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK; + if (pkt_len < ETH_ZLEN) +@@ -2658,9 +2665,10 @@ static int rx_bottom(struct r8152 *tp, int budget) + } + } + ++ /* Splice the remained list back to rx_done for next schedule */ + if (!list_empty(&rx_queue)) { + spin_lock_irqsave(&tp->rx_lock, flags); +- list_splice_tail(&rx_queue, &tp->rx_done); ++ list_splice(&rx_queue, &tp->rx_done); + spin_unlock_irqrestore(&tp->rx_lock, flags); + } + +-- +2.42.0 + diff --git a/queue-6.6/r8169-fix-rare-issue-with-broken-rx-after-link-down-.patch b/queue-6.6/r8169-fix-rare-issue-with-broken-rx-after-link-down-.patch new file mode 100644 index 00000000000..3493d1a949e --- /dev/null +++ b/queue-6.6/r8169-fix-rare-issue-with-broken-rx-after-link-down-.patch @@ -0,0 +1,52 @@ +From 4c462cc9523aa6fc98b2db304abbffef67f0df36 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Oct 2023 08:51:13 +0200 +Subject: r8169: fix rare issue with broken rx after link-down on RTL8125 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Heiner Kallweit + +[ Upstream commit 621735f590643e3048ca2060c285b80551660601 ] + +In very rare cases (I've seen two reports so far about different +RTL8125 chip versions) it seems the MAC locks up when link goes down +and requires a software reset to get revived. +Realtek doesn't publish hw errata information, therefore the root cause +is unknown. Realtek vendor drivers do a full hw re-initialization on +each link-up event, the slimmed-down variant here was reported to fix +the issue for the reporting user. +It's not fully clear which parts of the NIC are reset as part of the +software reset, therefore I can't rule out side effects. + +Fixes: f1bce4ad2f1c ("r8169: add support for RTL8125") +Reported-by: Martin Kjær Jørgensen +Link: https://lore.kernel.org/netdev/97ec2232-3257-316c-c3e7-a08192ce16a6@gmail.com/T/ +Signed-off-by: Heiner Kallweit +Link: https://lore.kernel.org/r/9edde757-9c3b-4730-be3b-0ef3a374ff71@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/realtek/r8169_main.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c +index 361b90007148b..a987defb575cf 100644 +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -4596,7 +4596,11 @@ static void r8169_phylink_handler(struct net_device *ndev) + if (netif_carrier_ok(ndev)) { + rtl_link_chg_patch(tp); + pm_request_resume(d); ++ netif_wake_queue(tp->dev); + } else { ++ /* In few cases rx is broken after link-down otherwise */ ++ if (rtl_is_8125(tp)) ++ rtl_reset_work(tp); + pm_runtime_idle(d); + } + +-- +2.42.0 + diff --git a/queue-6.6/rdma-core-use-size_-add-sub-mul-in-calls-to-struct_s.patch b/queue-6.6/rdma-core-use-size_-add-sub-mul-in-calls-to-struct_s.patch new file mode 100644 index 00000000000..d72eeab1bab --- /dev/null +++ b/queue-6.6/rdma-core-use-size_-add-sub-mul-in-calls-to-struct_s.patch @@ -0,0 +1,118 @@ +From f1fd173e8a9451ef75d9f3a7a450b33e30d525ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 17 Sep 2023 15:21:36 -0600 +Subject: RDMA/core: Use size_{add,sub,mul}() in calls to struct_size() + +From: Gustavo A. R. Silva + +[ Upstream commit 81760bedc65194ff38e1e4faefd5f9f0c95c19a4 ] + +If, for any reason, the open-coded arithmetic causes a wraparound, +the protection that `struct_size()` provides against potential integer +overflows is defeated. Fix this by hardening calls to `struct_size()` +with `size_add()`, `size_sub()` and `size_mul()`. + +Fixes: 467f432a521a ("RDMA/core: Split port and device counter sysfs attributes") +Fixes: a4676388e2e2 ("RDMA/core: Simplify how the gid_attrs sysfs is created") +Fixes: e9dd5daf884c ("IB/umad: Refactor code to use cdev_device_add()") +Fixes: 324e227ea7c9 ("RDMA/device: Add ib_device_get_by_netdev()") +Fixes: 5aad26a7eac5 ("IB/core: Use struct_size() in kzalloc()") +Signed-off-by: Gustavo A. R. Silva +Link: https://lore.kernel.org/r/ZQdt4NsJFwwOYxUR@work +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/core/device.c | 2 +- + drivers/infiniband/core/sa_query.c | 4 +++- + drivers/infiniband/core/sysfs.c | 10 +++++----- + drivers/infiniband/core/user_mad.c | 4 +++- + 4 files changed, 12 insertions(+), 8 deletions(-) + +diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c +index a666847bd7143..010718738d04c 100644 +--- a/drivers/infiniband/core/device.c ++++ b/drivers/infiniband/core/device.c +@@ -804,7 +804,7 @@ static int alloc_port_data(struct ib_device *device) + * empty slots at the beginning. + */ + pdata_rcu = kzalloc(struct_size(pdata_rcu, pdata, +- rdma_end_port(device) + 1), ++ size_add(rdma_end_port(device), 1)), + GFP_KERNEL); + if (!pdata_rcu) + return -ENOMEM; +diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c +index 59179cfc20ef9..8175dde60b0a8 100644 +--- a/drivers/infiniband/core/sa_query.c ++++ b/drivers/infiniband/core/sa_query.c +@@ -2159,7 +2159,9 @@ static int ib_sa_add_one(struct ib_device *device) + s = rdma_start_port(device); + e = rdma_end_port(device); + +- sa_dev = kzalloc(struct_size(sa_dev, port, e - s + 1), GFP_KERNEL); ++ sa_dev = kzalloc(struct_size(sa_dev, port, ++ size_add(size_sub(e, s), 1)), ++ GFP_KERNEL); + if (!sa_dev) + return -ENOMEM; + +diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c +index ee59d73915689..ec5efdc166601 100644 +--- a/drivers/infiniband/core/sysfs.c ++++ b/drivers/infiniband/core/sysfs.c +@@ -903,7 +903,7 @@ alloc_hw_stats_device(struct ib_device *ibdev) + * Two extra attribue elements here, one for the lifespan entry and + * one to NULL terminate the list for the sysfs core code + */ +- data = kzalloc(struct_size(data, attrs, stats->num_counters + 1), ++ data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)), + GFP_KERNEL); + if (!data) + goto err_free_stats; +@@ -1009,7 +1009,7 @@ alloc_hw_stats_port(struct ib_port *port, struct attribute_group *group) + * Two extra attribue elements here, one for the lifespan entry and + * one to NULL terminate the list for the sysfs core code + */ +- data = kzalloc(struct_size(data, attrs, stats->num_counters + 1), ++ data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)), + GFP_KERNEL); + if (!data) + goto err_free_stats; +@@ -1140,7 +1140,7 @@ static int setup_gid_attrs(struct ib_port *port, + int ret; + + gid_attr_group = kzalloc(struct_size(gid_attr_group, attrs_list, +- attr->gid_tbl_len * 2), ++ size_mul(attr->gid_tbl_len, 2)), + GFP_KERNEL); + if (!gid_attr_group) + return -ENOMEM; +@@ -1205,8 +1205,8 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num, + int ret; + + p = kvzalloc(struct_size(p, attrs_list, +- attr->gid_tbl_len + attr->pkey_tbl_len), +- GFP_KERNEL); ++ size_add(attr->gid_tbl_len, attr->pkey_tbl_len)), ++ GFP_KERNEL); + if (!p) + return ERR_PTR(-ENOMEM); + p->ibdev = device; +diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c +index 7e5c33aad1619..f5feca7fa9b9c 100644 +--- a/drivers/infiniband/core/user_mad.c ++++ b/drivers/infiniband/core/user_mad.c +@@ -1378,7 +1378,9 @@ static int ib_umad_add_one(struct ib_device *device) + s = rdma_start_port(device); + e = rdma_end_port(device); + +- umad_dev = kzalloc(struct_size(umad_dev, ports, e - s + 1), GFP_KERNEL); ++ umad_dev = kzalloc(struct_size(umad_dev, ports, ++ size_add(size_sub(e, s), 1)), ++ GFP_KERNEL); + if (!umad_dev) + return -ENOMEM; + +-- +2.42.0 + diff --git a/queue-6.6/rdma-hfi1-workaround-truncation-compilation-error.patch b/queue-6.6/rdma-hfi1-workaround-truncation-compilation-error.patch new file mode 100644 index 00000000000..934d62a4bd7 --- /dev/null +++ b/queue-6.6/rdma-hfi1-workaround-truncation-compilation-error.patch @@ -0,0 +1,57 @@ +From 5f1aa76b7964a7b9838beef856d6dc8e8e86a896 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Oct 2023 18:07:31 +0300 +Subject: RDMA/hfi1: Workaround truncation compilation error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Leon Romanovsky + +[ Upstream commit d4b2d165714c0ce8777d5131f6e0aad617b7adc4 ] + +Increase name array to be large enough to overcome the following +compilation error. + +drivers/infiniband/hw/hfi1/efivar.c: In function ‘read_hfi1_efi_var’: +drivers/infiniband/hw/hfi1/efivar.c:124:44: error: ‘snprintf’ output may be truncated before the last format character [-Werror=format-truncation=] + 124 | snprintf(name, sizeof(name), "%s-%s", prefix_name, kind); + | ^ +drivers/infiniband/hw/hfi1/efivar.c:124:9: note: ‘snprintf’ output 2 or more bytes (assuming 65) into a destination of size 64 + 124 | snprintf(name, sizeof(name), "%s-%s", prefix_name, kind); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +drivers/infiniband/hw/hfi1/efivar.c:133:52: error: ‘snprintf’ output may be truncated before the last format character [-Werror=format-truncation=] + 133 | snprintf(name, sizeof(name), "%s-%s", prefix_name, kind); + | ^ +drivers/infiniband/hw/hfi1/efivar.c:133:17: note: ‘snprintf’ output 2 or more bytes (assuming 65) into a destination of size 64 + 133 | snprintf(name, sizeof(name), "%s-%s", prefix_name, kind); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +cc1: all warnings being treated as errors +make[6]: *** [scripts/Makefile.build:243: drivers/infiniband/hw/hfi1/efivar.o] Error 1 + +Fixes: c03c08d50b3d ("IB/hfi1: Check upper-case EFI variables") +Signed-off-by: Leon Romanovsky +Link: https://lore.kernel.org/r/238fa39a8fd60e87a5ad7e1ca6584fcdf32e9519.1698159993.git.leonro@nvidia.com +Acked-by: Dennis Dalessandro +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hfi1/efivar.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/hfi1/efivar.c b/drivers/infiniband/hw/hfi1/efivar.c +index 7741a1d69097c..2b5d264f41e51 100644 +--- a/drivers/infiniband/hw/hfi1/efivar.c ++++ b/drivers/infiniband/hw/hfi1/efivar.c +@@ -112,7 +112,7 @@ int read_hfi1_efi_var(struct hfi1_devdata *dd, const char *kind, + unsigned long *size, void **return_data) + { + char prefix_name[64]; +- char name[64]; ++ char name[128]; + int result; + + /* create a common prefix */ +-- +2.42.0 + diff --git a/queue-6.6/rdma-hns-add-check-for-sl.patch b/queue-6.6/rdma-hns-add-check-for-sl.patch new file mode 100644 index 00000000000..73e55027a5f --- /dev/null +++ b/queue-6.6/rdma-hns-add-check-for-sl.patch @@ -0,0 +1,124 @@ +From 5d8357138e1c61489b69faaae83f372fad3c6efb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 20:52:36 +0800 +Subject: RDMA/hns: Add check for SL + +From: Luoyouming + +[ Upstream commit 5e617c18b1f34ec57ad5dce44f09de603cf6bd6c ] + +SL set by users may exceed the capability of devices. So add check +for this situation. + +Fixes: fba429fcf9a5 ("RDMA/hns: Fix missing fields in address vector") +Fixes: 70f92521584f ("RDMA/hns: Use the reserved loopback QPs to free MR before destroying MPT") +Fixes: f0cb411aad23 ("RDMA/hns: Use new interface to modify QP context") +Signed-off-by: Luoyouming +Signed-off-by: Junxian Huang +Link: https://lore.kernel.org/r/20231017125239.164455-5-huangjunxian6@hisilicon.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hns/hns_roce_ah.c | 13 +++++++++++- + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 23 ++++++++++++---------- + 2 files changed, 25 insertions(+), 11 deletions(-) + +diff --git a/drivers/infiniband/hw/hns/hns_roce_ah.c b/drivers/infiniband/hw/hns/hns_roce_ah.c +index e77fcc74f15c4..3df032ddda189 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_ah.c ++++ b/drivers/infiniband/hw/hns/hns_roce_ah.c +@@ -33,7 +33,9 @@ + #include + #include + #include ++#include "hnae3.h" + #include "hns_roce_device.h" ++#include "hns_roce_hw_v2.h" + + static inline u16 get_ah_udp_sport(const struct rdma_ah_attr *ah_attr) + { +@@ -57,6 +59,7 @@ int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr, + struct hns_roce_dev *hr_dev = to_hr_dev(ibah->device); + struct hns_roce_ah *ah = to_hr_ah(ibah); + int ret = 0; ++ u32 max_sl; + + if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08 && udata) + return -EOPNOTSUPP; +@@ -70,9 +73,17 @@ int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr, + ah->av.hop_limit = grh->hop_limit; + ah->av.flowlabel = grh->flow_label; + ah->av.udp_sport = get_ah_udp_sport(ah_attr); +- ah->av.sl = rdma_ah_get_sl(ah_attr); + ah->av.tclass = get_tclass(grh); + ++ ah->av.sl = rdma_ah_get_sl(ah_attr); ++ max_sl = min_t(u32, MAX_SERVICE_LEVEL, hr_dev->caps.sl_num - 1); ++ if (unlikely(ah->av.sl > max_sl)) { ++ ibdev_err_ratelimited(&hr_dev->ib_dev, ++ "failed to set sl, sl (%u) shouldn't be larger than %u.\n", ++ ah->av.sl, max_sl); ++ return -EINVAL; ++ } ++ + memcpy(ah->av.dgid, grh->dgid.raw, HNS_ROCE_GID_SIZE); + memcpy(ah->av.mac, ah_attr->roce.dmac, ETH_ALEN); + +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index 3daa684f88362..b7faf5c8f6ba8 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -4821,22 +4821,32 @@ static int hns_roce_v2_set_path(struct ib_qp *ibqp, + struct hns_roce_qp *hr_qp = to_hr_qp(ibqp); + struct ib_device *ibdev = &hr_dev->ib_dev; + const struct ib_gid_attr *gid_attr = NULL; ++ u8 sl = rdma_ah_get_sl(&attr->ah_attr); + int is_roce_protocol; + u16 vlan_id = 0xffff; + bool is_udp = false; ++ u32 max_sl; + u8 ib_port; + u8 hr_port; + int ret; + ++ max_sl = min_t(u32, MAX_SERVICE_LEVEL, hr_dev->caps.sl_num - 1); ++ if (unlikely(sl > max_sl)) { ++ ibdev_err_ratelimited(ibdev, ++ "failed to fill QPC, sl (%u) shouldn't be larger than %u.\n", ++ sl, max_sl); ++ return -EINVAL; ++ } ++ + /* + * If free_mr_en of qp is set, it means that this qp comes from + * free mr. This qp will perform the loopback operation. + * In the loopback scenario, only sl needs to be set. + */ + if (hr_qp->free_mr_en) { +- hr_reg_write(context, QPC_SL, rdma_ah_get_sl(&attr->ah_attr)); ++ hr_reg_write(context, QPC_SL, sl); + hr_reg_clear(qpc_mask, QPC_SL); +- hr_qp->sl = rdma_ah_get_sl(&attr->ah_attr); ++ hr_qp->sl = sl; + return 0; + } + +@@ -4903,14 +4913,7 @@ static int hns_roce_v2_set_path(struct ib_qp *ibqp, + memcpy(context->dgid, grh->dgid.raw, sizeof(grh->dgid.raw)); + memset(qpc_mask->dgid, 0, sizeof(grh->dgid.raw)); + +- hr_qp->sl = rdma_ah_get_sl(&attr->ah_attr); +- if (unlikely(hr_qp->sl > MAX_SERVICE_LEVEL)) { +- ibdev_err(ibdev, +- "failed to fill QPC, sl (%u) shouldn't be larger than %d.\n", +- hr_qp->sl, MAX_SERVICE_LEVEL); +- return -EINVAL; +- } +- ++ hr_qp->sl = sl; + hr_reg_write(context, QPC_SL, hr_qp->sl); + hr_reg_clear(qpc_mask, QPC_SL); + +-- +2.42.0 + diff --git a/queue-6.6/rdma-hns-fix-init-failure-of-roce-vf-and-hip08.patch b/queue-6.6/rdma-hns-fix-init-failure-of-roce-vf-and-hip08.patch new file mode 100644 index 00000000000..2c2cba7f8da --- /dev/null +++ b/queue-6.6/rdma-hns-fix-init-failure-of-roce-vf-and-hip08.patch @@ -0,0 +1,91 @@ +From 1d945bbfb31df580e23ae1ce37dc4fb7ccc21d7e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 20:52:39 +0800 +Subject: RDMA/hns: Fix init failure of RoCE VF and HIP08 + +From: Junxian Huang + +[ Upstream commit 07f06e0e5cd99555c861e874716d9e2627655fd5 ] + +During device init, a struct for HW stats will be allocated. As HW +stats are not supported for VF and HIP08, currently +hns_roce_alloc_hw_port_stats() returns NULL in this case. However, +ib-core considers the returned NULL pointer as memory allocation +failure and returns ENOMEM, eventually leading to the failure of VF +and HIP08 init. + +In the case where the driver does not support the .alloc_hw_port_stats() +ops, ib-core will return EOPNOTSUPP and ignore this error code in the +upper layer function. So for VF and HIP08, just don't set the HW stats +ops to ib-core. + +Fixes: 5a87279591a1 ("RDMA/hns: Support hns HW stats") +Signed-off-by: Junxian Huang +Link: https://lore.kernel.org/r/20231017125239.164455-8-huangjunxian6@hisilicon.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hns/hns_roce_main.c | 19 +++++++++---------- + 1 file changed, 9 insertions(+), 10 deletions(-) + +diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c +index e1a88f2d51b6c..4a9cd4d21bc99 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_main.c ++++ b/drivers/infiniband/hw/hns/hns_roce_main.c +@@ -553,10 +553,6 @@ static struct rdma_hw_stats *hns_roce_alloc_hw_port_stats( + return NULL; + } + +- if (hr_dev->pci_dev->revision <= PCI_REVISION_ID_HIP08 || +- hr_dev->is_vf) +- return NULL; +- + return rdma_alloc_hw_stats_struct(hns_roce_port_stats_descs, + ARRAY_SIZE(hns_roce_port_stats_descs), + RDMA_HW_STATS_DEFAULT_LIFESPAN); +@@ -576,10 +572,6 @@ static int hns_roce_get_hw_stats(struct ib_device *device, + if (port > hr_dev->caps.num_ports) + return -EINVAL; + +- if (hr_dev->pci_dev->revision <= PCI_REVISION_ID_HIP08 || +- hr_dev->is_vf) +- return -EOPNOTSUPP; +- + ret = hr_dev->hw->query_hw_counter(hr_dev, stats->value, port, + &num_counters); + if (ret) { +@@ -633,8 +625,6 @@ static const struct ib_device_ops hns_roce_dev_ops = { + .query_pkey = hns_roce_query_pkey, + .query_port = hns_roce_query_port, + .reg_user_mr = hns_roce_reg_user_mr, +- .alloc_hw_port_stats = hns_roce_alloc_hw_port_stats, +- .get_hw_stats = hns_roce_get_hw_stats, + + INIT_RDMA_OBJ_SIZE(ib_ah, hns_roce_ah, ibah), + INIT_RDMA_OBJ_SIZE(ib_cq, hns_roce_cq, ib_cq), +@@ -643,6 +633,11 @@ static const struct ib_device_ops hns_roce_dev_ops = { + INIT_RDMA_OBJ_SIZE(ib_ucontext, hns_roce_ucontext, ibucontext), + }; + ++static const struct ib_device_ops hns_roce_dev_hw_stats_ops = { ++ .alloc_hw_port_stats = hns_roce_alloc_hw_port_stats, ++ .get_hw_stats = hns_roce_get_hw_stats, ++}; ++ + static const struct ib_device_ops hns_roce_dev_mr_ops = { + .rereg_user_mr = hns_roce_rereg_user_mr, + }; +@@ -719,6 +714,10 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev) + if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_XRC) + ib_set_device_ops(ib_dev, &hns_roce_dev_xrcd_ops); + ++ if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09 && ++ !hr_dev->is_vf) ++ ib_set_device_ops(ib_dev, &hns_roce_dev_hw_stats_ops); ++ + ib_set_device_ops(ib_dev, hr_dev->hw->hns_roce_dev_ops); + ib_set_device_ops(ib_dev, &hns_roce_dev_ops); + ib_set_device_ops(ib_dev, &hns_roce_dev_restrack_ops); +-- +2.42.0 + diff --git a/queue-6.6/rdma-hns-fix-printing-level-of-asynchronous-events.patch b/queue-6.6/rdma-hns-fix-printing-level-of-asynchronous-events.patch new file mode 100644 index 00000000000..af8a3a78724 --- /dev/null +++ b/queue-6.6/rdma-hns-fix-printing-level-of-asynchronous-events.patch @@ -0,0 +1,57 @@ +From b125f5dcfca5b7ee36cbb2507b444fcf65c2a397 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 20:52:33 +0800 +Subject: RDMA/hns: Fix printing level of asynchronous events + +From: Chengchang Tang + +[ Upstream commit 9faef73ef4f6666b97e04d99734ac09251098185 ] + +The current driver will print all asynchronous events. Some of the +print levels are set improperly, e.g. SRQ limit reach and SRQ last +wqe reach, which may also occur during normal operation of the software. +Currently, the information of these event is printed as a warning, +which causes a large amount of printing even during normal use of the +application. As a result, the service performance deteriorates. + +This patch fixes the printing storms by modifying the print level. + +Fixes: b00a92c8f2ca ("RDMA/hns: Move all prints out of irq handle") +Signed-off-by: Chengchang Tang +Signed-off-by: Junxian Huang +Link: https://lore.kernel.org/r/20231017125239.164455-2-huangjunxian6@hisilicon.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index d82daff2d9bd5..2b8f6489ab3df 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -5804,7 +5804,7 @@ static void hns_roce_irq_work_handle(struct work_struct *work) + case HNS_ROCE_EVENT_TYPE_COMM_EST: + break; + case HNS_ROCE_EVENT_TYPE_SQ_DRAINED: +- ibdev_warn(ibdev, "send queue drained.\n"); ++ ibdev_dbg(ibdev, "send queue drained.\n"); + break; + case HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR: + ibdev_err(ibdev, "local work queue 0x%x catast error, sub_event type is: %d\n", +@@ -5819,10 +5819,10 @@ static void hns_roce_irq_work_handle(struct work_struct *work) + irq_work->queue_num, irq_work->sub_type); + break; + case HNS_ROCE_EVENT_TYPE_SRQ_LIMIT_REACH: +- ibdev_warn(ibdev, "SRQ limit reach.\n"); ++ ibdev_dbg(ibdev, "SRQ limit reach.\n"); + break; + case HNS_ROCE_EVENT_TYPE_SRQ_LAST_WQE_REACH: +- ibdev_warn(ibdev, "SRQ last wqe reach.\n"); ++ ibdev_dbg(ibdev, "SRQ last wqe reach.\n"); + break; + case HNS_ROCE_EVENT_TYPE_SRQ_CATAS_ERROR: + ibdev_err(ibdev, "SRQ catas error.\n"); +-- +2.42.0 + diff --git a/queue-6.6/rdma-hns-fix-signed-unsigned-mixed-comparisons.patch b/queue-6.6/rdma-hns-fix-signed-unsigned-mixed-comparisons.patch new file mode 100644 index 00000000000..b166e07e265 --- /dev/null +++ b/queue-6.6/rdma-hns-fix-signed-unsigned-mixed-comparisons.patch @@ -0,0 +1,41 @@ +From e084d17618810726a3843ccf33f67e115e84b5a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 20:52:35 +0800 +Subject: RDMA/hns: Fix signed-unsigned mixed comparisons + +From: Chengchang Tang + +[ Upstream commit b5f9efff101b06fd06a5e280a2b00b1335f5f476 ] + +The ib_mtu_enum_to_int() and uverbs_attr_get_len() may returns a negative +value. In this case, mixed comparisons of signed and unsigned types will +throw wrong results. + +This patch adds judgement for this situation. + +Fixes: 30b707886aeb ("RDMA/hns: Support inline data in extented sge space for RC") +Signed-off-by: Chengchang Tang +Signed-off-by: Junxian Huang +Link: https://lore.kernel.org/r/20231017125239.164455-4-huangjunxian6@hisilicon.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index 2b8f6489ab3df..3daa684f88362 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -270,7 +270,7 @@ static bool check_inl_data_len(struct hns_roce_qp *qp, unsigned int len) + struct hns_roce_dev *hr_dev = to_hr_dev(qp->ibqp.device); + int mtu = ib_mtu_enum_to_int(qp->path_mtu); + +- if (len > qp->max_inline_data || len > mtu) { ++ if (mtu < 0 || len > qp->max_inline_data || len > mtu) { + ibdev_err(&hr_dev->ib_dev, + "invalid length of data, data len = %u, max inline len = %u, path mtu = %d.\n", + len, qp->max_inline_data, mtu); +-- +2.42.0 + diff --git a/queue-6.6/rdma-hns-fix-uninitialized-ucmd-in-hns_roce_create_q.patch b/queue-6.6/rdma-hns-fix-uninitialized-ucmd-in-hns_roce_create_q.patch new file mode 100644 index 00000000000..d7373afd8ca --- /dev/null +++ b/queue-6.6/rdma-hns-fix-uninitialized-ucmd-in-hns_roce_create_q.patch @@ -0,0 +1,44 @@ +From bd80144bbf58318ade1c2a8b1caa75a3461d84ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 20:52:34 +0800 +Subject: RDMA/hns: Fix uninitialized ucmd in hns_roce_create_qp_common() + +From: Chengchang Tang + +[ Upstream commit c64e9710f9241e38a1c761ed1c1a30854784da66 ] + +ucmd in hns_roce_create_qp_common() are not initialized. But it works fine +until new member sdb_addr is added to struct hns_roce_ib_create_qp. + +If the user-mode driver uses an old version ABI, then the value of the new +member will be undefined after ib_copy_from_udata(). + +This patch fixes it by initialize this variable to 0. And the default value +of the new member sdb_addr will be 0 which is invalid. + +Fixes: 0425e3e6e0c7 ("RDMA/hns: Support flush cqe for hip08 in kernel space") +Signed-off-by: Chengchang Tang +Signed-off-by: Junxian Huang +Link: https://lore.kernel.org/r/20231017125239.164455-3-huangjunxian6@hisilicon.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hns/hns_roce_qp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c +index cdc1c6de43a17..828b58534aa97 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_qp.c ++++ b/drivers/infiniband/hw/hns/hns_roce_qp.c +@@ -1064,7 +1064,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev, + { + struct hns_roce_ib_create_qp_resp resp = {}; + struct ib_device *ibdev = &hr_dev->ib_dev; +- struct hns_roce_ib_create_qp ucmd; ++ struct hns_roce_ib_create_qp ucmd = {}; + int ret; + + mutex_init(&hr_qp->mutex); +-- +2.42.0 + diff --git a/queue-6.6/rdma-hns-fix-unnecessary-port_num-transition-in-hw-s.patch b/queue-6.6/rdma-hns-fix-unnecessary-port_num-transition-in-hw-s.patch new file mode 100644 index 00000000000..57fe3f78c0f --- /dev/null +++ b/queue-6.6/rdma-hns-fix-unnecessary-port_num-transition-in-hw-s.patch @@ -0,0 +1,40 @@ +From 69ed90ac19382063579ae28f9fb90cd4a69a93d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 20:52:38 +0800 +Subject: RDMA/hns: Fix unnecessary port_num transition in HW stats allocation + +From: Junxian Huang + +[ Upstream commit b4a797b894dc91a541ea230db6fa00cc74683bfd ] + +The num_ports capability of devices should be compared with the +number of port(i.e. the input param "port_num") but not the port +index(i.e. port_num - 1). + +Fixes: 5a87279591a1 ("RDMA/hns: Support hns HW stats") +Signed-off-by: Junxian Huang +Link: https://lore.kernel.org/r/20231017125239.164455-7-huangjunxian6@hisilicon.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hns/hns_roce_main.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c +index d9d546cdef525..e1a88f2d51b6c 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_main.c ++++ b/drivers/infiniband/hw/hns/hns_roce_main.c +@@ -547,9 +547,8 @@ static struct rdma_hw_stats *hns_roce_alloc_hw_port_stats( + struct ib_device *device, u32 port_num) + { + struct hns_roce_dev *hr_dev = to_hr_dev(device); +- u32 port = port_num - 1; + +- if (port > hr_dev->caps.num_ports) { ++ if (port_num > hr_dev->caps.num_ports) { + ibdev_err(device, "invalid port num.\n"); + return NULL; + } +-- +2.42.0 + diff --git a/queue-6.6/rdma-hns-the-ud-mode-can-only-be-configured-with-dcq.patch b/queue-6.6/rdma-hns-the-ud-mode-can-only-be-configured-with-dcq.patch new file mode 100644 index 00000000000..c8cdd884870 --- /dev/null +++ b/queue-6.6/rdma-hns-the-ud-mode-can-only-be-configured-with-dcq.patch @@ -0,0 +1,39 @@ +From 9a347d1a7eec1edf8bcbf971a896aa5791b4695e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 20:52:37 +0800 +Subject: RDMA/hns: The UD mode can only be configured with DCQCN + +From: Luoyouming + +[ Upstream commit 27c5fd271d8b8730fc0bb1b6cae953ad7808a874 ] + +Due to hardware limitations, only DCQCN is supported for UD. Therefore, the +default algorithm for UD is set to DCQCN. + +Fixes: f91696f2f053 ("RDMA/hns: Support congestion control type selection according to the FW") +Signed-off-by: Luoyouming +Signed-off-by: Junxian Huang +Link: https://lore.kernel.org/r/20231017125239.164455-6-huangjunxian6@hisilicon.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index b7faf5c8f6ba8..58d14f1562b9a 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -4725,6 +4725,9 @@ static int check_cong_type(struct ib_qp *ibqp, + { + struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device); + ++ if (ibqp->qp_type == IB_QPT_UD) ++ hr_dev->caps.cong_type = CONG_TYPE_DCQCN; ++ + /* different congestion types match different configurations */ + switch (hr_dev->caps.cong_type) { + case CONG_TYPE_DCQCN: +-- +2.42.0 + diff --git a/queue-6.6/regmap-debugfs-fix-a-erroneous-check-after-snprintf.patch b/queue-6.6/regmap-debugfs-fix-a-erroneous-check-after-snprintf.patch new file mode 100644 index 00000000000..13d6d6f7ccd --- /dev/null +++ b/queue-6.6/regmap-debugfs-fix-a-erroneous-check-after-snprintf.patch @@ -0,0 +1,37 @@ +From a77249a1b43ac5044ea4ad67d6386c587319bbc0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 22:04:06 +0200 +Subject: regmap: debugfs: Fix a erroneous check after snprintf() + +From: Christophe JAILLET + +[ Upstream commit d3601857e14de6369f00ae19564f1d817d175d19 ] + +This error handling looks really strange. +Check if the string has been truncated instead. + +Fixes: f0c2319f9f19 ("regmap: Expose the driver name in debugfs") +Signed-off-by: Christophe JAILLET +Link: https://lore.kernel.org/r/8595de2462c490561f70020a6d11f4d6b652b468.1693857825.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/base/regmap/regmap-debugfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c +index f36027591e1a8..bdd80b73c3e6c 100644 +--- a/drivers/base/regmap/regmap-debugfs.c ++++ b/drivers/base/regmap/regmap-debugfs.c +@@ -48,7 +48,7 @@ static ssize_t regmap_name_read_file(struct file *file, + name = map->dev->driver->name; + + ret = snprintf(buf, PAGE_SIZE, "%s\n", name); +- if (ret < 0) { ++ if (ret >= PAGE_SIZE) { + kfree(buf); + return ret; + } +-- +2.42.0 + diff --git a/queue-6.6/regmap-prevent-noinc-writes-from-clobbering-cache.patch b/queue-6.6/regmap-prevent-noinc-writes-from-clobbering-cache.patch new file mode 100644 index 00000000000..8f18429252a --- /dev/null +++ b/queue-6.6/regmap-prevent-noinc-writes-from-clobbering-cache.patch @@ -0,0 +1,57 @@ +From 990282f7da8742a91e2fe604fad3395746442cd6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Nov 2023 10:29:27 -0400 +Subject: regmap: prevent noinc writes from clobbering cache + +From: Ben Wolsieffer + +[ Upstream commit 984a4afdc87a1fc226fd657b1cd8255c13d3fc1a ] + +Currently, noinc writes are cached as if they were standard incrementing +writes, overwriting unrelated register values in the cache. Instead, we +want to cache the last value written to the register, as is done in the +accelerated noinc handler (regmap_noinc_readwrite). + +Fixes: cdf6b11daa77 ("regmap: Add regmap_noinc_write API") +Signed-off-by: Ben Wolsieffer +Link: https://lore.kernel.org/r/20231101142926.2722603-2-ben.wolsieffer@hefring.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/base/regmap/regmap.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c +index 234a84ecde8b1..ea61577471994 100644 +--- a/drivers/base/regmap/regmap.c ++++ b/drivers/base/regmap/regmap.c +@@ -1620,17 +1620,19 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg, + } + + if (!map->cache_bypass && map->format.parse_val) { +- unsigned int ival; ++ unsigned int ival, offset; + int val_bytes = map->format.val_bytes; +- for (i = 0; i < val_len / val_bytes; i++) { +- ival = map->format.parse_val(val + (i * val_bytes)); +- ret = regcache_write(map, +- reg + regmap_get_offset(map, i), +- ival); ++ ++ /* Cache the last written value for noinc writes */ ++ i = noinc ? val_len - val_bytes : 0; ++ for (; i < val_len; i += val_bytes) { ++ ival = map->format.parse_val(val + i); ++ offset = noinc ? 0 : regmap_get_offset(map, i / val_bytes); ++ ret = regcache_write(map, reg + offset, ival); + if (ret) { + dev_err(map->dev, + "Error in caching of register: %x ret: %d\n", +- reg + regmap_get_offset(map, i), ret); ++ reg + offset, ret); + return ret; + } + } +-- +2.42.0 + diff --git a/queue-6.6/regulator-mt6358-fail-probe-on-unknown-chip-id.patch b/queue-6.6/regulator-mt6358-fail-probe-on-unknown-chip-id.patch new file mode 100644 index 00000000000..ccceb61c38b --- /dev/null +++ b/queue-6.6/regulator-mt6358-fail-probe-on-unknown-chip-id.patch @@ -0,0 +1,62 @@ +From bed35449fcdd398cca50ed21c032ef956497d287 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 16:29:16 +0800 +Subject: regulator: mt6358: Fail probe on unknown chip ID + +From: Chen-Yu Tsai + +[ Upstream commit 7442edec72bc657e6ce38ae01de9f10e55decfaa ] + +The MT6358 and MT6366 PMICs, and likely many others from MediaTek, have +a chip ID register, making the chip semi-discoverable. + +The driver currently supports two PMICs and expects to be probed on one +or the other. It does not account for incorrect mfd driver entries or +device trees. While these should not happen, if they do, it could be +catastrophic for the device. The driver should be sure the hardware is +what it expects. + +Make the driver fail to probe if the chip ID presented is not a known +one. + +Suggested-by: AngeloGioacchino Del Regno +Fixes: f0e3c6261af1 ("regulator: mt6366: Add support for MT6366 regulator") +Signed-off-by: Chen-Yu Tsai +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230913082919.1631287-2-wenst@chromium.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/mt6358-regulator.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c +index 65fbd95f1dbb0..4ca8fbf4b3e2e 100644 +--- a/drivers/regulator/mt6358-regulator.c ++++ b/drivers/regulator/mt6358-regulator.c +@@ -688,12 +688,18 @@ static int mt6358_regulator_probe(struct platform_device *pdev) + const struct mt6358_regulator_info *mt6358_info; + int i, max_regulator, ret; + +- if (mt6397->chip_id == MT6366_CHIP_ID) { +- max_regulator = MT6366_MAX_REGULATOR; +- mt6358_info = mt6366_regulators; +- } else { ++ switch (mt6397->chip_id) { ++ case MT6358_CHIP_ID: + max_regulator = MT6358_MAX_REGULATOR; + mt6358_info = mt6358_regulators; ++ break; ++ case MT6366_CHIP_ID: ++ max_regulator = MT6366_MAX_REGULATOR; ++ mt6358_info = mt6366_regulators; ++ break; ++ default: ++ dev_err(&pdev->dev, "unsupported chip ID: %d\n", mt6397->chip_id); ++ return -EINVAL; + } + + ret = mt6358_sync_vcn33_setting(&pdev->dev); +-- +2.42.0 + diff --git a/queue-6.6/regulator-qcom-rpmh-fix-smps4-regulator-for-pm8550ve.patch b/queue-6.6/regulator-qcom-rpmh-fix-smps4-regulator-for-pm8550ve.patch new file mode 100644 index 00000000000..5f45fd2a904 --- /dev/null +++ b/queue-6.6/regulator-qcom-rpmh-fix-smps4-regulator-for-pm8550ve.patch @@ -0,0 +1,37 @@ +From 4e0c005adad9fcba0c055572b911896ebf50a03d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Oct 2023 16:46:26 +0300 +Subject: regulator: qcom-rpmh: Fix smps4 regulator for pm8550ve + +From: Abel Vesa + +[ Upstream commit bc00d9f3813a40bc2d854ae0edab14c6b43a3219 ] + +The type of the smps4 regulator from pm8550ve is actually FTSMPS525 +medium voltage. So fix it accordingly. + +Fixes: e6e3776d682d ("regulator: qcom-rpmh: Add support for PM8550 regulators") +Signed-off-by: Abel Vesa +Link: https://lore.kernel.org/r/20231024134626.2364426-1-abel.vesa@linaro.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/qcom-rpmh-regulator.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c +index d990ba19c50eb..b2e359ac31693 100644 +--- a/drivers/regulator/qcom-rpmh-regulator.c ++++ b/drivers/regulator/qcom-rpmh-regulator.c +@@ -1095,7 +1095,7 @@ static const struct rpmh_vreg_init_data pm8550ve_vreg_data[] = { + RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps525_lv, "vdd-s1"), + RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps525_lv, "vdd-s2"), + RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps525_lv, "vdd-s3"), +- RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps525_lv, "vdd-s4"), ++ RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps525_mv, "vdd-s4"), + RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps525_lv, "vdd-s5"), + RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps525_lv, "vdd-s6"), + RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps525_lv, "vdd-s7"), +-- +2.42.0 + diff --git a/queue-6.6/revert-hwmon-sch56xx-common-add-automatic-module-loa.patch b/queue-6.6/revert-hwmon-sch56xx-common-add-automatic-module-loa.patch new file mode 100644 index 00000000000..65424bb66e6 --- /dev/null +++ b/queue-6.6/revert-hwmon-sch56xx-common-add-automatic-module-loa.patch @@ -0,0 +1,103 @@ +From b806e2febfc9ae276b2656650a752fafe1ff589a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 14:32:40 -0700 +Subject: Revert "hwmon: (sch56xx-common) Add automatic module loading on + supported devices" + +From: Guenter Roeck + +[ Upstream commit d621a46d05107f4e510383d6a38f2160c62d28f7 ] + +This reverts commit 393935baa45e5ccb9603cf7f9f020ed1bc0915f7. + +As reported by Ian Nartowicz, this and the next patch +result in a failure to load the driver on Celsius W280. +While the alternative would be to add the board to the DMI +override table, it is quite likely that other systems are +also affected. Revert the offending patches to avoid future +problems. + +Fixes: 393935baa45e ("hwmon: (sch56xx-common) Add automatic module loading on supported devices") +Reported-by: Ian Nartowicz +Closes: https://lore.kernel.org/linux-hwmon/20231025192239.3c5389ae@debian.org/T/#t +Cc: Armin Wolf +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/sch56xx-common.c | 40 ++-------------------------------- + 1 file changed, 2 insertions(+), 38 deletions(-) + +diff --git a/drivers/hwmon/sch56xx-common.c b/drivers/hwmon/sch56xx-common.c +index 3ece53adabd62..ac1f725807155 100644 +--- a/drivers/hwmon/sch56xx-common.c ++++ b/drivers/hwmon/sch56xx-common.c +@@ -7,10 +7,8 @@ + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + + #include +-#include + #include + #include +-#include + #include + #include + #include +@@ -21,10 +19,7 @@ + #include + #include "sch56xx-common.h" + +-static bool ignore_dmi; +-module_param(ignore_dmi, bool, 0); +-MODULE_PARM_DESC(ignore_dmi, "Omit DMI check for supported devices (default=0)"); +- ++/* Insmod parameters */ + static bool nowayout = WATCHDOG_NOWAYOUT; + module_param(nowayout, bool, 0); + MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" +@@ -523,42 +518,11 @@ static int __init sch56xx_device_add(int address, const char *name) + return PTR_ERR_OR_ZERO(sch56xx_pdev); + } + +-/* For autoloading only */ +-static const struct dmi_system_id sch56xx_dmi_table[] __initconst = { +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- }, +- }, +- { } +-}; +-MODULE_DEVICE_TABLE(dmi, sch56xx_dmi_table); +- + static int __init sch56xx_init(void) + { +- const char *name = NULL; + int address; ++ const char *name = NULL; + +- if (!ignore_dmi) { +- if (!dmi_check_system(sch56xx_dmi_table)) +- return -ENODEV; +- +- /* +- * Some machines like the Esprimo P720 and Esprimo C700 have +- * onboard devices named " Antiope"/" Theseus" instead of +- * "Antiope"/"Theseus", so we need to check for both. +- */ +- if (!dmi_find_device(DMI_DEV_TYPE_OTHER, "Antiope", NULL) && +- !dmi_find_device(DMI_DEV_TYPE_OTHER, " Antiope", NULL) && +- !dmi_find_device(DMI_DEV_TYPE_OTHER, "Theseus", NULL) && +- !dmi_find_device(DMI_DEV_TYPE_OTHER, " Theseus", NULL)) +- return -ENODEV; +- } +- +- /* +- * Some devices like the Esprimo C700 have both onboard devices, +- * so we still have to check manually +- */ + address = sch56xx_find(0x4e, &name); + if (address < 0) + address = sch56xx_find(0x2e, &name); +-- +2.42.0 + diff --git a/queue-6.6/revert-hwmon-sch56xx-common-add-dmi-override-table.patch b/queue-6.6/revert-hwmon-sch56xx-common-add-dmi-override-table.patch new file mode 100644 index 00000000000..abb1a84c1e8 --- /dev/null +++ b/queue-6.6/revert-hwmon-sch56xx-common-add-dmi-override-table.patch @@ -0,0 +1,93 @@ +From c0d4c1b8a2891e31c0aafb698062a55e387e2240 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 14:28:49 -0700 +Subject: Revert "hwmon: (sch56xx-common) Add DMI override table" + +From: Guenter Roeck + +[ Upstream commit 28da9dee3594423534f3ea1e1f61e6bb2d2fa651 ] + +This reverts commit fd2d53c367ae9983c2100ac733a834e0c79d7537. + +As reported by Ian Nartowicz, this and the preceding patch +result in a failure to load the driver on Celsius W280. +While the alternative would be to add the board to the DMI +override table, it is quite likely that other systems are +also affected. Revert the offending patches to avoid future +problems. + +Fixes: fd2d53c367ae ("hwmon: (sch56xx-common) Add DMI override table") +Reported-by: Ian Nartowicz +Closes: https://lore.kernel.org/linux-hwmon/20231025192239.3c5389ae@debian.org/T/#t +Cc: Armin Wolf +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/sch56xx-common.c | 44 ++++++++-------------------------- + 1 file changed, 10 insertions(+), 34 deletions(-) + +diff --git a/drivers/hwmon/sch56xx-common.c b/drivers/hwmon/sch56xx-common.c +index de3a0886c2f72..3ece53adabd62 100644 +--- a/drivers/hwmon/sch56xx-common.c ++++ b/drivers/hwmon/sch56xx-common.c +@@ -523,28 +523,6 @@ static int __init sch56xx_device_add(int address, const char *name) + return PTR_ERR_OR_ZERO(sch56xx_pdev); + } + +-static const struct dmi_system_id sch56xx_dmi_override_table[] __initconst = { +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS W380"), +- }, +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO P710"), +- }, +- }, +- { +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO E9900"), +- }, +- }, +- { } +-}; +- + /* For autoloading only */ + static const struct dmi_system_id sch56xx_dmi_table[] __initconst = { + { +@@ -565,18 +543,16 @@ static int __init sch56xx_init(void) + if (!dmi_check_system(sch56xx_dmi_table)) + return -ENODEV; + +- if (!dmi_check_system(sch56xx_dmi_override_table)) { +- /* +- * Some machines like the Esprimo P720 and Esprimo C700 have +- * onboard devices named " Antiope"/" Theseus" instead of +- * "Antiope"/"Theseus", so we need to check for both. +- */ +- if (!dmi_find_device(DMI_DEV_TYPE_OTHER, "Antiope", NULL) && +- !dmi_find_device(DMI_DEV_TYPE_OTHER, " Antiope", NULL) && +- !dmi_find_device(DMI_DEV_TYPE_OTHER, "Theseus", NULL) && +- !dmi_find_device(DMI_DEV_TYPE_OTHER, " Theseus", NULL)) +- return -ENODEV; +- } ++ /* ++ * Some machines like the Esprimo P720 and Esprimo C700 have ++ * onboard devices named " Antiope"/" Theseus" instead of ++ * "Antiope"/"Theseus", so we need to check for both. ++ */ ++ if (!dmi_find_device(DMI_DEV_TYPE_OTHER, "Antiope", NULL) && ++ !dmi_find_device(DMI_DEV_TYPE_OTHER, " Antiope", NULL) && ++ !dmi_find_device(DMI_DEV_TYPE_OTHER, "Theseus", NULL) && ++ !dmi_find_device(DMI_DEV_TYPE_OTHER, " Theseus", NULL)) ++ return -ENODEV; + } + + /* +-- +2.42.0 + diff --git a/queue-6.6/riscv-dts-allwinner-remove-address-cells-from-intc-n.patch b/queue-6.6/riscv-dts-allwinner-remove-address-cells-from-intc-n.patch new file mode 100644 index 00000000000..1cb51abeb2c --- /dev/null +++ b/queue-6.6/riscv-dts-allwinner-remove-address-cells-from-intc-n.patch @@ -0,0 +1,41 @@ +From 4373c2699ef5c8ed86fce5e302870e88127674cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 16 Sep 2023 10:14:00 +0100 +Subject: riscv: dts: allwinner: remove address-cells from intc node + +From: Conor Dooley + +[ Upstream commit 267860b10c67dd396c73a9e6e8103670d78a4c01 ] + +A recent submission [1] from Rob has added additionalProperties: false +to the interrupt-controller child node of RISC-V cpus, highlighting that +the D1 DT has been incorrectly using #address-cells since its +introduction. It has no child nodes, so #address-cells is not needed. +Remove it. + +Fixes: 077e5f4f5528 ("riscv: dts: allwinner: Add the D1/D1s SoC devicetree") +Link: https://patchwork.kernel.org/project/linux-riscv/patch/20230915201946.4184468-1-robh@kernel.org/ [1] +Signed-off-by: Conor Dooley +Acked-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20230916-saddling-dastardly-8cf6d1263c24@spud +Signed-off-by: Jernej Skrabec +Signed-off-by: Sasha Levin +--- + arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi b/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi +index 8275630af977d..b8684312593e5 100644 +--- a/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi ++++ b/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi +@@ -30,7 +30,6 @@ cpu0: cpu@0 { + cpu0_intc: interrupt-controller { + compatible = "riscv,cpu-intc"; + interrupt-controller; +- #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; +-- +2.42.0 + diff --git a/queue-6.6/rtc-brcmstb-waketimer-support-level-alarm_irq.patch b/queue-6.6/rtc-brcmstb-waketimer-support-level-alarm_irq.patch new file mode 100644 index 00000000000..8bb17dde1e2 --- /dev/null +++ b/queue-6.6/rtc-brcmstb-waketimer-support-level-alarm_irq.patch @@ -0,0 +1,138 @@ +From f97d5c12af68f80b80178ec09c9683ba55e79c92 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Aug 2023 15:47:47 -0700 +Subject: rtc: brcmstb-waketimer: support level alarm_irq + +From: Doug Berger + +[ Upstream commit e005a9b35b464be5b2e0194f717e90e7e496785d ] + +Some devices (e.g. BCM72112) use an alarm_irq interrupt that is +connected to a level interrupt controller rather than an edge +interrupt controller. In this case, the interrupt cannot be left +enabled by the irq handler while preserving the hardware wake-up +signal on wake capable devices or an interrupt storm will occur. + +The alarm_expired flag is introduced to allow the disabling of +the interrupt when an alarm expires and to support balancing the +calls to disable_irq() and enable_irq() in accordance with the +existing design. + +Fixes: 24304a87158a ("rtc: brcmstb-waketimer: allow use as non-wake alarm") +Signed-off-by: Doug Berger +Reviewed-by: Florian Fainelli +Link: https://lore.kernel.org/r/20230830224747.1663044-1-opendmb@gmail.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/rtc/rtc-brcmstb-waketimer.c | 47 ++++++++++++++++++++++++++--- + 1 file changed, 42 insertions(+), 5 deletions(-) + +diff --git a/drivers/rtc/rtc-brcmstb-waketimer.c b/drivers/rtc/rtc-brcmstb-waketimer.c +index 3cdc015692ca6..1a65a4e0dc003 100644 +--- a/drivers/rtc/rtc-brcmstb-waketimer.c ++++ b/drivers/rtc/rtc-brcmstb-waketimer.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* +- * Copyright © 2014-2017 Broadcom ++ * Copyright © 2014-2023 Broadcom + */ + + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +@@ -34,6 +34,7 @@ struct brcmstb_waketmr { + u32 rate; + unsigned long rtc_alarm; + bool alarm_en; ++ bool alarm_expired; + }; + + #define BRCMSTB_WKTMR_EVENT 0x00 +@@ -64,6 +65,11 @@ static inline void brcmstb_waketmr_clear_alarm(struct brcmstb_waketmr *timer) + writel_relaxed(reg - 1, timer->base + BRCMSTB_WKTMR_ALARM); + writel_relaxed(WKTMR_ALARM_EVENT, timer->base + BRCMSTB_WKTMR_EVENT); + (void)readl_relaxed(timer->base + BRCMSTB_WKTMR_EVENT); ++ if (timer->alarm_expired) { ++ timer->alarm_expired = false; ++ /* maintain call balance */ ++ enable_irq(timer->alarm_irq); ++ } + } + + static void brcmstb_waketmr_set_alarm(struct brcmstb_waketmr *timer, +@@ -105,10 +111,17 @@ static irqreturn_t brcmstb_alarm_irq(int irq, void *data) + return IRQ_HANDLED; + + if (timer->alarm_en) { +- if (!device_may_wakeup(timer->dev)) ++ if (device_may_wakeup(timer->dev)) { ++ disable_irq_nosync(irq); ++ timer->alarm_expired = true; ++ } else { + writel_relaxed(WKTMR_ALARM_EVENT, + timer->base + BRCMSTB_WKTMR_EVENT); ++ } + rtc_update_irq(timer->rtc, 1, RTC_IRQF | RTC_AF); ++ } else { ++ writel_relaxed(WKTMR_ALARM_EVENT, ++ timer->base + BRCMSTB_WKTMR_EVENT); + } + + return IRQ_HANDLED; +@@ -221,8 +234,14 @@ static int brcmstb_waketmr_alarm_enable(struct device *dev, + !brcmstb_waketmr_is_pending(timer)) + return -EINVAL; + timer->alarm_en = true; +- if (timer->alarm_irq) ++ if (timer->alarm_irq) { ++ if (timer->alarm_expired) { ++ timer->alarm_expired = false; ++ /* maintain call balance */ ++ enable_irq(timer->alarm_irq); ++ } + enable_irq(timer->alarm_irq); ++ } + } else if (!enabled && timer->alarm_en) { + if (timer->alarm_irq) + disable_irq(timer->alarm_irq); +@@ -352,6 +371,17 @@ static int brcmstb_waketmr_suspend(struct device *dev) + return brcmstb_waketmr_prepare_suspend(timer); + } + ++static int brcmstb_waketmr_suspend_noirq(struct device *dev) ++{ ++ struct brcmstb_waketmr *timer = dev_get_drvdata(dev); ++ ++ /* Catch any alarms occurring prior to noirq */ ++ if (timer->alarm_expired && device_may_wakeup(dev)) ++ return -EBUSY; ++ ++ return 0; ++} ++ + static int brcmstb_waketmr_resume(struct device *dev) + { + struct brcmstb_waketmr *timer = dev_get_drvdata(dev); +@@ -368,10 +398,17 @@ static int brcmstb_waketmr_resume(struct device *dev) + + return ret; + } ++#else ++#define brcmstb_waketmr_suspend NULL ++#define brcmstb_waketmr_suspend_noirq NULL ++#define brcmstb_waketmr_resume NULL + #endif /* CONFIG_PM_SLEEP */ + +-static SIMPLE_DEV_PM_OPS(brcmstb_waketmr_pm_ops, +- brcmstb_waketmr_suspend, brcmstb_waketmr_resume); ++static const struct dev_pm_ops brcmstb_waketmr_pm_ops = { ++ .suspend = brcmstb_waketmr_suspend, ++ .suspend_noirq = brcmstb_waketmr_suspend_noirq, ++ .resume = brcmstb_waketmr_resume, ++}; + + static const __maybe_unused struct of_device_id brcmstb_waketmr_of_match[] = { + { .compatible = "brcm,brcmstb-waketimer" }, +-- +2.42.0 + diff --git a/queue-6.6/rtc-pcf85363-fix-wrong-mask-val-parameters-in-regmap.patch b/queue-6.6/rtc-pcf85363-fix-wrong-mask-val-parameters-in-regmap.patch new file mode 100644 index 00000000000..a5044dff333 --- /dev/null +++ b/queue-6.6/rtc-pcf85363-fix-wrong-mask-val-parameters-in-regmap.patch @@ -0,0 +1,43 @@ +From 9a96c58d77d647549cac705b10029deaa94f042f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Oct 2023 16:34:21 +0200 +Subject: rtc: pcf85363: fix wrong mask/val parameters in regmap_update_bits + call + +From: Javier Carrasco + +[ Upstream commit 2be36c09b6b07306be33519e1aa70d2e2a2161bb ] + +The current implementation passes PIN_IO_INTA_OUT (2) as a mask and +PIN_IO_INTAPM (GENMASK(1, 0)) as a value. +Swap the variables to assign mask and value the right way. + +This error was first introduced with the alarm support. For better or +worse it worked as expected because 0x02 was applied as a mask to 0x03, +resulting 0x02 anyway. This will of course not work for any other value. + +Fixes: e5aac267a10a ("rtc: pcf85363: add alarm support") +Signed-off-by: Javier Carrasco +Link: https://lore.kernel.org/r/20231013-topic-pcf85363_regmap_update_bits-v1-1-c454f016f71f@gmail.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/rtc/rtc-pcf85363.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c +index 06194674d71c5..540042b9eec8f 100644 +--- a/drivers/rtc/rtc-pcf85363.c ++++ b/drivers/rtc/rtc-pcf85363.c +@@ -438,7 +438,7 @@ static int pcf85363_probe(struct i2c_client *client) + if (client->irq > 0 || wakeup_source) { + regmap_write(pcf85363->regmap, CTRL_FLAGS, 0); + regmap_update_bits(pcf85363->regmap, CTRL_PIN_IO, +- PIN_IO_INTA_OUT, PIN_IO_INTAPM); ++ PIN_IO_INTAPM, PIN_IO_INTA_OUT); + } + + if (client->irq > 0) { +-- +2.42.0 + diff --git a/queue-6.6/rtla-fix-uninitialized-variable-found.patch b/queue-6.6/rtla-fix-uninitialized-variable-found.patch new file mode 100644 index 00000000000..779f6a113d1 --- /dev/null +++ b/queue-6.6/rtla-fix-uninitialized-variable-found.patch @@ -0,0 +1,39 @@ +From 5ce638e8a1a6bb4053e687f46b86c05298b6547e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Jul 2023 16:01:17 +0100 +Subject: rtla: Fix uninitialized variable found + +From: Colin Ian King + +[ Upstream commit 696444a544ecd6d62c1edc89516b376cefb28929 ] + +Variable found is not being initialized, in the case where the desired +mount is not found the variable contains garbage. Fix this by initializing +it to zero. + +Link: https://lore.kernel.org/all/20230727150117.627730-1-colin.i.king@gmail.com/ + +Fixes: a957cbc02531 ("rtla: Add -C cgroup support") +Signed-off-by: Colin Ian King +Signed-off-by: Daniel Bristot de Oliveira +Signed-off-by: Sasha Levin +--- + tools/tracing/rtla/src/utils.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c +index 623a38908ed5b..c769d7b3842c0 100644 +--- a/tools/tracing/rtla/src/utils.c ++++ b/tools/tracing/rtla/src/utils.c +@@ -538,7 +538,7 @@ static const int find_mount(const char *fs, char *mp, int sizeof_mp) + { + char mount_point[MAX_PATH]; + char type[100]; +- int found; ++ int found = 0; + FILE *fp; + + fp = fopen("/proc/mounts", "r"); +-- +2.42.0 + diff --git a/queue-6.6/s390-ap-re-init-ap-queues-on-config-on.patch b/queue-6.6/s390-ap-re-init-ap-queues-on-config-on.patch new file mode 100644 index 00000000000..3151bae8076 --- /dev/null +++ b/queue-6.6/s390-ap-re-init-ap-queues-on-config-on.patch @@ -0,0 +1,133 @@ +From b42ca55bfac437cd3420706c9fad868f54672e7c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 09:54:25 +0200 +Subject: s390/ap: re-init AP queues on config on + +From: Harald Freudenberger + +[ Upstream commit 32d1d9204f8db3360be55e65bd182a1a68f93308 ] + +On a state toggle from config off to config on and on the +state toggle from checkstop to not checkstop the queue's +internal states was set but the state machine was not +nudged. This did not care as on the first enqueue of a +request the state machine kick ran. + +However, within an Secure Execution guest a queue is +only chosen by the scheduler when it has been bound. +But to bind a queue, it needs to run through the initial +states (reset, enable interrupts, ...). So this is like +a chicken-and-egg problem and the result was in fact +that a queue was unusable after a config off/on toggle. + +With some slight rework of the handling of these states +now the new function _ap_queue_init_state() is called +which is the core of the ap_queue_init_state() function +but without locking handling. This has the benefit that +it can be called on all the places where a (re-)init +of the AP queue's state machine is needed. + +Fixes: 2d72eaf036d2 ("s390/ap: implement SE AP bind, unbind and associate") +Signed-off-by: Harald Freudenberger +Reviewed-by: Holger Dengler +Signed-off-by: Vasily Gorbik +Signed-off-by: Sasha Levin +--- + drivers/s390/crypto/ap_bus.c | 21 ++++++++++----------- + drivers/s390/crypto/ap_bus.h | 1 + + drivers/s390/crypto/ap_queue.c | 9 +++++++-- + 3 files changed, 18 insertions(+), 13 deletions(-) + +diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c +index 339812efe8221..d09e08b71cfba 100644 +--- a/drivers/s390/crypto/ap_bus.c ++++ b/drivers/s390/crypto/ap_bus.c +@@ -1865,15 +1865,18 @@ static inline void ap_scan_domains(struct ap_card *ac) + } + /* get it and thus adjust reference counter */ + get_device(dev); +- if (decfg) ++ if (decfg) { + AP_DBF_INFO("%s(%d,%d) new (decfg) queue dev created\n", + __func__, ac->id, dom); +- else if (chkstop) ++ } else if (chkstop) { + AP_DBF_INFO("%s(%d,%d) new (chkstop) queue dev created\n", + __func__, ac->id, dom); +- else ++ } else { ++ /* nudge the queue's state machine */ ++ ap_queue_init_state(aq); + AP_DBF_INFO("%s(%d,%d) new queue dev created\n", + __func__, ac->id, dom); ++ } + goto put_dev_and_continue; + } + /* handle state changes on already existing queue device */ +@@ -1895,10 +1898,8 @@ static inline void ap_scan_domains(struct ap_card *ac) + } else if (!chkstop && aq->chkstop) { + /* checkstop off */ + aq->chkstop = false; +- if (aq->dev_state > AP_DEV_STATE_UNINITIATED) { +- aq->dev_state = AP_DEV_STATE_OPERATING; +- aq->sm_state = AP_SM_STATE_RESET_START; +- } ++ if (aq->dev_state > AP_DEV_STATE_UNINITIATED) ++ _ap_queue_init_state(aq); + spin_unlock_bh(&aq->lock); + AP_DBF_DBG("%s(%d,%d) queue dev checkstop off\n", + __func__, ac->id, dom); +@@ -1922,10 +1923,8 @@ static inline void ap_scan_domains(struct ap_card *ac) + } else if (!decfg && !aq->config) { + /* config on this queue device */ + aq->config = true; +- if (aq->dev_state > AP_DEV_STATE_UNINITIATED) { +- aq->dev_state = AP_DEV_STATE_OPERATING; +- aq->sm_state = AP_SM_STATE_RESET_START; +- } ++ if (aq->dev_state > AP_DEV_STATE_UNINITIATED) ++ _ap_queue_init_state(aq); + spin_unlock_bh(&aq->lock); + AP_DBF_DBG("%s(%d,%d) queue dev config on\n", + __func__, ac->id, dom); +diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h +index be54b070c0316..3e34912a60506 100644 +--- a/drivers/s390/crypto/ap_bus.h ++++ b/drivers/s390/crypto/ap_bus.h +@@ -287,6 +287,7 @@ struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type); + void ap_queue_prepare_remove(struct ap_queue *aq); + void ap_queue_remove(struct ap_queue *aq); + void ap_queue_init_state(struct ap_queue *aq); ++void _ap_queue_init_state(struct ap_queue *aq); + + struct ap_card *ap_card_create(int id, int queue_depth, int raw_type, + int comp_type, unsigned int functions, int ml); +diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c +index 1336e632adc4a..2943b2529d3a0 100644 +--- a/drivers/s390/crypto/ap_queue.c ++++ b/drivers/s390/crypto/ap_queue.c +@@ -1160,14 +1160,19 @@ void ap_queue_remove(struct ap_queue *aq) + spin_unlock_bh(&aq->lock); + } + +-void ap_queue_init_state(struct ap_queue *aq) ++void _ap_queue_init_state(struct ap_queue *aq) + { +- spin_lock_bh(&aq->lock); + aq->dev_state = AP_DEV_STATE_OPERATING; + aq->sm_state = AP_SM_STATE_RESET_START; + aq->last_err_rc = 0; + aq->assoc_idx = ASSOC_IDX_INVALID; + ap_wait(ap_sm_event(aq, AP_SM_EVENT_POLL)); ++} ++ ++void ap_queue_init_state(struct ap_queue *aq) ++{ ++ spin_lock_bh(&aq->lock); ++ _ap_queue_init_state(aq); + spin_unlock_bh(&aq->lock); + } + EXPORT_SYMBOL(ap_queue_init_state); +-- +2.42.0 + diff --git a/queue-6.6/sched-fair-fix-cfs_rq_is_decayed-on-smp.patch b/queue-6.6/sched-fair-fix-cfs_rq_is_decayed-on-smp.patch new file mode 100644 index 00000000000..8c0e0610163 --- /dev/null +++ b/queue-6.6/sched-fair-fix-cfs_rq_is_decayed-on-smp.patch @@ -0,0 +1,47 @@ +From f0faa940ccf50634148d43fd74454ef7d32c297d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 13:20:31 +0000 +Subject: sched/fair: Fix cfs_rq_is_decayed() on !SMP + +From: Chengming Zhou + +[ Upstream commit c0490bc9bb62d9376f3dd4ec28e03ca0fef97152 ] + +We don't need to maintain per-queue leaf_cfs_rq_list on !SMP, since +it's used for cfs_rq load tracking & balancing on SMP. + +But sched debug interface uses it to print per-cfs_rq stats. + +This patch fixes the !SMP version of cfs_rq_is_decayed(), so the +per-queue leaf_cfs_rq_list is also maintained correctly on !SMP, +to fix the warning in assert_list_leaf_cfs_rq(). + +Fixes: 0a00a354644e ("sched/fair: Delete useless condition in tg_unthrottle_up()") +Reported-by: Leo Yu-Chi Liang +Signed-off-by: Chengming Zhou +Signed-off-by: Ingo Molnar +Tested-by: Leo Yu-Chi Liang +Reviewed-by: Vincent Guittot +Closes: https://lore.kernel.org/all/ZN87UsqkWcFLDxea@swlinux02/ +Link: https://lore.kernel.org/r/20230913132031.2242151-1-chengming.zhou@linux.dev +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index df348aa55d3c7..6af1d48d467ed 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -4932,7 +4932,7 @@ static inline void update_misfit_status(struct task_struct *p, struct rq *rq) + + static inline bool cfs_rq_is_decayed(struct cfs_rq *cfs_rq) + { +- return true; ++ return !cfs_rq->nr_running; + } + + #define UPDATE_TG 0x0 +-- +2.42.0 + diff --git a/queue-6.6/sched-fix-stop_one_cpu_nowait-vs-hotplug.patch b/queue-6.6/sched-fix-stop_one_cpu_nowait-vs-hotplug.patch new file mode 100644 index 00000000000..3a4af1fba7f --- /dev/null +++ b/queue-6.6/sched-fix-stop_one_cpu_nowait-vs-hotplug.patch @@ -0,0 +1,211 @@ +From 13ec9a8314dee311f28fa45eb78d5aa0c362fdc3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 20:57:39 +0200 +Subject: sched: Fix stop_one_cpu_nowait() vs hotplug +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Peter Zijlstra + +[ Upstream commit f0498d2a54e7966ce23cd7c7ff42c64fa0059b07 ] + +Kuyo reported sporadic failures on a sched_setaffinity() vs CPU +hotplug stress-test -- notably affine_move_task() remains stuck in +wait_for_completion(), leading to a hung-task detector warning. + +Specifically, it was reported that stop_one_cpu_nowait(.fn = +migration_cpu_stop) returns false -- this stopper is responsible for +the matching complete(). + +The race scenario is: + + CPU0 CPU1 + + // doing _cpu_down() + + __set_cpus_allowed_ptr() + task_rq_lock(); + takedown_cpu() + stop_machine_cpuslocked(take_cpu_down..) + + + ack_state() + MULTI_STOP_RUN + take_cpu_down() + __cpu_disable(); + stop_machine_park(); + stopper->enabled = false; + /> + /> + stop_one_cpu_nowait(.fn = migration_cpu_stop); + if (stopper->enabled) // false!!! + +That is, by doing stop_one_cpu_nowait() after dropping rq-lock, the +stopper thread gets a chance to preempt and allows the cpu-down for +the target CPU to complete. + +OTOH, since stop_one_cpu_nowait() / cpu_stop_queue_work() needs to +issue a wakeup, it must not be ran under the scheduler locks. + +Solve this apparent contradiction by keeping preemption disabled over +the unlock + queue_stopper combination: + + preempt_disable(); + task_rq_unlock(...); + if (!stop_pending) + stop_one_cpu_nowait(...) + preempt_enable(); + +This respects the lock ordering contraints while still avoiding the +above race. That is, if we find the CPU is online under rq-lock, the +targeted stop_one_cpu_nowait() must succeed. + +Apply this pattern to all similar stop_one_cpu_nowait() invocations. + +Fixes: 6d337eab041d ("sched: Fix migrate_disable() vs set_cpus_allowed_ptr()") +Reported-by: "Kuyo Chang (張建文)" +Signed-off-by: Peter Zijlstra (Intel) +Tested-by: "Kuyo Chang (張建文)" +Link: https://lkml.kernel.org/r/20231010200442.GA16515@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + kernel/sched/core.c | 10 ++++++++-- + kernel/sched/deadline.c | 2 ++ + kernel/sched/fair.c | 4 +++- + kernel/sched/rt.c | 4 ++++ + 4 files changed, 17 insertions(+), 3 deletions(-) + +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 802551e0009bf..9e9a45a3394fe 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -2664,9 +2664,11 @@ static int migration_cpu_stop(void *data) + * it. + */ + WARN_ON_ONCE(!pending->stop_pending); ++ preempt_disable(); + task_rq_unlock(rq, p, &rf); + stop_one_cpu_nowait(task_cpu(p), migration_cpu_stop, + &pending->arg, &pending->stop_work); ++ preempt_enable(); + return 0; + } + out: +@@ -2986,12 +2988,13 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag + complete = true; + } + ++ preempt_disable(); + task_rq_unlock(rq, p, rf); +- + if (push_task) { + stop_one_cpu_nowait(rq->cpu, push_cpu_stop, + p, &rq->push_work); + } ++ preempt_enable(); + + if (complete) + complete_all(&pending->done); +@@ -3057,12 +3060,13 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag + if (flags & SCA_MIGRATE_ENABLE) + p->migration_flags &= ~MDF_PUSH; + ++ preempt_disable(); + task_rq_unlock(rq, p, rf); +- + if (!stop_pending) { + stop_one_cpu_nowait(cpu_of(rq), migration_cpu_stop, + &pending->arg, &pending->stop_work); + } ++ preempt_enable(); + + if (flags & SCA_MIGRATE_ENABLE) + return 0; +@@ -9505,9 +9509,11 @@ static void balance_push(struct rq *rq) + * Temporarily drop rq->lock such that we can wake-up the stop task. + * Both preemption and IRQs are still disabled. + */ ++ preempt_disable(); + raw_spin_rq_unlock(rq); + stop_one_cpu_nowait(rq->cpu, __balance_push_cpu_stop, push_task, + this_cpu_ptr(&push_work)); ++ preempt_enable(); + /* + * At this point need_resched() is true and we'll take the loop in + * schedule(). The next pick is obviously going to be the stop task +diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c +index 58b542bf28934..d78f2e8769fb4 100644 +--- a/kernel/sched/deadline.c ++++ b/kernel/sched/deadline.c +@@ -2449,9 +2449,11 @@ static void pull_dl_task(struct rq *this_rq) + double_unlock_balance(this_rq, src_rq); + + if (push_task) { ++ preempt_disable(); + raw_spin_rq_unlock(this_rq); + stop_one_cpu_nowait(src_rq->cpu, push_cpu_stop, + push_task, &src_rq->push_work); ++ preempt_enable(); + raw_spin_rq_lock(this_rq); + } + } +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 4dee83c82ac33..1795f6fe991f3 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -11234,13 +11234,15 @@ static int load_balance(int this_cpu, struct rq *this_rq, + busiest->push_cpu = this_cpu; + active_balance = 1; + } +- raw_spin_rq_unlock_irqrestore(busiest, flags); + ++ preempt_disable(); ++ raw_spin_rq_unlock_irqrestore(busiest, flags); + if (active_balance) { + stop_one_cpu_nowait(cpu_of(busiest), + active_load_balance_cpu_stop, busiest, + &busiest->active_balance_work); + } ++ preempt_enable(); + } + } else { + sd->nr_balance_failed = 0; +diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c +index 0597ba0f85ff3..904dd85345973 100644 +--- a/kernel/sched/rt.c ++++ b/kernel/sched/rt.c +@@ -2109,9 +2109,11 @@ static int push_rt_task(struct rq *rq, bool pull) + */ + push_task = get_push_task(rq); + if (push_task) { ++ preempt_disable(); + raw_spin_rq_unlock(rq); + stop_one_cpu_nowait(rq->cpu, push_cpu_stop, + push_task, &rq->push_work); ++ preempt_enable(); + raw_spin_rq_lock(rq); + } + +@@ -2448,9 +2450,11 @@ static void pull_rt_task(struct rq *this_rq) + double_unlock_balance(this_rq, src_rq); + + if (push_task) { ++ preempt_disable(); + raw_spin_rq_unlock(this_rq); + stop_one_cpu_nowait(src_rq->cpu, push_cpu_stop, + push_task, &src_rq->push_work); ++ preempt_enable(); + raw_spin_rq_lock(this_rq); + } + } +-- +2.42.0 + diff --git a/queue-6.6/sched-topology-fix-sched_numa_find_nth_cpu-in-cpu-le.patch b/queue-6.6/sched-topology-fix-sched_numa_find_nth_cpu-in-cpu-le.patch new file mode 100644 index 00000000000..de2faa32071 --- /dev/null +++ b/queue-6.6/sched-topology-fix-sched_numa_find_nth_cpu-in-cpu-le.patch @@ -0,0 +1,56 @@ +From 57ea1086724953b69f8b3951e5c5832e892ff6aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 19 Aug 2023 07:12:35 -0700 +Subject: sched/topology: Fix sched_numa_find_nth_cpu() in CPU-less case + +From: Yury Norov + +[ Upstream commit 617f2c38cb5ce60226042081c09e2ee3a90d03f8 ] + +When the node provided by user is CPU-less, corresponding record in +sched_domains_numa_masks is not set. Trying to dereference it in the +following code leads to kernel crash. + +To avoid it, start searching from the nearest node with CPUs. + +Fixes: cd7f55359c90 ("sched: add sched_numa_find_nth_cpu()") +Reported-by: Yicong Yang +Reported-by: Guenter Roeck +Signed-off-by: Yury Norov +Signed-off-by: Ingo Molnar +Reviewed-by: Yicong Yang +Cc: Mel Gorman +Link: https://lore.kernel.org/r/20230819141239.287290-4-yury.norov@gmail.com + +Closes: https://lore.kernel.org/lkml/CAAH8bW8C5humYnfpW3y5ypwx0E-09A3QxFE1JFzR66v+mO4XfA@mail.gmail.com/T/ +Closes: https://lore.kernel.org/lkml/ZMHSNQfv39HN068m@yury-ThinkPad/T/#mf6431cb0b7f6f05193c41adeee444bc95bf2b1c4 +Signed-off-by: Sasha Levin +--- + kernel/sched/topology.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c +index 05a5bc678c089..423d08947962c 100644 +--- a/kernel/sched/topology.c ++++ b/kernel/sched/topology.c +@@ -2122,12 +2122,16 @@ static int hop_cmp(const void *a, const void *b) + */ + int sched_numa_find_nth_cpu(const struct cpumask *cpus, int cpu, int node) + { +- struct __cmp_key k = { .cpus = cpus, .node = node, .cpu = cpu }; ++ struct __cmp_key k = { .cpus = cpus, .cpu = cpu }; + struct cpumask ***hop_masks; + int hop, ret = nr_cpu_ids; + + rcu_read_lock(); + ++ /* CPU-less node entries are uninitialized in sched_domains_numa_masks */ ++ node = numa_nearest_node(node, N_CPU); ++ k.node = node; ++ + k.masks = rcu_dereference(sched_domains_numa_masks); + if (!k.masks) + goto unlock; +-- +2.42.0 + diff --git a/queue-6.6/sched-topology-fix-sched_numa_find_nth_cpu-in-non-nu.patch b/queue-6.6/sched-topology-fix-sched_numa_find_nth_cpu-in-non-nu.patch new file mode 100644 index 00000000000..0af2b44108b --- /dev/null +++ b/queue-6.6/sched-topology-fix-sched_numa_find_nth_cpu-in-non-nu.patch @@ -0,0 +1,41 @@ +From 6911513ba2af0a2a511358a0411e711a0903619a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 19 Aug 2023 07:12:36 -0700 +Subject: sched/topology: Fix sched_numa_find_nth_cpu() in non-NUMA case + +From: Yury Norov + +[ Upstream commit 8ab63d418d4339d996f80d02a00dbce0aa3ff972 ] + +When CONFIG_NUMA is enabled, sched_numa_find_nth_cpu() searches for a +CPU in sched_domains_numa_masks. The masks includes only online CPUs, +so effectively offline CPUs are skipped. + +When CONFIG_NUMA is disabled, the fallback function should be consistent. + +Fixes: cd7f55359c90 ("sched: add sched_numa_find_nth_cpu()") +Signed-off-by: Yury Norov +Signed-off-by: Ingo Molnar +Cc: Mel Gorman +Link: https://lore.kernel.org/r/20230819141239.287290-5-yury.norov@gmail.com +Signed-off-by: Sasha Levin +--- + include/linux/topology.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/topology.h b/include/linux/topology.h +index fea32377f7c77..52f5850730b3e 100644 +--- a/include/linux/topology.h ++++ b/include/linux/topology.h +@@ -251,7 +251,7 @@ extern const struct cpumask *sched_numa_hop_mask(unsigned int node, unsigned int + #else + static __always_inline int sched_numa_find_nth_cpu(const struct cpumask *cpus, int cpu, int node) + { +- return cpumask_nth(cpu, cpus); ++ return cpumask_nth_and(cpu, cpus, cpu_online_mask); + } + + static inline const struct cpumask * +-- +2.42.0 + diff --git a/queue-6.6/sched-uclamp-ignore-util-0-optimization-in-feec-when.patch b/queue-6.6/sched-uclamp-ignore-util-0-optimization-in-feec-when.patch new file mode 100644 index 00000000000..cf7b5c23a09 --- /dev/null +++ b/queue-6.6/sched-uclamp-ignore-util-0-optimization-in-feec-when.patch @@ -0,0 +1,73 @@ +From fa2056ca080969699ced9fc05ee97fa5cf1b3871 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 17 Sep 2023 00:29:54 +0100 +Subject: sched/uclamp: Ignore (util == 0) optimization in feec() when + p_util_max = 0 + +From: Qais Yousef + +[ Upstream commit 23c9519def98ee0fa97ea5871535e9b136f522fc ] + +find_energy_efficient_cpu() bails out early if effective util of the +task is 0 as the delta at this point will be zero and there's nothing +for EAS to do. When uclamp is being used, this could lead to wrong +decisions when uclamp_max is set to 0. In this case the task is capped +to performance point 0, but it is actually running and consuming energy +and we can benefit from EAS energy calculations. + +Rework the condition so that it bails out when both util and uclamp_min +are 0. + +We can do that without needing to use uclamp_task_util(); remove it. + +Fixes: d81304bc6193 ("sched/uclamp: Cater for uclamp in find_energy_efficient_cpu()'s early exit condition") +Signed-off-by: Qais Yousef (Google) +Signed-off-by: Ingo Molnar +Reviewed-by: Vincent Guittot +Reviewed-by: Dietmar Eggemann +Acked-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/r/20230916232955.2099394-3-qyousef@layalina.io +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 18 +----------------- + 1 file changed, 1 insertion(+), 17 deletions(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index a60b5d0edd039..4dee83c82ac33 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -4626,22 +4626,6 @@ static inline unsigned long task_util_est(struct task_struct *p) + return max(task_util(p), _task_util_est(p)); + } + +-#ifdef CONFIG_UCLAMP_TASK +-static inline unsigned long uclamp_task_util(struct task_struct *p, +- unsigned long uclamp_min, +- unsigned long uclamp_max) +-{ +- return clamp(task_util_est(p), uclamp_min, uclamp_max); +-} +-#else +-static inline unsigned long uclamp_task_util(struct task_struct *p, +- unsigned long uclamp_min, +- unsigned long uclamp_max) +-{ +- return task_util_est(p); +-} +-#endif +- + static inline void util_est_enqueue(struct cfs_rq *cfs_rq, + struct task_struct *p) + { +@@ -7756,7 +7740,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) + target = prev_cpu; + + sync_entity_load_avg(&p->se); +- if (!uclamp_task_util(p, p_util_min, p_util_max)) ++ if (!task_util_est(p) && p_util_min == 0) + goto unlock; + + eenv_task_busy_time(&eenv, p, prev_cpu); +-- +2.42.0 + diff --git a/queue-6.6/sched-uclamp-set-max_spare_cap_cpu-even-if-max_spare.patch b/queue-6.6/sched-uclamp-set-max_spare_cap_cpu-even-if-max_spare.patch new file mode 100644 index 00000000000..422b4089d46 --- /dev/null +++ b/queue-6.6/sched-uclamp-set-max_spare_cap_cpu-even-if-max_spare.patch @@ -0,0 +1,103 @@ +From 3b2010145392e908aee9203511a3694e2f8686ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 17 Sep 2023 00:29:53 +0100 +Subject: sched/uclamp: Set max_spare_cap_cpu even if max_spare_cap is 0 + +From: Qais Yousef + +[ Upstream commit 6b00a40147653c8ea748e8f4396510f252763364 ] + +When uclamp_max is being used, the util of the task could be higher than +the spare capacity of the CPU, but due to uclamp_max value we force-fit +it there. + +The way the condition for checking for max_spare_cap in +find_energy_efficient_cpu() was constructed; it ignored any CPU that has +its spare_cap less than or _equal_ to max_spare_cap. Since we initialize +max_spare_cap to 0; this lead to never setting max_spare_cap_cpu and +hence ending up never performing compute_energy() for this cluster and +missing an opportunity for a better energy efficient placement to honour +uclamp_max setting. + + max_spare_cap = 0; + cpu_cap = capacity_of(cpu) - cpu_util(p); // 0 if cpu_util(p) is high + + ... + + util_fits_cpu(...); // will return true if uclamp_max forces it to fit + + ... + + // this logic will fail to update max_spare_cap_cpu if cpu_cap is 0 + if (cpu_cap > max_spare_cap) { + max_spare_cap = cpu_cap; + max_spare_cap_cpu = cpu; + } + +prev_spare_cap suffers from a similar problem. + +Fix the logic by converting the variables into long and treating -1 +value as 'not populated' instead of 0 which is a viable and correct +spare capacity value. We need to be careful signed comparison is used +when comparing with cpu_cap in one of the conditions. + +Fixes: 1d42509e475c ("sched/fair: Make EAS wakeup placement consider uclamp restrictions") +Signed-off-by: Qais Yousef (Google) +Signed-off-by: Ingo Molnar +Reviewed-by: Vincent Guittot +Reviewed-by: Dietmar Eggemann +Acked-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/r/20230916232955.2099394-2-qyousef@layalina.io +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 6af1d48d467ed..a60b5d0edd039 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -7764,11 +7764,10 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) + for (; pd; pd = pd->next) { + unsigned long util_min = p_util_min, util_max = p_util_max; + unsigned long cpu_cap, cpu_thermal_cap, util; +- unsigned long cur_delta, max_spare_cap = 0; ++ long prev_spare_cap = -1, max_spare_cap = -1; + unsigned long rq_util_min, rq_util_max; +- unsigned long prev_spare_cap = 0; ++ unsigned long cur_delta, base_energy; + int max_spare_cap_cpu = -1; +- unsigned long base_energy; + int fits, max_fits = -1; + + cpumask_and(cpus, perf_domain_span(pd), cpu_online_mask); +@@ -7831,7 +7830,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) + prev_spare_cap = cpu_cap; + prev_fits = fits; + } else if ((fits > max_fits) || +- ((fits == max_fits) && (cpu_cap > max_spare_cap))) { ++ ((fits == max_fits) && ((long)cpu_cap > max_spare_cap))) { + /* + * Find the CPU with the maximum spare capacity + * among the remaining CPUs in the performance +@@ -7843,7 +7842,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) + } + } + +- if (max_spare_cap_cpu < 0 && prev_spare_cap == 0) ++ if (max_spare_cap_cpu < 0 && prev_spare_cap < 0) + continue; + + eenv_pd_busy_time(&eenv, cpus, p); +@@ -7851,7 +7850,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) + base_energy = compute_energy(&eenv, pd, cpus, p, -1); + + /* Evaluate the energy impact of using prev_cpu. */ +- if (prev_spare_cap > 0) { ++ if (prev_spare_cap > -1) { + prev_delta = compute_energy(&eenv, pd, cpus, p, + prev_cpu); + /* CPU utilization has changed */ +-- +2.42.0 + diff --git a/queue-6.6/scripts-gdb-fix-usage-of-mod_text-not-defined-when-c.patch b/queue-6.6/scripts-gdb-fix-usage-of-mod_text-not-defined-when-c.patch new file mode 100644 index 00000000000..e989adf5bde --- /dev/null +++ b/queue-6.6/scripts-gdb-fix-usage-of-mod_text-not-defined-when-c.patch @@ -0,0 +1,64 @@ +From 7f2b45ff2de2f3c1ce32dce10a94789a2d51d6a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Oct 2023 13:49:04 +0000 +Subject: scripts/gdb: fix usage of MOD_TEXT not defined when CONFIG_MODULES=n +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Clément Léger + +[ Upstream commit 16501630bdeb107141a0139ddc33f92ab5582c6f ] + +MOD_TEXT is only defined if CONFIG_MODULES=y which lead to loading failure +of the gdb scripts when kernel is built without CONFIG_MODULES=y: + +Reading symbols from vmlinux... +Traceback (most recent call last): + File "/foo/vmlinux-gdb.py", line 25, in + import linux.constants + File "/foo/scripts/gdb/linux/constants.py", line 14, in + LX_MOD_TEXT = gdb.parse_and_eval("MOD_TEXT") + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +gdb.error: No symbol "MOD_TEXT" in current context. + +Add a conditional check on CONFIG_MODULES to fix this error. + +Link: https://lkml.kernel.org/r/20231031134848.119391-1-da.gomez@samsung.com +Fixes: b4aff7513df3 ("scripts/gdb: use mem instead of core_layout to get the module address") +Signed-off-by: Clément Léger +Tested-by: Daniel Gomez +Signed-off-by: Daniel Gomez +Cc: Jan Kiszka +Cc: Kieran Bingham +Cc: Luis Chamberlain +Cc: Pankaj Raghav +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + scripts/gdb/linux/constants.py.in | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in +index e3517d4ab8ec9..04c87b570aabe 100644 +--- a/scripts/gdb/linux/constants.py.in ++++ b/scripts/gdb/linux/constants.py.in +@@ -66,10 +66,11 @@ LX_GDBPARSED(IRQD_LEVEL) + LX_GDBPARSED(IRQ_HIDDEN) + + /* linux/module.h */ +-LX_GDBPARSED(MOD_TEXT) +-LX_GDBPARSED(MOD_DATA) +-LX_GDBPARSED(MOD_RODATA) +-LX_GDBPARSED(MOD_RO_AFTER_INIT) ++if IS_BUILTIN(CONFIG_MODULES): ++ LX_GDBPARSED(MOD_TEXT) ++ LX_GDBPARSED(MOD_DATA) ++ LX_GDBPARSED(MOD_RODATA) ++ LX_GDBPARSED(MOD_RO_AFTER_INIT) + + /* linux/mount.h */ + LX_VALUE(MNT_NOSUID) +-- +2.42.0 + diff --git a/queue-6.6/scsi-ibmvfc-fix-erroneous-use-of-rtas_busy_delay-wit.patch b/queue-6.6/scsi-ibmvfc-fix-erroneous-use-of-rtas_busy_delay-wit.patch new file mode 100644 index 00000000000..c7cd560204a --- /dev/null +++ b/queue-6.6/scsi-ibmvfc-fix-erroneous-use-of-rtas_busy_delay-wit.patch @@ -0,0 +1,51 @@ +From 2d9f15a7cdd11beeae5cc54e7e222daeb4a2ec7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 17:54:28 -0500 +Subject: scsi: ibmvfc: Fix erroneous use of rtas_busy_delay with hcall return + code + +From: Tyrel Datwyler + +[ Upstream commit 670106eb4c8b23475f8c2b3416005a312afa622f ] + +Commit 0217a272fe13 ("scsi: ibmvfc: Store return code of H_FREE_SUB_CRQ +during cleanup") wrongly changed the busy loop check to use +rtas_busy_delay() instead of H_BUSY and H_IS_LONG_BUSY(). The busy return +codes for RTAS and hypercalls are not the same. + +Fix this issue by restoring the use of H_BUSY and H_IS_LONG_BUSY(). + +Fixes: 0217a272fe13 ("scsi: ibmvfc: Store return code of H_FREE_SUB_CRQ during cleanup") +Signed-off-by: Tyrel Datwyler +Link: https://lore.kernel.org/r/20230921225435.3537728-5-tyreld@linux.ibm.com +Reviewed-by: Brian King +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/ibmvscsi/ibmvfc.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c +index ce9eb00e2ca04..470e8e6c41b62 100644 +--- a/drivers/scsi/ibmvscsi/ibmvfc.c ++++ b/drivers/scsi/ibmvscsi/ibmvfc.c +@@ -22,7 +22,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -5804,7 +5803,7 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost, + irq_failed: + do { + rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq->cookie); +- } while (rtas_busy_delay(rc)); ++ } while (rc == H_BUSY || H_IS_LONG_BUSY(rc)); + reg_failed: + LEAVE; + return rc; +-- +2.42.0 + diff --git a/queue-6.6/scsi-ufs-core-leave-space-for-0-in-utf8-desc-string.patch b/queue-6.6/scsi-ufs-core-leave-space-for-0-in-utf8-desc-string.patch new file mode 100644 index 00000000000..5bfc5231880 --- /dev/null +++ b/queue-6.6/scsi-ufs-core-leave-space-for-0-in-utf8-desc-string.patch @@ -0,0 +1,48 @@ +From 632209bf7bc42626fa912a297e81b5555efb64ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 11:20:26 -0700 +Subject: scsi: ufs: core: Leave space for '\0' in utf8 desc string + +From: Daniel Mentz + +[ Upstream commit a75a16c62a2540f11eeae4f2b50e95deefb652ea ] + +utf16s_to_utf8s does not NULL terminate the output string. For us to be +able to add a NULL character when utf16s_to_utf8s returns, we need to make +sure that there is space for such NULL character at the end of the output +buffer. We can achieve this by passing an output buffer size to +utf16s_to_utf8s that is one character less than what we allocated. + +Other call sites of utf16s_to_utf8s appear to be using the same technique +where they artificially reduce the buffer size by one to leave space for a +NULL character or line feed character. + +Fixes: 4b828fe156a6 ("scsi: ufs: revamp string descriptor reading") +Reviewed-by: Mars Cheng +Reviewed-by: Bart Van Assche +Reviewed-by: Yen-lin Lai +Signed-off-by: Daniel Mentz +Link: https://lore.kernel.org/r/20231017182026.2141163-1-danielmentz@google.com +Reviewed-by: Avri Altman +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/core/ufshcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index 8382e8cfa414a..5767642982c13 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -3632,7 +3632,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, + */ + ret = utf16s_to_utf8s(uc_str->uc, + uc_str->len - QUERY_DESC_HDR_SIZE, +- UTF16_BIG_ENDIAN, str, ascii_len); ++ UTF16_BIG_ENDIAN, str, ascii_len - 1); + + /* replace non-printable or non-ASCII characters with spaces */ + for (i = 0; i < ret; i++) +-- +2.42.0 + diff --git a/queue-6.6/selftests-bpf-correct-map_fd-to-data_fd-in-tailcalls.patch b/queue-6.6/selftests-bpf-correct-map_fd-to-data_fd-in-tailcalls.patch new file mode 100644 index 00000000000..0d742e434cf --- /dev/null +++ b/queue-6.6/selftests-bpf-correct-map_fd-to-data_fd-in-tailcalls.patch @@ -0,0 +1,121 @@ +From d9efc409a1c1c33a7195cb6bf971b76abf6dabd2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 23:42:56 +0800 +Subject: selftests/bpf: Correct map_fd to data_fd in tailcalls + +From: Leon Hwang + +[ Upstream commit 96daa9874211d5497aa70fa409b67afc29f0cb86 ] + +Get and check data_fd. It should not check map_fd again. + +Meanwhile, correct some 'return' to 'goto out'. + +Thank the suggestion from Maciej in "bpf, x64: Fix tailcall infinite +loop"[0] discussions. + +[0] https://lore.kernel.org/bpf/e496aef8-1f80-0f8e-dcdd-25a8c300319a@gmail.com/T/#m7d3b601066ba66400d436b7e7579b2df4a101033 + +Fixes: 79d49ba048ec ("bpf, testing: Add various tail call test cases") +Fixes: 3b0379111197 ("selftests/bpf: Add tailcall_bpf2bpf tests") +Fixes: 5e0b0a4c52d3 ("selftests/bpf: Test tail call counting with bpf2bpf and data on stack") +Signed-off-by: Leon Hwang +Reviewed-by: Maciej Fijalkowski +Link: https://lore.kernel.org/r/20230906154256.95461-1-hffilwlqm@gmail.com +Signed-off-by: Martin KaFai Lau +Signed-off-by: Sasha Levin +--- + .../selftests/bpf/prog_tests/tailcalls.c | 32 +++++++++---------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/tailcalls.c b/tools/testing/selftests/bpf/prog_tests/tailcalls.c +index 58fe2c586ed76..09c189761926c 100644 +--- a/tools/testing/selftests/bpf/prog_tests/tailcalls.c ++++ b/tools/testing/selftests/bpf/prog_tests/tailcalls.c +@@ -271,11 +271,11 @@ static void test_tailcall_count(const char *which) + + data_map = bpf_object__find_map_by_name(obj, "tailcall.bss"); + if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map))) +- return; ++ goto out; + + data_fd = bpf_map__fd(data_map); +- if (CHECK_FAIL(map_fd < 0)) +- return; ++ if (CHECK_FAIL(data_fd < 0)) ++ goto out; + + i = 0; + err = bpf_map_lookup_elem(data_fd, &i, &val); +@@ -352,11 +352,11 @@ static void test_tailcall_4(void) + + data_map = bpf_object__find_map_by_name(obj, "tailcall.bss"); + if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map))) +- return; ++ goto out; + + data_fd = bpf_map__fd(data_map); +- if (CHECK_FAIL(map_fd < 0)) +- return; ++ if (CHECK_FAIL(data_fd < 0)) ++ goto out; + + for (i = 0; i < bpf_map__max_entries(prog_array); i++) { + snprintf(prog_name, sizeof(prog_name), "classifier_%d", i); +@@ -442,11 +442,11 @@ static void test_tailcall_5(void) + + data_map = bpf_object__find_map_by_name(obj, "tailcall.bss"); + if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map))) +- return; ++ goto out; + + data_fd = bpf_map__fd(data_map); +- if (CHECK_FAIL(map_fd < 0)) +- return; ++ if (CHECK_FAIL(data_fd < 0)) ++ goto out; + + for (i = 0; i < bpf_map__max_entries(prog_array); i++) { + snprintf(prog_name, sizeof(prog_name), "classifier_%d", i); +@@ -631,11 +631,11 @@ static void test_tailcall_bpf2bpf_2(void) + + data_map = bpf_object__find_map_by_name(obj, "tailcall.bss"); + if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map))) +- return; ++ goto out; + + data_fd = bpf_map__fd(data_map); +- if (CHECK_FAIL(map_fd < 0)) +- return; ++ if (CHECK_FAIL(data_fd < 0)) ++ goto out; + + i = 0; + err = bpf_map_lookup_elem(data_fd, &i, &val); +@@ -805,11 +805,11 @@ static void test_tailcall_bpf2bpf_4(bool noise) + + data_map = bpf_object__find_map_by_name(obj, "tailcall.bss"); + if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map))) +- return; ++ goto out; + + data_fd = bpf_map__fd(data_map); +- if (CHECK_FAIL(map_fd < 0)) +- return; ++ if (CHECK_FAIL(data_fd < 0)) ++ goto out; + + i = 0; + val.noise = noise; +@@ -872,7 +872,7 @@ static void test_tailcall_bpf2bpf_6(void) + ASSERT_EQ(topts.retval, 0, "tailcall retval"); + + data_fd = bpf_map__fd(obj->maps.bss); +- if (!ASSERT_GE(map_fd, 0, "bss map fd")) ++ if (!ASSERT_GE(data_fd, 0, "bss map fd")) + goto out; + + i = 0; +-- +2.42.0 + diff --git a/queue-6.6/selftests-bpf-define-sys_nanosleep_kprobe_name-for-r.patch b/queue-6.6/selftests-bpf-define-sys_nanosleep_kprobe_name-for-r.patch new file mode 100644 index 00000000000..a95a37f868c --- /dev/null +++ b/queue-6.6/selftests-bpf-define-sys_nanosleep_kprobe_name-for-r.patch @@ -0,0 +1,41 @@ +From d83f4c055a580bb1714ab146e6bbb2ca9ca55fa5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 13:09:05 +0200 +Subject: selftests/bpf: Define SYS_NANOSLEEP_KPROBE_NAME for riscv +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Björn Töpel + +[ Upstream commit b55b775f03166b8da60af80ef33da8bf83ca96c1 ] + +Add missing sys_nanosleep name for RISC-V, which is used by some tests +(e.g. attach_probe). + +Fixes: 08d0ce30e0e4 ("riscv: Implement syscall wrappers") +Signed-off-by: Björn Töpel +Signed-off-by: Andrii Nakryiko +Reviewed-by: Sami Tolvanen +Link: https://lore.kernel.org/bpf/20231004110905.49024-4-bjorn@kernel.org +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/test_progs.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h +index 77bd492c60248..2f9f6f250f171 100644 +--- a/tools/testing/selftests/bpf/test_progs.h ++++ b/tools/testing/selftests/bpf/test_progs.h +@@ -417,6 +417,8 @@ int get_bpf_max_tramp_links(void); + #define SYS_NANOSLEEP_KPROBE_NAME "__s390x_sys_nanosleep" + #elif defined(__aarch64__) + #define SYS_NANOSLEEP_KPROBE_NAME "__arm64_sys_nanosleep" ++#elif defined(__riscv) ++#define SYS_NANOSLEEP_KPROBE_NAME "__riscv_sys_nanosleep" + #else + #define SYS_NANOSLEEP_KPROBE_NAME "sys_nanosleep" + #endif +-- +2.42.0 + diff --git a/queue-6.6/selftests-bpf-define-sys_prefix-for-riscv.patch b/queue-6.6/selftests-bpf-define-sys_prefix-for-riscv.patch new file mode 100644 index 00000000000..810b8f7b0d8 --- /dev/null +++ b/queue-6.6/selftests-bpf-define-sys_prefix-for-riscv.patch @@ -0,0 +1,44 @@ +From 26ff2beda8b9aeb556a5afdf70a9c06bcf9974bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 13:09:04 +0200 +Subject: selftests/bpf: Define SYS_PREFIX for riscv +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Björn Töpel + +[ Upstream commit 0f2692ee4324679df6c80ccbb75660564009d187 ] + +SYS_PREFIX was missing for a RISC-V, which made a couple of kprobe +tests fail. + +Add missing SYS_PREFIX for RISC-V. + +Fixes: 08d0ce30e0e4 ("riscv: Implement syscall wrappers") +Signed-off-by: Björn Töpel +Signed-off-by: Andrii Nakryiko +Reviewed-by: Sami Tolvanen +Link: https://lore.kernel.org/bpf/20231004110905.49024-3-bjorn@kernel.org +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/progs/bpf_misc.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tools/testing/selftests/bpf/progs/bpf_misc.h b/tools/testing/selftests/bpf/progs/bpf_misc.h +index 38a57a2e70dbe..799fff4995d87 100644 +--- a/tools/testing/selftests/bpf/progs/bpf_misc.h ++++ b/tools/testing/selftests/bpf/progs/bpf_misc.h +@@ -99,6 +99,9 @@ + #elif defined(__TARGET_ARCH_arm64) + #define SYSCALL_WRAPPER 1 + #define SYS_PREFIX "__arm64_" ++#elif defined(__TARGET_ARCH_riscv) ++#define SYSCALL_WRAPPER 1 ++#define SYS_PREFIX "__riscv_" + #else + #define SYSCALL_WRAPPER 0 + #define SYS_PREFIX "__se_" +-- +2.42.0 + diff --git a/queue-6.6/selftests-bpf-make-linked_list-failure-test-more-rob.patch b/queue-6.6/selftests-bpf-make-linked_list-failure-test-more-rob.patch new file mode 100644 index 00000000000..7902f89c4b0 --- /dev/null +++ b/queue-6.6/selftests-bpf-make-linked_list-failure-test-more-rob.patch @@ -0,0 +1,69 @@ +From 219251c0f9e7a19917305815ee0fa59f07fbc466 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 14:48:39 +0000 +Subject: selftests/bpf: Make linked_list failure test more robust + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit da1055b673f3baac2249571c9882ce767a0aa746 ] + +The linked list failure test 'pop_front_off' and 'pop_back_off' +currently rely on matching exact instruction and register values. The +purpose of the test is to ensure the offset is correctly incremented for +the returned pointers from list pop helpers, which can then be used with +container_of to obtain the real object. Hence, somehow obtaining the +information that the offset is 48 will work for us. Make the test more +robust by relying on verifier error string of bpf_spin_lock and remove +dependence on fragile instruction index or register number, which can be +affected by different clang versions used to build the selftests. + +Fixes: 300f19dcdb99 ("selftests/bpf: Add BPF linked list API tests") +Reported-by: Andrii Nakryiko +Signed-off-by: Kumar Kartikeya Dwivedi +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20231020144839.2734006-1-memxor@gmail.com +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/linked_list.c | 10 ++-------- + tools/testing/selftests/bpf/progs/linked_list_fail.c | 4 +++- + 2 files changed, 5 insertions(+), 9 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/linked_list.c b/tools/testing/selftests/bpf/prog_tests/linked_list.c +index 18cf7b17463d9..98dde091d2825 100644 +--- a/tools/testing/selftests/bpf/prog_tests/linked_list.c ++++ b/tools/testing/selftests/bpf/prog_tests/linked_list.c +@@ -94,14 +94,8 @@ static struct { + { "incorrect_head_var_off2", "variable ptr_ access var_off=(0x0; 0xffffffff) disallowed" }, + { "incorrect_head_off1", "bpf_list_head not found at offset=25" }, + { "incorrect_head_off2", "bpf_list_head not found at offset=1" }, +- { "pop_front_off", +- "15: (bf) r1 = r6 ; R1_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=48,imm=0) " +- "R6_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=48,imm=0) refs=2,4\n" +- "16: (85) call bpf_this_cpu_ptr#154\nR1 type=ptr_or_null_ expected=percpu_ptr_" }, +- { "pop_back_off", +- "15: (bf) r1 = r6 ; R1_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=48,imm=0) " +- "R6_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=48,imm=0) refs=2,4\n" +- "16: (85) call bpf_this_cpu_ptr#154\nR1 type=ptr_or_null_ expected=percpu_ptr_" }, ++ { "pop_front_off", "off 48 doesn't point to 'struct bpf_spin_lock' that is at 40" }, ++ { "pop_back_off", "off 48 doesn't point to 'struct bpf_spin_lock' that is at 40" }, + }; + + static void test_linked_list_fail_prog(const char *prog_name, const char *err_msg) +diff --git a/tools/testing/selftests/bpf/progs/linked_list_fail.c b/tools/testing/selftests/bpf/progs/linked_list_fail.c +index f4c63daba2297..6438982b928bd 100644 +--- a/tools/testing/selftests/bpf/progs/linked_list_fail.c ++++ b/tools/testing/selftests/bpf/progs/linked_list_fail.c +@@ -591,7 +591,9 @@ int pop_ptr_off(void *(*op)(void *head)) + n = op(&p->head); + bpf_spin_unlock(&p->lock); + +- bpf_this_cpu_ptr(n); ++ if (!n) ++ return 0; ++ bpf_spin_lock((void *)n); + return 0; + } + +-- +2.42.0 + diff --git a/queue-6.6/selftests-bpf-skip-module_fentry_shadow-test-when-bp.patch b/queue-6.6/selftests-bpf-skip-module_fentry_shadow-test-when-bp.patch new file mode 100644 index 00000000000..a1c76da28ed --- /dev/null +++ b/queue-6.6/selftests-bpf-skip-module_fentry_shadow-test-when-bp.patch @@ -0,0 +1,40 @@ +From 91f62eebcfbe72ca209011ad4c155d48fdfd0505 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 14:49:28 +0200 +Subject: selftests/bpf: Skip module_fentry_shadow test when bpf_testmod is not + available + +From: Artem Savkov + +[ Upstream commit 971f7c32147f2d0953a815a109b22b8ed45949d4 ] + +This test relies on bpf_testmod, so skip it if the module is not available. + +Fixes: aa3d65de4b900 ("bpf/selftests: Test fentry attachment to shadowed functions") +Signed-off-by: Artem Savkov +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20230914124928.340701-1-asavkov@redhat.com +Signed-off-by: Sasha Levin +--- + .../testing/selftests/bpf/prog_tests/module_fentry_shadow.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tools/testing/selftests/bpf/prog_tests/module_fentry_shadow.c b/tools/testing/selftests/bpf/prog_tests/module_fentry_shadow.c +index c7636e18b1ebd..aa9f67eb1c95b 100644 +--- a/tools/testing/selftests/bpf/prog_tests/module_fentry_shadow.c ++++ b/tools/testing/selftests/bpf/prog_tests/module_fentry_shadow.c +@@ -61,6 +61,11 @@ void test_module_fentry_shadow(void) + int link_fd[2] = {}; + __s32 btf_id[2] = {}; + ++ if (!env.has_testmod) { ++ test__skip(); ++ return; ++ } ++ + LIBBPF_OPTS(bpf_prog_load_opts, load_opts, + .expected_attach_type = BPF_TRACE_FENTRY, + ); +-- +2.42.0 + diff --git a/queue-6.6/selftests-pidfd-fix-ksft-print-formats.patch b/queue-6.6/selftests-pidfd-fix-ksft-print-formats.patch new file mode 100644 index 00000000000..e16fd2424cf --- /dev/null +++ b/queue-6.6/selftests-pidfd-fix-ksft-print-formats.patch @@ -0,0 +1,102 @@ +From bf73ff74b74b75092fed0dad99c4762f290e1cda Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Oct 2023 13:36:28 +0200 +Subject: selftests/pidfd: Fix ksft print formats + +From: Maciej Wieczor-Retman + +[ Upstream commit 4d7f4e8158b62f63031510cdc24acc520956c091 ] + +Compiling pidfd selftest after adding a __printf() attribute to +ksft_print_msg() and ksft_test_result_pass() exposes -Wformat warnings +in error_report(), test_pidfd_poll_exec_thread(), +child_poll_exec_test(), test_pidfd_poll_leader_exit_thread(), +child_poll_leader_exit_test(). + +The ksft_test_result_pass() in error_report() expects a string but +doesn't provide any argument after the format string. All the other +calls to ksft_print_msg() in the functions mentioned above have format +strings that don't match with other passed arguments. + +Fix format specifiers so they match the passed variables. + +Add a missing variable to ksft_test_result_pass() inside +error_report() so it matches other cases in the switch statement. + +Fixes: 2def297ec7fb ("pidfd: add tests for NSpid info in fdinfo") + +Signed-off-by: Maciej Wieczor-Retman +Signed-off-by: Shuah Khan +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/pidfd/pidfd_fdinfo_test.c | 2 +- + tools/testing/selftests/pidfd/pidfd_test.c | 12 ++++++------ + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/tools/testing/selftests/pidfd/pidfd_fdinfo_test.c b/tools/testing/selftests/pidfd/pidfd_fdinfo_test.c +index 4e86f927880c3..01cc37bf611c3 100644 +--- a/tools/testing/selftests/pidfd/pidfd_fdinfo_test.c ++++ b/tools/testing/selftests/pidfd/pidfd_fdinfo_test.c +@@ -62,7 +62,7 @@ static void error_report(struct error *err, const char *test_name) + break; + + case PIDFD_PASS: +- ksft_test_result_pass("%s test: Passed\n"); ++ ksft_test_result_pass("%s test: Passed\n", test_name); + break; + + default: +diff --git a/tools/testing/selftests/pidfd/pidfd_test.c b/tools/testing/selftests/pidfd/pidfd_test.c +index 00a07e7c571cd..c081ae91313aa 100644 +--- a/tools/testing/selftests/pidfd/pidfd_test.c ++++ b/tools/testing/selftests/pidfd/pidfd_test.c +@@ -381,13 +381,13 @@ static int test_pidfd_send_signal_syscall_support(void) + + static void *test_pidfd_poll_exec_thread(void *priv) + { +- ksft_print_msg("Child Thread: starting. pid %d tid %d ; and sleeping\n", ++ ksft_print_msg("Child Thread: starting. pid %d tid %ld ; and sleeping\n", + getpid(), syscall(SYS_gettid)); + ksft_print_msg("Child Thread: doing exec of sleep\n"); + + execl("/bin/sleep", "sleep", str(CHILD_THREAD_MIN_WAIT), (char *)NULL); + +- ksft_print_msg("Child Thread: DONE. pid %d tid %d\n", ++ ksft_print_msg("Child Thread: DONE. pid %d tid %ld\n", + getpid(), syscall(SYS_gettid)); + return NULL; + } +@@ -427,7 +427,7 @@ static int child_poll_exec_test(void *args) + { + pthread_t t1; + +- ksft_print_msg("Child (pidfd): starting. pid %d tid %d\n", getpid(), ++ ksft_print_msg("Child (pidfd): starting. pid %d tid %ld\n", getpid(), + syscall(SYS_gettid)); + pthread_create(&t1, NULL, test_pidfd_poll_exec_thread, NULL); + /* +@@ -480,10 +480,10 @@ static void test_pidfd_poll_exec(int use_waitpid) + + static void *test_pidfd_poll_leader_exit_thread(void *priv) + { +- ksft_print_msg("Child Thread: starting. pid %d tid %d ; and sleeping\n", ++ ksft_print_msg("Child Thread: starting. pid %d tid %ld ; and sleeping\n", + getpid(), syscall(SYS_gettid)); + sleep(CHILD_THREAD_MIN_WAIT); +- ksft_print_msg("Child Thread: DONE. pid %d tid %d\n", getpid(), syscall(SYS_gettid)); ++ ksft_print_msg("Child Thread: DONE. pid %d tid %ld\n", getpid(), syscall(SYS_gettid)); + return NULL; + } + +@@ -492,7 +492,7 @@ static int child_poll_leader_exit_test(void *args) + { + pthread_t t1, t2; + +- ksft_print_msg("Child: starting. pid %d tid %d\n", getpid(), syscall(SYS_gettid)); ++ ksft_print_msg("Child: starting. pid %d tid %ld\n", getpid(), syscall(SYS_gettid)); + pthread_create(&t1, NULL, test_pidfd_poll_leader_exit_thread, NULL); + pthread_create(&t2, NULL, test_pidfd_poll_leader_exit_thread, NULL); + +-- +2.42.0 + diff --git a/queue-6.6/selftests-resctrl-ensure-the-benchmark-commands-fits.patch b/queue-6.6/selftests-resctrl-ensure-the-benchmark-commands-fits.patch new file mode 100644 index 00000000000..28836dfa561 --- /dev/null +++ b/queue-6.6/selftests-resctrl-ensure-the-benchmark-commands-fits.patch @@ -0,0 +1,55 @@ +From 839c2e88e865ef28bccaac92e747eb5c0105ef42 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 12:53:32 +0300 +Subject: selftests/resctrl: Ensure the benchmark commands fits to its array +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit 4a28c7665c2a1ac0400864eabb0c641e135f61aa ] + +Benchmark command is copied into an array in the stack. The array is +BENCHMARK_ARGS items long but the command line could try to provide a +longer command. Argument size is also fixed by BENCHMARK_ARG_SIZE (63 +bytes of space after fitting the terminating \0 character) and user +could have inputted argument longer than that. + +Return error in case the benchmark command does not fit to the space +allocated for it. + +Fixes: ecdbb911f22d ("selftests/resctrl: Add MBM test") +Signed-off-by: Ilpo Järvinen +Tested-by: Shaopeng Tan +Reviewed-by: Shaopeng Tan +Reviewed-by: "Wieczor-Retman, Maciej" +Reviewed-by: Reinette Chatre +Signed-off-by: Shuah Khan +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/resctrl/resctrl_tests.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c +index d511daeb6851e..9e2bc8ba95f13 100644 +--- a/tools/testing/selftests/resctrl/resctrl_tests.c ++++ b/tools/testing/selftests/resctrl/resctrl_tests.c +@@ -255,9 +255,14 @@ int main(int argc, char **argv) + return ksft_exit_skip("Not running as root. Skipping...\n"); + + if (has_ben) { ++ if (argc - ben_ind >= BENCHMARK_ARGS) ++ ksft_exit_fail_msg("Too long benchmark command.\n"); ++ + /* Extract benchmark command from command line. */ + for (i = ben_ind; i < argc; i++) { + benchmark_cmd[i - ben_ind] = benchmark_cmd_area[i]; ++ if (strlen(argv[i]) >= BENCHMARK_ARG_SIZE) ++ ksft_exit_fail_msg("Too long benchmark command argument.\n"); + sprintf(benchmark_cmd[i - ben_ind], "%s", argv[i]); + } + benchmark_cmd[ben_count] = NULL; +-- +2.42.0 + diff --git a/queue-6.6/selftests-x86-lam-zero-out-buffer-for-readlink.patch b/queue-6.6/selftests-x86-lam-zero-out-buffer-for-readlink.patch new file mode 100644 index 00000000000..4ab0ae683dd --- /dev/null +++ b/queue-6.6/selftests-x86-lam-zero-out-buffer-for-readlink.patch @@ -0,0 +1,57 @@ +From 546103aba344fd0ab05c2b336b1dd71e711ffd31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Oct 2023 14:24:46 +0800 +Subject: selftests/x86/lam: Zero out buffer for readlink() + +From: Binbin Wu + +[ Upstream commit 29060633411a02f6f2dd9d5245919385d69d81f0 ] + +Zero out the buffer for readlink() since readlink() does not append a +terminating null byte to the buffer. Also change the buffer length +passed to readlink() to 'PATH_MAX - 1' to ensure the resulting string +is always null terminated. + +Fixes: 833c12ce0f430 ("selftests/x86/lam: Add inherit test cases for linear-address masking") +Signed-off-by: Binbin Wu +Signed-off-by: Ingo Molnar +Reviewed-by: Kirill A. Shutemov +Link: https://lore.kernel.org/r/20231016062446.695-1-binbin.wu@linux.intel.com +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/x86/lam.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/testing/selftests/x86/lam.c b/tools/testing/selftests/x86/lam.c +index eb0e46905bf9d..8f9b06d9ce039 100644 +--- a/tools/testing/selftests/x86/lam.c ++++ b/tools/testing/selftests/x86/lam.c +@@ -573,7 +573,7 @@ int do_uring(unsigned long lam) + char path[PATH_MAX] = {0}; + + /* get current process path */ +- if (readlink("/proc/self/exe", path, PATH_MAX) <= 0) ++ if (readlink("/proc/self/exe", path, PATH_MAX - 1) <= 0) + return 1; + + int file_fd = open(path, O_RDONLY); +@@ -680,14 +680,14 @@ static int handle_execve(struct testcases *test) + perror("Fork failed."); + ret = 1; + } else if (pid == 0) { +- char path[PATH_MAX]; ++ char path[PATH_MAX] = {0}; + + /* Set LAM mode in parent process */ + if (set_lam(lam) != 0) + return 1; + + /* Get current binary's path and the binary was run by execve */ +- if (readlink("/proc/self/exe", path, PATH_MAX) <= 0) ++ if (readlink("/proc/self/exe", path, PATH_MAX - 1) <= 0) + exit(-1); + + /* run binary to get LAM mode and return to parent process */ +-- +2.42.0 + diff --git a/queue-6.6/series b/queue-6.6/series index a13f33e1ae6..0110fcc42c1 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -1 +1,535 @@ hwmon-nct6775-fix-incorrect-variable-reuse-in-fan_div-calculation.patch +numa-generalize-numa_map_to_online_node.patch +sched-topology-fix-sched_numa_find_nth_cpu-in-cpu-le.patch +sched-topology-fix-sched_numa_find_nth_cpu-in-non-nu.patch +sched-fair-fix-cfs_rq_is_decayed-on-smp.patch +iov_iter-x86-be-consistent-about-the-__user-tag-on-c.patch +sched-uclamp-set-max_spare_cap_cpu-even-if-max_spare.patch +sched-uclamp-ignore-util-0-optimization-in-feec-when.patch +objtool-propagate-early-errors.patch +sched-fix-stop_one_cpu_nowait-vs-hotplug.patch +nfsd-handle-eopenstale-correctly-in-the-filecache.patch +vfs-fix-readahead-2-on-block-devices.patch +writeback-cgroup-switch-inodes-with-dirty-timestamps.patch +x86-srso-fix-sbpb-enablement-for-possible-future-fix.patch +x86-srso-print-mitigation-for-retbleed-ibpb-case.patch +x86-srso-fix-vulnerability-reporting-for-missing-mic.patch +x86-srso-fix-unret-validation-dependencies.patch +futex-don-t-include-process-mm-in-futex-key-on-no-mm.patch +x86-numa-introduce-numa_fill_memblks.patch +acpi-numa-apply-srat-proximity-domain-to-entire-cfmw.patch +cgroup-cpuset-fix-load-balance-state-in-update_parti.patch +x86-sev-es-allow-copy_from_kernel_nofault-in-earlier.patch +x86-boot-fix-incorrect-startup_gdt_descr.size.patch +cpu-smt-make-smt-control-more-robust-against-enumera.patch +x86-apic-fake-primary-thread-mask-for-xen-pv.patch +srcu-fix-callbacks-acceleration-mishandling.patch +drivers-clocksource-timer-ti-dm-don-t-call-clk_get_r.patch +x86-nmi-fix-out-of-order-nmi-nesting-checks-false-po.patch +pstore-platform-add-check-for-kstrdup.patch +perf-optimize-perf_cgroup_switch.patch +selftests-x86-lam-zero-out-buffer-for-readlink.patch +pci-msi-provide-stubs-for-ims-functions.patch +string-adjust-strtomem-logic-to-allow-for-smaller-so.patch +genirq-matrix-exclude-managed-interrupts-in-irq_matr.patch +irqchip-sifive-plic-fix-syscore-registration-for-mul.patch +wifi-ath12k-fix-undefined-behavior-with-__fls-in-dp.patch +wifi-cfg80211-add-flush-functions-for-wiphy-work.patch +wifi-mac80211-move-radar-detect-work-to-wiphy-work.patch +wifi-mac80211-move-scan-work-to-wiphy-work.patch +wifi-mac80211-move-offchannel-works-to-wiphy-work.patch +wifi-mac80211-move-sched-scan-stop-work-to-wiphy-wor.patch +wifi-mac80211-fix-rcu-usage-warning-in-mesh-fast-xmi.patch +wifi-cfg80211-fix-off-by-one-in-element-defrag.patch +wifi-mac80211-fix-of-msdu-in-a-msdu-calculation.patch +wifi-iwlwifi-honor-the-enable_ini-value.patch +wifi-iwlwifi-don-t-use-an-uninitialized-variable.patch +i40e-fix-potential-memory-leaks-in-i40e_remove.patch +iavf-fix-promiscuous-mode-configuration-flow-message.patch +selftests-bpf-correct-map_fd-to-data_fd-in-tailcalls.patch +bpf-x64-fix-tailcall-infinite-loop.patch +wifi-cfg80211-fix-kernel-doc-for-wiphy_delayed_work_.patch +wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch +udp-introduce-udp-udp_flags.patch +udp-move-udp-no_check6_tx-to-udp-udp_flags.patch +udp-move-udp-no_check6_rx-to-udp-udp_flags.patch +udp-move-udp-gro_enabled-to-udp-udp_flags.patch +udp-add-missing-write_once-around-up-encap_rcv.patch +udp-move-udp-accept_udp_-l4-fraglist-to-udp-udp_flag.patch +udp-lockless-udp_encap_l2tpinudp-udp_gro.patch +udp-annotate-data-races-around-udp-encap_type.patch +udplite-remove-udplite_bit.patch +udplite-fix-various-data-races.patch +selftests-bpf-skip-module_fentry_shadow-test-when-bp.patch +tcp-call-tcp_try_undo_recovery-when-an-rtod-tfo-syna.patch +bpf-fix-kfunc-callback-register-type-handling.patch +gve-use-size_add-in-call-to-struct_size.patch +mlxsw-use-size_mul-in-call-to-struct_size.patch +tls-use-size_add-in-call-to-struct_size.patch +tipc-use-size_add-in-calls-to-struct_size.patch +net-spider_net-use-size_add-in-call-to-struct_size.patch +ice-fix-pin-assignment-for-e810-t-without-sma-contro.patch +net-ethernet-mtk_wed-fix-ext_int_status_rx_fbuf-defi.patch +wifi-rtw88-debug-fix-the-null-vs-is_err-bug-for-debu.patch +wifi-ath12k-fix-dma-unmap-warning-on-null-dma-addres.patch +wifi-ath11k-fix-boot-failure-with-one-msi-vector.patch +wifi-mac80211-fix-check-for-unusable-rx-result.patch +pm-sleep-fix-symbol-export-for-_simple_-variants-of-.patch +cpufreq-tegra194-fix-warning-due-to-missing-opp_put.patch +wifi-mt76-mt7603-rework-fix-rx-pse-hang-check.patch +wifi-mt76-mt7603-improve-watchdog-reset-reliablity.patch +wifi-mt76-mt7603-improve-stuck-beacon-handling.patch +wifi-mt76-remove-unused-error-path-in-mt76_connac_tx.patch +wifi-mt76-mt7996-set-correct-wcid-in-txp.patch +wifi-mt76-mt7996-fix-beamform-mcu-cmd-configuration.patch +wifi-mt76-mt7996-fix-beamformee-ss-subfield-in-eht-p.patch +wifi-mt76-mt7996-fix-wmm-queue-mapping.patch +wifi-mt76-mt7996-fix-rx-rate-report-for-cbw320-2.patch +wifi-mt76-mt7996-fix-twt-command-format.patch +wifi-mt76-update-beacon-size-limitation.patch +wifi-mt76-fix-potential-memory-leak-of-beacon-comman.patch +wifi-mt76-get-rid-of-false-alamrs-of-tx-emission-iss.patch +wifi-mt76-fix-per-band-ieee80211_conf_monitor-flag-c.patch +wifi-mt76-mt7915-fix-beamforming-availability-check.patch +wifi-mt76-move-struct-ieee80211_chanctx_conf-up-to-s.patch +wifi-mt76-mt7921-fix-the-wrong-rate-pickup-for-the-c.patch +wifi-mt76-mt7921-fix-the-wrong-rate-selected-in-fw-f.patch +wifi-ath-dfs_pattern_detector-fix-a-memory-initializ.patch +tcp_metrics-add-missing-barriers-on-delete.patch +tcp_metrics-properly-set-tp-snd_ssthresh-in-tcp_init.patch +tcp_metrics-do-not-create-an-entry-from-tcp_init_met.patch +wifi-rtlwifi-fix-edca-limit-set-by-bt-coexistence.patch +acpi-property-allow-_dsd-buffer-data-only-for-byte-a.patch +acpi-video-add-acpi_backlight-vendor-quirk-for-toshi.patch +can-etas_es58x-rework-the-version-check-logic-to-sil.patch +can-etas_es58x-add-missing-a-blank-line-after-declar.patch +libbpf-fix-syscall-access-arguments-on-riscv.patch +selftests-bpf-define-sys_prefix-for-riscv.patch +selftests-bpf-define-sys_nanosleep_kprobe_name-for-r.patch +r8152-break-the-loop-when-the-budget-is-exhausted.patch +wifi-ath11k-fix-tx-power-value-during-active-cac.patch +can-dev-can_restart-don-t-crash-kernel-if-carrier-is.patch +can-dev-can_restart-fix-race-condition-between-contr.patch +can-dev-can_put_echo_skb-don-t-crash-kernel-if-can_p.patch +pm-devfreq-rockchip-dfi-make-pmu-regmap-mandatory.patch +wifi-wfx-fix-case-where-rates-are-out-of-order.patch +netfilter-nf_tables-drop-pointless-memset-when-dumpi.patch +virtio-net-fix-mismatch-of-getting-tx-frames.patch +virtio-net-consistently-save-parameters-for-per-queu.patch +virtio-net-fix-per-queue-coalescing-parameter-settin.patch +virtio-net-fix-the-vq-coalescing-setting-for-vq-resi.patch +wifi-rtw88-remove-duplicate-null-check-before-callin.patch +thermal-core-prevent-potential-string-overflow.patch +r8169-fix-rare-issue-with-broken-rx-after-link-down-.patch +thermal-drivers-mediatek-fix-probe-for-thermal_v2.patch +bpf-fix-missed-rcu-read-lock-in-bpf_task_under_cgrou.patch +net-skb_find_text-ignore-patterns-extending-past-to.patch +selftests-bpf-make-linked_list-failure-test-more-rob.patch +thermal-core-don-t-update-trip-points-inside-the-hys.patch +chtls-fix-tp-rcv_tstamp-initialization.patch +tcp-fix-cookie_init_timestamp-overflows.patch +wifi-iwlwifi-mvm-update-station-s-mfp-flag-after-ass.patch +wifi-iwlwifi-mvm-fix-removing-pasn-station-for-respo.patch +wifi-iwlwifi-mvm-use-correct-sta-id-for-igtk-bigtk.patch +wifi-mac80211-don-t-recreate-driver-link-debugfs-in-.patch +wifi-mac80211-fix-setting-vif-links.patch +wifi-iwlwifi-yoyo-swap-cdb-and-jacket-bits-values.patch +wifi-iwlwifi-mvm-correctly-set-link-configuration.patch +wifi-iwlwifi-mvm-fix-key-flags-for-igtk-on-ap-interf.patch +wifi-iwlwifi-mvm-don-t-always-bind-link-the-p2p-devi.patch +wifi-iwlwifi-mvm-change-iwl_mvm_flush_sta-api.patch +wifi-iwlwifi-mvm-fix-iwl_mvm_mac_flush_sta.patch +wifi-iwlwifi-mvm-remove-tdls-stations-from-fw.patch +wifi-iwlwifi-increase-number-of-rx-buffers-for-eht-d.patch +wifi-iwlwifi-mvm-fix-netif-csum-flags.patch +wifi-iwlwifi-pcie-synchronize-irqs-before-napi.patch +wifi-iwlwifi-mvm-update-igtk-in-mvmvif-upon-d3-resum.patch +wifi-iwlwifi-empty-overflow-queue-during-flush.patch +bluetooth-iso-pass-big-encryption-info-through-qos.patch +bluetooth-make-handle-of-hci_conn-be-unique.patch +bluetooth-hci_sync-fix-opcode-prints-in-bt_dev_dbg-e.patch +bpf-fix-unnecessary-ebusy-from-htab_lock_bucket.patch +acpi-sysfs-fix-create_pnp_modalias-and-create_of_mod.patch +mptcp-properly-account-fastopen-data.patch +ipv6-avoid-atomic-fragment-on-gso-packets.patch +virtio_net-use-u64_stats_t-infra-to-avoid-data-races.patch +net-add-dev_stats_read-helper.patch +ipvlan-properly-track-tx_errors.patch +regmap-debugfs-fix-a-erroneous-check-after-snprintf.patch +spi-tegra-fix-missing-irq-check-in-tegra_slink_probe.patch +clk-qcom-ipq5332-drop-set-rate-parent-from-gpll0-dep.patch +clk-qcom-gcc-msm8996-remove-rpm-bus-clocks.patch +clk-qcom-clk-rcg2-fix-clock-rate-overflow-for-high-p.patch +clk-qcom-mmcc-msm8998-don-t-check-halt-bit-on-some-b.patch +clk-qcom-mmcc-msm8998-fix-the-smmu-gdsc.patch +clk-qcom-gcc-sm8150-fix-gcc_sdcc2_apps_clk_src.patch +gpio-sim-initialize-a-managed-pointer-when-declaring.patch +regulator-mt6358-fail-probe-on-unknown-chip-id.patch +clk-imx-select-mxc_clk-for-clk_imx8qxp.patch +clk-imx-imx8-fix-an-error-handling-path-in-clk_imx_a.patch +clk-imx-imx8-fix-an-error-handling-path-if-devm_clk_.patch +clk-imx-imx8-fix-an-error-handling-path-in-imx8_acm_.patch +clk-imx-imx8mq-correct-error-handling-path.patch +clk-imx-imx8qxp-fix-elcdif_pll-clock.patch +clk-renesas-rcar-gen3-extend-sdnh-divider-table.patch +clk-renesas-rzg2l-wait-for-status-bit-of-sd-mux-befo.patch +clk-renesas-rzg2l-lock-around-writes-to-mux-register.patch +clk-renesas-rzg2l-trust-value-returned-by-hardware.patch +clk-renesas-rzg2l-use-field_get-for-pll-register-fie.patch +clk-renesas-rzg2l-fix-computation-formula.patch +clk-linux-clk-provider.h-fix-kernel-doc-warnings-and.patch +spi-nxp-fspi-use-the-correct-ioremap-function.patch +clk-ralink-mtmips-quiet-unused-variable-warning.patch +clk-keystone-pll-fix-a-couple-null-vs-is_err-checks.patch +clk-ti-fix-double-free-in-of_ti_divider_clk_setup.patch +clk-npcm7xx-fix-incorrect-kfree.patch +clk-mediatek-clk-mt6765-add-check-for-mtk_alloc_clk_.patch +clk-mediatek-clk-mt6779-add-check-for-mtk_alloc_clk_.patch +clk-mediatek-clk-mt6797-add-check-for-mtk_alloc_clk_.patch +clk-mediatek-clk-mt7629-eth-add-check-for-mtk_alloc_.patch +clk-mediatek-clk-mt7629-add-check-for-mtk_alloc_clk_.patch +clk-mediatek-clk-mt2701-add-check-for-mtk_alloc_clk_.patch +clk-qcom-config-ipq_apss_6018-should-depend-on-qcom_.patch +clk-qcom-clk-alpha-pll-introduce-stromer-plus-ops.patch +clk-qcom-apss-ipq-pll-use-stromer-plus-ops-for-strom.patch +clk-qcom-apss-ipq-pll-fix-l-value-for-ipq5332_pll_co.patch +clk-qcom-ipq5018-drop-the-clk_set_rate_parent-flag-f.patch +clk-qcom-ipq9574-drop-the-clk_set_rate_parent-flag-f.patch +clk-qcom-ipq5332-drop-the-clk_set_rate_parent-flag-f.patch +clk-mediatek-fix-double-free-in-mtk_clk_register_pll.patch +platform-x86-wmi-fix-probe-failure-when-failing-to-r.patch +platform-x86-wmi-fix-opening-of-char-device.patch +regulator-qcom-rpmh-fix-smps4-regulator-for-pm8550ve.patch +hwmon-axi-fan-control-fix-possible-null-pointer-dere.patch +hwmon-coretemp-fix-potentially-truncated-sysfs-attri.patch +revert-hwmon-sch56xx-common-add-dmi-override-table.patch +revert-hwmon-sch56xx-common-add-automatic-module-loa.patch +hwmon-pmbus-mp2975-move-pgood-fix.patch +hwmon-sch5627-use-bit-macros-when-accessing-the-cont.patch +hwmon-sch5627-disallow-write-access-if-virtual-regis.patch +hte-tegra-fix-missing-error-code-in-tegra_hte_test_p.patch +platform-chrome-cros_ec_lpc-separate-host-command-an.patch +spi-omap2-mcspi-switch-to-use-modern-name.patch +spi-omap2-mcspi-fix-hardcoded-reference-clock.patch +drm-bridge-samsung-dsim-initialize-ulps-exit-for-i.m.patch +drm-bridge-for-generic_phy_mipi_dphy-also-select-gen.patch +drm-bridge-samsung-dsim-fix-waiting-for-empty-cmd-tr.patch +drm-loongson-fix-error-handling-in-lsdc_pixel_pll_se.patch +drm-rockchip-vop-fix-reset-of-state-in-duplicate-sta.patch +drm-rockchip-vop-fix-call-to-crtc-reset-helper.patch +drm-rockchip-vop2-don-t-crash-for-invalid-duplicate_.patch +drm-rockchip-vop2-add-missing-call-to-crtc-reset-hel.patch +drm-radeon-possible-buffer-overflow.patch +drm-radeon-remove-the-references-of-radeon_gem_-prea.patch +drm-bridge-it66121-fix-invalid-connector-dereference.patch +drm-bridge-lt8912b-fix-bridge_detach.patch +drm-bridge-lt8912b-fix-crash-on-bridge-detach.patch +drm-bridge-lt8912b-manually-disable-hpd-only-if-it-w.patch +drm-bridge-lt8912b-add-missing-drm_bridge_attach-cal.patch +drm-ssd130x-fix-screen-clearing.patch +drm-mediatek-fix-coverity-issue-with-unintentional-i.patch +x86-tdx-zero-out-the-missing-rsi-in-tdx_hypercall-ma.patch +drm-bridge-tc358768-fix-use-of-uninitialized-variabl.patch +drm-bridge-tc358768-fix-bit-updates.patch +drm-bridge-tc358768-use-struct-videomode.patch +drm-bridge-tc358768-print-logical-values-not-raw-reg.patch +drm-bridge-tc358768-use-dev-for-dbg-prints-not-priv-.patch +drm-bridge-tc358768-rename-dsibclk-to-hsbyteclk.patch +drm-bridge-tc358768-clean-up-clock-period-code.patch +drm-bridge-tc358768-fix-tc358768_ns_to_cnt.patch +drm-call-drm_atomic_helper_shutdown-at-shutdown-remo.patch +drm-amdgpu-increase-ih-soft-ring-size-for-gfx-v9.4.3.patch +drm-amdkfd-fix-some-race-conditions-in-vram-buffer-a.patch +drm-amdkfd-remove-svm-range-validated_once-flag.patch +drm-amdkfd-handle-errors-from-svm-validate-and-map.patch +drm-amd-display-fix-null-pointer-dereference-in-erro.patch +drm-amd-display-check-all-enabled-planes-in-dm_check.patch +drm-amd-display-refactor-dm_get_plane_scale-helper.patch +drm-amd-display-bail-from-dm_check_crtc_cursor-if-no.patch +io_uring-kbuf-fix-check-of-bid-wrapping-in-provided-.patch +io_uring-kbuf-allow-the-full-buffer-id-space-for-pro.patch +drm-mediatek-add-mmsys_dev_num-to-mt8188-vdosys0-dri.patch +drm-mediatek-fix-iommu-fault-by-swapping-fbs-after-u.patch +drm-mediatek-fix-iommu-fault-during-crtc-enabling.patch +accel-habanalabs-gaudi2-fix-incorrect-string-length-.patch +drm-msm-adreno-fix-sm6375-gpu-id.patch +drm-msm-a6xx-fix-unknown-speedbin-case.patch +drm-rockchip-cdn-dp-fix-some-error-handling-paths-in.patch +gpu-host1x-correct-allocated-size-for-contexts.patch +drm-bridge-lt9611uxc-fix-the-race-in-the-error-path.patch +arm64-arm-xen-enlighten-fix-kpti-checks.patch +drm-rockchip-fix-type-promotion-bug-in-rockchip_gem_.patch +xenbus-fix-error-exit-in-xenbus_init.patch +xen-make-struct-privcmd_irqfd-s-layout-architecture-.patch +xen-irqfd-use-_iow-instead-of-the-internal-_ioc-macr.patch +xen-pciback-consider-intx-disabled-when-msi-msi-x-is.patch +drm-msm-dsi-use-msm_gem_kernel_put-to-free-tx-buffer.patch +drm-msm-dsi-free-tx-buffer-in-unbind.patch +clocksource-drivers-arm_arch_timer-limit-xgene-1-wor.patch +drm-mediatek-mtk_dsi-fix-no_eot_packet-settings-hand.patch +drivers-perf-hisi-use-cpuhp_state_remove_instance_no.patch +drm-amd-pm-fix-a-memory-leak-on-an-error-path.patch +perf-arm-cmn-fix-dtc-domain-detection.patch +drivers-perf-hisi_pcie-check-the-type-first-in-pmu-e.patch +perf-hisi-fix-use-after-free-when-register-pmu-fails.patch +arm-dts-renesas-blanche-fix-typo-in-gp_11_2-pin-name.patch +arm64-dts-qcom-sdm845-fix-psci-power-domain-names.patch +arm64-dts-qcom-sdm845-cheza-doesn-t-support-lmh-node.patch +arm64-dts-qcom-sc7280-link-usb3_phy_wrapper_gcc_usb3.patch +arm64-dts-qcom-msm8916-fix-iommu-local-address-range.patch +arm64-dts-qcom-msm8992-libra-drop-duplicated-reserve.patch +arm64-dts-qcom-sm6125-pad-apps-iommu-address-to-8-ch.patch +arm64-dts-qcom-sc7280-add-missing-lmh-interrupts.patch +arm64-dts-qcom-qrb2210-rb1-swap-uart-index.patch +arm64-dts-qcom-qrb2210-rb1-fix-regulators.patch +arm64-dts-qcom-sdm670-fix-pdc-mapping.patch +arm64-dts-qcom-sc7280-drop-incorrect-eud-port-on-soc.patch +arm64-dts-qcom-sm8150-add-ref-clock-to-pcie-phys.patch +arm64-dts-qcom-sm8350-fix-pinctrl-for-uart18.patch +arm64-dts-qcom-sdm845-mtp-fix-wifi-configuration.patch +arm64-dts-qcom-sdx75-idp-align-rpmh-regulator-nodes-.patch +arm64-dts-marvell-cn9310-use-appropriate-label-for-s.patch +arm64-dts-qcom-msm8976-fix-ipc-bit-shifts.patch +arm64-dts-qcom-msm8939-fix-iommu-local-address-range.patch +riscv-dts-allwinner-remove-address-cells-from-intc-n.patch +arm64-dts-qcom-apq8016-sbc-add-missing-adv7533-regul.patch +arm-dts-qcom-apq8026-samsung-matisse-wifi-fix-invert.patch +arm-dts-qcom-mdm9615-populate-vsdcc-fixed-regulator.patch +soc-qcom-llcc-handle-a-second-device-without-data-co.patch +kunit-fix-missed-memory-release-in-kunit_free_suite_.patch +kunit-fix-the-wrong-kfree-of-copy-for-kunit_filter_s.patch +kunit-fix-possible-memory-leak-in-kunit_filter_suite.patch +kunit-test-fix-the-possible-memory-leak-in-executor_.patch +arm-dts-stm32-stm32f7-pinctrl-don-t-use-multiple-bla.patch +firmware-ti_sci-mark-driver-as-non-removable.patch +arm64-dts-ti-k3-j721s2-evm-gesi-specify-base-dtb-for.patch +arm64-dts-ti-verdin-am62-disable-mipi-dsi-bridge.patch +arm64-dts-ti-k3-am625-beagleplay-fix-typo-in-ramoops.patch +arm64-dts-ti-k3-am62a7-sk-drop-i2c-1-to-100khz.patch +arm64-dts-ti-fix-hdmi-audio-overlay-in-makefile.patch +firmware-arm_ffa-assign-the-missing-idr-allocation-i.patch +firmware-arm_ffa-allow-the-ff-a-drivers-to-use-32bit.patch +arm-dts-am3517-evm-fix-led3-4-pinmux.patch +clk-scmi-free-scmi_clk-allocated-when-the-clocks-wit.patch +arm64-dts-imx8qm-ss-img-fix-jpegenc-compatible-entry.patch +arm64-dts-imx8mp-debix-model-a-remove-usb-hub-reset-.patch +arm64-dts-imx8mm-add-sound-dai-cells-to-micfil-node.patch +arm64-dts-imx8mn-add-sound-dai-cells-to-micfil-node.patch +arm64-tegra-fix-p3767-card-detect-polarity.patch +arm64-tegra-fix-p3767-qspi-speed.patch +firmware-tegra-add-suspend-hook-and-reset-bpmp-ipc-e.patch +memory-tegra-set-bpmp-msg-flags-to-reset-ipc-channel.patch +arm64-tegra-use-correct-interrupts-for-tegra234-tke.patch +selftests-pidfd-fix-ksft-print-formats.patch +selftests-resctrl-ensure-the-benchmark-commands-fits.patch +soc-qcom-pmic_glink-fix-connector-type-to-be-display.patch +arm-dts-bcm5301x-explicitly-disable-unused-switch-cp.patch +iommufd-add-iopt_area_alloc.patch +module-decompress-use-vmalloc-for-gzip-decompression.patch +asoc-cs35l41-handle-mdsync_down-reg-write-errors.patch +asoc-cs35l41-handle-mdsync_up-reg-write-errors.patch +asoc-cs35l41-initialize-completion-object-before-req.patch +asoc-cs35l41-fix-broken-shared-boost-activation.patch +asoc-cs35l41-verify-pm-runtime-resume-errors-in-irq-.patch +asoc-cs35l41-undo-runtime-pm-changes-at-driver-exit-.patch +alsa-hda-cs35l41-fix-unbalanced-pm_runtime_get.patch +alsa-hda-cs35l41-undo-runtime-pm-changes-at-driver-e.patch +keys-include-linux-errno.h-in-linux-verification.h.patch +crypto-ccp-get-a-free-page-to-use-while-fetching-ini.patch +crypto-ccp-fix-ioctl-unit-tests.patch +crypto-ccp-fix-dbc-sample-application-error-handling.patch +crypto-ccp-fix-sample-application-signature-passing.patch +crypto-ccp-fix-some-unfused-tests.patch +crypto-hisilicon-hpre-fix-a-erroneous-check-after-sn.patch +hwrng-bcm2835-fix-hwrng-throughput-regression.patch +hwrng-geode-fix-accessing-registers.patch +rdma-core-use-size_-add-sub-mul-in-calls-to-struct_s.patch +crypto-qat-fix-state-machines-cleanup-paths.patch +crypto-qat-ignore-subsequent-state-up-commands.patch +crypto-qat-fix-unregistration-of-crypto-algorithms.patch +crypto-qat-fix-unregistration-of-compression-algorit.patch +scsi-ibmvfc-fix-erroneous-use-of-rtas_busy_delay-wit.patch +asoc-soc-pcm.c-make-sure-dai-parameters-cleared-if-t.patch +libnvdimm-of_pmem-use-devm_kstrdup-instead-of-kstrdu.patch +nd_btt-make-btt-lanes-preemptible.patch +crypto-caam-qi2-fix-chacha20-poly1305-self-test-fail.patch +crypto-caam-jr-fix-chacha20-poly1305-self-test-failu.patch +crypto-qat-increase-size-of-buffers.patch +asoc-sof-ipc4-topology-use-size_add-in-call-to-struc.patch +pci-vmd-correct-pci-header-type-register-s-multi-fun.patch +hid-cp2112-fix-duplicate-workqueue-initialization.patch +crypto-hisilicon-qm-fix-pf-queue-parameter-issue.patch +arm-9321-1-memset-cast-the-constant-byte-to-unsigned.patch +arm-9323-1-mm-fix-arch_low_address_limit-when-config.patch +ext4-add-missing-initialization-of-call_notify_error.patch +ext4-move-ix-sanity-check-to-corrent-position.patch +kselftest-vm-fix-mdwe-s-mmap_fixed-test-case.patch +asoc-fsl-mpc5200_dma.c-fix-warning-of-function-param.patch +backlight-pwm_bl-disable-pwm-on-shutdown-suspend-and.patch +asoc-intel-sof_sdw_rt_sdca_jack_common-add-rt713-sup.patch +asoc-fsl-asoc-card-add-comment-for-mclk-in-the-codec.patch +fs-dlm-fix-the-size-of-a-buffer-in-dlm_create_debug_.patch +dlm-fix-creating-multiple-node-structures.patch +dlm-fix-remove-member-after-close-call.patch +dlm-be-sure-we-reset-all-nodes-at-forced-shutdown.patch +dlm-fix-no-ack-after-final-message.patch +ib-mlx5-fix-rdma-counter-binding-for-raw-qp.patch +rdma-hns-fix-printing-level-of-asynchronous-events.patch +rdma-hns-fix-uninitialized-ucmd-in-hns_roce_create_q.patch +rdma-hns-fix-signed-unsigned-mixed-comparisons.patch +rdma-hns-add-check-for-sl.patch +rdma-hns-the-ud-mode-can-only-be-configured-with-dcq.patch +rdma-hns-fix-unnecessary-port_num-transition-in-hw-s.patch +rdma-hns-fix-init-failure-of-roce-vf-and-hip08.patch +asoc-sof-core-ensure-sof_ops_free-is-still-called-wh.patch +asoc-intel-sof_sdw-stop-processing-codecs-when-enoug.patch +asoc-fsl-fix-pm-disable-depth-imbalance-in-fsl_easrc.patch +scsi-ufs-core-leave-space-for-0-in-utf8-desc-string.patch +rdma-hfi1-workaround-truncation-compilation-error.patch +hid-cp2112-fix-irq-shutdown-stopping-polling-for-all.patch +hid-uclogic-fix-user-memory-access-bug-in-uclogic_pa.patch +hid-uclogic-fix-a-work-entry-not-empty-bug-in-__queu.patch +sh-bios-revive-earlyprintk-support.patch +hid-logitech-hidpp-don-t-restart-io-instead-defer-hi.patch +hid-logitech-hidpp-revert-don-t-restart-communicatio.patch +hid-logitech-hidpp-move-get_wireless_feature_index-c.patch +asoc-intel-skylake-fix-mem-leak-when-parsing-uuids-f.patch +pci-endpoint-fix-double-free-in-__pci_epc_create.patch +padata-fix-refcnt-handling-in-padata_free_shell.patch +certs-break-circular-dependency-when-selftest-is-mod.patch +crypto-qat-consolidate-services-structure.patch +crypto-qat-enable-dc-chaining-service.patch +crypto-qat-refactor-fw-config-related-functions.patch +crypto-qat-use-masks-for-ae-groups.patch +crypto-qat-fix-ring-to-service-map-for-qat-gen4.patch +crypto-qat-fix-deadlock-in-backlog-processing.patch +asoc-ams-delta.c-use-component-after-check.patch +erofs-fix-erofs_insert_workgroup-lockref-usage.patch +ib-mlx5-fix-init-stage-error-handling-to-avoid-doubl.patch +mfd-core-un-constify-mfd_cell.of_reg.patch +mfd-core-ensure-disabled-devices-are-skipped-without.patch +mfd-dln2-fix-double-put-in-dln2_probe.patch +dt-bindings-mfd-mt6397-split-out-compatible-for-medi.patch +mfd-arizona-spi-set-pdata.hpdet_channel-for-acpi-enu.patch +leds-turris-omnia-do-not-use-smbus-calls.patch +leds-pwm-don-t-disable-the-pwm-when-the-led-should-b.patch +leds-trigger-ledtrig-cpu-fix-output-may-be-truncated.patch +scripts-gdb-fix-usage-of-mod_text-not-defined-when-c.patch +apparmor-fix-invalid-reference-on-profile-disconnect.patch +perf-stat-fix-aggr-mode-initialization.patch +iio-frequency-adf4350-use-device-managed-functions-a.patch +pinctrl-baytrail-fix-debounce-disable-case.patch +perf-kwork-fix-incorrect-and-missing-free-atom-in-wo.patch +perf-kwork-add-the-supported-subcommands-to-the-docu.patch +perf-kwork-set-ordered_events-to-true-in-struct-perf.patch +f2fs-compress-fix-deadloop-in-f2fs_write_cache_pages.patch +f2fs-compress-fix-to-avoid-use-after-free-on-dic.patch +f2fs-compress-fix-to-avoid-redundant-compress-extens.patch +f2fs-fix-to-drop-meta_inode-s-page-cache-in-f2fs_put.patch +tty-tty_jobctrl-fix-pid-memleak-in-disassociate_ctty.patch +perf-parse-events-fix-tracepoint-name-memory-leak.patch +livepatch-fix-missing-newline-character-in-klp_resol.patch +pinctrl-renesas-rzg2l-make-reverse-order-of-enable-f.patch +perf-vendor-events-arm64-fix-for-ampereone-metrics.patch +perf-record-fix-btf-type-checks-in-the-off-cpu-profi.patch +dmaengine-idxd-register-dsa_bus_type-before-register.patch +usb-dwc2-fix-possible-null-pointer-dereference-cause.patch +usb-chipidea-fix-dma-overwrite-for-tegra.patch +usb-chipidea-simplify-tegra-dma-alignment-code.patch +dmaengine-ti-edma-handle-irq_of_parse_and_map-errors.patch +tools-perf-update-call-stack-check-in-builtin-lock.c.patch +misc-st_core-do-not-call-kfree_skb-under-spin_lock_i.patch +debugfs-fix-__rcu-type-comparison-warning.patch +tools-iio-iio_generic_buffer-ensure-alignment.patch +usb-usbip-fix-stub_dev-hub-disconnect.patch +dmaengine-pxa_dma-remove-an-erroneous-bug_on-in-pxad.patch +f2fs-fix-to-initialize-map.m_pblk-in-f2fs_precache_e.patch +interconnect-qcom-qdu1000-set-acv-enable_mask.patch +interconnect-qcom-sc7180-set-acv-enable_mask.patch +interconnect-qcom-sc7280-set-acv-enable_mask.patch +interconnect-qcom-sc8180x-set-acv-enable_mask.patch +interconnect-qcom-sc8280xp-set-acv-enable_mask.patch +interconnect-qcom-sdm670-set-acv-enable_mask.patch +interconnect-qcom-sdm845-set-acv-enable_mask.patch +interconnect-qcom-sm6350-set-acv-enable_mask.patch +interconnect-qcom-sm8150-set-acv-enable_mask.patch +interconnect-qcom-sm8250-set-acv-enable_mask.patch +interconnect-qcom-sm8350-set-acv-enable_mask.patch +interconnect-qcom-osm-l3-replace-custom-implementati.patch +powerpc-only-define-__parse_fpscr-when-required.patch +interconnect-fix-error-handling-in-qnoc_probe.patch +perf-build-add-missing-comment-about-no_libtraceeven.patch +perf-parse-events-fix-for-term-values-that-are-raw-e.patch +perf-mem-events-avoid-uninitialized-read.patch +s390-ap-re-init-ap-queues-on-config-on.patch +modpost-fix-tee-module_device_table-built-on-big-end.patch +modpost-fix-ishtp-module_device_table-built-on-big-e.patch +perf-tools-do-not-ignore-the-default-vmlinux.h.patch +powerpc-40x-remove-stale-pte_atomic_updates-macro.patch +powerpc-xive-fix-endian-conversion-size.patch +powerpc-hide-empty-pt_regs-at-base-of-the-stack.patch +perf-trace-use-the-right-bpf_probe_read-_str-variant.patch +powerpc-vas-limit-open-window-failure-messages-in-lo.patch +powerpc-imc-pmu-use-the-correct-spinlock-initializer.patch +powerpc-pseries-fix-potential-memory-leak-in-init_cp.patch +perf-vendor-events-update-pmc-used-in-pm_run_inst_cm.patch +xhci-loosen-rpm-as-default-policy-to-cover-for-amd-x.patch +usb-host-xhci-plat-fix-possible-kernel-oops-while-re.patch +powerpc-vmcore-add-mmu-information-to-vmcoreinfo.patch +perf-machine-avoid-out-of-bounds-lbr-memory-read.patch +libperf-rc_check-make-implicit-enabling-work-for-gcc.patch +perf-hist-add-missing-puts-to-hist__account_cycles.patch +perf-vendor-events-intel-fix-broadwellde-tma_info_sy.patch +perf-vendor-events-intel-add-broadwellde-two-metrics.patch +9p-net-fix-possible-memory-leak-in-p9_check_errors.patch +rtla-fix-uninitialized-variable-found.patch +i3c-fix-potential-refcount-leak-in-i3c_master_regist.patch +rtc-brcmstb-waketimer-support-level-alarm_irq.patch +cxl-pci-remove-unnecessary-device-reference-manageme.patch +cxl-pci-cleanup-sanitize-to-always-poll.patch +cxl-pci-remove-inconsistent-usage-of-dev_err_probe.patch +cxl-pci-clarify-devm-host-for-memdev-relative-setup.patch +cxl-pci-fix-sanitize-notifier-setup.patch +cxl-memdev-fix-sanitize-vs-decoder-setup-locking.patch +cxl-mem-fix-shutdown-order.patch +virt-sevguest-fix-passing-a-stack-buffer-as-a-scatte.patch +rtc-pcf85363-fix-wrong-mask-val-parameters-in-regmap.patch +cxl-region-prepare-the-decoder-match-range-helper-fo.patch +cxl-region-calculate-a-target-position-in-a-region-i.patch +cxl-region-use-cxl_calc_interleave_pos-for-auto-disc.patch +cxl-region-fix-cxl_region_rwsem-lock-held-when-retur.patch +cxl-core-regs-rename-dev-to-host-in-struct-cxl_regis.patch +cxl-port-fix-host-confusion-in-cxl_dport_setup_regs.patch +cxl-hdm-remove-broken-error-path.patch +pcmcia-cs-fix-possible-hung-task-and-memory-leak-pcc.patch +pcmcia-ds-fix-refcount-leak-in-pcmcia_device_add.patch +pcmcia-ds-fix-possible-name-leak-in-error-path-in-pc.patch +media-imx-jpeg-initiate-a-drain-of-the-capture-queue.patch +media-hantro-check-whether-reset-op-is-defined-befor.patch +media-verisilicon-do-not-enable-g2-postproc-downscal.patch +media-ov13b10-fix-some-error-checking-in-probe.patch +media-ov5640-fix-vblank-unchange-issue-when-work-at-.patch +media-i2c-max9286-fix-some-redundant-of_node_put-cal.patch +media-ov5640-fix-a-memory-leak-when-ov5640_probe-fai.patch +media-bttv-fix-use-after-free-error-due-to-btv-timeo.patch +media-amphion-handle-firmware-debug-message.patch +media-mtk-jpegenc-fix-bug-in-jpeg-encode-quality-sel.patch +media-s3c-camif-avoid-inappropriate-kfree.patch +media-vidtv-psi-add-check-for-kstrdup.patch +media-vidtv-mux-add-check-and-kfree-for-kstrdup.patch +media-cedrus-fix-clock-reset-sequence.patch +media-i2c-imx219-convert-to-cci-register-access-help.patch +media-i2c-imx219-replace-register-addresses-with-mac.patch +media-i2c-imx219-drop-imx219_reg_csi_lane_mode-from-.patch +media-cadence-csi2rx-unregister-v4l2-async-notifier.patch +media-dvb-usb-v2-af9035-fix-missing-unlock.patch +media-verisilicon-fixes-clock-list-for-rk3588-av1-de.patch +media-mediatek-vcodec-handle-invalid-encoder-vsi.patch +media-imx-jpeg-notify-source-chagne-event-when-the-f.patch +media-mediatek-vcodec-using-encoder-device-to-alloc-.patch +media-platform-mtk-mdp3-fix-uninitialized-variable-i.patch +media-cec-meson-always-include-meson-sub-directory-i.patch +cpupower-fix-reference-to-nonexistent-document.patch +regmap-prevent-noinc-writes-from-clobbering-cache.patch +drm-amdgpu-gfx10-11-use-memcpy_to-fromio-for-mqds.patch +drm-amdgpu-don-t-put-mqds-in-vram-on-arm-arm64.patch diff --git a/queue-6.6/sh-bios-revive-earlyprintk-support.patch b/queue-6.6/sh-bios-revive-earlyprintk-support.patch new file mode 100644 index 00000000000..2857530bf19 --- /dev/null +++ b/queue-6.6/sh-bios-revive-earlyprintk-support.patch @@ -0,0 +1,52 @@ +From 9f9cbc677588f107f816a2dc2710cdaffa34f894 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Oct 2023 11:46:43 +0200 +Subject: sh: bios: Revive earlyprintk support + +From: Geert Uytterhoeven + +[ Upstream commit 553f7ac78fbb41b2c93ab9b9d78e42274d27daa9 ] + +The SuperH BIOS earlyprintk code is protected by CONFIG_EARLY_PRINTK. +However, when this protection was added, it was missed that SuperH no +longer defines an EARLY_PRINTK config symbol since commit +e76fe57447e88916 ("sh: Remove old early serial console code V2"), so +BIOS earlyprintk can no longer be used. + +Fix this by reviving the EARLY_PRINTK config symbol. + +Fixes: d0380e6c3c0f6edb ("early_printk: consolidate random copies of identical code") +Signed-off-by: Geert Uytterhoeven +Reviewed-by: John Paul Adrian Glaubitz +Link: https://lore.kernel.org/r/c40972dfec3dcc6719808d5df388857360262878.1697708489.git.geert+renesas@glider.be +Signed-off-by: John Paul Adrian Glaubitz +Signed-off-by: Sasha Levin +--- + arch/sh/Kconfig.debug | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug +index c449e7c1b20ff..8bcd6c1431a95 100644 +--- a/arch/sh/Kconfig.debug ++++ b/arch/sh/Kconfig.debug +@@ -22,6 +22,17 @@ config STACK_DEBUG + every function call and will therefore incur a major + performance hit. Most users should say N. + ++config EARLY_PRINTK ++ bool "Early printk" ++ depends on SH_STANDARD_BIOS ++ help ++ Say Y here to redirect kernel printk messages to the serial port ++ used by the SH-IPL bootloader, starting very early in the boot ++ process and ending when the kernel's serial console is initialised. ++ This option is only useful while porting the kernel to a new machine, ++ when the kernel may crash or hang before the serial console is ++ initialised. If unsure, say N. ++ + config 4KSTACKS + bool "Use 4Kb for kernel stacks instead of 8Kb" + depends on DEBUG_KERNEL && (MMU || BROKEN) && !PAGE_SIZE_64KB +-- +2.42.0 + diff --git a/queue-6.6/soc-qcom-llcc-handle-a-second-device-without-data-co.patch b/queue-6.6/soc-qcom-llcc-handle-a-second-device-without-data-co.patch new file mode 100644 index 00000000000..23136d571ed --- /dev/null +++ b/queue-6.6/soc-qcom-llcc-handle-a-second-device-without-data-co.patch @@ -0,0 +1,42 @@ +From 678d2ac150ef7a8b0f57133264581789e79c513f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Sep 2023 10:32:29 +0200 +Subject: soc: qcom: llcc: Handle a second device without data corruption +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit f1a1bc8775b26345aba2be278118999e7f661d3d ] + +Usually there is only one llcc device. But if there were a second, even +a failed probe call would modify the global drv_data pointer. So check +if drv_data is valid before overwriting it. + +Signed-off-by: Uwe Kleine-König +Fixes: a3134fb09e0b ("drivers: soc: Add LLCC driver") +Link: https://lore.kernel.org/r/20230926083229.2073890-1-u.kleine-koenig@pengutronix.de +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/soc/qcom/llcc-qcom.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c +index e32a4161a8d02..c61848595da06 100644 +--- a/drivers/soc/qcom/llcc-qcom.c ++++ b/drivers/soc/qcom/llcc-qcom.c +@@ -944,6 +944,9 @@ static int qcom_llcc_probe(struct platform_device *pdev) + u32 version; + struct regmap *regmap; + ++ if (!IS_ERR(drv_data)) ++ return -EBUSY; ++ + drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); + if (!drv_data) { + ret = -ENOMEM; +-- +2.42.0 + diff --git a/queue-6.6/soc-qcom-pmic_glink-fix-connector-type-to-be-display.patch b/queue-6.6/soc-qcom-pmic_glink-fix-connector-type-to-be-display.patch new file mode 100644 index 00000000000..af4219b2685 --- /dev/null +++ b/queue-6.6/soc-qcom-pmic_glink-fix-connector-type-to-be-display.patch @@ -0,0 +1,44 @@ +From 85d52d202212019ca47e23840c9ba0135960e4a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 01:52:29 +0300 +Subject: soc: qcom: pmic_glink: fix connector type to be DisplayPort + +From: Dmitry Baryshkov + +[ Upstream commit f86955f2b1ff9fbc7ae4f6595112b2f896885366 ] + +As it was pointed out by Simon Ser, the DRM_MODE_CONNECTOR_USB connector +is reserved for the GUD devices. Other drivers (i915, amdgpu) use +DRM_MODE_CONNECTOR_DisplayPort even if the DP stream is handled by the +USB-C altmode. While we are still working on implementing the proper way +to let userspace know that the DP is wrapped into USB-C, change +connector type to be DRM_MODE_CONNECTOR_DisplayPort. + +Fixes: 080b4e24852b ("soc: qcom: pmic_glink: Introduce altmode support") +Cc: Simon Ser +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Neil Armstrong +Acked-by: Simon Ser +Link: https://lore.kernel.org/r/20231010225229.77027-1-dmitry.baryshkov@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/soc/qcom/pmic_glink_altmode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/soc/qcom/pmic_glink_altmode.c b/drivers/soc/qcom/pmic_glink_altmode.c +index d05e0d6edf493..974c14d1e0bfc 100644 +--- a/drivers/soc/qcom/pmic_glink_altmode.c ++++ b/drivers/soc/qcom/pmic_glink_altmode.c +@@ -465,7 +465,7 @@ static int pmic_glink_altmode_probe(struct auxiliary_device *adev, + alt_port->bridge.funcs = &pmic_glink_altmode_bridge_funcs; + alt_port->bridge.of_node = to_of_node(fwnode); + alt_port->bridge.ops = DRM_BRIDGE_OP_HPD; +- alt_port->bridge.type = DRM_MODE_CONNECTOR_USB; ++ alt_port->bridge.type = DRM_MODE_CONNECTOR_DisplayPort; + + ret = devm_drm_bridge_add(dev, &alt_port->bridge); + if (ret) +-- +2.42.0 + diff --git a/queue-6.6/spi-nxp-fspi-use-the-correct-ioremap-function.patch b/queue-6.6/spi-nxp-fspi-use-the-correct-ioremap-function.patch new file mode 100644 index 00000000000..f6c936ad803 --- /dev/null +++ b/queue-6.6/spi-nxp-fspi-use-the-correct-ioremap-function.patch @@ -0,0 +1,38 @@ +From 5cdbf499864ec3efb6106bc2bc24c02770edf4a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 15:15:24 -0500 +Subject: spi: nxp-fspi: use the correct ioremap function + +From: Han Xu + +[ Upstream commit c3aa5cb264a38ae9bbcce32abca4c155af0456df ] + +AHB memory as MMIO should be mapped with ioremap rather than ioremap_wc, +which should have been used initially just to handle unaligned access as +a workaround. + +Fixes: d166a73503ef ("spi: fspi: dynamically alloc AHB memory") +Signed-off-by: Han Xu +Link: https://lore.kernel.org/r/20231010201524.2021340-1-han.xu@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-nxp-fspi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c +index c964f41dcc428..168eff721ed37 100644 +--- a/drivers/spi/spi-nxp-fspi.c ++++ b/drivers/spi/spi-nxp-fspi.c +@@ -759,7 +759,7 @@ static int nxp_fspi_read_ahb(struct nxp_fspi *f, const struct spi_mem_op *op) + f->memmap_len = len > NXP_FSPI_MIN_IOMAP ? + len : NXP_FSPI_MIN_IOMAP; + +- f->ahb_addr = ioremap_wc(f->memmap_phy + f->memmap_start, ++ f->ahb_addr = ioremap(f->memmap_phy + f->memmap_start, + f->memmap_len); + + if (!f->ahb_addr) { +-- +2.42.0 + diff --git a/queue-6.6/spi-omap2-mcspi-fix-hardcoded-reference-clock.patch b/queue-6.6/spi-omap2-mcspi-fix-hardcoded-reference-clock.patch new file mode 100644 index 00000000000..f36707ba72f --- /dev/null +++ b/queue-6.6/spi-omap2-mcspi-fix-hardcoded-reference-clock.patch @@ -0,0 +1,118 @@ +From 718c83adbdc09afd93e4c5279d9bbe5b0e3bb45b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Sep 2023 17:08:12 +0530 +Subject: spi: omap2-mcspi: Fix hardcoded reference clock + +From: Vaishnav Achath + +[ Upstream commit 2d9f4877988f64f0f336983de65c365b6a7debfb ] + +A hardcoded reference clock of 48 MHz is used to calculate the +clock divisor values, but the reference clock frequency can be +different across devices and can be configured which can cause +a mismatch between the reported frequency and actual SPI clock +frequency observed. Fix this by fetching the clock rate from +the clock provider and falling back to hardcoded reference only +if the clock is not supplied. + +Fixes: 2cd7d393f461 ("arm64: dts: ti: k3-am654: Add McSPI DT nodes") + +Signed-off-by: Vaishnav Achath +Reviewed-by: Dhruva Gole +Link: https://lore.kernel.org/r/20230926113812.30692-1-vaishnav.a@ti.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-omap2-mcspi.c | 31 ++++++++++++++++++++----------- + 1 file changed, 20 insertions(+), 11 deletions(-) + +diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c +index 79888e6c54c25..ddf1c684bcc7d 100644 +--- a/drivers/spi/spi-omap2-mcspi.c ++++ b/drivers/spi/spi-omap2-mcspi.c +@@ -125,10 +125,12 @@ struct omap2_mcspi { + struct omap2_mcspi_dma *dma_channels; + struct device *dev; + struct omap2_mcspi_regs ctx; ++ struct clk *ref_clk; + int fifo_depth; + bool target_aborted; + unsigned int pin_dir:1; + size_t max_xfer_len; ++ u32 ref_clk_hz; + }; + + struct omap2_mcspi_cs { +@@ -880,12 +882,12 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) + return count - c; + } + +-static u32 omap2_mcspi_calc_divisor(u32 speed_hz) ++static u32 omap2_mcspi_calc_divisor(u32 speed_hz, u32 ref_clk_hz) + { + u32 div; + + for (div = 0; div < 15; div++) +- if (speed_hz >= (OMAP2_MCSPI_MAX_FREQ >> div)) ++ if (speed_hz >= (ref_clk_hz >> div)) + return div; + + return 15; +@@ -897,7 +899,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, + { + struct omap2_mcspi_cs *cs = spi->controller_state; + struct omap2_mcspi *mcspi; +- u32 l = 0, clkd = 0, div, extclk = 0, clkg = 0; ++ u32 ref_clk_hz, l = 0, clkd = 0, div, extclk = 0, clkg = 0; + u8 word_len = spi->bits_per_word; + u32 speed_hz = spi->max_speed_hz; + +@@ -911,14 +913,15 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, + if (t && t->speed_hz) + speed_hz = t->speed_hz; + +- speed_hz = min_t(u32, speed_hz, OMAP2_MCSPI_MAX_FREQ); +- if (speed_hz < (OMAP2_MCSPI_MAX_FREQ / OMAP2_MCSPI_MAX_DIVIDER)) { +- clkd = omap2_mcspi_calc_divisor(speed_hz); +- speed_hz = OMAP2_MCSPI_MAX_FREQ >> clkd; ++ ref_clk_hz = mcspi->ref_clk_hz; ++ speed_hz = min_t(u32, speed_hz, ref_clk_hz); ++ if (speed_hz < (ref_clk_hz / OMAP2_MCSPI_MAX_DIVIDER)) { ++ clkd = omap2_mcspi_calc_divisor(speed_hz, ref_clk_hz); ++ speed_hz = ref_clk_hz >> clkd; + clkg = 0; + } else { +- div = (OMAP2_MCSPI_MAX_FREQ + speed_hz - 1) / speed_hz; +- speed_hz = OMAP2_MCSPI_MAX_FREQ / div; ++ div = (ref_clk_hz + speed_hz - 1) / speed_hz; ++ speed_hz = ref_clk_hz / div; + clkd = (div - 1) & 0xf; + extclk = (div - 1) >> 4; + clkg = OMAP2_MCSPI_CHCONF_CLKG; +@@ -1448,8 +1451,6 @@ static int omap2_mcspi_probe(struct platform_device *pdev) + ctlr->cleanup = omap2_mcspi_cleanup; + ctlr->target_abort = omap2_mcspi_target_abort; + ctlr->dev.of_node = node; +- ctlr->max_speed_hz = OMAP2_MCSPI_MAX_FREQ; +- ctlr->min_speed_hz = OMAP2_MCSPI_MAX_FREQ >> 15; + ctlr->use_gpio_descriptors = true; + + platform_set_drvdata(pdev, ctlr); +@@ -1519,6 +1520,14 @@ static int omap2_mcspi_probe(struct platform_device *pdev) + goto free_ctlr; + } + ++ mcspi->ref_clk = devm_clk_get_optional_enabled(&pdev->dev, NULL); ++ if (mcspi->ref_clk) ++ mcspi->ref_clk_hz = clk_get_rate(mcspi->ref_clk); ++ else ++ mcspi->ref_clk_hz = OMAP2_MCSPI_MAX_FREQ; ++ ctlr->max_speed_hz = mcspi->ref_clk_hz; ++ ctlr->min_speed_hz = mcspi->ref_clk_hz >> 15; ++ + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); + pm_runtime_enable(&pdev->dev); +-- +2.42.0 + diff --git a/queue-6.6/spi-omap2-mcspi-switch-to-use-modern-name.patch b/queue-6.6/spi-omap2-mcspi-switch-to-use-modern-name.patch new file mode 100644 index 00000000000..3f0aea82c80 --- /dev/null +++ b/queue-6.6/spi-omap2-mcspi-switch-to-use-modern-name.patch @@ -0,0 +1,707 @@ +From f90d9e7e60a229e37e6782903e0960dd98588b0b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Aug 2023 11:30:03 +0800 +Subject: spi: omap2-mcspi: switch to use modern name + +From: Yang Yingliang + +[ Upstream commit ee0f793cc1881225dee04216f1080201603b46bb ] + +Change legacy name master/slave to modern name host/target or controller. + +No functional changed. + +Signed-off-by: Yang Yingliang +Link: https://lore.kernel.org/r/20230823033003.3407403-22-yangyingliang@huawei.com +Signed-off-by: Mark Brown +Stable-dep-of: 2d9f4877988f ("spi: omap2-mcspi: Fix hardcoded reference clock") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-omap2-mcspi.c | 236 +++++++++++++++++----------------- + 1 file changed, 118 insertions(+), 118 deletions(-) + +diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c +index e5cd82eb9e549..79888e6c54c25 100644 +--- a/drivers/spi/spi-omap2-mcspi.c ++++ b/drivers/spi/spi-omap2-mcspi.c +@@ -117,7 +117,7 @@ struct omap2_mcspi_regs { + + struct omap2_mcspi { + struct completion txdone; +- struct spi_master *master; ++ struct spi_controller *ctlr; + /* Virtual base address of the controller */ + void __iomem *base; + unsigned long phys; +@@ -126,7 +126,7 @@ struct omap2_mcspi { + struct device *dev; + struct omap2_mcspi_regs ctx; + int fifo_depth; +- bool slave_aborted; ++ bool target_aborted; + unsigned int pin_dir:1; + size_t max_xfer_len; + }; +@@ -141,17 +141,17 @@ struct omap2_mcspi_cs { + u32 chconf0, chctrl0; + }; + +-static inline void mcspi_write_reg(struct spi_master *master, ++static inline void mcspi_write_reg(struct spi_controller *ctlr, + int idx, u32 val) + { +- struct omap2_mcspi *mcspi = spi_master_get_devdata(master); ++ struct omap2_mcspi *mcspi = spi_controller_get_devdata(ctlr); + + writel_relaxed(val, mcspi->base + idx); + } + +-static inline u32 mcspi_read_reg(struct spi_master *master, int idx) ++static inline u32 mcspi_read_reg(struct spi_controller *ctlr, int idx) + { +- struct omap2_mcspi *mcspi = spi_master_get_devdata(master); ++ struct omap2_mcspi *mcspi = spi_controller_get_devdata(ctlr); + + return readl_relaxed(mcspi->base + idx); + } +@@ -235,7 +235,7 @@ static void omap2_mcspi_set_enable(const struct spi_device *spi, int enable) + + static void omap2_mcspi_set_cs(struct spi_device *spi, bool enable) + { +- struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master); ++ struct omap2_mcspi *mcspi = spi_controller_get_devdata(spi->controller); + u32 l; + + /* The controller handles the inverted chip selects +@@ -266,24 +266,24 @@ static void omap2_mcspi_set_cs(struct spi_device *spi, bool enable) + } + } + +-static void omap2_mcspi_set_mode(struct spi_master *master) ++static void omap2_mcspi_set_mode(struct spi_controller *ctlr) + { +- struct omap2_mcspi *mcspi = spi_master_get_devdata(master); ++ struct omap2_mcspi *mcspi = spi_controller_get_devdata(ctlr); + struct omap2_mcspi_regs *ctx = &mcspi->ctx; + u32 l; + + /* +- * Choose master or slave mode ++ * Choose host or target mode + */ +- l = mcspi_read_reg(master, OMAP2_MCSPI_MODULCTRL); ++ l = mcspi_read_reg(ctlr, OMAP2_MCSPI_MODULCTRL); + l &= ~(OMAP2_MCSPI_MODULCTRL_STEST); +- if (spi_controller_is_slave(master)) { ++ if (spi_controller_is_target(ctlr)) { + l |= (OMAP2_MCSPI_MODULCTRL_MS); + } else { + l &= ~(OMAP2_MCSPI_MODULCTRL_MS); + l |= OMAP2_MCSPI_MODULCTRL_SINGLE; + } +- mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l); ++ mcspi_write_reg(ctlr, OMAP2_MCSPI_MODULCTRL, l); + + ctx->modulctrl = l; + } +@@ -291,14 +291,14 @@ static void omap2_mcspi_set_mode(struct spi_master *master) + static void omap2_mcspi_set_fifo(const struct spi_device *spi, + struct spi_transfer *t, int enable) + { +- struct spi_master *master = spi->master; ++ struct spi_controller *ctlr = spi->controller; + struct omap2_mcspi_cs *cs = spi->controller_state; + struct omap2_mcspi *mcspi; + unsigned int wcnt; + int max_fifo_depth, bytes_per_word; + u32 chconf, xferlevel; + +- mcspi = spi_master_get_devdata(master); ++ mcspi = spi_controller_get_devdata(ctlr); + + chconf = mcspi_cached_chconf0(spi); + if (enable) { +@@ -326,7 +326,7 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi, + xferlevel |= bytes_per_word - 1; + } + +- mcspi_write_reg(master, OMAP2_MCSPI_XFERLEVEL, xferlevel); ++ mcspi_write_reg(ctlr, OMAP2_MCSPI_XFERLEVEL, xferlevel); + mcspi_write_chconf0(spi, chconf); + mcspi->fifo_depth = max_fifo_depth; + +@@ -364,9 +364,9 @@ static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit) + static int mcspi_wait_for_completion(struct omap2_mcspi *mcspi, + struct completion *x) + { +- if (spi_controller_is_slave(mcspi->master)) { ++ if (spi_controller_is_target(mcspi->ctlr)) { + if (wait_for_completion_interruptible(x) || +- mcspi->slave_aborted) ++ mcspi->target_aborted) + return -EINTR; + } else { + wait_for_completion(x); +@@ -378,7 +378,7 @@ static int mcspi_wait_for_completion(struct omap2_mcspi *mcspi, + static void omap2_mcspi_rx_callback(void *data) + { + struct spi_device *spi = data; +- struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master); ++ struct omap2_mcspi *mcspi = spi_controller_get_devdata(spi->controller); + struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi_get_chipselect(spi, 0)]; + + /* We must disable the DMA RX request */ +@@ -390,7 +390,7 @@ static void omap2_mcspi_rx_callback(void *data) + static void omap2_mcspi_tx_callback(void *data) + { + struct spi_device *spi = data; +- struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master); ++ struct omap2_mcspi *mcspi = spi_controller_get_devdata(spi->controller); + struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi_get_chipselect(spi, 0)]; + + /* We must disable the DMA TX request */ +@@ -407,7 +407,7 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi, + struct omap2_mcspi_dma *mcspi_dma; + struct dma_async_tx_descriptor *tx; + +- mcspi = spi_master_get_devdata(spi->master); ++ mcspi = spi_controller_get_devdata(spi->controller); + mcspi_dma = &mcspi->dma_channels[spi_get_chipselect(spi, 0)]; + + dmaengine_slave_config(mcspi_dma->dma_tx, &cfg); +@@ -445,13 +445,13 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, + void __iomem *chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0; + struct dma_async_tx_descriptor *tx; + +- mcspi = spi_master_get_devdata(spi->master); ++ mcspi = spi_controller_get_devdata(spi->controller); + mcspi_dma = &mcspi->dma_channels[spi_get_chipselect(spi, 0)]; + count = xfer->len; + + /* + * In the "End-of-Transfer Procedure" section for DMA RX in OMAP35x TRM +- * it mentions reducing DMA transfer length by one element in master ++ * it mentions reducing DMA transfer length by one element in host + * normal mode. + */ + if (mcspi->fifo_depth == 0) +@@ -514,7 +514,7 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, + omap2_mcspi_set_dma_req(spi, 1, 1); + + ret = mcspi_wait_for_completion(mcspi, &mcspi_dma->dma_rx_completion); +- if (ret || mcspi->slave_aborted) { ++ if (ret || mcspi->target_aborted) { + dmaengine_terminate_sync(mcspi_dma->dma_rx); + omap2_mcspi_set_dma_req(spi, 1, 0); + return 0; +@@ -590,7 +590,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) + void __iomem *irqstat_reg; + int wait_res; + +- mcspi = spi_master_get_devdata(spi->master); ++ mcspi = spi_controller_get_devdata(spi->controller); + mcspi_dma = &mcspi->dma_channels[spi_get_chipselect(spi, 0)]; + + if (cs->word_len <= 8) { +@@ -617,14 +617,14 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) + rx = xfer->rx_buf; + tx = xfer->tx_buf; + +- mcspi->slave_aborted = false; ++ mcspi->target_aborted = false; + reinit_completion(&mcspi_dma->dma_tx_completion); + reinit_completion(&mcspi_dma->dma_rx_completion); + reinit_completion(&mcspi->txdone); + if (tx) { +- /* Enable EOW IRQ to know end of tx in slave mode */ +- if (spi_controller_is_slave(spi->master)) +- mcspi_write_reg(spi->master, ++ /* Enable EOW IRQ to know end of tx in target mode */ ++ if (spi_controller_is_target(spi->controller)) ++ mcspi_write_reg(spi->controller, + OMAP2_MCSPI_IRQENABLE, + OMAP2_MCSPI_IRQSTATUS_EOW); + omap2_mcspi_tx_dma(spi, xfer, cfg); +@@ -637,15 +637,15 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) + int ret; + + ret = mcspi_wait_for_completion(mcspi, &mcspi_dma->dma_tx_completion); +- if (ret || mcspi->slave_aborted) { ++ if (ret || mcspi->target_aborted) { + dmaengine_terminate_sync(mcspi_dma->dma_tx); + omap2_mcspi_set_dma_req(spi, 0, 0); + return 0; + } + +- if (spi_controller_is_slave(mcspi->master)) { ++ if (spi_controller_is_target(mcspi->ctlr)) { + ret = mcspi_wait_for_completion(mcspi, &mcspi->txdone); +- if (ret || mcspi->slave_aborted) ++ if (ret || mcspi->target_aborted) + return 0; + } + +@@ -656,7 +656,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) + OMAP2_MCSPI_IRQSTATUS_EOW) < 0) + dev_err(&spi->dev, "EOW timed out\n"); + +- mcspi_write_reg(mcspi->master, OMAP2_MCSPI_IRQSTATUS, ++ mcspi_write_reg(mcspi->ctlr, OMAP2_MCSPI_IRQSTATUS, + OMAP2_MCSPI_IRQSTATUS_EOW); + } + +@@ -901,7 +901,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, + u8 word_len = spi->bits_per_word; + u32 speed_hz = spi->max_speed_hz; + +- mcspi = spi_master_get_devdata(spi->master); ++ mcspi = spi_controller_get_devdata(spi->controller); + + if (t != NULL && t->bits_per_word) + word_len = t->bits_per_word; +@@ -926,7 +926,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, + + l = mcspi_cached_chconf0(spi); + +- /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS ++ /* standard 4-wire host mode: SCK, MOSI/out, MISO/in, nCS + * REVISIT: this controller could support SPI_3WIRE mode. + */ + if (mcspi->pin_dir == MCSPI_PINDIR_D0_IN_D1_OUT) { +@@ -1017,13 +1017,13 @@ static int omap2_mcspi_request_dma(struct omap2_mcspi *mcspi, + return ret; + } + +-static void omap2_mcspi_release_dma(struct spi_master *master) ++static void omap2_mcspi_release_dma(struct spi_controller *ctlr) + { +- struct omap2_mcspi *mcspi = spi_master_get_devdata(master); ++ struct omap2_mcspi *mcspi = spi_controller_get_devdata(ctlr); + struct omap2_mcspi_dma *mcspi_dma; + int i; + +- for (i = 0; i < master->num_chipselect; i++) { ++ for (i = 0; i < ctlr->num_chipselect; i++) { + mcspi_dma = &mcspi->dma_channels[i]; + + if (mcspi_dma->dma_rx) { +@@ -1054,7 +1054,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) + { + bool initial_setup = false; + int ret; +- struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master); ++ struct omap2_mcspi *mcspi = spi_controller_get_devdata(spi->controller); + struct omap2_mcspi_regs *ctx = &mcspi->ctx; + struct omap2_mcspi_cs *cs = spi->controller_state; + +@@ -1096,24 +1096,24 @@ static irqreturn_t omap2_mcspi_irq_handler(int irq, void *data) + struct omap2_mcspi *mcspi = data; + u32 irqstat; + +- irqstat = mcspi_read_reg(mcspi->master, OMAP2_MCSPI_IRQSTATUS); ++ irqstat = mcspi_read_reg(mcspi->ctlr, OMAP2_MCSPI_IRQSTATUS); + if (!irqstat) + return IRQ_NONE; + +- /* Disable IRQ and wakeup slave xfer task */ +- mcspi_write_reg(mcspi->master, OMAP2_MCSPI_IRQENABLE, 0); ++ /* Disable IRQ and wakeup target xfer task */ ++ mcspi_write_reg(mcspi->ctlr, OMAP2_MCSPI_IRQENABLE, 0); + if (irqstat & OMAP2_MCSPI_IRQSTATUS_EOW) + complete(&mcspi->txdone); + + return IRQ_HANDLED; + } + +-static int omap2_mcspi_slave_abort(struct spi_master *master) ++static int omap2_mcspi_target_abort(struct spi_controller *ctlr) + { +- struct omap2_mcspi *mcspi = spi_master_get_devdata(master); ++ struct omap2_mcspi *mcspi = spi_controller_get_devdata(ctlr); + struct omap2_mcspi_dma *mcspi_dma = mcspi->dma_channels; + +- mcspi->slave_aborted = true; ++ mcspi->target_aborted = true; + complete(&mcspi_dma->dma_rx_completion); + complete(&mcspi_dma->dma_tx_completion); + complete(&mcspi->txdone); +@@ -1121,7 +1121,7 @@ static int omap2_mcspi_slave_abort(struct spi_master *master) + return 0; + } + +-static int omap2_mcspi_transfer_one(struct spi_master *master, ++static int omap2_mcspi_transfer_one(struct spi_controller *ctlr, + struct spi_device *spi, + struct spi_transfer *t) + { +@@ -1129,7 +1129,7 @@ static int omap2_mcspi_transfer_one(struct spi_master *master, + /* We only enable one channel at a time -- the one whose message is + * -- although this controller would gladly + * arbitrate among multiple channels. This corresponds to "single +- * channel" master mode. As a side effect, we need to manage the ++ * channel" host mode. As a side effect, we need to manage the + * chipselect with the FORCE bit ... CS != channel enable. + */ + +@@ -1141,13 +1141,13 @@ static int omap2_mcspi_transfer_one(struct spi_master *master, + int status = 0; + u32 chconf; + +- mcspi = spi_master_get_devdata(master); ++ mcspi = spi_controller_get_devdata(ctlr); + mcspi_dma = mcspi->dma_channels + spi_get_chipselect(spi, 0); + cs = spi->controller_state; + cd = spi->controller_data; + + /* +- * The slave driver could have changed spi->mode in which case ++ * The target driver could have changed spi->mode in which case + * it will be different from cs->mode (the current hardware setup). + * If so, set par_override (even though its not a parity issue) so + * omap2_mcspi_setup_transfer will be called to configure the hardware +@@ -1175,7 +1175,7 @@ static int omap2_mcspi_transfer_one(struct spi_master *master, + if (cd && cd->cs_per_word) { + chconf = mcspi->ctx.modulctrl; + chconf &= ~OMAP2_MCSPI_MODULCTRL_SINGLE; +- mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, chconf); ++ mcspi_write_reg(ctlr, OMAP2_MCSPI_MODULCTRL, chconf); + mcspi->ctx.modulctrl = + mcspi_read_cs_reg(spi, OMAP2_MCSPI_MODULCTRL); + } +@@ -1201,8 +1201,8 @@ static int omap2_mcspi_transfer_one(struct spi_master *master, + unsigned count; + + if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) && +- master->cur_msg_mapped && +- master->can_dma(master, spi, t)) ++ ctlr->cur_msg_mapped && ++ ctlr->can_dma(ctlr, spi, t)) + omap2_mcspi_set_fifo(spi, t, 1); + + omap2_mcspi_set_enable(spi, 1); +@@ -1213,8 +1213,8 @@ static int omap2_mcspi_transfer_one(struct spi_master *master, + + OMAP2_MCSPI_TX0); + + if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) && +- master->cur_msg_mapped && +- master->can_dma(master, spi, t)) ++ ctlr->cur_msg_mapped && ++ ctlr->can_dma(ctlr, spi, t)) + count = omap2_mcspi_txrx_dma(spi, t); + else + count = omap2_mcspi_txrx_pio(spi, t); +@@ -1240,7 +1240,7 @@ static int omap2_mcspi_transfer_one(struct spi_master *master, + if (cd && cd->cs_per_word) { + chconf = mcspi->ctx.modulctrl; + chconf |= OMAP2_MCSPI_MODULCTRL_SINGLE; +- mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, chconf); ++ mcspi_write_reg(ctlr, OMAP2_MCSPI_MODULCTRL, chconf); + mcspi->ctx.modulctrl = + mcspi_read_cs_reg(spi, OMAP2_MCSPI_MODULCTRL); + } +@@ -1256,10 +1256,10 @@ static int omap2_mcspi_transfer_one(struct spi_master *master, + return status; + } + +-static int omap2_mcspi_prepare_message(struct spi_master *master, ++static int omap2_mcspi_prepare_message(struct spi_controller *ctlr, + struct spi_message *msg) + { +- struct omap2_mcspi *mcspi = spi_master_get_devdata(master); ++ struct omap2_mcspi *mcspi = spi_controller_get_devdata(ctlr); + struct omap2_mcspi_regs *ctx = &mcspi->ctx; + struct omap2_mcspi_cs *cs; + +@@ -1283,29 +1283,29 @@ static int omap2_mcspi_prepare_message(struct spi_master *master, + return 0; + } + +-static bool omap2_mcspi_can_dma(struct spi_master *master, ++static bool omap2_mcspi_can_dma(struct spi_controller *ctlr, + struct spi_device *spi, + struct spi_transfer *xfer) + { +- struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master); ++ struct omap2_mcspi *mcspi = spi_controller_get_devdata(spi->controller); + struct omap2_mcspi_dma *mcspi_dma = + &mcspi->dma_channels[spi_get_chipselect(spi, 0)]; + + if (!mcspi_dma->dma_rx || !mcspi_dma->dma_tx) + return false; + +- if (spi_controller_is_slave(master)) ++ if (spi_controller_is_target(ctlr)) + return true; + +- master->dma_rx = mcspi_dma->dma_rx; +- master->dma_tx = mcspi_dma->dma_tx; ++ ctlr->dma_rx = mcspi_dma->dma_rx; ++ ctlr->dma_tx = mcspi_dma->dma_tx; + + return (xfer->len >= DMA_MIN_BYTES); + } + + static size_t omap2_mcspi_max_xfer_size(struct spi_device *spi) + { +- struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master); ++ struct omap2_mcspi *mcspi = spi_controller_get_devdata(spi->controller); + struct omap2_mcspi_dma *mcspi_dma = + &mcspi->dma_channels[spi_get_chipselect(spi, 0)]; + +@@ -1317,7 +1317,7 @@ static size_t omap2_mcspi_max_xfer_size(struct spi_device *spi) + + static int omap2_mcspi_controller_setup(struct omap2_mcspi *mcspi) + { +- struct spi_master *master = mcspi->master; ++ struct spi_controller *ctlr = mcspi->ctlr; + struct omap2_mcspi_regs *ctx = &mcspi->ctx; + int ret = 0; + +@@ -1325,11 +1325,11 @@ static int omap2_mcspi_controller_setup(struct omap2_mcspi *mcspi) + if (ret < 0) + return ret; + +- mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, ++ mcspi_write_reg(ctlr, OMAP2_MCSPI_WAKEUPENABLE, + OMAP2_MCSPI_WAKEUPENABLE_WKEN); + ctx->wakeupenable = OMAP2_MCSPI_WAKEUPENABLE_WKEN; + +- omap2_mcspi_set_mode(master); ++ omap2_mcspi_set_mode(ctlr); + pm_runtime_mark_last_busy(mcspi->dev); + pm_runtime_put_autosuspend(mcspi->dev); + return 0; +@@ -1353,8 +1353,8 @@ static int omap_mcspi_runtime_suspend(struct device *dev) + */ + static int omap_mcspi_runtime_resume(struct device *dev) + { +- struct spi_master *master = dev_get_drvdata(dev); +- struct omap2_mcspi *mcspi = spi_master_get_devdata(master); ++ struct spi_controller *ctlr = dev_get_drvdata(dev); ++ struct omap2_mcspi *mcspi = spi_controller_get_devdata(ctlr); + struct omap2_mcspi_regs *ctx = &mcspi->ctx; + struct omap2_mcspi_cs *cs; + int error; +@@ -1364,8 +1364,8 @@ static int omap_mcspi_runtime_resume(struct device *dev) + dev_warn(dev, "%s: failed to set pins: %i\n", __func__, error); + + /* McSPI: context restore */ +- mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, ctx->modulctrl); +- mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, ctx->wakeupenable); ++ mcspi_write_reg(ctlr, OMAP2_MCSPI_MODULCTRL, ctx->modulctrl); ++ mcspi_write_reg(ctlr, OMAP2_MCSPI_WAKEUPENABLE, ctx->wakeupenable); + + list_for_each_entry(cs, &ctx->cs, node) { + /* +@@ -1420,7 +1420,7 @@ MODULE_DEVICE_TABLE(of, omap_mcspi_of_match); + + static int omap2_mcspi_probe(struct platform_device *pdev) + { +- struct spi_master *master; ++ struct spi_controller *ctlr; + const struct omap2_mcspi_platform_config *pdata; + struct omap2_mcspi *mcspi; + struct resource *r; +@@ -1430,32 +1430,32 @@ static int omap2_mcspi_probe(struct platform_device *pdev) + const struct of_device_id *match; + + if (of_property_read_bool(node, "spi-slave")) +- master = spi_alloc_slave(&pdev->dev, sizeof(*mcspi)); ++ ctlr = spi_alloc_target(&pdev->dev, sizeof(*mcspi)); + else +- master = spi_alloc_master(&pdev->dev, sizeof(*mcspi)); +- if (!master) ++ ctlr = spi_alloc_host(&pdev->dev, sizeof(*mcspi)); ++ if (!ctlr) + return -ENOMEM; + + /* the spi->mode bits understood by this driver: */ +- master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; +- master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); +- master->setup = omap2_mcspi_setup; +- master->auto_runtime_pm = true; +- master->prepare_message = omap2_mcspi_prepare_message; +- master->can_dma = omap2_mcspi_can_dma; +- master->transfer_one = omap2_mcspi_transfer_one; +- master->set_cs = omap2_mcspi_set_cs; +- master->cleanup = omap2_mcspi_cleanup; +- master->slave_abort = omap2_mcspi_slave_abort; +- master->dev.of_node = node; +- master->max_speed_hz = OMAP2_MCSPI_MAX_FREQ; +- master->min_speed_hz = OMAP2_MCSPI_MAX_FREQ >> 15; +- master->use_gpio_descriptors = true; +- +- platform_set_drvdata(pdev, master); +- +- mcspi = spi_master_get_devdata(master); +- mcspi->master = master; ++ ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; ++ ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); ++ ctlr->setup = omap2_mcspi_setup; ++ ctlr->auto_runtime_pm = true; ++ ctlr->prepare_message = omap2_mcspi_prepare_message; ++ ctlr->can_dma = omap2_mcspi_can_dma; ++ ctlr->transfer_one = omap2_mcspi_transfer_one; ++ ctlr->set_cs = omap2_mcspi_set_cs; ++ ctlr->cleanup = omap2_mcspi_cleanup; ++ ctlr->target_abort = omap2_mcspi_target_abort; ++ ctlr->dev.of_node = node; ++ ctlr->max_speed_hz = OMAP2_MCSPI_MAX_FREQ; ++ ctlr->min_speed_hz = OMAP2_MCSPI_MAX_FREQ >> 15; ++ ctlr->use_gpio_descriptors = true; ++ ++ platform_set_drvdata(pdev, ctlr); ++ ++ mcspi = spi_controller_get_devdata(ctlr); ++ mcspi->ctlr = ctlr; + + match = of_match_device(omap_mcspi_of_match, &pdev->dev); + if (match) { +@@ -1463,24 +1463,24 @@ static int omap2_mcspi_probe(struct platform_device *pdev) + pdata = match->data; + + of_property_read_u32(node, "ti,spi-num-cs", &num_cs); +- master->num_chipselect = num_cs; ++ ctlr->num_chipselect = num_cs; + if (of_property_read_bool(node, "ti,pindir-d0-out-d1-in")) + mcspi->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN; + } else { + pdata = dev_get_platdata(&pdev->dev); +- master->num_chipselect = pdata->num_cs; ++ ctlr->num_chipselect = pdata->num_cs; + mcspi->pin_dir = pdata->pin_dir; + } + regs_offset = pdata->regs_offset; + if (pdata->max_xfer_len) { + mcspi->max_xfer_len = pdata->max_xfer_len; +- master->max_transfer_size = omap2_mcspi_max_xfer_size; ++ ctlr->max_transfer_size = omap2_mcspi_max_xfer_size; + } + + mcspi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &r); + if (IS_ERR(mcspi->base)) { + status = PTR_ERR(mcspi->base); +- goto free_master; ++ goto free_ctlr; + } + mcspi->phys = r->start + regs_offset; + mcspi->base += regs_offset; +@@ -1489,34 +1489,34 @@ static int omap2_mcspi_probe(struct platform_device *pdev) + + INIT_LIST_HEAD(&mcspi->ctx.cs); + +- mcspi->dma_channels = devm_kcalloc(&pdev->dev, master->num_chipselect, ++ mcspi->dma_channels = devm_kcalloc(&pdev->dev, ctlr->num_chipselect, + sizeof(struct omap2_mcspi_dma), + GFP_KERNEL); + if (mcspi->dma_channels == NULL) { + status = -ENOMEM; +- goto free_master; ++ goto free_ctlr; + } + +- for (i = 0; i < master->num_chipselect; i++) { ++ for (i = 0; i < ctlr->num_chipselect; i++) { + sprintf(mcspi->dma_channels[i].dma_rx_ch_name, "rx%d", i); + sprintf(mcspi->dma_channels[i].dma_tx_ch_name, "tx%d", i); + + status = omap2_mcspi_request_dma(mcspi, + &mcspi->dma_channels[i]); + if (status == -EPROBE_DEFER) +- goto free_master; ++ goto free_ctlr; + } + + status = platform_get_irq(pdev, 0); + if (status < 0) +- goto free_master; ++ goto free_ctlr; + init_completion(&mcspi->txdone); + status = devm_request_irq(&pdev->dev, status, + omap2_mcspi_irq_handler, 0, pdev->name, + mcspi); + if (status) { + dev_err(&pdev->dev, "Cannot request IRQ"); +- goto free_master; ++ goto free_ctlr; + } + + pm_runtime_use_autosuspend(&pdev->dev); +@@ -1527,7 +1527,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev) + if (status < 0) + goto disable_pm; + +- status = devm_spi_register_controller(&pdev->dev, master); ++ status = devm_spi_register_controller(&pdev->dev, ctlr); + if (status < 0) + goto disable_pm; + +@@ -1537,18 +1537,18 @@ static int omap2_mcspi_probe(struct platform_device *pdev) + pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); +-free_master: +- omap2_mcspi_release_dma(master); +- spi_master_put(master); ++free_ctlr: ++ omap2_mcspi_release_dma(ctlr); ++ spi_controller_put(ctlr); + return status; + } + + static void omap2_mcspi_remove(struct platform_device *pdev) + { +- struct spi_master *master = platform_get_drvdata(pdev); +- struct omap2_mcspi *mcspi = spi_master_get_devdata(master); ++ struct spi_controller *ctlr = platform_get_drvdata(pdev); ++ struct omap2_mcspi *mcspi = spi_controller_get_devdata(ctlr); + +- omap2_mcspi_release_dma(master); ++ omap2_mcspi_release_dma(ctlr); + + pm_runtime_dont_use_autosuspend(mcspi->dev); + pm_runtime_put_sync(mcspi->dev); +@@ -1560,8 +1560,8 @@ MODULE_ALIAS("platform:omap2_mcspi"); + + static int __maybe_unused omap2_mcspi_suspend(struct device *dev) + { +- struct spi_master *master = dev_get_drvdata(dev); +- struct omap2_mcspi *mcspi = spi_master_get_devdata(master); ++ struct spi_controller *ctlr = dev_get_drvdata(dev); ++ struct omap2_mcspi *mcspi = spi_controller_get_devdata(ctlr); + int error; + + error = pinctrl_pm_select_sleep_state(dev); +@@ -1569,9 +1569,9 @@ static int __maybe_unused omap2_mcspi_suspend(struct device *dev) + dev_warn(mcspi->dev, "%s: failed to set pins: %i\n", + __func__, error); + +- error = spi_master_suspend(master); ++ error = spi_controller_suspend(ctlr); + if (error) +- dev_warn(mcspi->dev, "%s: master suspend failed: %i\n", ++ dev_warn(mcspi->dev, "%s: controller suspend failed: %i\n", + __func__, error); + + return pm_runtime_force_suspend(dev); +@@ -1579,13 +1579,13 @@ static int __maybe_unused omap2_mcspi_suspend(struct device *dev) + + static int __maybe_unused omap2_mcspi_resume(struct device *dev) + { +- struct spi_master *master = dev_get_drvdata(dev); +- struct omap2_mcspi *mcspi = spi_master_get_devdata(master); ++ struct spi_controller *ctlr = dev_get_drvdata(dev); ++ struct omap2_mcspi *mcspi = spi_controller_get_devdata(ctlr); + int error; + +- error = spi_master_resume(master); ++ error = spi_controller_resume(ctlr); + if (error) +- dev_warn(mcspi->dev, "%s: master resume failed: %i\n", ++ dev_warn(mcspi->dev, "%s: controller resume failed: %i\n", + __func__, error); + + return pm_runtime_force_resume(dev); +-- +2.42.0 + diff --git a/queue-6.6/spi-tegra-fix-missing-irq-check-in-tegra_slink_probe.patch b/queue-6.6/spi-tegra-fix-missing-irq-check-in-tegra_slink_probe.patch new file mode 100644 index 00000000000..9d334ecd53c --- /dev/null +++ b/queue-6.6/spi-tegra-fix-missing-irq-check-in-tegra_slink_probe.patch @@ -0,0 +1,41 @@ +From dc2c9357496c4246aa9d13130496c5cff2b285be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Aug 2023 18:02:54 +0800 +Subject: spi: tegra: Fix missing IRQ check in tegra_slink_probe() + +From: Zhang Shurong + +[ Upstream commit eb9913b511f10968a02cfa5329a896855dd152a3 ] + +This func misses checking for platform_get_irq()'s call and may passes the +negative error codes to request_irq(), which takes unsigned IRQ #, +causing it to fail with -EINVAL, overriding an original error code. + +Fix this by stop calling request_irq() with invalid IRQ #s. + +Fixes: dc4dc3605639 ("spi: tegra: add spi driver for SLINK controller") +Signed-off-by: Zhang Shurong +Reviewed-by: Helen Koike +Link: https://lore.kernel.org/r/tencent_73FCC06A3D1C14EE5175253C6FB46A07B709@qq.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-tegra20-slink.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c +index 4d6db6182c5ed..f5cd365c913a8 100644 +--- a/drivers/spi/spi-tegra20-slink.c ++++ b/drivers/spi/spi-tegra20-slink.c +@@ -1086,6 +1086,8 @@ static int tegra_slink_probe(struct platform_device *pdev) + reset_control_deassert(tspi->rst); + + spi_irq = platform_get_irq(pdev, 0); ++ if (spi_irq < 0) ++ return spi_irq; + tspi->irq = spi_irq; + ret = request_threaded_irq(tspi->irq, tegra_slink_isr, + tegra_slink_isr_thread, IRQF_ONESHOT, +-- +2.42.0 + diff --git a/queue-6.6/srcu-fix-callbacks-acceleration-mishandling.patch b/queue-6.6/srcu-fix-callbacks-acceleration-mishandling.patch new file mode 100644 index 00000000000..532f2596daa --- /dev/null +++ b/queue-6.6/srcu-fix-callbacks-acceleration-mishandling.patch @@ -0,0 +1,157 @@ +From f0e1cfeed2c386c7e325b2a55e4bce7bdfc25290 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 01:28:59 +0200 +Subject: srcu: Fix callbacks acceleration mishandling + +From: Frederic Weisbecker + +[ Upstream commit 4a8e65b0c348e42107c64381e692e282900be361 ] + +SRCU callbacks acceleration might fail if the preceding callbacks +advance also fails. This can happen when the following steps are met: + +1) The RCU_WAIT_TAIL segment has callbacks (say for gp_num 8) and the + RCU_NEXT_READY_TAIL also has callbacks (say for gp_num 12). + +2) The grace period for RCU_WAIT_TAIL is observed as started but not yet + completed so rcu_seq_current() returns 4 + SRCU_STATE_SCAN1 = 5. + +3) This value is passed to rcu_segcblist_advance() which can't move + any segment forward and fails. + +4) srcu_gp_start_if_needed() still proceeds with callback acceleration. + But then the call to rcu_seq_snap() observes the grace period for the + RCU_WAIT_TAIL segment (gp_num 8) as completed and the subsequent one + for the RCU_NEXT_READY_TAIL segment as started + (ie: 8 + SRCU_STATE_SCAN1 = 9) so it returns a snapshot of the + next grace period, which is 16. + +5) The value of 16 is passed to rcu_segcblist_accelerate() but the + freshly enqueued callback in RCU_NEXT_TAIL can't move to + RCU_NEXT_READY_TAIL which already has callbacks for a previous grace + period (gp_num = 12). So acceleration fails. + +6) Note in all these steps, srcu_invoke_callbacks() hadn't had a chance + to run srcu_invoke_callbacks(). + +Then some very bad outcome may happen if the following happens: + +7) Some other CPU races and starts the grace period number 16 before the + CPU handling previous steps had a chance. Therefore srcu_gp_start() + isn't called on the latter sdp to fix the acceleration leak from + previous steps with a new pair of call to advance/accelerate. + +8) The grace period 16 completes and srcu_invoke_callbacks() is finally + called. All the callbacks from previous grace periods (8 and 12) are + correctly advanced and executed but callbacks in RCU_NEXT_READY_TAIL + still remain. Then rcu_segcblist_accelerate() is called with a + snaphot of 20. + +9) Since nothing started the grace period number 20, callbacks stay + unhandled. + +This has been reported in real load: + + [3144162.608392] INFO: task kworker/136:12:252684 blocked for more + than 122 seconds. + [3144162.615986] Tainted: G O K 5.4.203-1-tlinux4-0011.1 #1 + [3144162.623053] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" + disables this message. + [3144162.631162] kworker/136:12 D 0 252684 2 0x90004000 + [3144162.631189] Workqueue: kvm-irqfd-cleanup irqfd_shutdown [kvm] + [3144162.631192] Call Trace: + [3144162.631202] __schedule+0x2ee/0x660 + [3144162.631206] schedule+0x33/0xa0 + [3144162.631209] schedule_timeout+0x1c4/0x340 + [3144162.631214] ? update_load_avg+0x82/0x660 + [3144162.631217] ? raw_spin_rq_lock_nested+0x1f/0x30 + [3144162.631218] wait_for_completion+0x119/0x180 + [3144162.631220] ? wake_up_q+0x80/0x80 + [3144162.631224] __synchronize_srcu.part.19+0x81/0xb0 + [3144162.631226] ? __bpf_trace_rcu_utilization+0x10/0x10 + [3144162.631227] synchronize_srcu+0x5f/0xc0 + [3144162.631236] irqfd_shutdown+0x3c/0xb0 [kvm] + [3144162.631239] ? __schedule+0x2f6/0x660 + [3144162.631243] process_one_work+0x19a/0x3a0 + [3144162.631244] worker_thread+0x37/0x3a0 + [3144162.631247] kthread+0x117/0x140 + [3144162.631247] ? process_one_work+0x3a0/0x3a0 + [3144162.631248] ? __kthread_cancel_work+0x40/0x40 + [3144162.631250] ret_from_fork+0x1f/0x30 + +Fix this with taking the snapshot for acceleration _before_ the read +of the current grace period number. + +The only side effect of this solution is that callbacks advancing happen +then _after_ the full barrier in rcu_seq_snap(). This is not a problem +because that barrier only cares about: + +1) Ordering accesses of the update side before call_srcu() so they don't + bleed. +2) See all the accesses prior to the grace period of the current gp_num + +The only things callbacks advancing need to be ordered against are +carried by snp locking. + +Reported-by: Yong He +Co-developed-by:: Yong He +Signed-off-by: Yong He +Co-developed-by: Joel Fernandes (Google) +Signed-off-by: Joel Fernandes (Google) +Co-developed-by: Neeraj upadhyay +Signed-off-by: Neeraj upadhyay +Link: http://lore.kernel.org/CANZk6aR+CqZaqmMWrC2eRRPY12qAZnDZLwLnHZbNi=xXMB401g@mail.gmail.com +Fixes: da915ad5cf25 ("srcu: Parallelize callback handling") +Signed-off-by: Frederic Weisbecker +Signed-off-by: Sasha Levin +--- + kernel/rcu/srcutree.c | 31 +++++++++++++++++++++++++++++-- + 1 file changed, 29 insertions(+), 2 deletions(-) + +diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c +index 20d7a238d675a..253ed509b6abb 100644 +--- a/kernel/rcu/srcutree.c ++++ b/kernel/rcu/srcutree.c +@@ -1242,10 +1242,37 @@ static unsigned long srcu_gp_start_if_needed(struct srcu_struct *ssp, + spin_lock_irqsave_sdp_contention(sdp, &flags); + if (rhp) + rcu_segcblist_enqueue(&sdp->srcu_cblist, rhp); ++ /* ++ * The snapshot for acceleration must be taken _before_ the read of the ++ * current gp sequence used for advancing, otherwise advancing may fail ++ * and acceleration may then fail too. ++ * ++ * This could happen if: ++ * ++ * 1) The RCU_WAIT_TAIL segment has callbacks (gp_num = X + 4) and the ++ * RCU_NEXT_READY_TAIL also has callbacks (gp_num = X + 8). ++ * ++ * 2) The grace period for RCU_WAIT_TAIL is seen as started but not ++ * completed so rcu_seq_current() returns X + SRCU_STATE_SCAN1. ++ * ++ * 3) This value is passed to rcu_segcblist_advance() which can't move ++ * any segment forward and fails. ++ * ++ * 4) srcu_gp_start_if_needed() still proceeds with callback acceleration. ++ * But then the call to rcu_seq_snap() observes the grace period for the ++ * RCU_WAIT_TAIL segment as completed and the subsequent one for the ++ * RCU_NEXT_READY_TAIL segment as started (ie: X + 4 + SRCU_STATE_SCAN1) ++ * so it returns a snapshot of the next grace period, which is X + 12. ++ * ++ * 5) The value of X + 12 is passed to rcu_segcblist_accelerate() but the ++ * freshly enqueued callback in RCU_NEXT_TAIL can't move to ++ * RCU_NEXT_READY_TAIL which already has callbacks for a previous grace ++ * period (gp_num = X + 8). So acceleration fails. ++ */ ++ s = rcu_seq_snap(&ssp->srcu_sup->srcu_gp_seq); + rcu_segcblist_advance(&sdp->srcu_cblist, + rcu_seq_current(&ssp->srcu_sup->srcu_gp_seq)); +- s = rcu_seq_snap(&ssp->srcu_sup->srcu_gp_seq); +- (void)rcu_segcblist_accelerate(&sdp->srcu_cblist, s); ++ WARN_ON_ONCE(!rcu_segcblist_accelerate(&sdp->srcu_cblist, s) && rhp); + if (ULONG_CMP_LT(sdp->srcu_gp_seq_needed, s)) { + sdp->srcu_gp_seq_needed = s; + needgp = true; +-- +2.42.0 + diff --git a/queue-6.6/string-adjust-strtomem-logic-to-allow-for-smaller-so.patch b/queue-6.6/string-adjust-strtomem-logic-to-allow-for-smaller-so.patch new file mode 100644 index 00000000000..d92e52ff0f3 --- /dev/null +++ b/queue-6.6/string-adjust-strtomem-logic-to-allow-for-smaller-so.patch @@ -0,0 +1,74 @@ +From 59cf6193560a80110ab2bc7c7233ff96f21894a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Oct 2023 10:53:58 -0700 +Subject: string: Adjust strtomem() logic to allow for smaller sources + +From: Kees Cook + +[ Upstream commit 0e108725f6cc5b3be9e607f89c9fbcbb236367b7 ] + +Arnd noticed we have a case where a shorter source string is being copied +into a destination byte array, but this results in a strnlen() call that +exceeds the size of the source. This is seen with -Wstringop-overread: + +In file included from ../include/linux/uuid.h:11, + from ../include/linux/mod_devicetable.h:14, + from ../include/linux/cpufeature.h:12, + from ../arch/x86/coco/tdx/tdx.c:7: +../arch/x86/coco/tdx/tdx.c: In function 'tdx_panic.constprop': +../include/linux/string.h:284:9: error: 'strnlen' specified bound 64 exceeds source size 60 [-Werror=stringop-overread] + 284 | memcpy_and_pad(dest, _dest_len, src, strnlen(src, _dest_len), pad); \ + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +../arch/x86/coco/tdx/tdx.c:124:9: note: in expansion of macro 'strtomem_pad' + 124 | strtomem_pad(message.str, msg, '\0'); + | ^~~~~~~~~~~~ + +Use the smaller of the two buffer sizes when calling strnlen(). When +src length is unknown (SIZE_MAX), it is adjusted to use dest length, +which is what the original code did. + +Reported-by: Arnd Bergmann +Fixes: dfbafa70bde2 ("string: Introduce strtomem() and strtomem_pad()") +Tested-by: Arnd Bergmann +Cc: Andy Shevchenko +Cc: linux-hardening@vger.kernel.org +Signed-off-by: Kees Cook +Signed-off-by: Sasha Levin +--- + include/linux/string.h | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/include/linux/string.h b/include/linux/string.h +index dbfc66400050f..9e3cb6923b0ef 100644 +--- a/include/linux/string.h ++++ b/include/linux/string.h +@@ -277,10 +277,12 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count, + */ + #define strtomem_pad(dest, src, pad) do { \ + const size_t _dest_len = __builtin_object_size(dest, 1); \ ++ const size_t _src_len = __builtin_object_size(src, 1); \ + \ + BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \ + _dest_len == (size_t)-1); \ +- memcpy_and_pad(dest, _dest_len, src, strnlen(src, _dest_len), pad); \ ++ memcpy_and_pad(dest, _dest_len, src, \ ++ strnlen(src, min(_src_len, _dest_len)), pad); \ + } while (0) + + /** +@@ -298,10 +300,11 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count, + */ + #define strtomem(dest, src) do { \ + const size_t _dest_len = __builtin_object_size(dest, 1); \ ++ const size_t _src_len = __builtin_object_size(src, 1); \ + \ + BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \ + _dest_len == (size_t)-1); \ +- memcpy(dest, src, min(_dest_len, strnlen(src, _dest_len))); \ ++ memcpy(dest, src, strnlen(src, min(_src_len, _dest_len))); \ + } while (0) + + /** +-- +2.42.0 + diff --git a/queue-6.6/tcp-call-tcp_try_undo_recovery-when-an-rtod-tfo-syna.patch b/queue-6.6/tcp-call-tcp_try_undo_recovery-when-an-rtod-tfo-syna.patch new file mode 100644 index 00000000000..7c732be0c7e --- /dev/null +++ b/queue-6.6/tcp-call-tcp_try_undo_recovery-when-an-rtod-tfo-syna.patch @@ -0,0 +1,71 @@ +From 1cd0f47f86493cc3e41f53356818154b3f137712 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 14:36:20 +0000 +Subject: tcp: call tcp_try_undo_recovery when an RTOd TFO SYNACK is ACKed + +From: Aananth V + +[ Upstream commit e326578a21414738de45f77badd332fb00bd0f58 ] + +For passive TCP Fast Open sockets that had SYN/ACK timeout and did not +send more data in SYN_RECV, upon receiving the final ACK in 3WHS, the +congestion state may awkwardly stay in CA_Loss mode unless the CA state +was undone due to TCP timestamp checks. However, if +tcp_rcv_synrecv_state_fastopen() decides not to undo, then we should +enter CA_Open, because at that point we have received an ACK covering +the retransmitted SYNACKs. Currently, the icsk_ca_state is only set to +CA_Open after we receive an ACK for a data-packet. This is because +tcp_ack does not call tcp_fastretrans_alert (and tcp_process_loss) if +!prior_packets + +Note that tcp_process_loss() calls tcp_try_undo_recovery(), so having +tcp_rcv_synrecv_state_fastopen() decide that if we're in CA_Loss we +should call tcp_try_undo_recovery() is consistent with that, and +low risk. + +Fixes: dad8cea7add9 ("tcp: fix TFO SYNACK undo to avoid double-timestamp-undo") +Signed-off-by: Aananth V +Signed-off-by: Neal Cardwell +Signed-off-by: Yuchung Cheng +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp_input.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 804821d6bd4d4..1f9d1d445fb3b 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -6450,22 +6450,23 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, + + static void tcp_rcv_synrecv_state_fastopen(struct sock *sk) + { ++ struct tcp_sock *tp = tcp_sk(sk); + struct request_sock *req; + + /* If we are still handling the SYNACK RTO, see if timestamp ECR allows + * undo. If peer SACKs triggered fast recovery, we can't undo here. + */ +- if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss) +- tcp_try_undo_loss(sk, false); ++ if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss && !tp->packets_out) ++ tcp_try_undo_recovery(sk); + + /* Reset rtx states to prevent spurious retransmits_timed_out() */ +- tcp_sk(sk)->retrans_stamp = 0; ++ tp->retrans_stamp = 0; + inet_csk(sk)->icsk_retransmits = 0; + + /* Once we leave TCP_SYN_RECV or TCP_FIN_WAIT_1, + * we no longer need req so release it. + */ +- req = rcu_dereference_protected(tcp_sk(sk)->fastopen_rsk, ++ req = rcu_dereference_protected(tp->fastopen_rsk, + lockdep_sock_is_held(sk)); + reqsk_fastopen_remove(sk, req, false); + +-- +2.42.0 + diff --git a/queue-6.6/tcp-fix-cookie_init_timestamp-overflows.patch b/queue-6.6/tcp-fix-cookie_init_timestamp-overflows.patch new file mode 100644 index 00000000000..c60230cc566 --- /dev/null +++ b/queue-6.6/tcp-fix-cookie_init_timestamp-overflows.patch @@ -0,0 +1,102 @@ +From bd2d4146d5ffed300e7417f5c13bc5a0dc3f4e8e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 12:57:37 +0000 +Subject: tcp: fix cookie_init_timestamp() overflows + +From: Eric Dumazet + +[ Upstream commit 73ed8e03388d16c12fc577e5c700b58a29045a15 ] + +cookie_init_timestamp() is supposed to return a 64bit timestamp +suitable for both TSval determination and setting of skb->tstamp. + +Unfortunately it uses 32bit fields and overflows after +2^32 * 10^6 nsec (~49 days) of uptime. + +Generated TSval are still correct, but skb->tstamp might be set +far away in the past, potentially confusing other layers. + +tcp_ns_to_ts() is changed to return a full 64bit value, +ts and ts_now variables are changed to u64 type, +and TSMASK is removed in favor of shifts operations. + +While we are at it, change this sequence: + ts >>= TSBITS; + ts--; + ts <<= TSBITS; + ts |= options; +to: + ts -= (1UL << TSBITS); + +Fixes: 9a568de4818d ("tcp: switch TCP TS option (RFC 7323) to 1ms clock") +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/net/tcp.h | 2 +- + net/ipv4/syncookies.c | 20 +++++++------------- + 2 files changed, 8 insertions(+), 14 deletions(-) + +diff --git a/include/net/tcp.h b/include/net/tcp.h +index 4b03ca7cb8a5e..0239e815edf71 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -801,7 +801,7 @@ static inline u32 tcp_time_stamp(const struct tcp_sock *tp) + } + + /* Convert a nsec timestamp into TCP TSval timestamp (ms based currently) */ +-static inline u32 tcp_ns_to_ts(u64 ns) ++static inline u64 tcp_ns_to_ts(u64 ns) + { + return div_u64(ns, NSEC_PER_SEC / TCP_TS_HZ); + } +diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c +index dc478a0574cbe..3b4dafefb4b03 100644 +--- a/net/ipv4/syncookies.c ++++ b/net/ipv4/syncookies.c +@@ -41,7 +41,6 @@ static siphash_aligned_key_t syncookie_secret[2]; + * requested/supported by the syn/synack exchange. + */ + #define TSBITS 6 +-#define TSMASK (((__u32)1 << TSBITS) - 1) + + static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, + u32 count, int c) +@@ -62,27 +61,22 @@ static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, + */ + u64 cookie_init_timestamp(struct request_sock *req, u64 now) + { +- struct inet_request_sock *ireq; +- u32 ts, ts_now = tcp_ns_to_ts(now); ++ const struct inet_request_sock *ireq = inet_rsk(req); ++ u64 ts, ts_now = tcp_ns_to_ts(now); + u32 options = 0; + +- ireq = inet_rsk(req); +- + options = ireq->wscale_ok ? ireq->snd_wscale : TS_OPT_WSCALE_MASK; + if (ireq->sack_ok) + options |= TS_OPT_SACK; + if (ireq->ecn_ok) + options |= TS_OPT_ECN; + +- ts = ts_now & ~TSMASK; ++ ts = (ts_now >> TSBITS) << TSBITS; + ts |= options; +- if (ts > ts_now) { +- ts >>= TSBITS; +- ts--; +- ts <<= TSBITS; +- ts |= options; +- } +- return (u64)ts * (NSEC_PER_SEC / TCP_TS_HZ); ++ if (ts > ts_now) ++ ts -= (1UL << TSBITS); ++ ++ return ts * (NSEC_PER_SEC / TCP_TS_HZ); + } + + +-- +2.42.0 + diff --git a/queue-6.6/tcp_metrics-add-missing-barriers-on-delete.patch b/queue-6.6/tcp_metrics-add-missing-barriers-on-delete.patch new file mode 100644 index 00000000000..f445c399a99 --- /dev/null +++ b/queue-6.6/tcp_metrics-add-missing-barriers-on-delete.patch @@ -0,0 +1,47 @@ +From 516b2fd2af551010c37ff92f6bbee267bcbd2d23 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 22:03:53 +0000 +Subject: tcp_metrics: add missing barriers on delete + +From: Eric Dumazet + +[ Upstream commit cbc3a153222805d65f821e10f4f78b6afce06f86 ] + +When removing an item from RCU protected list, we must prevent +store-tearing, using rcu_assign_pointer() or WRITE_ONCE(). + +Fixes: 04f721c671656 ("tcp_metrics: Rewrite tcp_metrics_flush_all") +Signed-off-by: Eric Dumazet +Reviewed-by: David Ahern +Acked-by: Neal Cardwell +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp_metrics.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c +index c196759f1d3bd..4bfa2fb27de54 100644 +--- a/net/ipv4/tcp_metrics.c ++++ b/net/ipv4/tcp_metrics.c +@@ -908,7 +908,7 @@ static void tcp_metrics_flush_all(struct net *net) + match = net ? net_eq(tm_net(tm), net) : + !refcount_read(&tm_net(tm)->ns.count); + if (match) { +- *pp = tm->tcpm_next; ++ rcu_assign_pointer(*pp, tm->tcpm_next); + kfree_rcu(tm, rcu_head); + } else { + pp = &tm->tcpm_next; +@@ -949,7 +949,7 @@ static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info) + if (addr_same(&tm->tcpm_daddr, &daddr) && + (!src || addr_same(&tm->tcpm_saddr, &saddr)) && + net_eq(tm_net(tm), net)) { +- *pp = tm->tcpm_next; ++ rcu_assign_pointer(*pp, tm->tcpm_next); + kfree_rcu(tm, rcu_head); + found = true; + } else { +-- +2.42.0 + diff --git a/queue-6.6/tcp_metrics-do-not-create-an-entry-from-tcp_init_met.patch b/queue-6.6/tcp_metrics-do-not-create-an-entry-from-tcp_init_met.patch new file mode 100644 index 00000000000..97510164fbe --- /dev/null +++ b/queue-6.6/tcp_metrics-do-not-create-an-entry-from-tcp_init_met.patch @@ -0,0 +1,39 @@ +From fa14ea8db9889489324a8b2ab6ef51d0803f391b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 22:03:55 +0000 +Subject: tcp_metrics: do not create an entry from tcp_init_metrics() + +From: Eric Dumazet + +[ Upstream commit a135798e6e200ecb2f864cecca6d257ba278370c ] + +tcp_init_metrics() only wants to get metrics if they were +previously stored in the cache. Creating an entry is adding +useless costs, especially when tcp_no_metrics_save is set. + +Fixes: 51c5d0c4b169 ("tcp: Maintain dynamic metrics in local cache.") +Signed-off-by: Eric Dumazet +Reviewed-by: David Ahern +Acked-by: Neal Cardwell +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp_metrics.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c +index 0c03f564878ff..7aca12c59c184 100644 +--- a/net/ipv4/tcp_metrics.c ++++ b/net/ipv4/tcp_metrics.c +@@ -478,7 +478,7 @@ void tcp_init_metrics(struct sock *sk) + goto reset; + + rcu_read_lock(); +- tm = tcp_get_metrics(sk, dst, true); ++ tm = tcp_get_metrics(sk, dst, false); + if (!tm) { + rcu_read_unlock(); + goto reset; +-- +2.42.0 + diff --git a/queue-6.6/tcp_metrics-properly-set-tp-snd_ssthresh-in-tcp_init.patch b/queue-6.6/tcp_metrics-properly-set-tp-snd_ssthresh-in-tcp_init.patch new file mode 100644 index 00000000000..a402820492f --- /dev/null +++ b/queue-6.6/tcp_metrics-properly-set-tp-snd_ssthresh-in-tcp_init.patch @@ -0,0 +1,52 @@ +From 29c3bc268390ed4543118e70d9e8b1e6dd5e0f74 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 22:03:54 +0000 +Subject: tcp_metrics: properly set tp->snd_ssthresh in tcp_init_metrics() + +From: Eric Dumazet + +[ Upstream commit 081480014a64a69d901f8ef1ffdd56d6085cf87e ] + +We need to set tp->snd_ssthresh to TCP_INFINITE_SSTHRESH +in the case tcp_get_metrics() fails for some reason. + +Fixes: 9ad7c049f0f7 ("tcp: RFC2988bis + taking RTT sample from 3WHS for the passive open side") +Signed-off-by: Eric Dumazet +Reviewed-by: David Ahern +Acked-by: Neal Cardwell +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp_metrics.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c +index 4bfa2fb27de54..0c03f564878ff 100644 +--- a/net/ipv4/tcp_metrics.c ++++ b/net/ipv4/tcp_metrics.c +@@ -470,6 +470,10 @@ void tcp_init_metrics(struct sock *sk) + u32 val, crtt = 0; /* cached RTT scaled by 8 */ + + sk_dst_confirm(sk); ++ /* ssthresh may have been reduced unnecessarily during. ++ * 3WHS. Restore it back to its initial default. ++ */ ++ tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; + if (!dst) + goto reset; + +@@ -489,11 +493,6 @@ void tcp_init_metrics(struct sock *sk) + tp->snd_ssthresh = val; + if (tp->snd_ssthresh > tp->snd_cwnd_clamp) + tp->snd_ssthresh = tp->snd_cwnd_clamp; +- } else { +- /* ssthresh may have been reduced unnecessarily during. +- * 3WHS. Restore it back to its initial default. +- */ +- tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; + } + val = tcp_metric_get(tm, TCP_METRIC_REORDERING); + if (val && tp->reordering != val) +-- +2.42.0 + diff --git a/queue-6.6/thermal-core-don-t-update-trip-points-inside-the-hys.patch b/queue-6.6/thermal-core-don-t-update-trip-points-inside-the-hys.patch new file mode 100644 index 00000000000..bc52ce0d4b9 --- /dev/null +++ b/queue-6.6/thermal-core-don-t-update-trip-points-inside-the-hys.patch @@ -0,0 +1,127 @@ +From 51886e0beb3cf6c507fb72c2e8b3aad80c59dc3d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 14:44:03 -0400 +Subject: thermal: core: Don't update trip points inside the hysteresis range +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Nícolas F. R. A. Prado + +[ Upstream commit cf3986f8c01d355490d0ac6024391b989a9d1e9d ] + +When searching for the trip points that need to be set, the nearest +higher trip point's temperature is used for the high trip, while the +nearest lower trip point's temperature minus the hysteresis is used for +the low trip. The issue with this logic is that when the current +temperature is inside a trip point's hysteresis range, both high and low +trips will come from the same trip point. As a consequence instability +can still occur like this: +* the temperature rises slightly and enters the hysteresis range of a + trip point +* polling happens and updates the trip points to the hysteresis range +* the temperature falls slightly, exiting the hysteresis range, crossing + the trip point and triggering an IRQ, the trip points are updated +* repeat + +So even though the current hysteresis implementation prevents +instability from happening due to IRQs triggering on the same +temperature value, both ways, it doesn't prevent it from happening due +to an IRQ on one way and polling on the other. + +To properly implement a hysteresis behavior, when inside the hysteresis +range, don't update the trip points. This way, the previously set trip +points will stay in effect, which will in a way remember the previous +state (if the temperature signal came from above or below the range) and +therefore have the right trip point already set. + +The exception is if there was no previous trip point set, in which case +a previous state doesn't exist, and so it's sensible to allow the +hysteresis range as trip points. + +The following logs show the current behavior when running on a real +machine: + +[ 202.524658] thermal thermal_zone0: new temperature boundaries: -2147483647 < x < 40000 + 203.562817: thermal_temperature: thermal_zone=vpu0-thermal id=0 temp_prev=36986 temp=37979 +[ 203.562845] thermal thermal_zone0: new temperature boundaries: 37000 < x < 40000 + 204.176059: thermal_temperature: thermal_zone=vpu0-thermal id=0 temp_prev=37979 temp=40028 +[ 204.176089] thermal thermal_zone0: new temperature boundaries: 37000 < x < 100000 + 205.226813: thermal_temperature: thermal_zone=vpu0-thermal id=0 temp_prev=40028 temp=38652 +[ 205.226842] thermal thermal_zone0: new temperature boundaries: 37000 < x < 40000 + +And with this patch applied: + +[ 184.933415] thermal thermal_zone0: new temperature boundaries: -2147483647 < x < 40000 + 185.981182: thermal_temperature: thermal_zone=vpu0-thermal id=0 temp_prev=36986 temp=37872 + 186.744685: thermal_temperature: thermal_zone=vpu0-thermal id=0 temp_prev=37872 temp=40058 +[ 186.744716] thermal thermal_zone0: new temperature boundaries: 37000 < x < 100000 + 187.773284: thermal_temperature: thermal_zone=vpu0-thermal id=0 temp_prev=40058 temp=38698 + +Fixes: 060c034a9741 ("thermal: Add support for hardware-tracked trip points") +Signed-off-by: Nícolas F. R. A. Prado +Reviewed-by: AngeloGioacchino Del Regno +Co-developed-by: Rafael J. Wysocki +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/thermal/thermal_trip.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c +index 024e2e365a26b..597ac4144e331 100644 +--- a/drivers/thermal/thermal_trip.c ++++ b/drivers/thermal/thermal_trip.c +@@ -55,6 +55,7 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz) + { + struct thermal_trip trip; + int low = -INT_MAX, high = INT_MAX; ++ bool same_trip = false; + int i, ret; + + lockdep_assert_held(&tz->lock); +@@ -63,6 +64,7 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz) + return; + + for (i = 0; i < tz->num_trips; i++) { ++ bool low_set = false; + int trip_low; + + ret = __thermal_zone_get_trip(tz, i , &trip); +@@ -71,18 +73,31 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz) + + trip_low = trip.temperature - trip.hysteresis; + +- if (trip_low < tz->temperature && trip_low > low) ++ if (trip_low < tz->temperature && trip_low > low) { + low = trip_low; ++ low_set = true; ++ same_trip = false; ++ } + + if (trip.temperature > tz->temperature && +- trip.temperature < high) ++ trip.temperature < high) { + high = trip.temperature; ++ same_trip = low_set; ++ } + } + + /* No need to change trip points */ + if (tz->prev_low_trip == low && tz->prev_high_trip == high) + return; + ++ /* ++ * If "high" and "low" are the same, skip the change unless this is the ++ * first time. ++ */ ++ if (same_trip && (tz->prev_low_trip != -INT_MAX || ++ tz->prev_high_trip != INT_MAX)) ++ return; ++ + tz->prev_low_trip = low; + tz->prev_high_trip = high; + +-- +2.42.0 + diff --git a/queue-6.6/thermal-core-prevent-potential-string-overflow.patch b/queue-6.6/thermal-core-prevent-potential-string-overflow.patch new file mode 100644 index 00000000000..5dd93460351 --- /dev/null +++ b/queue-6.6/thermal-core-prevent-potential-string-overflow.patch @@ -0,0 +1,47 @@ +From 7c0974a58d1601d5934b2a4f4ae3078f598625a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Oct 2023 11:59:39 +0300 +Subject: thermal: core: prevent potential string overflow + +From: Dan Carpenter + +[ Upstream commit c99626092efca3061b387043d4a7399bf75fbdd5 ] + +The dev->id value comes from ida_alloc() so it's a number between zero +and INT_MAX. If it's too high then these sprintf()s will overflow. + +Fixes: 203d3d4aa482 ("the generic thermal sysfs driver") +Signed-off-by: Dan Carpenter +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/thermal/thermal_core.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c +index 58533ea75cd92..e6f3166a9208f 100644 +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -689,7 +689,8 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, + if (result) + goto release_ida; + +- sprintf(dev->attr_name, "cdev%d_trip_point", dev->id); ++ snprintf(dev->attr_name, sizeof(dev->attr_name), "cdev%d_trip_point", ++ dev->id); + sysfs_attr_init(&dev->attr.attr); + dev->attr.attr.name = dev->attr_name; + dev->attr.attr.mode = 0444; +@@ -698,7 +699,8 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, + if (result) + goto remove_symbol_link; + +- sprintf(dev->weight_attr_name, "cdev%d_weight", dev->id); ++ snprintf(dev->weight_attr_name, sizeof(dev->weight_attr_name), ++ "cdev%d_weight", dev->id); + sysfs_attr_init(&dev->weight_attr.attr); + dev->weight_attr.attr.name = dev->weight_attr_name; + dev->weight_attr.attr.mode = S_IWUSR | S_IRUGO; +-- +2.42.0 + diff --git a/queue-6.6/thermal-drivers-mediatek-fix-probe-for-thermal_v2.patch b/queue-6.6/thermal-drivers-mediatek-fix-probe-for-thermal_v2.patch new file mode 100644 index 00000000000..5a74198d063 --- /dev/null +++ b/queue-6.6/thermal-drivers-mediatek-fix-probe-for-thermal_v2.patch @@ -0,0 +1,43 @@ +From 298b1d2216be38aa9d51e4dfbbda8bdb50810bb9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Sep 2023 12:07:06 +0200 +Subject: thermal/drivers/mediatek: Fix probe for THERMAL_V2 + +From: Markus Schneider-Pargmann + +[ Upstream commit 5055fadfa7e16f2427d5b3c40b2bf563ddfdab22 ] + +Fix the probe function to call mtk_thermal_release_periodic_ts for +everything != MTK_THERMAL_V1. This was accidentally changed from V1 +to V2 in the original patch. + +Reported-by: Frank Wunderlich +Closes: https://lore.kernel.org/lkml/B0B3775B-B8D1-4284-814F-4F41EC22F532@public-files.de/ +Reported-by: Daniel Lezcano +Closes: https://lore.kernel.org/lkml/07a569b9-e691-64ea-dd65-3b49842af33d@linaro.org/ +Fixes: 33140e668b10 ("thermal/drivers/mediatek: Control buffer enablement tweaks") +Signed-off-by: Markus Schneider-Pargmann +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20230918100706.1229239-1-msp@baylibre.com +Signed-off-by: Sasha Levin +--- + drivers/thermal/mediatek/auxadc_thermal.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/thermal/mediatek/auxadc_thermal.c b/drivers/thermal/mediatek/auxadc_thermal.c +index 843214d30bd8b..8b0edb2048443 100644 +--- a/drivers/thermal/mediatek/auxadc_thermal.c ++++ b/drivers/thermal/mediatek/auxadc_thermal.c +@@ -1267,7 +1267,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) + + mtk_thermal_turn_on_buffer(mt, apmixed_base); + +- if (mt->conf->version != MTK_THERMAL_V2) ++ if (mt->conf->version != MTK_THERMAL_V1) + mtk_thermal_release_periodic_ts(mt, auxadc_base); + + if (mt->conf->version == MTK_THERMAL_V1) +-- +2.42.0 + diff --git a/queue-6.6/tipc-use-size_add-in-calls-to-struct_size.patch b/queue-6.6/tipc-use-size_add-in-calls-to-struct_size.patch new file mode 100644 index 00000000000..7e55c777c1b --- /dev/null +++ b/queue-6.6/tipc-use-size_add-in-calls-to-struct_size.patch @@ -0,0 +1,48 @@ +From 727330856aaa09e11915e155d42a0c1c9f6d686a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 13:16:26 -0600 +Subject: tipc: Use size_add() in calls to struct_size() + +From: Gustavo A. R. Silva + +[ Upstream commit 2506a91734754de690869824fb0d1ac592ec1266 ] + +If, for any reason, the open-coded arithmetic causes a wraparound, +the protection that `struct_size()` adds against potential integer +overflows is defeated. Fix this by hardening call to `struct_size()` +with `size_add()`. + +Fixes: e034c6d23bc4 ("tipc: Use struct_size() helper") +Signed-off-by: Gustavo A. R. Silva +Reviewed-by: Kees Cook +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/tipc/link.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/tipc/link.c b/net/tipc/link.c +index e33b4f29f77cf..d0143823658d5 100644 +--- a/net/tipc/link.c ++++ b/net/tipc/link.c +@@ -1446,7 +1446,7 @@ u16 tipc_get_gap_ack_blks(struct tipc_gap_ack_blks **ga, struct tipc_link *l, + p = (struct tipc_gap_ack_blks *)msg_data(hdr); + sz = ntohs(p->len); + /* Sanity check */ +- if (sz == struct_size(p, gacks, p->ugack_cnt + p->bgack_cnt)) { ++ if (sz == struct_size(p, gacks, size_add(p->ugack_cnt, p->bgack_cnt))) { + /* Good, check if the desired type exists */ + if ((uc && p->ugack_cnt) || (!uc && p->bgack_cnt)) + goto ok; +@@ -1533,7 +1533,7 @@ static u16 tipc_build_gap_ack_blks(struct tipc_link *l, struct tipc_msg *hdr) + __tipc_build_gap_ack_blks(ga, l, ga->bgack_cnt) : 0; + + /* Total len */ +- len = struct_size(ga, gacks, ga->bgack_cnt + ga->ugack_cnt); ++ len = struct_size(ga, gacks, size_add(ga->bgack_cnt, ga->ugack_cnt)); + ga->len = htons(len); + return len; + } +-- +2.42.0 + diff --git a/queue-6.6/tls-use-size_add-in-call-to-struct_size.patch b/queue-6.6/tls-use-size_add-in-call-to-struct_size.patch new file mode 100644 index 00000000000..512c62adf2f --- /dev/null +++ b/queue-6.6/tls-use-size_add-in-call-to-struct_size.patch @@ -0,0 +1,39 @@ +From a23e075cc521da5ec87dcda5cd4fbc837246f247 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 13:12:38 -0600 +Subject: tls: Use size_add() in call to struct_size() + +From: Gustavo A. R. Silva + +[ Upstream commit a2713257ee2be22827d7bc248302d408c91bfb95 ] + +If, for any reason, the open-coded arithmetic causes a wraparound, +the protection that `struct_size()` adds against potential integer +overflows is defeated. Fix this by hardening call to `struct_size()` +with `size_add()`. + +Fixes: b89fec54fd61 ("tls: rx: wrap decrypt params in a struct") +Signed-off-by: Gustavo A. R. Silva +Reviewed-by: Kees Cook +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/tls/tls_sw.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c +index e9d1e83a859d1..9634dfd636fd6 100644 +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -1491,7 +1491,7 @@ static int tls_decrypt_sg(struct sock *sk, struct iov_iter *out_iov, + */ + aead_size = sizeof(*aead_req) + crypto_aead_reqsize(ctx->aead_recv); + aead_size = ALIGN(aead_size, __alignof__(*dctx)); +- mem = kmalloc(aead_size + struct_size(dctx, sg, n_sgin + n_sgout), ++ mem = kmalloc(aead_size + struct_size(dctx, sg, size_add(n_sgin, n_sgout)), + sk->sk_allocation); + if (!mem) { + err = -ENOMEM; +-- +2.42.0 + diff --git a/queue-6.6/tools-iio-iio_generic_buffer-ensure-alignment.patch b/queue-6.6/tools-iio-iio_generic_buffer-ensure-alignment.patch new file mode 100644 index 00000000000..9c33a4bc95e --- /dev/null +++ b/queue-6.6/tools-iio-iio_generic_buffer-ensure-alignment.patch @@ -0,0 +1,65 @@ +From cf7b28b8ef7701abcf30454aa1f616164fbd29e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Oct 2023 12:57:47 +0300 +Subject: tools: iio: iio_generic_buffer ensure alignment + +From: Matti Vaittinen + +[ Upstream commit 2d3dff577dd0ea8fe9637a13822f7603c4a881c8 ] + +The iio_generic_buffer can return garbage values when the total size of +scan data is not a multiple of the largest element in the scan. This can be +demonstrated by reading a scan, consisting, for example of one 4-byte and +one 2-byte element, where the 4-byte element is first in the buffer. + +The IIO generic buffer code does not take into account the last two +padding bytes that are needed to ensure that the 4-byte data for next +scan is correctly aligned. + +Add the padding bytes required to align the next sample with the scan size. + +Signed-off-by: Matti Vaittinen +Fixes: e58537ccce73 ("staging: iio: update example application.") +Link: https://lore.kernel.org/r/ZRvlm4ktNLu+qmlf@dc78bmyyyyyyyyyyyyydt-3.rev.dnainternet.fi +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + tools/iio/iio_generic_buffer.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/tools/iio/iio_generic_buffer.c b/tools/iio/iio_generic_buffer.c +index 44bbf80f0cfdd..0d0a7a19d6f95 100644 +--- a/tools/iio/iio_generic_buffer.c ++++ b/tools/iio/iio_generic_buffer.c +@@ -54,9 +54,12 @@ enum autochan { + static unsigned int size_from_channelarray(struct iio_channel_info *channels, int num_channels) + { + unsigned int bytes = 0; +- int i = 0; ++ int i = 0, max = 0; ++ unsigned int misalignment; + + while (i < num_channels) { ++ if (channels[i].bytes > max) ++ max = channels[i].bytes; + if (bytes % channels[i].bytes == 0) + channels[i].location = bytes; + else +@@ -66,6 +69,14 @@ static unsigned int size_from_channelarray(struct iio_channel_info *channels, in + bytes = channels[i].location + channels[i].bytes; + i++; + } ++ /* ++ * We want the data in next sample to also be properly aligned so ++ * we'll add padding at the end if needed. Adding padding only ++ * works for channel data which size is 2^n bytes. ++ */ ++ misalignment = bytes % max; ++ if (misalignment) ++ bytes += max - misalignment; + + return bytes; + } +-- +2.42.0 + diff --git a/queue-6.6/tools-perf-update-call-stack-check-in-builtin-lock.c.patch b/queue-6.6/tools-perf-update-call-stack-check-in-builtin-lock.c.patch new file mode 100644 index 00000000000..76562b5f962 --- /dev/null +++ b/queue-6.6/tools-perf-update-call-stack-check-in-builtin-lock.c.patch @@ -0,0 +1,148 @@ +From c92192982ed51f8aa9d3cd88c7de5a1471728923 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Oct 2023 14:51:13 +0530 +Subject: tools/perf: Update call stack check in builtin-lock.c + +From: Kajol Jain + +[ Upstream commit d7c9ae8d5d1be0c4156d1e20e4369a77b711a4cc ] + +The perf test named "kernel lock contention analysis test" +fails in powerpc system with below error: + + [command]# ./perf test 81 -vv + 81: kernel lock contention analysis test : + --- start --- + test child forked, pid 2140 + Testing perf lock record and perf lock contention + Testing perf lock contention --use-bpf + [Skip] No BPF support + Testing perf lock record and perf lock contention at the same time + Testing perf lock contention --threads + Testing perf lock contention --lock-addr + Testing perf lock contention --type-filter (w/ spinlock) + Testing perf lock contention --lock-filter (w/ tasklist_lock) + Testing perf lock contention --callstack-filter (w/ unix_stream) + [Fail] Recorded result should have a lock from unix_stream: + test child finished with -1 + ---- end ---- + kernel lock contention analysis test: FAILED! + +The test is failing because we get an address entry with 0 in +perf lock samples for powerpc, and code for lock contention +option "--callstack-filter" will not check further entries after +address 0. + +Below are some of the samples from test generated perf.data file, which +have 0 address in the 2nd entry of callstack: + -------- +sched-messaging 3409 [001] 7152.904029: lock:contention_begin: 0xc00000c80904ef00 (flags=SPIN) + c0000000001e926c __traceiter_contention_begin+0x6c ([kernel.kallsyms]) + 0 [unknown] ([unknown]) + c000000000f8a178 native_queued_spin_lock_slowpath+0x1f8 ([kernel.kallsyms]) + c000000000f89f44 _raw_spin_lock_irqsave+0x84 ([kernel.kallsyms]) + c0000000001d9fd0 prepare_to_wait+0x50 ([kernel.kallsyms]) + c000000000c80f50 sock_alloc_send_pskb+0x1b0 ([kernel.kallsyms]) + c000000000e82298 unix_stream_sendmsg+0x2b8 ([kernel.kallsyms]) + c000000000c78980 sock_sendmsg+0x80 ([kernel.kallsyms]) + +sched-messaging 3408 [005] 7152.904036: lock:contention_begin: 0xc00000c80904ef00 (flags=SPIN) + c0000000001e926c __traceiter_contention_begin+0x6c ([kernel.kallsyms]) + 0 [unknown] ([unknown]) + c000000000f8a178 native_queued_spin_lock_slowpath+0x1f8 ([kernel.kallsyms]) + c000000000f89f44 _raw_spin_lock_irqsave+0x84 ([kernel.kallsyms]) + c0000000001d9fd0 prepare_to_wait+0x50 ([kernel.kallsyms]) + c000000000c80f50 sock_alloc_send_pskb+0x1b0 ([kernel.kallsyms]) + c000000000e82298 unix_stream_sendmsg+0x2b8 ([kernel.kallsyms]) + c000000000c78980 sock_sendmsg+0x80 ([kernel.kallsyms]) + -------- + +Based on commit 20002ded4d93 ("perf_counter: powerpc: Add callchain support"), +incase of powerpc, the callchain saved by kernel always includes first +three entries as the NIP (next instruction pointer), LR (link register), and +the contents of LR save area in the second stack frame. In certain scenarios +its possible to have invalid kernel instruction addresses in either of LR or the +second stack frame's LR. In that case, kernel will store the address as zer0. +Hence, its possible to have 2nd or 3rd callstack entry as 0. + +As per the current code in match_callstack_filter function, we skip the callstack +check incase we get 0 address. And hence the test case is failing in powerpc. + +Fix this issue by updating the check in match_callstack_filter function, +to not skip callstack check if the 2nd or 3rd entry have 0 address +for powerpc. + +Result in powerpc after patch changes: + + [command]# ./perf test 81 -vv + 81: kernel lock contention analysis test : + --- start --- + test child forked, pid 4570 + Testing perf lock record and perf lock contention + Testing perf lock contention --use-bpf + [Skip] No BPF support + Testing perf lock record and perf lock contention at the same time + Testing perf lock contention --threads + Testing perf lock contention --lock-addr + Testing perf lock contention --type-filter (w/ spinlock) + Testing perf lock contention --lock-filter (w/ tasklist_lock) + [Skip] Could not find 'tasklist_lock' + Testing perf lock contention --callstack-filter (w/ unix_stream) + Testing perf lock contention --callstack-filter with task aggregation + Testing perf lock contention CSV output + [Skip] No BPF support + test child finished with 0 + ---- end ---- + kernel lock contention analysis test: Ok + +Fixes: ebab291641be ("perf lock contention: Support filters for different aggregation") +Reported-by: Disha Goel +Tested-by: Disha Goel +Signed-off-by: Kajol Jain +Cc: maddy@linux.ibm.com +Cc: atrajeev@linux.vnet.ibm.com +Link: https://lore.kernel.org/r/20231003092113.252380-1-kjain@linux.ibm.com +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-lock.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c +index b141f21342740..0b4b4445c5207 100644 +--- a/tools/perf/builtin-lock.c ++++ b/tools/perf/builtin-lock.c +@@ -524,6 +524,7 @@ bool match_callstack_filter(struct machine *machine, u64 *callstack) + struct map *kmap; + struct symbol *sym; + u64 ip; ++ const char *arch = perf_env__arch(machine->env); + + if (list_empty(&callstack_filters)) + return true; +@@ -531,7 +532,21 @@ bool match_callstack_filter(struct machine *machine, u64 *callstack) + for (int i = 0; i < max_stack_depth; i++) { + struct callstack_filter *filter; + +- if (!callstack || !callstack[i]) ++ /* ++ * In powerpc, the callchain saved by kernel always includes ++ * first three entries as the NIP (next instruction pointer), ++ * LR (link register), and the contents of LR save area in the ++ * second stack frame. In certain scenarios its possible to have ++ * invalid kernel instruction addresses in either LR or the second ++ * stack frame's LR. In that case, kernel will store that address as ++ * zero. ++ * ++ * The below check will continue to look into callstack, ++ * incase first or second callstack index entry has 0 ++ * address for powerpc. ++ */ ++ if (!callstack || (!callstack[i] && (strcmp(arch, "powerpc") || ++ (i != 1 && i != 2)))) + break; + + ip = callstack[i]; +-- +2.42.0 + diff --git a/queue-6.6/tty-tty_jobctrl-fix-pid-memleak-in-disassociate_ctty.patch b/queue-6.6/tty-tty_jobctrl-fix-pid-memleak-in-disassociate_ctty.patch new file mode 100644 index 00000000000..583a568d867 --- /dev/null +++ b/queue-6.6/tty-tty_jobctrl-fix-pid-memleak-in-disassociate_ctty.patch @@ -0,0 +1,117 @@ +From b750bd1b71de239dcf81153404d06f9d4be3586b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 31 Aug 2023 10:33:29 +0800 +Subject: tty: tty_jobctrl: fix pid memleak in disassociate_ctty() + +From: Yi Yang + +[ Upstream commit 11e7f27b79757b6586645d87b95d5b78375ecdfc ] + +There is a pid leakage: +------------------------------ +unreferenced object 0xffff88810c181940 (size 224): + comm "sshd", pid 8191, jiffies 4294946950 (age 524.570s) + hex dump (first 32 bytes): + 01 00 00 00 00 00 00 00 00 00 00 00 ad 4e ad de .............N.. + ff ff ff ff 6b 6b 6b 6b ff ff ff ff ff ff ff ff ....kkkk........ + backtrace: + [] kmem_cache_alloc+0x5c6/0x9b0 + [] alloc_pid+0x72/0x570 + [] copy_process+0x1374/0x2470 + [] kernel_clone+0xb7/0x900 + [] __se_sys_clone+0x85/0xb0 + [] __x64_sys_clone+0x2b/0x30 + [] do_syscall_64+0x32/0x80 + [] entry_SYSCALL_64_after_hwframe+0x61/0xc6 + +It turns out that there is a race condition between disassociate_ctty() and +tty_signal_session_leader(), which caused this leakage. + +The pid memleak is triggered by the following race: +task[sshd] task[bash] +----------------------- ----------------------- + disassociate_ctty(); + spin_lock_irq(¤t->sighand->siglock); + put_pid(current->signal->tty_old_pgrp); + current->signal->tty_old_pgrp = NULL; + tty = tty_kref_get(current->signal->tty); + spin_unlock_irq(¤t->sighand->siglock); +tty_vhangup(); +tty_lock(tty); +... +tty_signal_session_leader(); +spin_lock_irq(&p->sighand->siglock); +... +if (tty->ctrl.pgrp) //tty->ctrl.pgrp is not NULL +p->signal->tty_old_pgrp = get_pid(tty->ctrl.pgrp); //An extra get +spin_unlock_irq(&p->sighand->siglock); +... +tty_unlock(tty); + if (tty) { + tty_lock(tty); + ... + put_pid(tty->ctrl.pgrp); + tty->ctrl.pgrp = NULL; //It's too late + ... + tty_unlock(tty); + } + +The issue is believed to be introduced by commit c8bcd9c5be24 ("tty: +Fix ->session locking") who moves the unlock of siglock in +disassociate_ctty() above "if (tty)", making a small window allowing +tty_signal_session_leader() to kick in. It can be easily reproduced by +adding a delay before "if (tty)" and at the entrance of +tty_signal_session_leader(). + +To fix this issue, we move "put_pid(current->signal->tty_old_pgrp)" after +"tty->ctrl.pgrp = NULL". + +Fixes: c8bcd9c5be24 ("tty: Fix ->session locking") +Signed-off-by: Yi Yang +Co-developed-by: GUO Zihua +Signed-off-by: GUO Zihua +Link: https://lore.kernel.org/r/20230831023329.165737-1-yiyang13@huawei.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/tty/tty_jobctrl.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/drivers/tty/tty_jobctrl.c b/drivers/tty/tty_jobctrl.c +index 0d04287da0984..ef8741c3e6629 100644 +--- a/drivers/tty/tty_jobctrl.c ++++ b/drivers/tty/tty_jobctrl.c +@@ -300,12 +300,7 @@ void disassociate_ctty(int on_exit) + return; + } + +- spin_lock_irq(¤t->sighand->siglock); +- put_pid(current->signal->tty_old_pgrp); +- current->signal->tty_old_pgrp = NULL; +- tty = tty_kref_get(current->signal->tty); +- spin_unlock_irq(¤t->sighand->siglock); +- ++ tty = get_current_tty(); + if (tty) { + unsigned long flags; + +@@ -320,6 +315,16 @@ void disassociate_ctty(int on_exit) + tty_kref_put(tty); + } + ++ /* If tty->ctrl.pgrp is not NULL, it may be assigned to ++ * current->signal->tty_old_pgrp in a race condition, and ++ * cause pid memleak. Release current->signal->tty_old_pgrp ++ * after tty->ctrl.pgrp set to NULL. ++ */ ++ spin_lock_irq(¤t->sighand->siglock); ++ put_pid(current->signal->tty_old_pgrp); ++ current->signal->tty_old_pgrp = NULL; ++ spin_unlock_irq(¤t->sighand->siglock); ++ + /* Now clear signal->tty under the lock */ + read_lock(&tasklist_lock); + session_clear_tty(task_session(current)); +-- +2.42.0 + diff --git a/queue-6.6/udp-add-missing-write_once-around-up-encap_rcv.patch b/queue-6.6/udp-add-missing-write_once-around-up-encap_rcv.patch new file mode 100644 index 00000000000..5e4bf4daf40 --- /dev/null +++ b/queue-6.6/udp-add-missing-write_once-around-up-encap_rcv.patch @@ -0,0 +1,43 @@ +From 60eba94f0fb1be6a39849125d48ca4633b870229 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 09:17:25 +0000 +Subject: udp: add missing WRITE_ONCE() around up->encap_rcv + +From: Eric Dumazet + +[ Upstream commit 6d5a12eb91224d707f8691dccb40a5719fe5466d ] + +UDP_ENCAP_ESPINUDP_NON_IKE setsockopt() writes over up->encap_rcv +while other cpus read it. + +Fixes: 067b207b281d ("[UDP]: Cleanup UDP encapsulation code") +Signed-off-by: Eric Dumazet +Reviewed-by: Willem de Bruijn +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/ipv4/udp.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 1debc10a0f029..db43907b9a3e8 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -2675,10 +2675,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, + case UDP_ENCAP_ESPINUDP_NON_IKE: + #if IS_ENABLED(CONFIG_IPV6) + if (sk->sk_family == AF_INET6) +- up->encap_rcv = ipv6_stub->xfrm6_udp_encap_rcv; ++ WRITE_ONCE(up->encap_rcv, ++ ipv6_stub->xfrm6_udp_encap_rcv); + else + #endif +- up->encap_rcv = xfrm4_udp_encap_rcv; ++ WRITE_ONCE(up->encap_rcv, ++ xfrm4_udp_encap_rcv); + #endif + fallthrough; + case UDP_ENCAP_L2TPINUDP: +-- +2.42.0 + diff --git a/queue-6.6/udp-annotate-data-races-around-udp-encap_type.patch b/queue-6.6/udp-annotate-data-races-around-udp-encap_type.patch new file mode 100644 index 00000000000..6ffdeadcbe5 --- /dev/null +++ b/queue-6.6/udp-annotate-data-races-around-udp-encap_type.patch @@ -0,0 +1,205 @@ +From 0e673ea6cb8260cb13e9da41009508853329b0b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 09:17:28 +0000 +Subject: udp: annotate data-races around udp->encap_type + +From: Eric Dumazet + +[ Upstream commit 70a36f571362a8de8b8c02d21ae524fc776287f2 ] + +syzbot/KCSAN complained about UDP_ENCAP_L2TPINUDP setsockopt() racing. + +Add READ_ONCE()/WRITE_ONCE() to document races on this lockless field. + +syzbot report was: +BUG: KCSAN: data-race in udp_lib_setsockopt / udp_lib_setsockopt + +read-write to 0xffff8881083603fa of 1 bytes by task 16557 on cpu 0: +udp_lib_setsockopt+0x682/0x6c0 +udp_setsockopt+0x73/0xa0 net/ipv4/udp.c:2779 +sock_common_setsockopt+0x61/0x70 net/core/sock.c:3697 +__sys_setsockopt+0x1c9/0x230 net/socket.c:2263 +__do_sys_setsockopt net/socket.c:2274 [inline] +__se_sys_setsockopt net/socket.c:2271 [inline] +__x64_sys_setsockopt+0x66/0x80 net/socket.c:2271 +do_syscall_x64 arch/x86/entry/common.c:50 [inline] +do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 +entry_SYSCALL_64_after_hwframe+0x63/0xcd + +read-write to 0xffff8881083603fa of 1 bytes by task 16554 on cpu 1: +udp_lib_setsockopt+0x682/0x6c0 +udp_setsockopt+0x73/0xa0 net/ipv4/udp.c:2779 +sock_common_setsockopt+0x61/0x70 net/core/sock.c:3697 +__sys_setsockopt+0x1c9/0x230 net/socket.c:2263 +__do_sys_setsockopt net/socket.c:2274 [inline] +__se_sys_setsockopt net/socket.c:2271 [inline] +__x64_sys_setsockopt+0x66/0x80 net/socket.c:2271 +do_syscall_x64 arch/x86/entry/common.c:50 [inline] +do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 +entry_SYSCALL_64_after_hwframe+0x63/0xcd + +value changed: 0x01 -> 0x05 + +Reported by Kernel Concurrency Sanitizer on: +CPU: 1 PID: 16554 Comm: syz-executor.5 Not tainted 6.5.0-rc7-syzkaller-00004-gf7757129e3de #0 + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Reviewed-by: Willem de Bruijn +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/gtp.c | 4 ++-- + net/ipv4/udp.c | 9 +++++---- + net/ipv4/xfrm4_input.c | 4 ++-- + net/ipv6/udp.c | 5 +++-- + net/ipv6/xfrm6_input.c | 4 ++-- + net/l2tp/l2tp_core.c | 6 +++--- + 6 files changed, 17 insertions(+), 15 deletions(-) + +diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c +index b22596b18ee8c..b1919278e931f 100644 +--- a/drivers/net/gtp.c ++++ b/drivers/net/gtp.c +@@ -630,7 +630,7 @@ static void __gtp_encap_destroy(struct sock *sk) + gtp->sk0 = NULL; + else + gtp->sk1u = NULL; +- udp_sk(sk)->encap_type = 0; ++ WRITE_ONCE(udp_sk(sk)->encap_type, 0); + rcu_assign_sk_user_data(sk, NULL); + release_sock(sk); + sock_put(sk); +@@ -682,7 +682,7 @@ static int gtp_encap_recv(struct sock *sk, struct sk_buff *skb) + + netdev_dbg(gtp->dev, "encap_recv sk=%p\n", sk); + +- switch (udp_sk(sk)->encap_type) { ++ switch (READ_ONCE(udp_sk(sk)->encap_type)) { + case UDP_ENCAP_GTP0: + netdev_dbg(gtp->dev, "received GTP0 packet\n"); + ret = gtp0_udp_encap_recv(gtp, skb); +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 637a4faf9aff6..2eeab4af17a13 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -714,7 +714,7 @@ int __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable) + iph->saddr, uh->source, skb->dev->ifindex, + inet_sdif(skb), udptable, NULL); + +- if (!sk || udp_sk(sk)->encap_type) { ++ if (!sk || READ_ONCE(udp_sk(sk)->encap_type)) { + /* No socket for error: try tunnels before discarding */ + if (static_branch_unlikely(&udp_encap_needed_key)) { + sk = __udp4_lib_err_encap(net, iph, uh, udptable, sk, skb, +@@ -2081,7 +2081,8 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) + } + nf_reset_ct(skb); + +- if (static_branch_unlikely(&udp_encap_needed_key) && up->encap_type) { ++ if (static_branch_unlikely(&udp_encap_needed_key) && ++ READ_ONCE(up->encap_type)) { + int (*encap_rcv)(struct sock *sk, struct sk_buff *skb); + + /* +@@ -2684,7 +2685,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, + #endif + fallthrough; + case UDP_ENCAP_L2TPINUDP: +- up->encap_type = val; ++ WRITE_ONCE(up->encap_type, val); + udp_tunnel_encap_enable(sk); + break; + default: +@@ -2785,7 +2786,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname, + break; + + case UDP_ENCAP: +- val = up->encap_type; ++ val = READ_ONCE(up->encap_type); + break; + + case UDP_NO_CHECK6_TX: +diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c +index eac206a290d05..183f6dc372429 100644 +--- a/net/ipv4/xfrm4_input.c ++++ b/net/ipv4/xfrm4_input.c +@@ -85,11 +85,11 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb) + struct udphdr *uh; + struct iphdr *iph; + int iphlen, len; +- + __u8 *udpdata; + __be32 *udpdata32; +- __u16 encap_type = up->encap_type; ++ u16 encap_type; + ++ encap_type = READ_ONCE(up->encap_type); + /* if this is not encapsulated socket, then just return now */ + if (!encap_type) + return 1; +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 90688877e9004..0e79d189613be 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -571,7 +571,7 @@ int __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, + sk = __udp6_lib_lookup(net, daddr, uh->dest, saddr, uh->source, + inet6_iif(skb), inet6_sdif(skb), udptable, NULL); + +- if (!sk || udp_sk(sk)->encap_type) { ++ if (!sk || READ_ONCE(udp_sk(sk)->encap_type)) { + /* No socket for error: try tunnels before discarding */ + if (static_branch_unlikely(&udpv6_encap_needed_key)) { + sk = __udp6_lib_err_encap(net, hdr, offset, uh, +@@ -688,7 +688,8 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) + } + nf_reset_ct(skb); + +- if (static_branch_unlikely(&udpv6_encap_needed_key) && up->encap_type) { ++ if (static_branch_unlikely(&udpv6_encap_needed_key) && ++ READ_ONCE(up->encap_type)) { + int (*encap_rcv)(struct sock *sk, struct sk_buff *skb); + + /* +diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c +index 4907ab241d6be..4156387248e40 100644 +--- a/net/ipv6/xfrm6_input.c ++++ b/net/ipv6/xfrm6_input.c +@@ -81,14 +81,14 @@ int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb) + struct ipv6hdr *ip6h; + int len; + int ip6hlen = sizeof(struct ipv6hdr); +- + __u8 *udpdata; + __be32 *udpdata32; +- __u16 encap_type = up->encap_type; ++ u16 encap_type; + + if (skb->protocol == htons(ETH_P_IP)) + return xfrm4_udp_encap_rcv(sk, skb); + ++ encap_type = READ_ONCE(up->encap_type); + /* if this is not encapsulated socket, then just return now */ + if (!encap_type) + return 1; +diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c +index 03608d3ded4b8..8d21ff25f1602 100644 +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -1139,9 +1139,9 @@ static void l2tp_tunnel_destruct(struct sock *sk) + switch (tunnel->encap) { + case L2TP_ENCAPTYPE_UDP: + /* No longer an encapsulation socket. See net/ipv4/udp.c */ +- (udp_sk(sk))->encap_type = 0; +- (udp_sk(sk))->encap_rcv = NULL; +- (udp_sk(sk))->encap_destroy = NULL; ++ WRITE_ONCE(udp_sk(sk)->encap_type, 0); ++ udp_sk(sk)->encap_rcv = NULL; ++ udp_sk(sk)->encap_destroy = NULL; + break; + case L2TP_ENCAPTYPE_IP: + break; +-- +2.42.0 + diff --git a/queue-6.6/udp-introduce-udp-udp_flags.patch b/queue-6.6/udp-introduce-udp-udp_flags.patch new file mode 100644 index 00000000000..8bde3ea9eb7 --- /dev/null +++ b/queue-6.6/udp-introduce-udp-udp_flags.patch @@ -0,0 +1,171 @@ +From 99d9646cd6950aaa8112f7dc56ebec6dd7afe8d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 09:17:21 +0000 +Subject: udp: introduce udp->udp_flags + +From: Eric Dumazet + +[ Upstream commit 81b36803ac139827538ac5ce4028e750a3c53f53 ] + +According to syzbot, it is time to use proper atomic flags +for various UDP flags. + +Add udp_flags field, and convert udp->corkflag to first +bit in it. + +Signed-off-by: Eric Dumazet +Reviewed-by: Willem de Bruijn +Signed-off-by: Paolo Abeni +Stable-dep-of: a0002127cd74 ("udp: move udp->no_check6_tx to udp->udp_flags") +Signed-off-by: Sasha Levin +--- + include/linux/udp.h | 28 +++++++++++++++++++++------- + net/ipv4/udp.c | 12 ++++++------ + net/ipv6/udp.c | 6 +++--- + 3 files changed, 30 insertions(+), 16 deletions(-) + +diff --git a/include/linux/udp.h b/include/linux/udp.h +index 43c1fb2d2c21a..23f0693e0d9cc 100644 +--- a/include/linux/udp.h ++++ b/include/linux/udp.h +@@ -32,14 +32,20 @@ static inline u32 udp_hashfn(const struct net *net, u32 num, u32 mask) + return (num + net_hash_mix(net)) & mask; + } + ++enum { ++ UDP_FLAGS_CORK, /* Cork is required */ ++}; ++ + struct udp_sock { + /* inet_sock has to be the first member */ + struct inet_sock inet; + #define udp_port_hash inet.sk.__sk_common.skc_u16hashes[0] + #define udp_portaddr_hash inet.sk.__sk_common.skc_u16hashes[1] + #define udp_portaddr_node inet.sk.__sk_common.skc_portaddr_node ++ ++ unsigned long udp_flags; ++ + int pending; /* Any pending frames ? */ +- unsigned int corkflag; /* Cork is required */ + __u8 encap_type; /* Is this an Encapsulation socket? */ + unsigned char no_check6_tx:1,/* Send zero UDP6 checksums on TX? */ + no_check6_rx:1,/* Allow zero UDP6 checksums on RX? */ +@@ -51,6 +57,11 @@ struct udp_sock { + gro_enabled:1, /* Request GRO aggregation */ + accept_udp_l4:1, + accept_udp_fraglist:1; ++/* indicator bits used by pcflag: */ ++#define UDPLITE_BIT 0x1 /* set by udplite proto init function */ ++#define UDPLITE_SEND_CC 0x2 /* set via udplite setsockopt */ ++#define UDPLITE_RECV_CC 0x4 /* set via udplite setsocktopt */ ++ __u8 pcflag; /* marks socket as UDP-Lite if > 0 */ + /* + * Following member retains the information to create a UDP header + * when the socket is uncorked. +@@ -62,12 +73,6 @@ struct udp_sock { + */ + __u16 pcslen; + __u16 pcrlen; +-/* indicator bits used by pcflag: */ +-#define UDPLITE_BIT 0x1 /* set by udplite proto init function */ +-#define UDPLITE_SEND_CC 0x2 /* set via udplite setsockopt */ +-#define UDPLITE_RECV_CC 0x4 /* set via udplite setsocktopt */ +- __u8 pcflag; /* marks socket as UDP-Lite if > 0 */ +- __u8 unused[3]; + /* + * For encapsulation sockets. + */ +@@ -95,6 +100,15 @@ struct udp_sock { + int forward_threshold; + }; + ++#define udp_test_bit(nr, sk) \ ++ test_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags) ++#define udp_set_bit(nr, sk) \ ++ set_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags) ++#define udp_clear_bit(nr, sk) \ ++ clear_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags) ++#define udp_assign_bit(nr, sk, val) \ ++ assign_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags, val) ++ + #define UDP_MAX_SEGMENTS (1 << 6UL) + + #define udp_sk(ptr) container_of_const(ptr, struct udp_sock, inet.sk) +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index f39b9c8445808..9709f8a532dc3 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -1051,7 +1051,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + u8 tos, scope; + __be16 dport; + int err, is_udplite = IS_UDPLITE(sk); +- int corkreq = READ_ONCE(up->corkflag) || msg->msg_flags&MSG_MORE; ++ int corkreq = udp_test_bit(CORK, sk) || msg->msg_flags & MSG_MORE; + int (*getfrag)(void *, char *, int, int, int, struct sk_buff *); + struct sk_buff *skb; + struct ip_options_data opt_copy; +@@ -1315,11 +1315,11 @@ void udp_splice_eof(struct socket *sock) + struct sock *sk = sock->sk; + struct udp_sock *up = udp_sk(sk); + +- if (!up->pending || READ_ONCE(up->corkflag)) ++ if (!up->pending || udp_test_bit(CORK, sk)) + return; + + lock_sock(sk); +- if (up->pending && !READ_ONCE(up->corkflag)) ++ if (up->pending && !udp_test_bit(CORK, sk)) + udp_push_pending_frames(sk); + release_sock(sk); + } +@@ -2658,9 +2658,9 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, + switch (optname) { + case UDP_CORK: + if (val != 0) { +- WRITE_ONCE(up->corkflag, 1); ++ udp_set_bit(CORK, sk); + } else { +- WRITE_ONCE(up->corkflag, 0); ++ udp_clear_bit(CORK, sk); + lock_sock(sk); + push_pending_frames(sk); + release_sock(sk); +@@ -2783,7 +2783,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname, + + switch (optname) { + case UDP_CORK: +- val = READ_ONCE(up->corkflag); ++ val = udp_test_bit(CORK, sk); + break; + + case UDP_ENCAP: +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 86b5d509a4688..0c6973cd22ce4 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -1332,7 +1332,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + int addr_len = msg->msg_namelen; + bool connected = false; + int ulen = len; +- int corkreq = READ_ONCE(up->corkflag) || msg->msg_flags&MSG_MORE; ++ int corkreq = udp_test_bit(CORK, sk) || msg->msg_flags & MSG_MORE; + int err; + int is_udplite = IS_UDPLITE(sk); + int (*getfrag)(void *, char *, int, int, int, struct sk_buff *); +@@ -1644,11 +1644,11 @@ static void udpv6_splice_eof(struct socket *sock) + struct sock *sk = sock->sk; + struct udp_sock *up = udp_sk(sk); + +- if (!up->pending || READ_ONCE(up->corkflag)) ++ if (!up->pending || udp_test_bit(CORK, sk)) + return; + + lock_sock(sk); +- if (up->pending && !READ_ONCE(up->corkflag)) ++ if (up->pending && !udp_test_bit(CORK, sk)) + udp_v6_push_pending_frames(sk); + release_sock(sk); + } +-- +2.42.0 + diff --git a/queue-6.6/udp-lockless-udp_encap_l2tpinudp-udp_gro.patch b/queue-6.6/udp-lockless-udp_encap_l2tpinudp-udp_gro.patch new file mode 100644 index 00000000000..e736c015096 --- /dev/null +++ b/queue-6.6/udp-lockless-udp_encap_l2tpinudp-udp_gro.patch @@ -0,0 +1,154 @@ +From 472db66e153fcd0f1d5cf2add1ce2db021489011 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 09:17:27 +0000 +Subject: udp: lockless UDP_ENCAP_L2TPINUDP / UDP_GRO + +From: Eric Dumazet + +[ Upstream commit ac9a7f4ce5dda1472e8f44096f33066c6ec1a3b4 ] + +Move udp->encap_enabled to udp->udp_flags. + +Add udp_test_and_set_bit() helper to allow lockless +udp_tunnel_encap_enable() implementation. + +Signed-off-by: Eric Dumazet +Reviewed-by: Willem de Bruijn +Signed-off-by: Paolo Abeni +Stable-dep-of: 70a36f571362 ("udp: annotate data-races around udp->encap_type") +Signed-off-by: Sasha Levin +--- + include/linux/udp.h | 9 ++++----- + include/net/udp_tunnel.h | 9 +++------ + net/ipv4/udp.c | 10 +++------- + net/ipv4/udp_tunnel_core.c | 2 +- + net/ipv6/udp.c | 2 +- + 5 files changed, 12 insertions(+), 20 deletions(-) + +diff --git a/include/linux/udp.h b/include/linux/udp.h +index bb2b87adfbea9..0cf83270a4a28 100644 +--- a/include/linux/udp.h ++++ b/include/linux/udp.h +@@ -39,6 +39,7 @@ enum { + UDP_FLAGS_GRO_ENABLED, /* Request GRO aggregation */ + UDP_FLAGS_ACCEPT_FRAGLIST, + UDP_FLAGS_ACCEPT_L4, ++ UDP_FLAGS_ENCAP_ENABLED, /* This socket enabled encap */ + }; + + struct udp_sock { +@@ -52,11 +53,7 @@ struct udp_sock { + + int pending; /* Any pending frames ? */ + __u8 encap_type; /* Is this an Encapsulation socket? */ +- unsigned char encap_enabled:1; /* This socket enabled encap +- * processing; UDP tunnels and +- * different encapsulation layer set +- * this +- */ ++ + /* indicator bits used by pcflag: */ + #define UDPLITE_BIT 0x1 /* set by udplite proto init function */ + #define UDPLITE_SEND_CC 0x2 /* set via udplite setsockopt */ +@@ -104,6 +101,8 @@ struct udp_sock { + test_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags) + #define udp_set_bit(nr, sk) \ + set_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags) ++#define udp_test_and_set_bit(nr, sk) \ ++ test_and_set_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags) + #define udp_clear_bit(nr, sk) \ + clear_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags) + #define udp_assign_bit(nr, sk, val) \ +diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h +index 0ca9b7a11baf5..29251c3519cf0 100644 +--- a/include/net/udp_tunnel.h ++++ b/include/net/udp_tunnel.h +@@ -174,16 +174,13 @@ static inline int udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum) + } + #endif + +-static inline void udp_tunnel_encap_enable(struct socket *sock) ++static inline void udp_tunnel_encap_enable(struct sock *sk) + { +- struct udp_sock *up = udp_sk(sock->sk); +- +- if (up->encap_enabled) ++ if (udp_test_and_set_bit(ENCAP_ENABLED, sk)) + return; + +- up->encap_enabled = 1; + #if IS_ENABLED(CONFIG_IPV6) +- if (sock->sk->sk_family == PF_INET6) ++ if (READ_ONCE(sk->sk_family) == PF_INET6) + ipv6_stub->udpv6_encap_enable(); + #endif + udp_encap_enable(); +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 75ba86a87bb62..637a4faf9aff6 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -2618,7 +2618,7 @@ void udp_destroy_sock(struct sock *sk) + if (encap_destroy) + encap_destroy(sk); + } +- if (up->encap_enabled) ++ if (udp_test_bit(ENCAP_ENABLED, sk)) + static_branch_dec(&udp_encap_needed_key); + } + } +@@ -2685,9 +2685,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, + fallthrough; + case UDP_ENCAP_L2TPINUDP: + up->encap_type = val; +- lock_sock(sk); +- udp_tunnel_encap_enable(sk->sk_socket); +- release_sock(sk); ++ udp_tunnel_encap_enable(sk); + break; + default: + err = -ENOPROTOOPT; +@@ -2710,14 +2708,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, + break; + + case UDP_GRO: +- lock_sock(sk); + + /* when enabling GRO, accept the related GSO packet type */ + if (valbool) +- udp_tunnel_encap_enable(sk->sk_socket); ++ udp_tunnel_encap_enable(sk); + udp_assign_bit(GRO_ENABLED, sk, valbool); + udp_assign_bit(ACCEPT_L4, sk, valbool); +- release_sock(sk); + break; + + /* +diff --git a/net/ipv4/udp_tunnel_core.c b/net/ipv4/udp_tunnel_core.c +index 9b18f371af0d4..1e7e4aecdc48a 100644 +--- a/net/ipv4/udp_tunnel_core.c ++++ b/net/ipv4/udp_tunnel_core.c +@@ -78,7 +78,7 @@ void setup_udp_tunnel_sock(struct net *net, struct socket *sock, + udp_sk(sk)->gro_receive = cfg->gro_receive; + udp_sk(sk)->gro_complete = cfg->gro_complete; + +- udp_tunnel_encap_enable(sock); ++ udp_tunnel_encap_enable(sk); + } + EXPORT_SYMBOL_GPL(setup_udp_tunnel_sock); + +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 2c3281879b6df..90688877e9004 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -1670,7 +1670,7 @@ void udpv6_destroy_sock(struct sock *sk) + if (encap_destroy) + encap_destroy(sk); + } +- if (up->encap_enabled) { ++ if (udp_test_bit(ENCAP_ENABLED, sk)) { + static_branch_dec(&udpv6_encap_needed_key); + udp_encap_disable(); + } +-- +2.42.0 + diff --git a/queue-6.6/udp-move-udp-accept_udp_-l4-fraglist-to-udp-udp_flag.patch b/queue-6.6/udp-move-udp-accept_udp_-l4-fraglist-to-udp-udp_flag.patch new file mode 100644 index 00000000000..f54993da4d0 --- /dev/null +++ b/queue-6.6/udp-move-udp-accept_udp_-l4-fraglist-to-udp-udp_flag.patch @@ -0,0 +1,91 @@ +From 1284e0c29cd96f0546170628936cde7e8ab29574 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 09:17:26 +0000 +Subject: udp: move udp->accept_udp_{l4|fraglist} to udp->udp_flags + +From: Eric Dumazet + +[ Upstream commit f5f52f0884a595ff99ab1a608643fe4025fca2d5 ] + +These are read locklessly, move them to udp_flags to fix data-races. + +Signed-off-by: Eric Dumazet +Reviewed-by: Willem de Bruijn +Signed-off-by: Paolo Abeni +Stable-dep-of: 70a36f571362 ("udp: annotate data-races around udp->encap_type") +Signed-off-by: Sasha Levin +--- + include/linux/udp.h | 16 +++++++++------- + net/ipv4/udp.c | 2 +- + 2 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/include/linux/udp.h b/include/linux/udp.h +index b344bd2e41fc9..bb2b87adfbea9 100644 +--- a/include/linux/udp.h ++++ b/include/linux/udp.h +@@ -37,6 +37,8 @@ enum { + UDP_FLAGS_NO_CHECK6_TX, /* Send zero UDP6 checksums on TX? */ + UDP_FLAGS_NO_CHECK6_RX, /* Allow zero UDP6 checksums on RX? */ + UDP_FLAGS_GRO_ENABLED, /* Request GRO aggregation */ ++ UDP_FLAGS_ACCEPT_FRAGLIST, ++ UDP_FLAGS_ACCEPT_L4, + }; + + struct udp_sock { +@@ -50,13 +52,11 @@ struct udp_sock { + + int pending; /* Any pending frames ? */ + __u8 encap_type; /* Is this an Encapsulation socket? */ +- unsigned char encap_enabled:1, /* This socket enabled encap ++ unsigned char encap_enabled:1; /* This socket enabled encap + * processing; UDP tunnels and + * different encapsulation layer set + * this + */ +- accept_udp_l4:1, +- accept_udp_fraglist:1; + /* indicator bits used by pcflag: */ + #define UDPLITE_BIT 0x1 /* set by udplite proto init function */ + #define UDPLITE_SEND_CC 0x2 /* set via udplite setsockopt */ +@@ -149,10 +149,12 @@ static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb) + if (!skb_is_gso(skb)) + return false; + +- if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4 && !udp_sk(sk)->accept_udp_l4) ++ if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4 && ++ !udp_test_bit(ACCEPT_L4, sk)) + return true; + +- if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST && !udp_sk(sk)->accept_udp_fraglist) ++ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST && ++ !udp_test_bit(ACCEPT_FRAGLIST, sk)) + return true; + + return false; +@@ -160,8 +162,8 @@ static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb) + + static inline void udp_allow_gso(struct sock *sk) + { +- udp_sk(sk)->accept_udp_l4 = 1; +- udp_sk(sk)->accept_udp_fraglist = 1; ++ udp_set_bit(ACCEPT_L4, sk); ++ udp_set_bit(ACCEPT_FRAGLIST, sk); + } + + #define udp_portaddr_for_each_entry(__sk, list) \ +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index db43907b9a3e8..75ba86a87bb62 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -2716,7 +2716,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, + if (valbool) + udp_tunnel_encap_enable(sk->sk_socket); + udp_assign_bit(GRO_ENABLED, sk, valbool); +- up->accept_udp_l4 = valbool; ++ udp_assign_bit(ACCEPT_L4, sk, valbool); + release_sock(sk); + break; + +-- +2.42.0 + diff --git a/queue-6.6/udp-move-udp-gro_enabled-to-udp-udp_flags.patch b/queue-6.6/udp-move-udp-gro_enabled-to-udp-udp_flags.patch new file mode 100644 index 00000000000..ff3d16effe9 --- /dev/null +++ b/queue-6.6/udp-move-udp-gro_enabled-to-udp-udp_flags.patch @@ -0,0 +1,109 @@ +From ff6a0c838fb4d9058469b2a1813dfa1018547912 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 09:17:24 +0000 +Subject: udp: move udp->gro_enabled to udp->udp_flags + +From: Eric Dumazet + +[ Upstream commit e1dc0615c6b08ef36414f08c011965b8fb56198b ] + +syzbot reported that udp->gro_enabled can be read locklessly. +Use one atomic bit from udp->udp_flags. + +Fixes: e20cf8d3f1f7 ("udp: implement GRO for plain UDP sockets.") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Reviewed-by: Willem de Bruijn +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + include/linux/udp.h | 2 +- + net/ipv4/udp.c | 6 +++--- + net/ipv4/udp_offload.c | 4 ++-- + net/ipv6/udp.c | 2 +- + 4 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/include/linux/udp.h b/include/linux/udp.h +index 8d4c3835b1b21..b344bd2e41fc9 100644 +--- a/include/linux/udp.h ++++ b/include/linux/udp.h +@@ -36,6 +36,7 @@ enum { + UDP_FLAGS_CORK, /* Cork is required */ + UDP_FLAGS_NO_CHECK6_TX, /* Send zero UDP6 checksums on TX? */ + UDP_FLAGS_NO_CHECK6_RX, /* Allow zero UDP6 checksums on RX? */ ++ UDP_FLAGS_GRO_ENABLED, /* Request GRO aggregation */ + }; + + struct udp_sock { +@@ -54,7 +55,6 @@ struct udp_sock { + * different encapsulation layer set + * this + */ +- gro_enabled:1, /* Request GRO aggregation */ + accept_udp_l4:1, + accept_udp_fraglist:1; + /* indicator bits used by pcflag: */ +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index cb32826a1db20..1debc10a0f029 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -1868,7 +1868,7 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags, + (struct sockaddr *)sin); + } + +- if (udp_sk(sk)->gro_enabled) ++ if (udp_test_bit(GRO_ENABLED, sk)) + udp_cmsg_recv(msg, sk, skb); + + if (inet_cmsg_flags(inet)) +@@ -2713,7 +2713,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, + /* when enabling GRO, accept the related GSO packet type */ + if (valbool) + udp_tunnel_encap_enable(sk->sk_socket); +- up->gro_enabled = valbool; ++ udp_assign_bit(GRO_ENABLED, sk, valbool); + up->accept_udp_l4 = valbool; + release_sock(sk); + break; +@@ -2803,7 +2803,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname, + break; + + case UDP_GRO: +- val = up->gro_enabled; ++ val = udp_test_bit(GRO_ENABLED, sk); + break; + + /* The following two cannot be changed on UDP sockets, the return is +diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c +index 0f46b3c2e4ac5..6c95d28d0c4a7 100644 +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -557,10 +557,10 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb, + NAPI_GRO_CB(skb)->is_flist = 0; + if (!sk || !udp_sk(sk)->gro_receive) { + if (skb->dev->features & NETIF_F_GRO_FRAGLIST) +- NAPI_GRO_CB(skb)->is_flist = sk ? !udp_sk(sk)->gro_enabled : 1; ++ NAPI_GRO_CB(skb)->is_flist = sk ? !udp_test_bit(GRO_ENABLED, sk) : 1; + + if ((!sk && (skb->dev->features & NETIF_F_GRO_UDP_FWD)) || +- (sk && udp_sk(sk)->gro_enabled) || NAPI_GRO_CB(skb)->is_flist) ++ (sk && udp_test_bit(GRO_ENABLED, sk)) || NAPI_GRO_CB(skb)->is_flist) + return call_gro_receive(udp_gro_receive_segment, head, skb); + + /* no GRO, be sure flush the current packet */ +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 6e1ea3029260e..2c3281879b6df 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -413,7 +413,7 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, + (struct sockaddr *)sin6); + } + +- if (udp_sk(sk)->gro_enabled) ++ if (udp_test_bit(GRO_ENABLED, sk)) + udp_cmsg_recv(msg, sk, skb); + + if (np->rxopt.all) +-- +2.42.0 + diff --git a/queue-6.6/udp-move-udp-no_check6_rx-to-udp-udp_flags.patch b/queue-6.6/udp-move-udp-no_check6_rx-to-udp-udp_flags.patch new file mode 100644 index 00000000000..3392e9c1ffc --- /dev/null +++ b/queue-6.6/udp-move-udp-no_check6_rx-to-udp-udp_flags.patch @@ -0,0 +1,123 @@ +From f485fd1263170d56e3cb29d63a452151fcfd5d92 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 09:17:23 +0000 +Subject: udp: move udp->no_check6_rx to udp->udp_flags + +From: Eric Dumazet + +[ Upstream commit bcbc1b1de884647aa0318bf74eb7f293d72a1e40 ] + +syzbot reported that udp->no_check6_rx can be read locklessly. +Use one atomic bit from udp->udp_flags. + +Fixes: 1c19448c9ba6 ("net: Make enabling of zero UDP6 csums more restrictive") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Reviewed-by: Willem de Bruijn +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + include/linux/udp.h | 10 +++++----- + net/ipv4/udp.c | 4 ++-- + net/ipv6/udp.c | 6 +++--- + 3 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/include/linux/udp.h b/include/linux/udp.h +index e3f2a6c7ac1d1..8d4c3835b1b21 100644 +--- a/include/linux/udp.h ++++ b/include/linux/udp.h +@@ -35,6 +35,7 @@ static inline u32 udp_hashfn(const struct net *net, u32 num, u32 mask) + enum { + UDP_FLAGS_CORK, /* Cork is required */ + UDP_FLAGS_NO_CHECK6_TX, /* Send zero UDP6 checksums on TX? */ ++ UDP_FLAGS_NO_CHECK6_RX, /* Allow zero UDP6 checksums on RX? */ + }; + + struct udp_sock { +@@ -48,8 +49,7 @@ struct udp_sock { + + int pending; /* Any pending frames ? */ + __u8 encap_type; /* Is this an Encapsulation socket? */ +- unsigned char no_check6_rx:1,/* Allow zero UDP6 checksums on RX? */ +- encap_enabled:1, /* This socket enabled encap ++ unsigned char encap_enabled:1, /* This socket enabled encap + * processing; UDP tunnels and + * different encapsulation layer set + * this +@@ -120,7 +120,7 @@ static inline void udp_set_no_check6_tx(struct sock *sk, bool val) + + static inline void udp_set_no_check6_rx(struct sock *sk, bool val) + { +- udp_sk(sk)->no_check6_rx = val; ++ udp_assign_bit(NO_CHECK6_RX, sk, val); + } + + static inline bool udp_get_no_check6_tx(const struct sock *sk) +@@ -128,9 +128,9 @@ static inline bool udp_get_no_check6_tx(const struct sock *sk) + return udp_test_bit(NO_CHECK6_TX, sk); + } + +-static inline bool udp_get_no_check6_rx(struct sock *sk) ++static inline bool udp_get_no_check6_rx(const struct sock *sk) + { +- return udp_sk(sk)->no_check6_rx; ++ return udp_test_bit(NO_CHECK6_RX, sk); + } + + static inline void udp_cmsg_recv(struct msghdr *msg, struct sock *sk, +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 0c6998291c99d..cb32826a1db20 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -2698,7 +2698,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, + break; + + case UDP_NO_CHECK6_RX: +- up->no_check6_rx = valbool; ++ udp_set_no_check6_rx(sk, valbool); + break; + + case UDP_SEGMENT: +@@ -2795,7 +2795,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname, + break; + + case UDP_NO_CHECK6_RX: +- val = up->no_check6_rx; ++ val = udp_get_no_check6_rx(sk); + break; + + case UDP_SEGMENT: +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 469df0ca561f7..6e1ea3029260e 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -858,7 +858,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, + /* If zero checksum and no_check is not on for + * the socket then skip it. + */ +- if (!uh->check && !udp_sk(sk)->no_check6_rx) ++ if (!uh->check && !udp_get_no_check6_rx(sk)) + continue; + if (!first) { + first = sk; +@@ -980,7 +980,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, + if (unlikely(rcu_dereference(sk->sk_rx_dst) != dst)) + udp6_sk_rx_dst_set(sk, dst); + +- if (!uh->check && !udp_sk(sk)->no_check6_rx) { ++ if (!uh->check && !udp_get_no_check6_rx(sk)) { + if (refcounted) + sock_put(sk); + goto report_csum_error; +@@ -1002,7 +1002,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, + /* Unicast */ + sk = __udp6_lib_lookup_skb(skb, uh->source, uh->dest, udptable); + if (sk) { +- if (!uh->check && !udp_sk(sk)->no_check6_rx) ++ if (!uh->check && !udp_get_no_check6_rx(sk)) + goto report_csum_error; + return udp6_unicast_rcv_skb(sk, skb, uh); + } +-- +2.42.0 + diff --git a/queue-6.6/udp-move-udp-no_check6_tx-to-udp-udp_flags.patch b/queue-6.6/udp-move-udp-no_check6_tx-to-udp-udp_flags.patch new file mode 100644 index 00000000000..b387c49c55e --- /dev/null +++ b/queue-6.6/udp-move-udp-no_check6_tx-to-udp-udp_flags.patch @@ -0,0 +1,114 @@ +From 534d401d5b8c9a59795fa36d4449ccef63ca4b7c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 09:17:22 +0000 +Subject: udp: move udp->no_check6_tx to udp->udp_flags + +From: Eric Dumazet + +[ Upstream commit a0002127cd746fcaa182ad3386ef6931c37f3bda ] + +syzbot reported that udp->no_check6_tx can be read locklessly. +Use one atomic bit from udp->udp_flags + +Fixes: 1c19448c9ba6 ("net: Make enabling of zero UDP6 csums more restrictive") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Reviewed-by: Willem de Bruijn +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + include/linux/udp.h | 10 +++++----- + net/ipv4/udp.c | 4 ++-- + net/ipv6/udp.c | 4 ++-- + 3 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/include/linux/udp.h b/include/linux/udp.h +index 23f0693e0d9cc..e3f2a6c7ac1d1 100644 +--- a/include/linux/udp.h ++++ b/include/linux/udp.h +@@ -34,6 +34,7 @@ static inline u32 udp_hashfn(const struct net *net, u32 num, u32 mask) + + enum { + UDP_FLAGS_CORK, /* Cork is required */ ++ UDP_FLAGS_NO_CHECK6_TX, /* Send zero UDP6 checksums on TX? */ + }; + + struct udp_sock { +@@ -47,8 +48,7 @@ struct udp_sock { + + int pending; /* Any pending frames ? */ + __u8 encap_type; /* Is this an Encapsulation socket? */ +- unsigned char no_check6_tx:1,/* Send zero UDP6 checksums on TX? */ +- no_check6_rx:1,/* Allow zero UDP6 checksums on RX? */ ++ unsigned char no_check6_rx:1,/* Allow zero UDP6 checksums on RX? */ + encap_enabled:1, /* This socket enabled encap + * processing; UDP tunnels and + * different encapsulation layer set +@@ -115,7 +115,7 @@ struct udp_sock { + + static inline void udp_set_no_check6_tx(struct sock *sk, bool val) + { +- udp_sk(sk)->no_check6_tx = val; ++ udp_assign_bit(NO_CHECK6_TX, sk, val); + } + + static inline void udp_set_no_check6_rx(struct sock *sk, bool val) +@@ -123,9 +123,9 @@ static inline void udp_set_no_check6_rx(struct sock *sk, bool val) + udp_sk(sk)->no_check6_rx = val; + } + +-static inline bool udp_get_no_check6_tx(struct sock *sk) ++static inline bool udp_get_no_check6_tx(const struct sock *sk) + { +- return udp_sk(sk)->no_check6_tx; ++ return udp_test_bit(NO_CHECK6_TX, sk); + } + + static inline bool udp_get_no_check6_rx(struct sock *sk) +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 9709f8a532dc3..0c6998291c99d 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -2694,7 +2694,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, + break; + + case UDP_NO_CHECK6_TX: +- up->no_check6_tx = valbool; ++ udp_set_no_check6_tx(sk, valbool); + break; + + case UDP_NO_CHECK6_RX: +@@ -2791,7 +2791,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname, + break; + + case UDP_NO_CHECK6_TX: +- val = up->no_check6_tx; ++ val = udp_get_no_check6_tx(sk); + break; + + case UDP_NO_CHECK6_RX: +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 0c6973cd22ce4..469df0ca561f7 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -1241,7 +1241,7 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6, + kfree_skb(skb); + return -EINVAL; + } +- if (udp_sk(sk)->no_check6_tx) { ++ if (udp_get_no_check6_tx(sk)) { + kfree_skb(skb); + return -EINVAL; + } +@@ -1262,7 +1262,7 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6, + + if (is_udplite) + csum = udplite_csum(skb); +- else if (udp_sk(sk)->no_check6_tx) { /* UDP csum disabled */ ++ else if (udp_get_no_check6_tx(sk)) { /* UDP csum disabled */ + skb->ip_summed = CHECKSUM_NONE; + goto send; + } else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */ +-- +2.42.0 + diff --git a/queue-6.6/udplite-fix-various-data-races.patch b/queue-6.6/udplite-fix-various-data-races.patch new file mode 100644 index 00000000000..e95878f7ce2 --- /dev/null +++ b/queue-6.6/udplite-fix-various-data-races.patch @@ -0,0 +1,178 @@ +From cfc5d7cf739e4ed8c6f1f990d6ca9fbd42a4ad15 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 09:17:30 +0000 +Subject: udplite: fix various data-races + +From: Eric Dumazet + +[ Upstream commit 882af43a0fc37e26d85fb0df0c9edd3bed928de4 ] + +udp->pcflag, udp->pcslen and udp->pcrlen reads/writes are racy. + +Move udp->pcflag to udp->udp_flags for atomicity, +and add READ_ONCE()/WRITE_ONCE() annotations for pcslen and pcrlen. + +Fixes: ba4e58eca8aa ("[NET]: Supporting UDP-Lite (RFC 3828) in Linux") +Signed-off-by: Eric Dumazet +Reviewed-by: Willem de Bruijn +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + include/linux/udp.h | 6 ++---- + include/net/udplite.h | 14 +++++++++----- + net/ipv4/udp.c | 21 +++++++++++---------- + net/ipv6/udp.c | 9 +++++---- + 4 files changed, 27 insertions(+), 23 deletions(-) + +diff --git a/include/linux/udp.h b/include/linux/udp.h +index 58156edec0096..d04188714dca1 100644 +--- a/include/linux/udp.h ++++ b/include/linux/udp.h +@@ -40,6 +40,8 @@ enum { + UDP_FLAGS_ACCEPT_FRAGLIST, + UDP_FLAGS_ACCEPT_L4, + UDP_FLAGS_ENCAP_ENABLED, /* This socket enabled encap */ ++ UDP_FLAGS_UDPLITE_SEND_CC, /* set via udplite setsockopt */ ++ UDP_FLAGS_UDPLITE_RECV_CC, /* set via udplite setsockopt */ + }; + + struct udp_sock { +@@ -54,10 +56,6 @@ struct udp_sock { + int pending; /* Any pending frames ? */ + __u8 encap_type; /* Is this an Encapsulation socket? */ + +-/* indicator bits used by pcflag: */ +-#define UDPLITE_SEND_CC 0x1 /* set via udplite setsockopt */ +-#define UDPLITE_RECV_CC 0x2 /* set via udplite setsocktopt */ +- __u8 pcflag; /* marks socket as UDP-Lite if > 0 */ + /* + * Following member retains the information to create a UDP header + * when the socket is uncorked. +diff --git a/include/net/udplite.h b/include/net/udplite.h +index bd33ff2b8f426..786919d29f8de 100644 +--- a/include/net/udplite.h ++++ b/include/net/udplite.h +@@ -66,14 +66,18 @@ static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh) + /* Fast-path computation of checksum. Socket may not be locked. */ + static inline __wsum udplite_csum(struct sk_buff *skb) + { +- const struct udp_sock *up = udp_sk(skb->sk); + const int off = skb_transport_offset(skb); ++ const struct sock *sk = skb->sk; + int len = skb->len - off; + +- if ((up->pcflag & UDPLITE_SEND_CC) && up->pcslen < len) { +- if (0 < up->pcslen) +- len = up->pcslen; +- udp_hdr(skb)->len = htons(up->pcslen); ++ if (udp_test_bit(UDPLITE_SEND_CC, sk)) { ++ u16 pcslen = READ_ONCE(udp_sk(sk)->pcslen); ++ ++ if (pcslen < len) { ++ if (pcslen > 0) ++ len = pcslen; ++ udp_hdr(skb)->len = htons(pcslen); ++ } + } + skb->ip_summed = CHECKSUM_NONE; /* no HW support for checksumming */ + +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 2eeab4af17a13..c3ff984b63547 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -2120,7 +2120,8 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) + /* + * UDP-Lite specific tests, ignored on UDP sockets + */ +- if ((up->pcflag & UDPLITE_RECV_CC) && UDP_SKB_CB(skb)->partial_cov) { ++ if (udp_test_bit(UDPLITE_RECV_CC, sk) && UDP_SKB_CB(skb)->partial_cov) { ++ u16 pcrlen = READ_ONCE(up->pcrlen); + + /* + * MIB statistics other than incrementing the error count are +@@ -2133,7 +2134,7 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) + * delivery of packets with coverage values less than a value + * provided by the application." + */ +- if (up->pcrlen == 0) { /* full coverage was set */ ++ if (pcrlen == 0) { /* full coverage was set */ + net_dbg_ratelimited("UDPLite: partial coverage %d while full coverage %d requested\n", + UDP_SKB_CB(skb)->cscov, skb->len); + goto drop; +@@ -2144,9 +2145,9 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) + * that it wants x while sender emits packets of smaller size y. + * Therefore the above ...()->partial_cov statement is essential. + */ +- if (UDP_SKB_CB(skb)->cscov < up->pcrlen) { ++ if (UDP_SKB_CB(skb)->cscov < pcrlen) { + net_dbg_ratelimited("UDPLite: coverage %d too small, need min %d\n", +- UDP_SKB_CB(skb)->cscov, up->pcrlen); ++ UDP_SKB_CB(skb)->cscov, pcrlen); + goto drop; + } + } +@@ -2729,8 +2730,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, + val = 8; + else if (val > USHRT_MAX) + val = USHRT_MAX; +- up->pcslen = val; +- up->pcflag |= UDPLITE_SEND_CC; ++ WRITE_ONCE(up->pcslen, val); ++ udp_set_bit(UDPLITE_SEND_CC, sk); + break; + + /* The receiver specifies a minimum checksum coverage value. To make +@@ -2743,8 +2744,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, + val = 8; + else if (val > USHRT_MAX) + val = USHRT_MAX; +- up->pcrlen = val; +- up->pcflag |= UDPLITE_RECV_CC; ++ WRITE_ONCE(up->pcrlen, val); ++ udp_set_bit(UDPLITE_RECV_CC, sk); + break; + + default: +@@ -2808,11 +2809,11 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname, + /* The following two cannot be changed on UDP sockets, the return is + * always 0 (which corresponds to the full checksum coverage of UDP). */ + case UDPLITE_SEND_CSCOV: +- val = up->pcslen; ++ val = READ_ONCE(up->pcslen); + break; + + case UDPLITE_RECV_CSCOV: +- val = up->pcrlen; ++ val = READ_ONCE(up->pcrlen); + break; + + default: +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 0e79d189613be..f60ba42954352 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -727,16 +727,17 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) + /* + * UDP-Lite specific tests, ignored on UDP sockets (see net/ipv4/udp.c). + */ +- if ((up->pcflag & UDPLITE_RECV_CC) && UDP_SKB_CB(skb)->partial_cov) { ++ if (udp_test_bit(UDPLITE_RECV_CC, sk) && UDP_SKB_CB(skb)->partial_cov) { ++ u16 pcrlen = READ_ONCE(up->pcrlen); + +- if (up->pcrlen == 0) { /* full coverage was set */ ++ if (pcrlen == 0) { /* full coverage was set */ + net_dbg_ratelimited("UDPLITE6: partial coverage %d while full coverage %d requested\n", + UDP_SKB_CB(skb)->cscov, skb->len); + goto drop; + } +- if (UDP_SKB_CB(skb)->cscov < up->pcrlen) { ++ if (UDP_SKB_CB(skb)->cscov < pcrlen) { + net_dbg_ratelimited("UDPLITE6: coverage %d too small, need min %d\n", +- UDP_SKB_CB(skb)->cscov, up->pcrlen); ++ UDP_SKB_CB(skb)->cscov, pcrlen); + goto drop; + } + } +-- +2.42.0 + diff --git a/queue-6.6/udplite-remove-udplite_bit.patch b/queue-6.6/udplite-remove-udplite_bit.patch new file mode 100644 index 00000000000..dcb4e2e4bfe --- /dev/null +++ b/queue-6.6/udplite-remove-udplite_bit.patch @@ -0,0 +1,65 @@ +From 081ba38a389c71a2fc66e29922bce52a880d20af Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 09:17:29 +0000 +Subject: udplite: remove UDPLITE_BIT + +From: Eric Dumazet + +[ Upstream commit 729549aa350c56a777bb342941ed4d69b6585769 ] + +This flag is set but never read, we can remove it. + +Signed-off-by: Eric Dumazet +Reviewed-by: Willem de Bruijn +Signed-off-by: Paolo Abeni +Stable-dep-of: 882af43a0fc3 ("udplite: fix various data-races") +Signed-off-by: Sasha Levin +--- + include/linux/udp.h | 5 ++--- + net/ipv4/udplite.c | 1 - + net/ipv6/udplite.c | 1 - + 3 files changed, 2 insertions(+), 5 deletions(-) + +diff --git a/include/linux/udp.h b/include/linux/udp.h +index 0cf83270a4a28..58156edec0096 100644 +--- a/include/linux/udp.h ++++ b/include/linux/udp.h +@@ -55,9 +55,8 @@ struct udp_sock { + __u8 encap_type; /* Is this an Encapsulation socket? */ + + /* indicator bits used by pcflag: */ +-#define UDPLITE_BIT 0x1 /* set by udplite proto init function */ +-#define UDPLITE_SEND_CC 0x2 /* set via udplite setsockopt */ +-#define UDPLITE_RECV_CC 0x4 /* set via udplite setsocktopt */ ++#define UDPLITE_SEND_CC 0x1 /* set via udplite setsockopt */ ++#define UDPLITE_RECV_CC 0x2 /* set via udplite setsocktopt */ + __u8 pcflag; /* marks socket as UDP-Lite if > 0 */ + /* + * Following member retains the information to create a UDP header +diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c +index 39ecdad1b50ce..af37af3ab727b 100644 +--- a/net/ipv4/udplite.c ++++ b/net/ipv4/udplite.c +@@ -21,7 +21,6 @@ EXPORT_SYMBOL(udplite_table); + static int udplite_sk_init(struct sock *sk) + { + udp_init_sock(sk); +- udp_sk(sk)->pcflag = UDPLITE_BIT; + pr_warn_once("UDP-Lite is deprecated and scheduled to be removed in 2025, " + "please contact the netdev mailing list\n"); + return 0; +diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c +index 267d491e97075..a60bec9b14f14 100644 +--- a/net/ipv6/udplite.c ++++ b/net/ipv6/udplite.c +@@ -17,7 +17,6 @@ + static int udplitev6_sk_init(struct sock *sk) + { + udpv6_init_sock(sk); +- udp_sk(sk)->pcflag = UDPLITE_BIT; + pr_warn_once("UDP-Lite is deprecated and scheduled to be removed in 2025, " + "please contact the netdev mailing list\n"); + return 0; +-- +2.42.0 + diff --git a/queue-6.6/usb-chipidea-fix-dma-overwrite-for-tegra.patch b/queue-6.6/usb-chipidea-fix-dma-overwrite-for-tegra.patch new file mode 100644 index 00000000000..b467280c304 --- /dev/null +++ b/queue-6.6/usb-chipidea-fix-dma-overwrite-for-tegra.patch @@ -0,0 +1,102 @@ +From 51f24c3dbbbea4258914e1e912ad34d47adde624 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Sep 2023 23:06:03 +0200 +Subject: usb: chipidea: Fix DMA overwrite for Tegra +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michał Mirosław + +[ Upstream commit 7ab8716713c931ac79988f2592e1cf8b2e4fec1b ] + +Tegra USB controllers seem to issue DMA in full 32-bit words only and thus +may overwrite unevenly-sized buffers. One such occurrence is detected by +SLUB when receiving a reply to a 1-byte buffer (below). Fix this by +allocating a bounce buffer also for buffers with sizes not a multiple of 4. + +============================================================================= +BUG kmalloc-64 (Tainted: G B ): kmalloc Redzone overwritten +----------------------------------------------------------------------------- + +0x8555cd02-0x8555cd03 @offset=3330. First byte 0x0 instead of 0xcc +Allocated in usb_get_status+0x2b/0xac age=1 cpu=3 pid=41 + __kmem_cache_alloc_node+0x12f/0x1e4 + __kmalloc+0x33/0x8c + usb_get_status+0x2b/0xac + hub_probe+0x5e9/0xcec + usb_probe_interface+0xbf/0x21c + really_probe+0xa5/0x2c4 + __driver_probe_device+0x75/0x174 + driver_probe_device+0x31/0x94 + __device_attach_driver+0x65/0xc0 + bus_for_each_drv+0x4b/0x74 + __device_attach+0x69/0x120 + bus_probe_device+0x65/0x6c + device_add+0x48b/0x5f8 + usb_set_configuration+0x37b/0x6b4 + usb_generic_driver_probe+0x37/0x68 + usb_probe_device+0x35/0xb4 +Slab 0xbf622b80 objects=21 used=18 fp=0x8555cdc0 flags=0x800(slab|zone=0) +Object 0x8555cd00 @offset=3328 fp=0x00000000 + +Redzone 8555ccc0: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc ................ +Redzone 8555ccd0: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc ................ +Redzone 8555cce0: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc ................ +Redzone 8555ccf0: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc ................ +Object 8555cd00: 01 00 00 00 cc cc cc cc cc cc cc cc cc cc cc cc ................ +Object 8555cd10: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc ................ +Object 8555cd20: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc ................ +Object 8555cd30: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc ................ +Redzone 8555cd40: cc cc cc cc .... +Padding 8555cd74: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZ +CPU: 3 PID: 41 Comm: kworker/3:1 Tainted: G B 6.6.0-rc1mq-00118-g59786f827ea1 #1115 +Hardware name: NVIDIA Tegra SoC (Flattened Device Tree) +Workqueue: usb_hub_wq hub_event +[<8010ca28>] (unwind_backtrace) from [<801090a5>] (show_stack+0x11/0x14) +[<801090a5>] (show_stack) from [<805da2fb>] (dump_stack_lvl+0x4d/0x7c) +[<805da2fb>] (dump_stack_lvl) from [<8026464f>] (check_bytes_and_report+0xb3/0xe4) +[<8026464f>] (check_bytes_and_report) from [<802648e1>] (check_object+0x261/0x290) +[<802648e1>] (check_object) from [<802671b1>] (free_to_partial_list+0x105/0x3f8) +[<802671b1>] (free_to_partial_list) from [<80268613>] (__kmem_cache_free+0x103/0x128) +[<80268613>] (__kmem_cache_free) from [<80425a67>] (usb_get_status+0x73/0xac) +[<80425a67>] (usb_get_status) from [<80421b31>] (hub_probe+0x5e9/0xcec) +[<80421b31>] (hub_probe) from [<80428bbb>] (usb_probe_interface+0xbf/0x21c) +[<80428bbb>] (usb_probe_interface) from [<803ee13d>] (really_probe+0xa5/0x2c4) +[<803ee13d>] (really_probe) from [<803ee3d1>] (__driver_probe_device+0x75/0x174) +[<803ee3d1>] (__driver_probe_device) from [<803ee501>] (driver_probe_device+0x31/0x94) +usb 1-1: device descriptor read/8, error -71 + +Fixes: fc53d5279094 ("usb: chipidea: tegra: Support host mode") +Signed-off-by: Michał Mirosław +Link: https://lore.kernel.org/r/ef8466b834c1726f5404c95c3e192e90460146f8.1695934946.git.mirq-linux@rere.qmqm.pl +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/chipidea/host.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c +index 08af26b762a2d..abddd39d1ff1e 100644 +--- a/drivers/usb/chipidea/host.c ++++ b/drivers/usb/chipidea/host.c +@@ -411,12 +411,13 @@ static int ci_hdrc_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags) + const unsigned int ci_hdrc_usb_dma_align = 32; + size_t kmalloc_size; + +- if (urb->num_sgs || urb->sg || urb->transfer_buffer_length == 0 || +- !((uintptr_t)urb->transfer_buffer & (ci_hdrc_usb_dma_align - 1))) ++ if (urb->num_sgs || urb->sg || urb->transfer_buffer_length == 0) ++ return 0; ++ if (!((uintptr_t)urb->transfer_buffer & (ci_hdrc_usb_dma_align - 1)) && !(urb->transfer_buffer_length & 3)) + return 0; + + /* Allocate a buffer with enough padding for alignment */ +- kmalloc_size = urb->transfer_buffer_length + ++ kmalloc_size = ALIGN(urb->transfer_buffer_length, 4) + + sizeof(struct ci_hdrc_dma_aligned_buffer) + + ci_hdrc_usb_dma_align - 1; + +-- +2.42.0 + diff --git a/queue-6.6/usb-chipidea-simplify-tegra-dma-alignment-code.patch b/queue-6.6/usb-chipidea-simplify-tegra-dma-alignment-code.patch new file mode 100644 index 00000000000..9391c991e47 --- /dev/null +++ b/queue-6.6/usb-chipidea-simplify-tegra-dma-alignment-code.patch @@ -0,0 +1,138 @@ +From 9ca01556ce2d705ad00276e8a5dcbcdb70b431e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Sep 2023 23:06:03 +0200 +Subject: usb: chipidea: Simplify Tegra DMA alignment code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michał Mirosław + +[ Upstream commit 2ae61a2562c0d1720545b0845829a65fb6a9c2c6 ] + +The USB host on Tegra3 works with 32-bit alignment. Previous code tried +to align the buffer, but it did align the wrapper struct instead, so +the buffer was at a constant offset of 8 bytes (two pointers) from +expected alignment. Since kmalloc() guarantees at least 8-byte +alignment already, the alignment-extending is removed. + +Fixes: fc53d5279094 ("usb: chipidea: tegra: Support host mode") +Signed-off-by: Michał Mirosław +Link: https://lore.kernel.org/r/a0d917d492b1f91ee0019e68b8e8bca9c585393f.1695934946.git.mirq-linux@rere.qmqm.pl +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/chipidea/host.c | 45 +++++++++++++++---------------------- + 1 file changed, 18 insertions(+), 27 deletions(-) + +diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c +index abddd39d1ff1e..0cce192083701 100644 +--- a/drivers/usb/chipidea/host.c ++++ b/drivers/usb/chipidea/host.c +@@ -30,8 +30,7 @@ struct ehci_ci_priv { + }; + + struct ci_hdrc_dma_aligned_buffer { +- void *kmalloc_ptr; +- void *old_xfer_buffer; ++ void *original_buffer; + u8 data[]; + }; + +@@ -380,60 +379,52 @@ static int ci_ehci_bus_suspend(struct usb_hcd *hcd) + return 0; + } + +-static void ci_hdrc_free_dma_aligned_buffer(struct urb *urb) ++static void ci_hdrc_free_dma_aligned_buffer(struct urb *urb, bool copy_back) + { + struct ci_hdrc_dma_aligned_buffer *temp; +- size_t length; + + if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER)) + return; ++ urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER; + + temp = container_of(urb->transfer_buffer, + struct ci_hdrc_dma_aligned_buffer, data); ++ urb->transfer_buffer = temp->original_buffer; ++ ++ if (copy_back && usb_urb_dir_in(urb)) { ++ size_t length; + +- if (usb_urb_dir_in(urb)) { + if (usb_pipeisoc(urb->pipe)) + length = urb->transfer_buffer_length; + else + length = urb->actual_length; + +- memcpy(temp->old_xfer_buffer, temp->data, length); ++ memcpy(temp->original_buffer, temp->data, length); + } +- urb->transfer_buffer = temp->old_xfer_buffer; +- kfree(temp->kmalloc_ptr); + +- urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER; ++ kfree(temp); + } + + static int ci_hdrc_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags) + { +- struct ci_hdrc_dma_aligned_buffer *temp, *kmalloc_ptr; +- const unsigned int ci_hdrc_usb_dma_align = 32; +- size_t kmalloc_size; ++ struct ci_hdrc_dma_aligned_buffer *temp; + + if (urb->num_sgs || urb->sg || urb->transfer_buffer_length == 0) + return 0; +- if (!((uintptr_t)urb->transfer_buffer & (ci_hdrc_usb_dma_align - 1)) && !(urb->transfer_buffer_length & 3)) ++ if (IS_ALIGNED((uintptr_t)urb->transfer_buffer, 4) ++ && IS_ALIGNED(urb->transfer_buffer_length, 4)) + return 0; + +- /* Allocate a buffer with enough padding for alignment */ +- kmalloc_size = ALIGN(urb->transfer_buffer_length, 4) + +- sizeof(struct ci_hdrc_dma_aligned_buffer) + +- ci_hdrc_usb_dma_align - 1; +- +- kmalloc_ptr = kmalloc(kmalloc_size, mem_flags); +- if (!kmalloc_ptr) ++ temp = kmalloc(sizeof(*temp) + ALIGN(urb->transfer_buffer_length, 4), mem_flags); ++ if (!temp) + return -ENOMEM; + +- /* Position our struct dma_aligned_buffer such that data is aligned */ +- temp = PTR_ALIGN(kmalloc_ptr + 1, ci_hdrc_usb_dma_align) - 1; +- temp->kmalloc_ptr = kmalloc_ptr; +- temp->old_xfer_buffer = urb->transfer_buffer; + if (usb_urb_dir_out(urb)) + memcpy(temp->data, urb->transfer_buffer, + urb->transfer_buffer_length); +- urb->transfer_buffer = temp->data; + ++ temp->original_buffer = urb->transfer_buffer; ++ urb->transfer_buffer = temp->data; + urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER; + + return 0; +@@ -450,7 +441,7 @@ static int ci_hdrc_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, + + ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags); + if (ret) +- ci_hdrc_free_dma_aligned_buffer(urb); ++ ci_hdrc_free_dma_aligned_buffer(urb, false); + + return ret; + } +@@ -458,7 +449,7 @@ static int ci_hdrc_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, + static void ci_hdrc_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) + { + usb_hcd_unmap_urb_for_dma(hcd, urb); +- ci_hdrc_free_dma_aligned_buffer(urb); ++ ci_hdrc_free_dma_aligned_buffer(urb, true); + } + + #ifdef CONFIG_PM_SLEEP +-- +2.42.0 + diff --git a/queue-6.6/usb-dwc2-fix-possible-null-pointer-dereference-cause.patch b/queue-6.6/usb-dwc2-fix-possible-null-pointer-dereference-cause.patch new file mode 100644 index 00000000000..890aca7a3d2 --- /dev/null +++ b/queue-6.6/usb-dwc2-fix-possible-null-pointer-dereference-cause.patch @@ -0,0 +1,69 @@ +From daebc792d117f5837d66bbab1dee4c7d66166110 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Sep 2023 10:44:04 +0800 +Subject: usb: dwc2: fix possible NULL pointer dereference caused by driver + concurrency + +From: Jia-Ju Bai + +[ Upstream commit ef307bc6ef04e8c1ea843231db58e3afaafa9fa6 ] + +In _dwc2_hcd_urb_enqueue(), "urb->hcpriv = NULL" is executed without +holding the lock "hsotg->lock". In _dwc2_hcd_urb_dequeue(): + + spin_lock_irqsave(&hsotg->lock, flags); + ... + if (!urb->hcpriv) { + dev_dbg(hsotg->dev, "## urb->hcpriv is NULL ##\n"); + goto out; + } + rc = dwc2_hcd_urb_dequeue(hsotg, urb->hcpriv); // Use urb->hcpriv + ... +out: + spin_unlock_irqrestore(&hsotg->lock, flags); + +When _dwc2_hcd_urb_enqueue() and _dwc2_hcd_urb_dequeue() are +concurrently executed, the NULL check of "urb->hcpriv" can be executed +before "urb->hcpriv = NULL". After urb->hcpriv is NULL, it can be used +in the function call to dwc2_hcd_urb_dequeue(), which can cause a NULL +pointer dereference. + +This possible bug is found by an experimental static analysis tool +developed by myself. This tool analyzes the locking APIs to extract +function pairs that can be concurrently executed, and then analyzes the +instructions in the paired functions to identify possible concurrency +bugs including data races and atomicity violations. The above possible +bug is reported, when my tool analyzes the source code of Linux 6.5. + +To fix this possible bug, "urb->hcpriv = NULL" should be executed with +holding the lock "hsotg->lock". After using this patch, my tool never +reports the possible bug, with the kernelconfiguration allyesconfig for +x86_64. Because I have no associated hardware, I cannot test the patch +in runtime testing, and just verify it according to the code logic. + +Fixes: 33ad261aa62b ("usb: dwc2: host: spinlock urb_enqueue") +Signed-off-by: Jia-Ju Bai +Link: https://lore.kernel.org/r/20230926024404.832096-1-baijiaju@buaa.edu.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/hcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c +index 657f1f659ffaf..35c7a4df8e717 100644 +--- a/drivers/usb/dwc2/hcd.c ++++ b/drivers/usb/dwc2/hcd.c +@@ -4769,8 +4769,8 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, + if (qh_allocated && qh->channel && qh->channel->qh == qh) + qh->channel->qh = NULL; + fail2: +- spin_unlock_irqrestore(&hsotg->lock, flags); + urb->hcpriv = NULL; ++ spin_unlock_irqrestore(&hsotg->lock, flags); + kfree(qtd); + fail1: + if (qh_allocated) { +-- +2.42.0 + diff --git a/queue-6.6/usb-host-xhci-plat-fix-possible-kernel-oops-while-re.patch b/queue-6.6/usb-host-xhci-plat-fix-possible-kernel-oops-while-re.patch new file mode 100644 index 00000000000..6f18b5513cd --- /dev/null +++ b/queue-6.6/usb-host-xhci-plat-fix-possible-kernel-oops-while-re.patch @@ -0,0 +1,80 @@ +From c3913021c3bf1840e01e4f8819814265e5f36289 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Oct 2023 13:29:23 +0300 +Subject: usb: host: xhci-plat: fix possible kernel oops while resuming + +From: Sergey Shtylyov + +[ Upstream commit a5f928db59519a15e82ecba4ae3e7cbf5a44715a ] + +If this driver enables the xHC clocks while resuming from sleep, it calls +clk_prepare_enable() without checking for errors and blithely goes on to +read/write the xHC's registers -- which, with the xHC not being clocked, +at least on ARM32 usually causes an imprecise external abort exceptions +which cause kernel oops. Currently, the chips for which the driver does +the clock dance on suspend/resume seem to be the Broadcom STB SoCs, based +on ARM32 CPUs, as it seems... + +Found by Linux Verification Center (linuxtesting.org) with the Svace static +analysis tool. + +Fixes: 8bd954c56197 ("usb: host: xhci-plat: suspend and resume clocks") +Signed-off-by: Sergey Shtylyov +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20231019102924.2797346-19-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/host/xhci-plat.c | 23 +++++++++++++++++++---- + 1 file changed, 19 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c +index 28218c8f18376..b93161374293b 100644 +--- a/drivers/usb/host/xhci-plat.c ++++ b/drivers/usb/host/xhci-plat.c +@@ -458,23 +458,38 @@ static int __maybe_unused xhci_plat_resume(struct device *dev) + int ret; + + if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) { +- clk_prepare_enable(xhci->clk); +- clk_prepare_enable(xhci->reg_clk); ++ ret = clk_prepare_enable(xhci->clk); ++ if (ret) ++ return ret; ++ ++ ret = clk_prepare_enable(xhci->reg_clk); ++ if (ret) { ++ clk_disable_unprepare(xhci->clk); ++ return ret; ++ } + } + + ret = xhci_priv_resume_quirk(hcd); + if (ret) +- return ret; ++ goto disable_clks; + + ret = xhci_resume(xhci, PMSG_RESUME); + if (ret) +- return ret; ++ goto disable_clks; + + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + return 0; ++ ++disable_clks: ++ if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) { ++ clk_disable_unprepare(xhci->clk); ++ clk_disable_unprepare(xhci->reg_clk); ++ } ++ ++ return ret; + } + + static int __maybe_unused xhci_plat_runtime_suspend(struct device *dev) +-- +2.42.0 + diff --git a/queue-6.6/usb-usbip-fix-stub_dev-hub-disconnect.patch b/queue-6.6/usb-usbip-fix-stub_dev-hub-disconnect.patch new file mode 100644 index 00000000000..cff721e5d1d --- /dev/null +++ b/queue-6.6/usb-usbip-fix-stub_dev-hub-disconnect.patch @@ -0,0 +1,46 @@ +From a18c78c1e34c96d5f80acbb558c27e665da734dd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Jun 2023 11:28:10 +0200 +Subject: USB: usbip: fix stub_dev hub disconnect + +From: Jonas Blixt + +[ Upstream commit 97475763484245916735a1aa9a3310a01d46b008 ] + +If a hub is disconnected that has device(s) that's attached to the usbip layer +the disconnect function might fail because it tries to release the port +on an already disconnected hub. + +Fixes: 6080cd0e9239 ("staging: usbip: claim ports used by shared devices") +Signed-off-by: Jonas Blixt +Acked-by: Shuah Khan +Link: https://lore.kernel.org/r/20230615092810.1215490-1-jonas.blixt@actia.se +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/usbip/stub_dev.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c +index 9c6954aad6c88..ce625b1ce9a51 100644 +--- a/drivers/usb/usbip/stub_dev.c ++++ b/drivers/usb/usbip/stub_dev.c +@@ -464,8 +464,13 @@ static void stub_disconnect(struct usb_device *udev) + /* release port */ + rc = usb_hub_release_port(udev->parent, udev->portnum, + (struct usb_dev_state *) udev); +- if (rc) { +- dev_dbg(&udev->dev, "unable to release port\n"); ++ /* ++ * NOTE: If a HUB disconnect triggered disconnect of the down stream ++ * device usb_hub_release_port will return -ENODEV so we can safely ignore ++ * that error here. ++ */ ++ if (rc && (rc != -ENODEV)) { ++ dev_dbg(&udev->dev, "unable to release port (%i)\n", rc); + return; + } + +-- +2.42.0 + diff --git a/queue-6.6/vfs-fix-readahead-2-on-block-devices.patch b/queue-6.6/vfs-fix-readahead-2-on-block-devices.patch new file mode 100644 index 00000000000..fc8eae6bb1e --- /dev/null +++ b/queue-6.6/vfs-fix-readahead-2-on-block-devices.patch @@ -0,0 +1,43 @@ +From dcd40640059506f14d39bd84ac96d6565679a4ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Oct 2023 20:57:04 -0500 +Subject: vfs: fix readahead(2) on block devices + +From: Reuben Hawkins + +[ Upstream commit 7116c0af4b8414b2f19fdb366eea213cbd9d91c2 ] + +Readahead was factored to call generic_fadvise. That refactor added an +S_ISREG restriction which broke readahead on block devices. + +In addition to S_ISREG, this change checks S_ISBLK to fix block device +readahead. There is no change in behavior with any file type besides block +devices in this change. + +Fixes: 3d8f7615319b ("vfs: implement readahead(2) using POSIX_FADV_WILLNEED") +Signed-off-by: Reuben Hawkins +Link: https://lore.kernel.org/r/20231003015704.2415-1-reubenhwk@gmail.com +Reviewed-by: Amir Goldstein +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + mm/readahead.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/mm/readahead.c b/mm/readahead.c +index e815c114de21e..6925e6959fd3f 100644 +--- a/mm/readahead.c ++++ b/mm/readahead.c +@@ -735,7 +735,8 @@ ssize_t ksys_readahead(int fd, loff_t offset, size_t count) + */ + ret = -EINVAL; + if (!f.file->f_mapping || !f.file->f_mapping->a_ops || +- !S_ISREG(file_inode(f.file)->i_mode)) ++ (!S_ISREG(file_inode(f.file)->i_mode) && ++ !S_ISBLK(file_inode(f.file)->i_mode))) + goto out; + + ret = vfs_fadvise(f.file, offset, count, POSIX_FADV_WILLNEED); +-- +2.42.0 + diff --git a/queue-6.6/virt-sevguest-fix-passing-a-stack-buffer-as-a-scatte.patch b/queue-6.6/virt-sevguest-fix-passing-a-stack-buffer-as-a-scatte.patch new file mode 100644 index 00000000000..fdb2e2a9198 --- /dev/null +++ b/queue-6.6/virt-sevguest-fix-passing-a-stack-buffer-as-a-scatte.patch @@ -0,0 +1,198 @@ +From 7f41346bbd7dfc1599d151b970c27bb62c621691 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 12:53:33 -0700 +Subject: virt: sevguest: Fix passing a stack buffer as a scatterlist target + +From: Dan Williams + +[ Upstream commit db10cb9b574675402bfd8fe1a31aafdd45b002df ] + +CONFIG_DEBUG_SG highlights that get_{report,ext_report,derived_key)()} +are passing stack buffers as the @req_buf argument to +handle_guest_request(), generating a Call Trace of the following form: + + WARNING: CPU: 0 PID: 1175 at include/linux/scatterlist.h:187 enc_dec_message+0x518/0x5b0 [sev_guest] + [..] + Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/26/2023 + RIP: 0010:enc_dec_message+0x518/0x5b0 [sev_guest] + Call Trace: + + [..] + handle_guest_request+0x135/0x520 [sev_guest] + get_ext_report+0x1ec/0x3e0 [sev_guest] + snp_guest_ioctl+0x157/0x200 [sev_guest] + +Note that the above Call Trace was with the DEBUG_SG BUG_ON()s converted +to WARN_ON()s. + +This is benign as long as there are no hardware crypto accelerators +loaded for the aead cipher, and no subsequent dma_map_sg() is performed +on the scatterlist. However, sev-guest can not assume the presence of +an aead accelerator nor can it assume that CONFIG_DEBUG_SG is disabled. + +Resolve this bug by allocating virt_addr_valid() memory, similar to the +other buffers am @snp_dev instance carries, to marshal requests from +user buffers to kernel buffers. + +Reported-by: Peter Gonda +Closes: http://lore.kernel.org/r/CAMkAt6r2VPPMZ__SQfJse8qWsUyYW3AgYbOUVM0S_Vtk=KvkxQ@mail.gmail.com +Fixes: fce96cf04430 ("virt: Add SEV-SNP guest driver") +Cc: Borislav Petkov +Cc: Tom Lendacky +Cc: Dionna Glaze +Cc: Jeremi Piotrowski +Tested-by: Kuppuswamy Sathyanarayanan +Reviewed-by: Tom Lendacky +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + drivers/virt/coco/sev-guest/sev-guest.c | 45 ++++++++++++++----------- + 1 file changed, 25 insertions(+), 20 deletions(-) + +diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c +index 97dbe715e96ad..5bee58ef5f1e3 100644 +--- a/drivers/virt/coco/sev-guest/sev-guest.c ++++ b/drivers/virt/coco/sev-guest/sev-guest.c +@@ -57,6 +57,11 @@ struct snp_guest_dev { + + struct snp_secrets_page_layout *layout; + struct snp_req_data input; ++ union { ++ struct snp_report_req report; ++ struct snp_derived_key_req derived_key; ++ struct snp_ext_report_req ext_report; ++ } req; + u32 *os_area_msg_seqno; + u8 *vmpck; + }; +@@ -473,8 +478,8 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, + static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg) + { + struct snp_guest_crypto *crypto = snp_dev->crypto; ++ struct snp_report_req *req = &snp_dev->req.report; + struct snp_report_resp *resp; +- struct snp_report_req req; + int rc, resp_len; + + lockdep_assert_held(&snp_cmd_mutex); +@@ -482,7 +487,7 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io + if (!arg->req_data || !arg->resp_data) + return -EINVAL; + +- if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req))) ++ if (copy_from_user(req, (void __user *)arg->req_data, sizeof(*req))) + return -EFAULT; + + /* +@@ -496,7 +501,7 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io + return -ENOMEM; + + rc = handle_guest_request(snp_dev, SVM_VMGEXIT_GUEST_REQUEST, arg, +- SNP_MSG_REPORT_REQ, &req, sizeof(req), resp->data, ++ SNP_MSG_REPORT_REQ, req, sizeof(*req), resp->data, + resp_len); + if (rc) + goto e_free; +@@ -511,9 +516,9 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io + + static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg) + { ++ struct snp_derived_key_req *req = &snp_dev->req.derived_key; + struct snp_guest_crypto *crypto = snp_dev->crypto; + struct snp_derived_key_resp resp = {0}; +- struct snp_derived_key_req req; + int rc, resp_len; + /* Response data is 64 bytes and max authsize for GCM is 16 bytes. */ + u8 buf[64 + 16]; +@@ -532,11 +537,11 @@ static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_reque + if (sizeof(buf) < resp_len) + return -ENOMEM; + +- if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req))) ++ if (copy_from_user(req, (void __user *)arg->req_data, sizeof(*req))) + return -EFAULT; + + rc = handle_guest_request(snp_dev, SVM_VMGEXIT_GUEST_REQUEST, arg, +- SNP_MSG_KEY_REQ, &req, sizeof(req), buf, resp_len); ++ SNP_MSG_KEY_REQ, req, sizeof(*req), buf, resp_len); + if (rc) + return rc; + +@@ -552,8 +557,8 @@ static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_reque + + static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg) + { ++ struct snp_ext_report_req *req = &snp_dev->req.ext_report; + struct snp_guest_crypto *crypto = snp_dev->crypto; +- struct snp_ext_report_req req; + struct snp_report_resp *resp; + int ret, npages = 0, resp_len; + +@@ -562,18 +567,18 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques + if (!arg->req_data || !arg->resp_data) + return -EINVAL; + +- if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req))) ++ if (copy_from_user(req, (void __user *)arg->req_data, sizeof(*req))) + return -EFAULT; + + /* userspace does not want certificate data */ +- if (!req.certs_len || !req.certs_address) ++ if (!req->certs_len || !req->certs_address) + goto cmd; + +- if (req.certs_len > SEV_FW_BLOB_MAX_SIZE || +- !IS_ALIGNED(req.certs_len, PAGE_SIZE)) ++ if (req->certs_len > SEV_FW_BLOB_MAX_SIZE || ++ !IS_ALIGNED(req->certs_len, PAGE_SIZE)) + return -EINVAL; + +- if (!access_ok((const void __user *)req.certs_address, req.certs_len)) ++ if (!access_ok((const void __user *)req->certs_address, req->certs_len)) + return -EFAULT; + + /* +@@ -582,8 +587,8 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques + * the host. If host does not supply any certs in it, then copy + * zeros to indicate that certificate data was not provided. + */ +- memset(snp_dev->certs_data, 0, req.certs_len); +- npages = req.certs_len >> PAGE_SHIFT; ++ memset(snp_dev->certs_data, 0, req->certs_len); ++ npages = req->certs_len >> PAGE_SHIFT; + cmd: + /* + * The intermediate response buffer is used while decrypting the +@@ -597,14 +602,14 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques + + snp_dev->input.data_npages = npages; + ret = handle_guest_request(snp_dev, SVM_VMGEXIT_EXT_GUEST_REQUEST, arg, +- SNP_MSG_REPORT_REQ, &req.data, +- sizeof(req.data), resp->data, resp_len); ++ SNP_MSG_REPORT_REQ, &req->data, ++ sizeof(req->data), resp->data, resp_len); + + /* If certs length is invalid then copy the returned length */ + if (arg->vmm_error == SNP_GUEST_VMM_ERR_INVALID_LEN) { +- req.certs_len = snp_dev->input.data_npages << PAGE_SHIFT; ++ req->certs_len = snp_dev->input.data_npages << PAGE_SHIFT; + +- if (copy_to_user((void __user *)arg->req_data, &req, sizeof(req))) ++ if (copy_to_user((void __user *)arg->req_data, req, sizeof(*req))) + ret = -EFAULT; + } + +@@ -612,8 +617,8 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques + goto e_free; + + if (npages && +- copy_to_user((void __user *)req.certs_address, snp_dev->certs_data, +- req.certs_len)) { ++ copy_to_user((void __user *)req->certs_address, snp_dev->certs_data, ++ req->certs_len)) { + ret = -EFAULT; + goto e_free; + } +-- +2.42.0 + diff --git a/queue-6.6/virtio-net-consistently-save-parameters-for-per-queu.patch b/queue-6.6/virtio-net-consistently-save-parameters-for-per-queu.patch new file mode 100644 index 00000000000..10a08942cbc --- /dev/null +++ b/queue-6.6/virtio-net-consistently-save-parameters-for-per-queu.patch @@ -0,0 +1,59 @@ +From d6e64338ed191f80f04de05552ee10931e978a32 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Oct 2023 14:27:41 +0800 +Subject: virtio-net: consistently save parameters for per-queue + +From: Heng Qi + +[ Upstream commit e9420838ab4ffb82850095549e94dcee3f7fe0cb ] + +When using .set_coalesce interface to set all queue coalescing +parameters, we need to update both per-queue and global save values. + +Fixes: 394bd87764b6 ("virtio_net: support per queue interrupt coalesce command") +Cc: Gavin Li +Signed-off-by: Heng Qi +Acked-by: Jason Wang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/virtio_net.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index b218c2bafddcc..d3b976a591c84 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -3233,6 +3233,7 @@ static int virtnet_send_notf_coal_cmds(struct virtnet_info *vi, + struct ethtool_coalesce *ec) + { + struct scatterlist sgs_tx, sgs_rx; ++ int i; + + vi->ctrl->coal_tx.tx_usecs = cpu_to_le32(ec->tx_coalesce_usecs); + vi->ctrl->coal_tx.tx_max_packets = cpu_to_le32(ec->tx_max_coalesced_frames); +@@ -3246,6 +3247,10 @@ static int virtnet_send_notf_coal_cmds(struct virtnet_info *vi, + /* Save parameters */ + vi->intr_coal_tx.max_usecs = ec->tx_coalesce_usecs; + vi->intr_coal_tx.max_packets = ec->tx_max_coalesced_frames; ++ for (i = 0; i < vi->max_queue_pairs; i++) { ++ vi->sq[i].intr_coal.max_usecs = ec->tx_coalesce_usecs; ++ vi->sq[i].intr_coal.max_packets = ec->tx_max_coalesced_frames; ++ } + + vi->ctrl->coal_rx.rx_usecs = cpu_to_le32(ec->rx_coalesce_usecs); + vi->ctrl->coal_rx.rx_max_packets = cpu_to_le32(ec->rx_max_coalesced_frames); +@@ -3259,6 +3264,10 @@ static int virtnet_send_notf_coal_cmds(struct virtnet_info *vi, + /* Save parameters */ + vi->intr_coal_rx.max_usecs = ec->rx_coalesce_usecs; + vi->intr_coal_rx.max_packets = ec->rx_max_coalesced_frames; ++ for (i = 0; i < vi->max_queue_pairs; i++) { ++ vi->rq[i].intr_coal.max_usecs = ec->rx_coalesce_usecs; ++ vi->rq[i].intr_coal.max_packets = ec->rx_max_coalesced_frames; ++ } + + return 0; + } +-- +2.42.0 + diff --git a/queue-6.6/virtio-net-fix-mismatch-of-getting-tx-frames.patch b/queue-6.6/virtio-net-fix-mismatch-of-getting-tx-frames.patch new file mode 100644 index 00000000000..182c8f8a7c1 --- /dev/null +++ b/queue-6.6/virtio-net-fix-mismatch-of-getting-tx-frames.patch @@ -0,0 +1,38 @@ +From 346e9c92cc605c0f5810809bd4b007aadeeea348 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Oct 2023 14:27:40 +0800 +Subject: virtio-net: fix mismatch of getting tx-frames + +From: Heng Qi + +[ Upstream commit 134674c1877be5e35e35802517c67a9ecce21153 ] + +Since virtio-net allows switching napi_tx for per txq, we have to +get the specific txq's result now. + +Fixes: 394bd87764b6 ("virtio_net: support per queue interrupt coalesce command") +Cc: Gavin Li +Signed-off-by: Heng Qi +Acked-by: Jason Wang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/virtio_net.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index d67f742fbd4c5..b218c2bafddcc 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -3453,7 +3453,7 @@ static int virtnet_get_per_queue_coalesce(struct net_device *dev, + } else { + ec->rx_max_coalesced_frames = 1; + +- if (vi->sq[0].napi.weight) ++ if (vi->sq[queue].napi.weight) + ec->tx_max_coalesced_frames = 1; + } + +-- +2.42.0 + diff --git a/queue-6.6/virtio-net-fix-per-queue-coalescing-parameter-settin.patch b/queue-6.6/virtio-net-fix-per-queue-coalescing-parameter-settin.patch new file mode 100644 index 00000000000..bbeb223c1a2 --- /dev/null +++ b/queue-6.6/virtio-net-fix-per-queue-coalescing-parameter-settin.patch @@ -0,0 +1,74 @@ +From 726004f60ae921c05551215dc11bb4fd02ade807 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Oct 2023 14:27:42 +0800 +Subject: virtio-net: fix per queue coalescing parameter setting + +From: Heng Qi + +[ Upstream commit bfb2b3609162135625bf96acf5118051cd0d082e ] + +When the user sets a non-zero coalescing parameter to 0 for a specific +virtqueue, it does not work as expected, so let's fix this. + +Fixes: 394bd87764b6 ("virtio_net: support per queue interrupt coalesce command") +Reported-by: Xiaoming Zhao +Cc: Gavin Li +Signed-off-by: Heng Qi +Acked-by: Jason Wang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/virtio_net.c | 36 ++++++++++++++++-------------------- + 1 file changed, 16 insertions(+), 20 deletions(-) + +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index d3b976a591c84..4211f28c59dc8 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -3296,27 +3296,23 @@ static int virtnet_send_notf_coal_vq_cmds(struct virtnet_info *vi, + { + int err; + +- if (ec->rx_coalesce_usecs || ec->rx_max_coalesced_frames) { +- err = virtnet_send_ctrl_coal_vq_cmd(vi, rxq2vq(queue), +- ec->rx_coalesce_usecs, +- ec->rx_max_coalesced_frames); +- if (err) +- return err; +- /* Save parameters */ +- vi->rq[queue].intr_coal.max_usecs = ec->rx_coalesce_usecs; +- vi->rq[queue].intr_coal.max_packets = ec->rx_max_coalesced_frames; +- } ++ err = virtnet_send_ctrl_coal_vq_cmd(vi, rxq2vq(queue), ++ ec->rx_coalesce_usecs, ++ ec->rx_max_coalesced_frames); ++ if (err) ++ return err; + +- if (ec->tx_coalesce_usecs || ec->tx_max_coalesced_frames) { +- err = virtnet_send_ctrl_coal_vq_cmd(vi, txq2vq(queue), +- ec->tx_coalesce_usecs, +- ec->tx_max_coalesced_frames); +- if (err) +- return err; +- /* Save parameters */ +- vi->sq[queue].intr_coal.max_usecs = ec->tx_coalesce_usecs; +- vi->sq[queue].intr_coal.max_packets = ec->tx_max_coalesced_frames; +- } ++ vi->rq[queue].intr_coal.max_usecs = ec->rx_coalesce_usecs; ++ vi->rq[queue].intr_coal.max_packets = ec->rx_max_coalesced_frames; ++ ++ err = virtnet_send_ctrl_coal_vq_cmd(vi, txq2vq(queue), ++ ec->tx_coalesce_usecs, ++ ec->tx_max_coalesced_frames); ++ if (err) ++ return err; ++ ++ vi->sq[queue].intr_coal.max_usecs = ec->tx_coalesce_usecs; ++ vi->sq[queue].intr_coal.max_packets = ec->tx_max_coalesced_frames; + + return 0; + } +-- +2.42.0 + diff --git a/queue-6.6/virtio-net-fix-the-vq-coalescing-setting-for-vq-resi.patch b/queue-6.6/virtio-net-fix-the-vq-coalescing-setting-for-vq-resi.patch new file mode 100644 index 00000000000..b26239aa0bc --- /dev/null +++ b/queue-6.6/virtio-net-fix-the-vq-coalescing-setting-for-vq-resi.patch @@ -0,0 +1,89 @@ +From 6d15a71f407dec481732ab287daaaa92e79f301d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Oct 2023 14:27:43 +0800 +Subject: virtio-net: fix the vq coalescing setting for vq resize + +From: Heng Qi + +[ Upstream commit f61fe5f081cf40de08d0a4c89659baf23c900f0c ] + +According to the definition of virtqueue coalescing spec[1]: + + Upon disabling and re-enabling a transmit virtqueue, the device MUST set + the coalescing parameters of the virtqueue to those configured through the + VIRTIO_NET_CTRL_NOTF_COAL_TX_SET command, or, if the driver did not set + any TX coalescing parameters, to 0. + + Upon disabling and re-enabling a receive virtqueue, the device MUST set + the coalescing parameters of the virtqueue to those configured through the + VIRTIO_NET_CTRL_NOTF_COAL_RX_SET command, or, if the driver did not set + any RX coalescing parameters, to 0. + +We need to add this setting for vq resize (ethtool -G) where vq_reset happens. + +[1] https://lists.oasis-open.org/archives/virtio-dev/202303/msg00415.html + +Fixes: 394bd87764b6 ("virtio_net: support per queue interrupt coalesce command") +Cc: Gavin Li +Signed-off-by: Heng Qi +Acked-by: Jason Wang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/virtio_net.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 4211f28c59dc8..cd1e9e87eaa35 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -2855,6 +2855,9 @@ static void virtnet_get_ringparam(struct net_device *dev, + ring->tx_pending = virtqueue_get_vring_size(vi->sq[0].vq); + } + ++static int virtnet_send_ctrl_coal_vq_cmd(struct virtnet_info *vi, ++ u16 vqn, u32 max_usecs, u32 max_packets); ++ + static int virtnet_set_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring, + struct kernel_ethtool_ringparam *kernel_ring, +@@ -2890,12 +2893,36 @@ static int virtnet_set_ringparam(struct net_device *dev, + err = virtnet_tx_resize(vi, sq, ring->tx_pending); + if (err) + return err; ++ ++ /* Upon disabling and re-enabling a transmit virtqueue, the device must ++ * set the coalescing parameters of the virtqueue to those configured ++ * through the VIRTIO_NET_CTRL_NOTF_COAL_TX_SET command, or, if the driver ++ * did not set any TX coalescing parameters, to 0. ++ */ ++ err = virtnet_send_ctrl_coal_vq_cmd(vi, txq2vq(i), ++ vi->intr_coal_tx.max_usecs, ++ vi->intr_coal_tx.max_packets); ++ if (err) ++ return err; ++ ++ vi->sq[i].intr_coal.max_usecs = vi->intr_coal_tx.max_usecs; ++ vi->sq[i].intr_coal.max_packets = vi->intr_coal_tx.max_packets; + } + + if (ring->rx_pending != rx_pending) { + err = virtnet_rx_resize(vi, rq, ring->rx_pending); + if (err) + return err; ++ ++ /* The reason is same as the transmit virtqueue reset */ ++ err = virtnet_send_ctrl_coal_vq_cmd(vi, rxq2vq(i), ++ vi->intr_coal_rx.max_usecs, ++ vi->intr_coal_rx.max_packets); ++ if (err) ++ return err; ++ ++ vi->rq[i].intr_coal.max_usecs = vi->intr_coal_rx.max_usecs; ++ vi->rq[i].intr_coal.max_packets = vi->intr_coal_rx.max_packets; + } + } + +-- +2.42.0 + diff --git a/queue-6.6/virtio_net-use-u64_stats_t-infra-to-avoid-data-races.patch b/queue-6.6/virtio_net-use-u64_stats_t-infra-to-avoid-data-races.patch new file mode 100644 index 00000000000..be58363e11d --- /dev/null +++ b/queue-6.6/virtio_net-use-u64_stats_t-infra-to-avoid-data-races.patch @@ -0,0 +1,430 @@ +From 176d54dfbc24143b7a89ab1fb88ce6106f532fd3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Oct 2023 17:18:40 +0000 +Subject: virtio_net: use u64_stats_t infra to avoid data-races + +From: Eric Dumazet + +[ Upstream commit 61217d8f6360437329af1b16b8bbd9143167718d ] + +syzbot reported a data-race in virtnet_poll / virtnet_stats [1] + +u64_stats_t infra has very nice accessors that must be used +to avoid potential load-store tearing. + +[1] +BUG: KCSAN: data-race in virtnet_poll / virtnet_stats + +read-write to 0xffff88810271b1a0 of 8 bytes by interrupt on cpu 0: +virtnet_receive drivers/net/virtio_net.c:2102 [inline] +virtnet_poll+0x6c8/0xb40 drivers/net/virtio_net.c:2148 +__napi_poll+0x60/0x3b0 net/core/dev.c:6527 +napi_poll net/core/dev.c:6594 [inline] +net_rx_action+0x32b/0x750 net/core/dev.c:6727 +__do_softirq+0xc1/0x265 kernel/softirq.c:553 +invoke_softirq kernel/softirq.c:427 [inline] +__irq_exit_rcu kernel/softirq.c:632 [inline] +irq_exit_rcu+0x3b/0x90 kernel/softirq.c:644 +common_interrupt+0x7f/0x90 arch/x86/kernel/irq.c:247 +asm_common_interrupt+0x26/0x40 arch/x86/include/asm/idtentry.h:636 +__sanitizer_cov_trace_const_cmp8+0x0/0x80 kernel/kcov.c:306 +jbd2_write_access_granted fs/jbd2/transaction.c:1174 [inline] +jbd2_journal_get_write_access+0x94/0x1c0 fs/jbd2/transaction.c:1239 +__ext4_journal_get_write_access+0x154/0x3f0 fs/ext4/ext4_jbd2.c:241 +ext4_reserve_inode_write+0x14e/0x200 fs/ext4/inode.c:5745 +__ext4_mark_inode_dirty+0x8e/0x440 fs/ext4/inode.c:5919 +ext4_evict_inode+0xaf0/0xdc0 fs/ext4/inode.c:299 +evict+0x1aa/0x410 fs/inode.c:664 +iput_final fs/inode.c:1775 [inline] +iput+0x42c/0x5b0 fs/inode.c:1801 +do_unlinkat+0x2b9/0x4f0 fs/namei.c:4405 +__do_sys_unlink fs/namei.c:4446 [inline] +__se_sys_unlink fs/namei.c:4444 [inline] +__x64_sys_unlink+0x30/0x40 fs/namei.c:4444 +do_syscall_x64 arch/x86/entry/common.c:50 [inline] +do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 +entry_SYSCALL_64_after_hwframe+0x63/0xcd + +read to 0xffff88810271b1a0 of 8 bytes by task 2814 on cpu 1: +virtnet_stats+0x1b3/0x340 drivers/net/virtio_net.c:2564 +dev_get_stats+0x6d/0x860 net/core/dev.c:10511 +rtnl_fill_stats+0x45/0x320 net/core/rtnetlink.c:1261 +rtnl_fill_ifinfo+0xd0e/0x1120 net/core/rtnetlink.c:1867 +rtnl_dump_ifinfo+0x7f9/0xc20 net/core/rtnetlink.c:2240 +netlink_dump+0x390/0x720 net/netlink/af_netlink.c:2266 +netlink_recvmsg+0x425/0x780 net/netlink/af_netlink.c:1992 +sock_recvmsg_nosec net/socket.c:1027 [inline] +sock_recvmsg net/socket.c:1049 [inline] +____sys_recvmsg+0x156/0x310 net/socket.c:2760 +___sys_recvmsg net/socket.c:2802 [inline] +__sys_recvmsg+0x1ea/0x270 net/socket.c:2832 +__do_sys_recvmsg net/socket.c:2842 [inline] +__se_sys_recvmsg net/socket.c:2839 [inline] +__x64_sys_recvmsg+0x46/0x50 net/socket.c:2839 +do_syscall_x64 arch/x86/entry/common.c:50 [inline] +do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 +entry_SYSCALL_64_after_hwframe+0x63/0xcd + +value changed: 0x000000000045c334 -> 0x000000000045c376 + +Fixes: 3fa2a1df9094 ("virtio-net: per cpu 64 bit stats (v2)") +Signed-off-by: Eric Dumazet +Acked-by: Michael S. Tsirkin +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/virtio_net.c | 124 ++++++++++++++++++++------------------- + 1 file changed, 65 insertions(+), 59 deletions(-) + +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index cd1e9e87eaa35..0c0be6b872c6a 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -81,24 +81,24 @@ struct virtnet_stat_desc { + + struct virtnet_sq_stats { + struct u64_stats_sync syncp; +- u64 packets; +- u64 bytes; +- u64 xdp_tx; +- u64 xdp_tx_drops; +- u64 kicks; +- u64 tx_timeouts; ++ u64_stats_t packets; ++ u64_stats_t bytes; ++ u64_stats_t xdp_tx; ++ u64_stats_t xdp_tx_drops; ++ u64_stats_t kicks; ++ u64_stats_t tx_timeouts; + }; + + struct virtnet_rq_stats { + struct u64_stats_sync syncp; +- u64 packets; +- u64 bytes; +- u64 drops; +- u64 xdp_packets; +- u64 xdp_tx; +- u64 xdp_redirects; +- u64 xdp_drops; +- u64 kicks; ++ u64_stats_t packets; ++ u64_stats_t bytes; ++ u64_stats_t drops; ++ u64_stats_t xdp_packets; ++ u64_stats_t xdp_tx; ++ u64_stats_t xdp_redirects; ++ u64_stats_t xdp_drops; ++ u64_stats_t kicks; + }; + + #define VIRTNET_SQ_STAT(m) offsetof(struct virtnet_sq_stats, m) +@@ -775,8 +775,8 @@ static void free_old_xmit_skbs(struct send_queue *sq, bool in_napi) + return; + + u64_stats_update_begin(&sq->stats.syncp); +- sq->stats.bytes += bytes; +- sq->stats.packets += packets; ++ u64_stats_add(&sq->stats.bytes, bytes); ++ u64_stats_add(&sq->stats.packets, packets); + u64_stats_update_end(&sq->stats.syncp); + } + +@@ -975,11 +975,11 @@ static int virtnet_xdp_xmit(struct net_device *dev, + } + out: + u64_stats_update_begin(&sq->stats.syncp); +- sq->stats.bytes += bytes; +- sq->stats.packets += packets; +- sq->stats.xdp_tx += n; +- sq->stats.xdp_tx_drops += n - nxmit; +- sq->stats.kicks += kicks; ++ u64_stats_add(&sq->stats.bytes, bytes); ++ u64_stats_add(&sq->stats.packets, packets); ++ u64_stats_add(&sq->stats.xdp_tx, n); ++ u64_stats_add(&sq->stats.xdp_tx_drops, n - nxmit); ++ u64_stats_add(&sq->stats.kicks, kicks); + u64_stats_update_end(&sq->stats.syncp); + + virtnet_xdp_put_sq(vi, sq); +@@ -1011,14 +1011,14 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp, + u32 act; + + act = bpf_prog_run_xdp(xdp_prog, xdp); +- stats->xdp_packets++; ++ u64_stats_inc(&stats->xdp_packets); + + switch (act) { + case XDP_PASS: + return act; + + case XDP_TX: +- stats->xdp_tx++; ++ u64_stats_inc(&stats->xdp_tx); + xdpf = xdp_convert_buff_to_frame(xdp); + if (unlikely(!xdpf)) { + netdev_dbg(dev, "convert buff to frame failed for xdp\n"); +@@ -1036,7 +1036,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp, + return act; + + case XDP_REDIRECT: +- stats->xdp_redirects++; ++ u64_stats_inc(&stats->xdp_redirects); + err = xdp_do_redirect(dev, xdp, xdp_prog); + if (err) + return XDP_DROP; +@@ -1232,9 +1232,9 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev, + return skb; + + err_xdp: +- stats->xdp_drops++; ++ u64_stats_inc(&stats->xdp_drops); + err: +- stats->drops++; ++ u64_stats_inc(&stats->drops); + put_page(page); + xdp_xmit: + return NULL; +@@ -1253,7 +1253,7 @@ static struct sk_buff *receive_small(struct net_device *dev, + struct sk_buff *skb; + + len -= vi->hdr_len; +- stats->bytes += len; ++ u64_stats_add(&stats->bytes, len); + + if (unlikely(len > GOOD_PACKET_LEN)) { + pr_debug("%s: rx error: len %u exceeds max size %d\n", +@@ -1282,7 +1282,7 @@ static struct sk_buff *receive_small(struct net_device *dev, + return skb; + + err: +- stats->drops++; ++ u64_stats_inc(&stats->drops); + put_page(page); + return NULL; + } +@@ -1298,14 +1298,14 @@ static struct sk_buff *receive_big(struct net_device *dev, + struct sk_buff *skb = + page_to_skb(vi, rq, page, 0, len, PAGE_SIZE, 0); + +- stats->bytes += len - vi->hdr_len; ++ u64_stats_add(&stats->bytes, len - vi->hdr_len); + if (unlikely(!skb)) + goto err; + + return skb; + + err: +- stats->drops++; ++ u64_stats_inc(&stats->drops); + give_pages(rq, page); + return NULL; + } +@@ -1326,7 +1326,7 @@ static void mergeable_buf_free(struct receive_queue *rq, int num_buf, + dev->stats.rx_length_errors++; + break; + } +- stats->bytes += len; ++ u64_stats_add(&stats->bytes, len); + page = virt_to_head_page(buf); + put_page(page); + } +@@ -1436,7 +1436,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev, + goto err; + } + +- stats->bytes += len; ++ u64_stats_add(&stats->bytes, len); + page = virt_to_head_page(buf); + offset = buf - page_address(page); + +@@ -1600,8 +1600,8 @@ static struct sk_buff *receive_mergeable_xdp(struct net_device *dev, + put_page(page); + mergeable_buf_free(rq, num_buf, dev, stats); + +- stats->xdp_drops++; +- stats->drops++; ++ u64_stats_inc(&stats->xdp_drops); ++ u64_stats_inc(&stats->drops); + return NULL; + } + +@@ -1625,7 +1625,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, + unsigned int room = SKB_DATA_ALIGN(headroom + tailroom); + + head_skb = NULL; +- stats->bytes += len - vi->hdr_len; ++ u64_stats_add(&stats->bytes, len - vi->hdr_len); + + if (unlikely(len > truesize - room)) { + pr_debug("%s: rx error: len %u exceeds truesize %lu\n", +@@ -1666,7 +1666,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, + goto err_buf; + } + +- stats->bytes += len; ++ u64_stats_add(&stats->bytes, len); + page = virt_to_head_page(buf); + + truesize = mergeable_ctx_to_truesize(ctx); +@@ -1718,7 +1718,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, + mergeable_buf_free(rq, num_buf, dev, stats); + + err_buf: +- stats->drops++; ++ u64_stats_inc(&stats->drops); + dev_kfree_skb(head_skb); + return NULL; + } +@@ -1985,7 +1985,7 @@ static bool try_fill_recv(struct virtnet_info *vi, struct receive_queue *rq, + unsigned long flags; + + flags = u64_stats_update_begin_irqsave(&rq->stats.syncp); +- rq->stats.kicks++; ++ u64_stats_inc(&rq->stats.kicks); + u64_stats_update_end_irqrestore(&rq->stats.syncp, flags); + } + +@@ -2065,22 +2065,23 @@ static int virtnet_receive(struct receive_queue *rq, int budget, + struct virtnet_info *vi = rq->vq->vdev->priv; + struct virtnet_rq_stats stats = {}; + unsigned int len; ++ int packets = 0; + void *buf; + int i; + + if (!vi->big_packets || vi->mergeable_rx_bufs) { + void *ctx; + +- while (stats.packets < budget && ++ while (packets < budget && + (buf = virtnet_rq_get_buf(rq, &len, &ctx))) { + receive_buf(vi, rq, buf, len, ctx, xdp_xmit, &stats); +- stats.packets++; ++ packets++; + } + } else { +- while (stats.packets < budget && ++ while (packets < budget && + (buf = virtnet_rq_get_buf(rq, &len, NULL)) != NULL) { + receive_buf(vi, rq, buf, len, NULL, xdp_xmit, &stats); +- stats.packets++; ++ packets++; + } + } + +@@ -2093,17 +2094,19 @@ static int virtnet_receive(struct receive_queue *rq, int budget, + } + } + ++ u64_stats_set(&stats.packets, packets); + u64_stats_update_begin(&rq->stats.syncp); + for (i = 0; i < VIRTNET_RQ_STATS_LEN; i++) { + size_t offset = virtnet_rq_stats_desc[i].offset; +- u64 *item; ++ u64_stats_t *item, *src; + +- item = (u64 *)((u8 *)&rq->stats + offset); +- *item += *(u64 *)((u8 *)&stats + offset); ++ item = (u64_stats_t *)((u8 *)&rq->stats + offset); ++ src = (u64_stats_t *)((u8 *)&stats + offset); ++ u64_stats_add(item, u64_stats_read(src)); + } + u64_stats_update_end(&rq->stats.syncp); + +- return stats.packets; ++ return packets; + } + + static void virtnet_poll_cleantx(struct receive_queue *rq) +@@ -2158,7 +2161,7 @@ static int virtnet_poll(struct napi_struct *napi, int budget) + sq = virtnet_xdp_get_sq(vi); + if (virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq)) { + u64_stats_update_begin(&sq->stats.syncp); +- sq->stats.kicks++; ++ u64_stats_inc(&sq->stats.kicks); + u64_stats_update_end(&sq->stats.syncp); + } + virtnet_xdp_put_sq(vi, sq); +@@ -2370,7 +2373,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) + if (kick || netif_xmit_stopped(txq)) { + if (virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq)) { + u64_stats_update_begin(&sq->stats.syncp); +- sq->stats.kicks++; ++ u64_stats_inc(&sq->stats.kicks); + u64_stats_update_end(&sq->stats.syncp); + } + } +@@ -2553,16 +2556,16 @@ static void virtnet_stats(struct net_device *dev, + + do { + start = u64_stats_fetch_begin(&sq->stats.syncp); +- tpackets = sq->stats.packets; +- tbytes = sq->stats.bytes; +- terrors = sq->stats.tx_timeouts; ++ tpackets = u64_stats_read(&sq->stats.packets); ++ tbytes = u64_stats_read(&sq->stats.bytes); ++ terrors = u64_stats_read(&sq->stats.tx_timeouts); + } while (u64_stats_fetch_retry(&sq->stats.syncp, start)); + + do { + start = u64_stats_fetch_begin(&rq->stats.syncp); +- rpackets = rq->stats.packets; +- rbytes = rq->stats.bytes; +- rdrops = rq->stats.drops; ++ rpackets = u64_stats_read(&rq->stats.packets); ++ rbytes = u64_stats_read(&rq->stats.bytes); ++ rdrops = u64_stats_read(&rq->stats.drops); + } while (u64_stats_fetch_retry(&rq->stats.syncp, start)); + + tot->rx_packets += rpackets; +@@ -3191,17 +3194,19 @@ static void virtnet_get_ethtool_stats(struct net_device *dev, + struct virtnet_info *vi = netdev_priv(dev); + unsigned int idx = 0, start, i, j; + const u8 *stats_base; ++ const u64_stats_t *p; + size_t offset; + + for (i = 0; i < vi->curr_queue_pairs; i++) { + struct receive_queue *rq = &vi->rq[i]; + +- stats_base = (u8 *)&rq->stats; ++ stats_base = (const u8 *)&rq->stats; + do { + start = u64_stats_fetch_begin(&rq->stats.syncp); + for (j = 0; j < VIRTNET_RQ_STATS_LEN; j++) { + offset = virtnet_rq_stats_desc[j].offset; +- data[idx + j] = *(u64 *)(stats_base + offset); ++ p = (const u64_stats_t *)(stats_base + offset); ++ data[idx + j] = u64_stats_read(p); + } + } while (u64_stats_fetch_retry(&rq->stats.syncp, start)); + idx += VIRTNET_RQ_STATS_LEN; +@@ -3210,12 +3215,13 @@ static void virtnet_get_ethtool_stats(struct net_device *dev, + for (i = 0; i < vi->curr_queue_pairs; i++) { + struct send_queue *sq = &vi->sq[i]; + +- stats_base = (u8 *)&sq->stats; ++ stats_base = (const u8 *)&sq->stats; + do { + start = u64_stats_fetch_begin(&sq->stats.syncp); + for (j = 0; j < VIRTNET_SQ_STATS_LEN; j++) { + offset = virtnet_sq_stats_desc[j].offset; +- data[idx + j] = *(u64 *)(stats_base + offset); ++ p = (const u64_stats_t *)(stats_base + offset); ++ data[idx + j] = u64_stats_read(p); + } + } while (u64_stats_fetch_retry(&sq->stats.syncp, start)); + idx += VIRTNET_SQ_STATS_LEN; +@@ -3898,7 +3904,7 @@ static void virtnet_tx_timeout(struct net_device *dev, unsigned int txqueue) + struct netdev_queue *txq = netdev_get_tx_queue(dev, txqueue); + + u64_stats_update_begin(&sq->stats.syncp); +- sq->stats.tx_timeouts++; ++ u64_stats_inc(&sq->stats.tx_timeouts); + u64_stats_update_end(&sq->stats.syncp); + + netdev_err(dev, "TX timeout on queue: %u, sq: %s, vq: 0x%x, name: %s, %u usecs ago\n", +-- +2.42.0 + diff --git a/queue-6.6/wifi-ath-dfs_pattern_detector-fix-a-memory-initializ.patch b/queue-6.6/wifi-ath-dfs_pattern_detector-fix-a-memory-initializ.patch new file mode 100644 index 00000000000..640d248302a --- /dev/null +++ b/queue-6.6/wifi-ath-dfs_pattern_detector-fix-a-memory-initializ.patch @@ -0,0 +1,42 @@ +From 3e994bc19a5acee5425b5dea1fc5b785bb3e071d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 30 Sep 2023 07:54:47 +0300 +Subject: wifi: ath: dfs_pattern_detector: Fix a memory initialization issue + +From: Christophe JAILLET + +[ Upstream commit 79bd60ee87e1136718a686d6617ced5de88ee350 ] + +If an error occurs and channel_detector_exit() is called, it relies on +entries of the 'detectors' array to be NULL. +Otherwise, it may access to un-initialized memory. + +Fix it and initialize the memory, as what was done before the commit in +Fixes. + +Fixes: a063b650ce5d ("ath: dfs_pattern_detector: Avoid open coded arithmetic in memory allocation") +Signed-off-by: Christophe JAILLET +Reviewed-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/ad8c55b97ee4b330cb053ce2c448123c309cc91c.1695538105.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/dfs_pattern_detector.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/dfs_pattern_detector.c b/drivers/net/wireless/ath/dfs_pattern_detector.c +index 27f4d74a41c80..2788a1b06c17c 100644 +--- a/drivers/net/wireless/ath/dfs_pattern_detector.c ++++ b/drivers/net/wireless/ath/dfs_pattern_detector.c +@@ -206,7 +206,7 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq) + + INIT_LIST_HEAD(&cd->head); + cd->freq = freq; +- cd->detectors = kmalloc_array(dpd->num_radar_types, ++ cd->detectors = kcalloc(dpd->num_radar_types, + sizeof(*cd->detectors), GFP_ATOMIC); + if (cd->detectors == NULL) + goto fail; +-- +2.42.0 + diff --git a/queue-6.6/wifi-ath11k-fix-boot-failure-with-one-msi-vector.patch b/queue-6.6/wifi-ath11k-fix-boot-failure-with-one-msi-vector.patch new file mode 100644 index 00000000000..ece3e719098 --- /dev/null +++ b/queue-6.6/wifi-ath11k-fix-boot-failure-with-one-msi-vector.patch @@ -0,0 +1,113 @@ +From 9d7ba83c53000e323391a8df00367c3ee9239e70 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 09:56:06 +0800 +Subject: wifi: ath11k: fix boot failure with one MSI vector + +From: Baochen Qiang + +[ Upstream commit 39564b475ac5a589e6c22c43a08cbd283c295d2c ] + +Commit 5b32b6dd96633 ("ath11k: Remove core PCI references from +PCI common code") breaks with one MSI vector because it moves +affinity setting after IRQ request, see below log: + +[ 1417.278835] ath11k_pci 0000:02:00.0: failed to receive control response completion, polling.. +[ 1418.302829] ath11k_pci 0000:02:00.0: Service connect timeout +[ 1418.302833] ath11k_pci 0000:02:00.0: failed to connect to HTT: -110 +[ 1418.303669] ath11k_pci 0000:02:00.0: failed to start core: -110 + +The detail is, if do affinity request after IRQ activated, +which is done in request_irq(), kernel caches that request and +returns success directly. Later when a subsequent MHI interrupt is +fired, kernel will do the real affinity setting work, as a result, +changs the MSI vector. However at that time host has configured +old vector to hardware, so host never receives CE or DP interrupts. + +Fix it by setting affinity before registering MHI controller +where host is, for the first time, doing IRQ request. + +Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 +Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23 +Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-01160-QCAMSLSWPLZ-1 + +Fixes: 5b32b6dd9663 ("ath11k: Remove core PCI references from PCI common code") +Signed-off-by: Baochen Qiang +Acked-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230907015606.16297-1-quic_bqiang@quicinc.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath11k/pci.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c +index a5aa1857ec14b..09e65c5e55c4a 100644 +--- a/drivers/net/wireless/ath/ath11k/pci.c ++++ b/drivers/net/wireless/ath/ath11k/pci.c +@@ -854,10 +854,16 @@ static int ath11k_pci_probe(struct pci_dev *pdev, + if (ret) + goto err_pci_disable_msi; + ++ ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0)); ++ if (ret) { ++ ath11k_err(ab, "failed to set irq affinity %d\n", ret); ++ goto err_pci_disable_msi; ++ } ++ + ret = ath11k_mhi_register(ab_pci); + if (ret) { + ath11k_err(ab, "failed to register mhi: %d\n", ret); +- goto err_pci_disable_msi; ++ goto err_irq_affinity_cleanup; + } + + ret = ath11k_hal_srng_init(ab); +@@ -878,12 +884,6 @@ static int ath11k_pci_probe(struct pci_dev *pdev, + goto err_ce_free; + } + +- ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0)); +- if (ret) { +- ath11k_err(ab, "failed to set irq affinity %d\n", ret); +- goto err_free_irq; +- } +- + /* kernel may allocate a dummy vector before request_irq and + * then allocate a real vector when request_irq is called. + * So get msi_data here again to avoid spurious interrupt +@@ -892,20 +892,17 @@ static int ath11k_pci_probe(struct pci_dev *pdev, + ret = ath11k_pci_config_msi_data(ab_pci); + if (ret) { + ath11k_err(ab, "failed to config msi_data: %d\n", ret); +- goto err_irq_affinity_cleanup; ++ goto err_free_irq; + } + + ret = ath11k_core_init(ab); + if (ret) { + ath11k_err(ab, "failed to init core: %d\n", ret); +- goto err_irq_affinity_cleanup; ++ goto err_free_irq; + } + ath11k_qmi_fwreset_from_cold_boot(ab); + return 0; + +-err_irq_affinity_cleanup: +- ath11k_pci_set_irq_affinity_hint(ab_pci, NULL); +- + err_free_irq: + ath11k_pcic_free_irq(ab); + +@@ -918,6 +915,9 @@ static int ath11k_pci_probe(struct pci_dev *pdev, + err_mhi_unregister: + ath11k_mhi_unregister(ab_pci); + ++err_irq_affinity_cleanup: ++ ath11k_pci_set_irq_affinity_hint(ab_pci, NULL); ++ + err_pci_disable_msi: + ath11k_pci_free_msi(ab_pci); + +-- +2.42.0 + diff --git a/queue-6.6/wifi-ath11k-fix-tx-power-value-during-active-cac.patch b/queue-6.6/wifi-ath11k-fix-tx-power-value-during-active-cac.patch new file mode 100644 index 00000000000..e8ebd119afe --- /dev/null +++ b/queue-6.6/wifi-ath11k-fix-tx-power-value-during-active-cac.patch @@ -0,0 +1,53 @@ +From 10288794a6a7904287354a906b12f6189b2a5863 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Oct 2023 17:26:54 +0300 +Subject: wifi: ath11k: fix Tx power value during active CAC + +From: Aditya Kumar Singh + +[ Upstream commit 77f1ee6fd8b6e470f721d05a2e269039d5cafcb7 ] + +Tx power is fetched from firmware's pdev stats. However, during active +CAC, firmware does not fill the current Tx power and sends the max +initialised value filled during firmware init. If host sends this power +to user space, this is wrong since in certain situations, the Tx power +could be greater than the max allowed by the regulatory. Hence, host +should not be fetching the Tx power during an active CAC. + +Fix this issue by returning -EAGAIN error so that user space knows that there's +no valid value available. + +Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 + +Fixes: 9a2aa68afe3d ("wifi: ath11k: add get_txpower mac ops") +Signed-off-by: Aditya Kumar Singh +Acked-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230912051857.2284-4-quic_adisi@quicinc.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath11k/mac.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index c071bf5841af6..b328a0599818b 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -9042,6 +9042,14 @@ static int ath11k_mac_op_get_txpower(struct ieee80211_hw *hw, + if (ar->state != ATH11K_STATE_ON) + goto err_fallback; + ++ /* Firmware doesn't provide Tx power during CAC hence no need to fetch ++ * the stats. ++ */ ++ if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) { ++ mutex_unlock(&ar->conf_mutex); ++ return -EAGAIN; ++ } ++ + req_param.pdev_id = ar->pdev->pdev_id; + req_param.stats_id = WMI_REQUEST_PDEV_STAT; + +-- +2.42.0 + diff --git a/queue-6.6/wifi-ath12k-fix-dma-unmap-warning-on-null-dma-addres.patch b/queue-6.6/wifi-ath12k-fix-dma-unmap-warning-on-null-dma-addres.patch new file mode 100644 index 00000000000..315a0dbebee --- /dev/null +++ b/queue-6.6/wifi-ath12k-fix-dma-unmap-warning-on-null-dma-addres.patch @@ -0,0 +1,51 @@ +From 2da9d2c2f569624badbd3a85e1c5d7e8806205f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Sep 2023 16:43:42 +0300 +Subject: wifi: ath12k: fix DMA unmap warning on NULL DMA address + +From: Baochen Qiang + +[ Upstream commit 9ae8c496d211155a3f220b63da364fba1a794292 ] + +In ath12k_dp_tx(), if we reach fail_dma_unmap due to some errors, +current code does DMA unmap unconditionally on skb_cb->paddr_ext_desc. +However, skb_cb->paddr_ext_desc may be NULL and thus we get below +warning: + +kernel: [ 8887.076212] WARNING: CPU: 3 PID: 0 at drivers/iommu/dma-iommu.c:1077 iommu_dma_unmap_page+0x79/0x90 + +Fix it by checking skb_cb->paddr_ext_desc before unmap it. + +Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4 + +Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") +Signed-off-by: Baochen Qiang +Acked-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230830021131.5610-1-quic_bqiang@quicinc.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/dp_tx.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c +index 8874c815d7faf..16d889fc20433 100644 +--- a/drivers/net/wireless/ath/ath12k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath12k/dp_tx.c +@@ -330,8 +330,11 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif, + + fail_unmap_dma: + dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE); +- dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, +- sizeof(struct hal_tx_msdu_ext_desc), DMA_TO_DEVICE); ++ ++ if (skb_cb->paddr_ext_desc) ++ dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, ++ sizeof(struct hal_tx_msdu_ext_desc), ++ DMA_TO_DEVICE); + + fail_remove_tx_buf: + ath12k_dp_tx_release_txbuf(dp, tx_desc, pool_id); +-- +2.42.0 + diff --git a/queue-6.6/wifi-ath12k-fix-undefined-behavior-with-__fls-in-dp.patch b/queue-6.6/wifi-ath12k-fix-undefined-behavior-with-__fls-in-dp.patch new file mode 100644 index 00000000000..d6621ad3859 --- /dev/null +++ b/queue-6.6/wifi-ath12k-fix-undefined-behavior-with-__fls-in-dp.patch @@ -0,0 +1,44 @@ +From 72a0e2726132def6fb7fb82b2614eeb00f272a28 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Aug 2023 08:42:44 +0300 +Subject: wifi: ath12k: fix undefined behavior with __fls in dp + +From: Harshitha Prem + +[ Upstream commit d48f55e773dcce8fcf9e587073452a4944011b11 ] + +When max virtual ap interfaces are configured in all the bands +with ACS and hostapd restart is done every 60s, +a crash is observed at random times because of handling the +uninitialized peer fragments with fragment id of packet as 0. + +"__fls" would have an undefined behavior if the argument is passed +as "0". Hence, added changes to handle the same. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 + +Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") +Signed-off-by: Harshitha Prem +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230821130343.29495-3-quic_hprem@quicinc.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/dp_rx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c +index e6e64d437c47a..17da39bd3ab4d 100644 +--- a/drivers/net/wireless/ath/ath12k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c +@@ -3229,7 +3229,7 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, + goto out_unlock; + } + +- if (frag_no > __fls(rx_tid->rx_frag_bitmap)) ++ if ((!rx_tid->rx_frag_bitmap || frag_no > __fls(rx_tid->rx_frag_bitmap))) + __skb_queue_tail(&rx_tid->rx_frags, msdu); + else + ath12k_dp_rx_h_sort_frags(ab, &rx_tid->rx_frags, msdu); +-- +2.42.0 + diff --git a/queue-6.6/wifi-cfg80211-add-flush-functions-for-wiphy-work.patch b/queue-6.6/wifi-cfg80211-add-flush-functions-for-wiphy-work.patch new file mode 100644 index 00000000000..2cd02af5e55 --- /dev/null +++ b/queue-6.6/wifi-cfg80211-add-flush-functions-for-wiphy-work.patch @@ -0,0 +1,173 @@ +From e89acc4259ae788bd0263f5676d75ce57146ce1e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Aug 2023 13:59:33 +0200 +Subject: wifi: cfg80211: add flush functions for wiphy work + +From: Johannes Berg + +[ Upstream commit 56cfb8ce1f7f6c4e5ca571a2ec0880e131cd0311 ] + +There may be sometimes reasons to actually run the work +if it's pending, add flush functions for both regular and +delayed wiphy work that will do this. + +Signed-off-by: Johannes Berg +Stable-dep-of: eadfb54756ae ("wifi: mac80211: move sched-scan stop work to wiphy work") +Signed-off-by: Sasha Levin +--- + include/net/cfg80211.h | 21 +++++++++++++++++++++ + net/wireless/core.c | 34 ++++++++++++++++++++++++++++++++-- + net/wireless/core.h | 3 ++- + net/wireless/sysfs.c | 4 ++-- + 4 files changed, 57 insertions(+), 5 deletions(-) + +diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h +index 7192346e4a22d..308a004c1d1dc 100644 +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -5826,6 +5826,16 @@ void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work); + */ + void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work); + ++/** ++ * wiphy_work_flush - flush previously queued work ++ * @wiphy: the wiphy, for debug purposes ++ * @work: the work to flush, this can be %NULL to flush all work ++ * ++ * Flush the work (i.e. run it if pending). This must be called ++ * under the wiphy mutex acquired by wiphy_lock(). ++ */ ++void wiphy_work_flush(struct wiphy *wiphy, struct wiphy_work *work); ++ + struct wiphy_delayed_work { + struct wiphy_work work; + struct wiphy *wiphy; +@@ -5869,6 +5879,17 @@ void wiphy_delayed_work_queue(struct wiphy *wiphy, + void wiphy_delayed_work_cancel(struct wiphy *wiphy, + struct wiphy_delayed_work *dwork); + ++/** ++ * wiphy_delayed work_flush - flush previously queued delayed work ++ * @wiphy: the wiphy, for debug purposes ++ * @work: the work to flush ++ * ++ * Flush the work (i.e. run it if pending). This must be called ++ * under the wiphy mutex acquired by wiphy_lock(). ++ */ ++void wiphy_delayed_work_flush(struct wiphy *wiphy, ++ struct wiphy_delayed_work *dwork); ++ + /** + * struct wireless_dev - wireless device state + * +diff --git a/net/wireless/core.c b/net/wireless/core.c +index acec41c1809a8..563cfbe3237c9 100644 +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -1049,7 +1049,8 @@ void wiphy_rfkill_start_polling(struct wiphy *wiphy) + } + EXPORT_SYMBOL(wiphy_rfkill_start_polling); + +-void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev) ++void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev, ++ struct wiphy_work *end) + { + unsigned int runaway_limit = 100; + unsigned long flags; +@@ -1068,6 +1069,10 @@ void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev) + wk->func(&rdev->wiphy, wk); + + spin_lock_irqsave(&rdev->wiphy_work_lock, flags); ++ ++ if (wk == end) ++ break; ++ + if (WARN_ON(--runaway_limit == 0)) + INIT_LIST_HEAD(&rdev->wiphy_work_list); + } +@@ -1118,7 +1123,7 @@ void wiphy_unregister(struct wiphy *wiphy) + #endif + + /* surely nothing is reachable now, clean up work */ +- cfg80211_process_wiphy_works(rdev); ++ cfg80211_process_wiphy_works(rdev, NULL); + wiphy_unlock(&rdev->wiphy); + rtnl_unlock(); + +@@ -1640,6 +1645,21 @@ void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work) + } + EXPORT_SYMBOL_GPL(wiphy_work_cancel); + ++void wiphy_work_flush(struct wiphy *wiphy, struct wiphy_work *work) ++{ ++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); ++ unsigned long flags; ++ bool run; ++ ++ spin_lock_irqsave(&rdev->wiphy_work_lock, flags); ++ run = !work || !list_empty(&work->entry); ++ spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); ++ ++ if (run) ++ cfg80211_process_wiphy_works(rdev, work); ++} ++EXPORT_SYMBOL_GPL(wiphy_work_flush); ++ + void wiphy_delayed_work_timer(struct timer_list *t) + { + struct wiphy_delayed_work *dwork = from_timer(dwork, t, timer); +@@ -1672,6 +1692,16 @@ void wiphy_delayed_work_cancel(struct wiphy *wiphy, + } + EXPORT_SYMBOL_GPL(wiphy_delayed_work_cancel); + ++void wiphy_delayed_work_flush(struct wiphy *wiphy, ++ struct wiphy_delayed_work *dwork) ++{ ++ lockdep_assert_held(&wiphy->mtx); ++ ++ del_timer_sync(&dwork->timer); ++ wiphy_work_flush(wiphy, &dwork->work); ++} ++EXPORT_SYMBOL_GPL(wiphy_delayed_work_flush); ++ + static int __init cfg80211_init(void) + { + int err; +diff --git a/net/wireless/core.h b/net/wireless/core.h +index ba9c7170afa44..e536c0b615a09 100644 +--- a/net/wireless/core.h ++++ b/net/wireless/core.h +@@ -464,7 +464,8 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, + struct net_device *dev, enum nl80211_iftype ntype, + struct vif_params *params); + void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); +-void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev); ++void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev, ++ struct wiphy_work *end); + void cfg80211_process_wdev_events(struct wireless_dev *wdev); + + bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range, +diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c +index c629bac3f2983..565511a3f461e 100644 +--- a/net/wireless/sysfs.c ++++ b/net/wireless/sysfs.c +@@ -105,14 +105,14 @@ static int wiphy_suspend(struct device *dev) + cfg80211_leave_all(rdev); + cfg80211_process_rdev_events(rdev); + } +- cfg80211_process_wiphy_works(rdev); ++ cfg80211_process_wiphy_works(rdev, NULL); + if (rdev->ops->suspend) + ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config); + if (ret == 1) { + /* Driver refuse to configure wowlan */ + cfg80211_leave_all(rdev); + cfg80211_process_rdev_events(rdev); +- cfg80211_process_wiphy_works(rdev); ++ cfg80211_process_wiphy_works(rdev, NULL); + ret = rdev_suspend(rdev, NULL); + } + if (ret == 0) +-- +2.42.0 + diff --git a/queue-6.6/wifi-cfg80211-fix-kernel-doc-for-wiphy_delayed_work_.patch b/queue-6.6/wifi-cfg80211-fix-kernel-doc-for-wiphy_delayed_work_.patch new file mode 100644 index 00000000000..4f34eecc690 --- /dev/null +++ b/queue-6.6/wifi-cfg80211-fix-kernel-doc-for-wiphy_delayed_work_.patch @@ -0,0 +1,36 @@ +From ba716b6dd5d88d071689de7fc91f2e951e92e571 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 09:34:25 +0200 +Subject: wifi: cfg80211: fix kernel-doc for wiphy_delayed_work_flush() + +From: Johannes Berg + +[ Upstream commit 8c73d5248dcf112611654bcd32352dc330b02397 ] + +Clearly, there's no space in the function name, not sure how +that could've happened. Put the underscore that it should be. + +Reported-by: Stephen Rothwell +Fixes: 56cfb8ce1f7f ("wifi: cfg80211: add flush functions for wiphy work") +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + include/net/cfg80211.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h +index 308a004c1d1dc..153a8c3e7213d 100644 +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -5880,7 +5880,7 @@ void wiphy_delayed_work_cancel(struct wiphy *wiphy, + struct wiphy_delayed_work *dwork); + + /** +- * wiphy_delayed work_flush - flush previously queued delayed work ++ * wiphy_delayed_work_flush - flush previously queued delayed work + * @wiphy: the wiphy, for debug purposes + * @work: the work to flush + * +-- +2.42.0 + diff --git a/queue-6.6/wifi-cfg80211-fix-off-by-one-in-element-defrag.patch b/queue-6.6/wifi-cfg80211-fix-off-by-one-in-element-defrag.patch new file mode 100644 index 00000000000..4237e625b71 --- /dev/null +++ b/queue-6.6/wifi-cfg80211-fix-off-by-one-in-element-defrag.patch @@ -0,0 +1,48 @@ +From 29363d75aff33f34da814be33c27c0dd00a465b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 27 Aug 2023 14:05:19 +0300 +Subject: wifi: cfg80211: fix off-by-one in element defrag + +From: Johannes Berg + +[ Upstream commit 43125539fc69c6aa63d34b516939431391bddeac ] + +If a fragment is the last element, it's erroneously not +accepted. Fix that. + +Fixes: f837a653a097 ("wifi: cfg80211: add element defragmentation helper") +Signed-off-by: Johannes Berg +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20230827135854.adca9fbd3317.I6b2df45eb71513f3e48efd196ae3cddec362dc1c@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/scan.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index 8210a6090ac16..e4cc6209c7b9b 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -2358,8 +2358,8 @@ ssize_t cfg80211_defragment_element(const struct element *elem, const u8 *ies, + + /* elem might be invalid after the memmove */ + next = (void *)(elem->data + elem->datalen); +- + elem_datalen = elem->datalen; ++ + if (elem->id == WLAN_EID_EXTENSION) { + copied = elem->datalen - 1; + if (copied > data_len) +@@ -2380,7 +2380,7 @@ ssize_t cfg80211_defragment_element(const struct element *elem, const u8 *ies, + + for (elem = next; + elem->data < ies + ieslen && +- elem->data + elem->datalen < ies + ieslen; ++ elem->data + elem->datalen <= ies + ieslen; + elem = next) { + /* elem might be invalid after the memmove */ + next = (void *)(elem->data + elem->datalen); +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-don-t-use-an-uninitialized-variable.patch b/queue-6.6/wifi-iwlwifi-don-t-use-an-uninitialized-variable.patch new file mode 100644 index 00000000000..82075c72017 --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-don-t-use-an-uninitialized-variable.patch @@ -0,0 +1,42 @@ +From 4dac8da73fcbd357952b4de0395a3163767459aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Aug 2023 11:30:54 +0300 +Subject: wifi: iwlwifi: don't use an uninitialized variable + +From: Miri Korenblit + +[ Upstream commit c46fcc6e43d617252945e706f04e5f82a59f2b8e ] + +Don't use variable err uninitialized. +The reason for removing the check instead of initializing it +in the beginning of the function is because that way +static checkers will be able to catch issues if we do something +wrong in the future. + +Fixes: bf976c814c86 ("wifi: iwlwifi: mvm: implement link change ops") +Signed-off-by: Miri Korenblit +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20230830112059.431b01bd8779.I31fc4ab35f551b85a10f974a6b18fc30191e9c35@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +index b719843e94576..778a311b500bc 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +@@ -1089,9 +1089,6 @@ iwl_mvm_mld_change_vif_links(struct ieee80211_hw *hw, + } + } + +- if (err) +- goto out_err; +- + err = 0; + if (new_links == 0) { + mvmvif->link[0] = &mvmvif->deflink; +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-empty-overflow-queue-during-flush.patch b/queue-6.6/wifi-iwlwifi-empty-overflow-queue-during-flush.patch new file mode 100644 index 00000000000..bf21dd55fb4 --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-empty-overflow-queue-during-flush.patch @@ -0,0 +1,169 @@ +From 82b0fc094bfd07963b8dfef5329b079740f09e30 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 22 Oct 2023 17:55:51 +0300 +Subject: wifi: iwlwifi: empty overflow queue during flush + +From: Miri Korenblit + +[ Upstream commit 658939fc68d3241f9a0019e224cd7154438c23f2 ] + +If a TX queue has no space for new TX frames, the driver will keep +these frames in the overflow queue, and during reclaim flow it +will retry to send the frames from that queue. +But if the reclaim flow was invoked from TX queue flush, we will also +TX these frames, which is wrong as we don't want to TX anything +after flush. +This might also cause assert 0x125F when removing the queue, +saying that the driver removes a non-empty queue +Fix this by TXing the overflow queue's frames only if we are +not in flush queue flow. + +Fixes: a44509805895 ("iwlwifi: move reclaim flows to the queue file") +Signed-off-by: Miri Korenblit +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20231022173519.caf06c8709d9.Ibf664ccb3f952e836f8fa461ea58fc08e5c46e88@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/dvm/tx.c | 5 +++-- + drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 7 ++++--- + drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 4 ++-- + drivers/net/wireless/intel/iwlwifi/queue/tx.c | 9 +++++---- + drivers/net/wireless/intel/iwlwifi/queue/tx.h | 2 +- + 5 files changed, 15 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c +index 60a7b61d59aa3..ca1daec641c4f 100644 +--- a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c +@@ -3,6 +3,7 @@ + * + * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. + * Copyright (C) 2019 Intel Corporation ++ * Copyright (C) 2023 Intel Corporation + *****************************************************************************/ + + #include +@@ -1169,7 +1170,7 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb) + iwlagn_check_ratid_empty(priv, sta_id, tid); + } + +- iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs); ++ iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs, false); + + freed = 0; + +@@ -1315,7 +1316,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, + * block-ack window (we assume that they've been successfully + * transmitted ... if not, it's too late anyway). */ + iwl_trans_reclaim(priv->trans, scd_flow, ba_resp_scd_ssn, +- &reclaimed_skbs); ++ &reclaimed_skbs, false); + + IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, " + "sta_id = %d\n", +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +index 1b3c976d19feb..168eda2132fb8 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +@@ -588,7 +588,7 @@ struct iwl_trans_ops { + int (*tx)(struct iwl_trans *trans, struct sk_buff *skb, + struct iwl_device_tx_cmd *dev_cmd, int queue); + void (*reclaim)(struct iwl_trans *trans, int queue, int ssn, +- struct sk_buff_head *skbs); ++ struct sk_buff_head *skbs, bool is_flush); + + void (*set_q_ptrs)(struct iwl_trans *trans, int queue, int ptr); + +@@ -1273,14 +1273,15 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, + } + + static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue, +- int ssn, struct sk_buff_head *skbs) ++ int ssn, struct sk_buff_head *skbs, ++ bool is_flush) + { + if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) { + IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state); + return; + } + +- trans->ops->reclaim(trans, queue, ssn, skbs); ++ trans->ops->reclaim(trans, queue, ssn, skbs, is_flush); + } + + static inline void iwl_trans_set_q_ptrs(struct iwl_trans *trans, int queue, +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index 8bdb239295c39..177a4628a913e 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -1603,7 +1603,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, + seq_ctl = le16_to_cpu(tx_resp->seq_ctl); + + /* we can free until ssn % q.n_bd not inclusive */ +- iwl_trans_reclaim(mvm->trans, txq_id, ssn, &skbs); ++ iwl_trans_reclaim(mvm->trans, txq_id, ssn, &skbs, false); + + while (!skb_queue_empty(&skbs)) { + struct sk_buff *skb = __skb_dequeue(&skbs); +@@ -1955,7 +1955,7 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, + * block-ack window (we assume that they've been successfully + * transmitted ... if not, it's too late anyway). + */ +- iwl_trans_reclaim(mvm->trans, txq, index, &reclaimed_skbs); ++ iwl_trans_reclaim(mvm->trans, txq, index, &reclaimed_skbs, is_flush); + + skb_queue_walk(&reclaimed_skbs, skb) { + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +diff --git a/drivers/net/wireless/intel/iwlwifi/queue/tx.c b/drivers/net/wireless/intel/iwlwifi/queue/tx.c +index 340240b8954f6..ca74b1b63cac1 100644 +--- a/drivers/net/wireless/intel/iwlwifi/queue/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/queue/tx.c +@@ -1575,7 +1575,7 @@ void iwl_txq_progress(struct iwl_txq *txq) + + /* Frees buffers until index _not_ inclusive */ + void iwl_txq_reclaim(struct iwl_trans *trans, int txq_id, int ssn, +- struct sk_buff_head *skbs) ++ struct sk_buff_head *skbs, bool is_flush) + { + struct iwl_txq *txq = trans->txqs.txq[txq_id]; + int tfd_num, read_ptr, last_to_free; +@@ -1650,9 +1650,11 @@ void iwl_txq_reclaim(struct iwl_trans *trans, int txq_id, int ssn, + if (iwl_txq_space(trans, txq) > txq->low_mark && + test_bit(txq_id, trans->txqs.queue_stopped)) { + struct sk_buff_head overflow_skbs; ++ struct sk_buff *skb; + + __skb_queue_head_init(&overflow_skbs); +- skb_queue_splice_init(&txq->overflow_q, &overflow_skbs); ++ skb_queue_splice_init(&txq->overflow_q, ++ is_flush ? skbs : &overflow_skbs); + + /* + * We are going to transmit from the overflow queue. +@@ -1672,8 +1674,7 @@ void iwl_txq_reclaim(struct iwl_trans *trans, int txq_id, int ssn, + */ + spin_unlock_bh(&txq->lock); + +- while (!skb_queue_empty(&overflow_skbs)) { +- struct sk_buff *skb = __skb_dequeue(&overflow_skbs); ++ while ((skb = __skb_dequeue(&overflow_skbs))) { + struct iwl_device_tx_cmd *dev_cmd_ptr; + + dev_cmd_ptr = *(void **)((u8 *)skb->cb + +diff --git a/drivers/net/wireless/intel/iwlwifi/queue/tx.h b/drivers/net/wireless/intel/iwlwifi/queue/tx.h +index b7d3808588bfb..4c09bc1930fa1 100644 +--- a/drivers/net/wireless/intel/iwlwifi/queue/tx.h ++++ b/drivers/net/wireless/intel/iwlwifi/queue/tx.h +@@ -179,7 +179,7 @@ void iwl_txq_gen1_update_byte_cnt_tbl(struct iwl_trans *trans, + struct iwl_txq *txq, u16 byte_cnt, + int num_tbs); + void iwl_txq_reclaim(struct iwl_trans *trans, int txq_id, int ssn, +- struct sk_buff_head *skbs); ++ struct sk_buff_head *skbs, bool is_flush); + void iwl_txq_set_q_ptrs(struct iwl_trans *trans, int txq_id, int ptr); + void iwl_trans_txq_freeze_timer(struct iwl_trans *trans, unsigned long txqs, + bool freeze); +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-honor-the-enable_ini-value.patch b/queue-6.6/wifi-iwlwifi-honor-the-enable_ini-value.patch new file mode 100644 index 00000000000..5d07b303bc0 --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-honor-the-enable_ini-value.patch @@ -0,0 +1,157 @@ +From 5244442819af91ae94dbb1c9427f8b97347bea1a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Aug 2023 11:30:52 +0300 +Subject: wifi: iwlwifi: honor the enable_ini value + +From: Emmanuel Grumbach + +[ Upstream commit e0c1ca236e28e4263fba76d47a108ed95dcae33e ] + +In case the user sets the enable_ini to some preset, we want to honor +the value. + +Remove the ops to set the value of the module parameter is runtime, we +don't want to allow to modify the value in runtime since we configure +the firmware once at the beginning on its life. + +Fixes: b49c2b252b58 ("iwlwifi: Configure FW debug preset via module param.") +Signed-off-by: Emmanuel Grumbach +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20230830112059.5734e0f374bb.I6698eda8ed2112378dd47ac5d62866ebe7a94f77@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + .../wireless/intel/iwlwifi/fw/api/dbg-tlv.h | 1 + + .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h | 5 +- + drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 51 +++++++------------ + .../net/wireless/intel/iwlwifi/iwl-trans.h | 4 ++ + 4 files changed, 25 insertions(+), 36 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h +index ba538d70985f4..39bee9c00e071 100644 +--- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h ++++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h +@@ -13,6 +13,7 @@ + #define IWL_FW_INI_DOMAIN_ALWAYS_ON 0 + #define IWL_FW_INI_REGION_ID_MASK GENMASK(15, 0) + #define IWL_FW_INI_REGION_DUMP_POLICY_MASK GENMASK(31, 16) ++#define IWL_FW_INI_PRESET_DISABLE 0xff + + /** + * struct iwl_fw_ini_hcmd +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h +index 128059ca77e60..06fb7d6653905 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h +@@ -1,6 +1,6 @@ + /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ + /* +- * Copyright (C) 2018-2022 Intel Corporation ++ * Copyright (C) 2018-2023 Intel Corporation + */ + #ifndef __iwl_dbg_tlv_h__ + #define __iwl_dbg_tlv_h__ +@@ -10,7 +10,8 @@ + #include + #include + +-#define IWL_DBG_TLV_MAX_PRESET 15 ++#define IWL_DBG_TLV_MAX_PRESET 15 ++#define ENABLE_INI (IWL_DBG_TLV_MAX_PRESET + 1) + + /** + * struct iwl_dbg_tlv_node - debug TLV node +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +index 3d87d26845e74..fb5e254757e71 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +@@ -1795,6 +1795,22 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans) + #endif + + drv->trans->dbg.domains_bitmap = IWL_TRANS_FW_DBG_DOMAIN(drv->trans); ++ if (iwlwifi_mod_params.enable_ini != ENABLE_INI) { ++ /* We have a non-default value in the module parameter, ++ * take its value ++ */ ++ drv->trans->dbg.domains_bitmap &= 0xffff; ++ if (iwlwifi_mod_params.enable_ini != IWL_FW_INI_PRESET_DISABLE) { ++ if (iwlwifi_mod_params.enable_ini > ENABLE_INI) { ++ IWL_ERR(trans, ++ "invalid enable_ini module parameter value: max = %d, using 0 instead\n", ++ ENABLE_INI); ++ iwlwifi_mod_params.enable_ini = 0; ++ } ++ drv->trans->dbg.domains_bitmap = ++ BIT(IWL_FW_DBG_DOMAIN_POS + iwlwifi_mod_params.enable_ini); ++ } ++ } + + ret = iwl_request_firmware(drv, true); + if (ret) { +@@ -1843,8 +1859,6 @@ void iwl_drv_stop(struct iwl_drv *drv) + kfree(drv); + } + +-#define ENABLE_INI (IWL_DBG_TLV_MAX_PRESET + 1) +- + /* shared module parameters */ + struct iwl_mod_params iwlwifi_mod_params = { + .fw_restart = true, +@@ -1964,38 +1978,7 @@ module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, uint, 0644); + MODULE_PARM_DESC(uapsd_disable, + "disable U-APSD functionality bitmap 1: BSS 2: P2P Client (default: 3)"); + +-static int enable_ini_set(const char *arg, const struct kernel_param *kp) +-{ +- int ret = 0; +- bool res; +- __u32 new_enable_ini; +- +- /* in case the argument type is a number */ +- ret = kstrtou32(arg, 0, &new_enable_ini); +- if (!ret) { +- if (new_enable_ini > ENABLE_INI) { +- pr_err("enable_ini cannot be %d, in range 0-16\n", new_enable_ini); +- return -EINVAL; +- } +- goto out; +- } +- +- /* in case the argument type is boolean */ +- ret = kstrtobool(arg, &res); +- if (ret) +- return ret; +- new_enable_ini = (res ? ENABLE_INI : 0); +- +-out: +- iwlwifi_mod_params.enable_ini = new_enable_ini; +- return 0; +-} +- +-static const struct kernel_param_ops enable_ini_ops = { +- .set = enable_ini_set +-}; +- +-module_param_cb(enable_ini, &enable_ini_ops, &iwlwifi_mod_params.enable_ini, 0644); ++module_param_named(enable_ini, iwlwifi_mod_params.enable_ini, uint, 0444); + MODULE_PARM_DESC(enable_ini, + "0:disable, 1-15:FW_DBG_PRESET Values, 16:enabled without preset value defined," + "Debug INI TLV FW debug infrastructure (default: 16)"); +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +index 3b6b0e03037f1..1b3c976d19feb 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +@@ -56,6 +56,10 @@ + * 6) Eventually, the free function will be called. + */ + ++/* default preset 0 (start from bit 16)*/ ++#define IWL_FW_DBG_DOMAIN_POS 16 ++#define IWL_FW_DBG_DOMAIN BIT(IWL_FW_DBG_DOMAIN_POS) ++ + #define IWL_TRANS_FW_DBG_DOMAIN(trans) IWL_FW_INI_DOMAIN_ALWAYS_ON + + #define FH_RSCSR_FRAME_SIZE_MSK 0x00003FFF /* bits 0-13 */ +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-increase-number-of-rx-buffers-for-eht-d.patch b/queue-6.6/wifi-iwlwifi-increase-number-of-rx-buffers-for-eht-d.patch new file mode 100644 index 00000000000..39eda48f37e --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-increase-number-of-rx-buffers-for-eht-d.patch @@ -0,0 +1,93 @@ +From e6d319b05149c572e8207b061fb1f983266825c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Aug 2023 11:31:04 +0300 +Subject: wifi: iwlwifi: increase number of RX buffers for EHT devices + +From: Johannes Berg + +[ Upstream commit 2cf254c1e24fa8f01f42f5a8c77617e56bf50b86 ] + +EHT devices can support 512 MPDUs in an A-MPDU, each of +which might be an A-MSDU and thus further contain multiple +MSDUs, which need their own buffer each. Increase the number +of buffers to avoid running out in high-throughput scenarios. + +Signed-off-by: Johannes Berg +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20230830112059.824e522927f1.Ie5b4a2d3953072b9d76054ae67e2e45900d6bba4@changeid +Signed-off-by: Johannes Berg +Stable-dep-of: 08365d3b9140 ("wifi: iwlwifi: mvm: fix netif csum flags") +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/cfg/bz.c | 10 ++++------ + drivers/net/wireless/intel/iwlwifi/cfg/sc.c | 8 +++----- + 2 files changed, 7 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c +index b9893b22e41da..3d223014cfe6d 100644 +--- a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c ++++ b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c +@@ -134,12 +134,10 @@ static const struct iwl_base_params iwl_bz_base_params = { + .ht_params = &iwl_gl_a_ht_params + + /* +- * If the device doesn't support HE, no need to have that many buffers. +- * These sizes were picked according to 8 MSDUs inside 256 A-MSDUs in an ++ * This size was picked according to 8 MSDUs inside 512 A-MSDUs in an + * A-MPDU, with additional overhead to account for processing time. + */ +-#define IWL_NUM_RBDS_NON_HE 512 +-#define IWL_NUM_RBDS_BZ_HE 4096 ++#define IWL_NUM_RBDS_BZ_EHT (512 * 16) + + const struct iwl_cfg_trans_params iwl_bz_trans_cfg = { + .device_family = IWL_DEVICE_FAMILY_BZ, +@@ -161,7 +159,7 @@ const struct iwl_cfg iwl_cfg_bz = { + .uhb_supported = true, + IWL_DEVICE_BZ, + .features = IWL_TX_CSUM_NETIF_FLAGS_BZ | NETIF_F_RXCSUM, +- .num_rbds = IWL_NUM_RBDS_BZ_HE, ++ .num_rbds = IWL_NUM_RBDS_BZ_EHT, + }; + + const struct iwl_cfg iwl_cfg_gl = { +@@ -169,7 +167,7 @@ const struct iwl_cfg iwl_cfg_gl = { + .uhb_supported = true, + IWL_DEVICE_BZ, + .features = IWL_TX_CSUM_NETIF_FLAGS_BZ | NETIF_F_RXCSUM, +- .num_rbds = IWL_NUM_RBDS_BZ_HE, ++ .num_rbds = IWL_NUM_RBDS_BZ_EHT, + }; + + +diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c +index ad283fd22e2a2..d6243025993ea 100644 +--- a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c ++++ b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c +@@ -127,12 +127,10 @@ static const struct iwl_base_params iwl_sc_base_params = { + .ht_params = &iwl_22000_ht_params + + /* +- * If the device doesn't support HE, no need to have that many buffers. +- * These sizes were picked according to 8 MSDUs inside 256 A-MSDUs in an ++ * This size was picked according to 8 MSDUs inside 512 A-MSDUs in an + * A-MPDU, with additional overhead to account for processing time. + */ +-#define IWL_NUM_RBDS_NON_HE 512 +-#define IWL_NUM_RBDS_SC_HE 4096 ++#define IWL_NUM_RBDS_SC_EHT (512 * 16) + + const struct iwl_cfg_trans_params iwl_sc_trans_cfg = { + .device_family = IWL_DEVICE_FAMILY_SC, +@@ -154,7 +152,7 @@ const struct iwl_cfg iwl_cfg_sc = { + .uhb_supported = true, + IWL_DEVICE_SC, + .features = IWL_TX_CSUM_NETIF_FLAGS_BZ | NETIF_F_RXCSUM, +- .num_rbds = IWL_NUM_RBDS_SC_HE, ++ .num_rbds = IWL_NUM_RBDS_SC_EHT, + }; + + MODULE_FIRMWARE(IWL_SC_A_FM_B_FW_MODULE_FIRMWARE(IWL_SC_UCODE_API_MAX)); +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-mvm-change-iwl_mvm_flush_sta-api.patch b/queue-6.6/wifi-iwlwifi-mvm-change-iwl_mvm_flush_sta-api.patch new file mode 100644 index 00000000000..6182e06fefd --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-mvm-change-iwl_mvm_flush_sta-api.patch @@ -0,0 +1,173 @@ +From 224ac9826d2453a16dfc3f98f68ae372fc188e04 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 13:07:28 +0300 +Subject: wifi: iwlwifi: mvm: change iwl_mvm_flush_sta() API + +From: Johannes Berg + +[ Upstream commit 391762969769b089c808defc8fce5544a945f9eb ] + +This API is type unsafe and needs an extra parameter to know +what kind of station was passed, so it has two, but really it +only needs two values. Just pass the values instead of doing +this type-unsafe dance, which will also make it better to use +for multi-link. + +Signed-off-by: Johannes Berg +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20231011130030.aeb3bf4204cd.I5b0e6d64a67455784bc8fbdaf9ceaf03699d9ce1@changeid +Signed-off-by: Johannes Berg +Stable-dep-of: 43874283ce6c ("wifi: iwlwifi: mvm: fix iwl_mvm_mac_flush_sta()") +Signed-off-by: Sasha Levin +--- + .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 6 ++++-- + .../net/wireless/intel/iwlwifi/mvm/mld-sta.c | 2 +- + drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +- + drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 9 ++++++--- + .../wireless/intel/iwlwifi/mvm/time-event.c | 7 ++++--- + drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 18 ++---------------- + 6 files changed, 18 insertions(+), 26 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +index a3058d7c77574..e68026a657059 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +@@ -5579,7 +5579,8 @@ void iwl_mvm_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + } + + if (drop) { +- if (iwl_mvm_flush_sta(mvm, mvmsta, false)) ++ if (iwl_mvm_flush_sta(mvm, mvmsta->deflink.sta_id, ++ mvmsta->tfd_queue_msk)) + IWL_ERR(mvm, "flush request fail\n"); + } else { + if (iwl_mvm_has_new_tx_api(mvm)) +@@ -5616,7 +5617,8 @@ void iwl_mvm_mac_flush_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + + mvmsta = iwl_mvm_sta_from_mac80211(sta); + +- if (iwl_mvm_flush_sta(mvm, mvmsta, false)) ++ if (iwl_mvm_flush_sta(mvm, mvmsta->deflink.sta_id, ++ mvmsta->tfd_queue_msk)) + IWL_ERR(mvm, "flush request fail\n"); + } + mutex_unlock(&mvm->mutex); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c +index 524852cf5cd2d..56f51344c193c 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c +@@ -347,7 +347,7 @@ static int iwl_mvm_mld_rm_int_sta(struct iwl_mvm *mvm, + return -EINVAL; + + if (flush) +- iwl_mvm_flush_sta(mvm, int_sta, true); ++ iwl_mvm_flush_sta(mvm, int_sta->sta_id, int_sta->tfd_queue_msk); + + iwl_mvm_mld_disable_txq(mvm, BIT(int_sta->sta_id), queuptr, tid); + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +index b596eca562166..218f3bc31104b 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +@@ -1658,7 +1658,7 @@ const char *iwl_mvm_get_tx_fail_reason(u32 status); + static inline const char *iwl_mvm_get_tx_fail_reason(u32 status) { return ""; } + #endif + int iwl_mvm_flush_tx_path(struct iwl_mvm *mvm, u32 tfd_msk); +-int iwl_mvm_flush_sta(struct iwl_mvm *mvm, void *sta, bool internal); ++int iwl_mvm_flush_sta(struct iwl_mvm *mvm, u32 sta_id, u32 tfd_queue_mask); + int iwl_mvm_flush_sta_tids(struct iwl_mvm *mvm, u32 sta_id, u16 tids); + + /* Utils to extract sta related data */ +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +index 3b9a343d4f672..ebbe165510587 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +@@ -2097,7 +2097,8 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, + return ret; + + /* flush its queues here since we are freeing mvm_sta */ +- ret = iwl_mvm_flush_sta(mvm, mvm_sta, false); ++ ret = iwl_mvm_flush_sta(mvm, mvm_sta->deflink.sta_id, ++ mvm_sta->tfd_queue_msk); + if (ret) + return ret; + if (iwl_mvm_has_new_tx_api(mvm)) { +@@ -2408,7 +2409,8 @@ void iwl_mvm_free_bcast_sta_queues(struct iwl_mvm *mvm, + + lockdep_assert_held(&mvm->mutex); + +- iwl_mvm_flush_sta(mvm, &mvmvif->deflink.bcast_sta, true); ++ iwl_mvm_flush_sta(mvm, mvmvif->deflink.bcast_sta.sta_id, ++ mvmvif->deflink.bcast_sta.tfd_queue_msk); + + switch (vif->type) { + case NL80211_IFTYPE_AP: +@@ -2664,7 +2666,8 @@ int iwl_mvm_rm_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) + + lockdep_assert_held(&mvm->mutex); + +- iwl_mvm_flush_sta(mvm, &mvmvif->deflink.mcast_sta, true); ++ iwl_mvm_flush_sta(mvm, mvmvif->deflink.mcast_sta.sta_id, ++ mvmvif->deflink.mcast_sta.tfd_queue_msk); + + iwl_mvm_disable_txq(mvm, NULL, mvmvif->deflink.mcast_sta.sta_id, + &mvmvif->deflink.cab_queue, 0); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +index ff213247569a7..158266719ffd7 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +@@ -81,8 +81,8 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk) + struct ieee80211_vif *vif = mvm->p2p_device_vif; + + mvmvif = iwl_mvm_vif_from_mac80211(vif); +- iwl_mvm_flush_sta(mvm, &mvmvif->deflink.bcast_sta, +- true); ++ iwl_mvm_flush_sta(mvm, mvmvif->deflink.bcast_sta.sta_id, ++ mvmvif->deflink.bcast_sta.tfd_queue_msk); + + if (mvm->mld_api_is_used) { + iwl_mvm_mld_rm_bcast_sta(mvm, vif, +@@ -113,7 +113,8 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk) + */ + if (test_and_clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status)) { + /* do the same in case of hot spot 2.0 */ +- iwl_mvm_flush_sta(mvm, &mvm->aux_sta, true); ++ iwl_mvm_flush_sta(mvm, mvm->aux_sta.sta_id, ++ mvm->aux_sta.tfd_queue_msk); + + if (mvm->mld_api_is_used) { + iwl_mvm_mld_rm_aux_sta(mvm); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index 8158e6d9ef190..8bdb239295c39 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -2297,24 +2297,10 @@ int iwl_mvm_flush_sta_tids(struct iwl_mvm *mvm, u32 sta_id, u16 tids) + return ret; + } + +-int iwl_mvm_flush_sta(struct iwl_mvm *mvm, void *sta, bool internal) ++int iwl_mvm_flush_sta(struct iwl_mvm *mvm, u32 sta_id, u32 tfd_queue_mask) + { +- u32 sta_id, tfd_queue_msk; +- +- if (internal) { +- struct iwl_mvm_int_sta *int_sta = sta; +- +- sta_id = int_sta->sta_id; +- tfd_queue_msk = int_sta->tfd_queue_msk; +- } else { +- struct iwl_mvm_sta *mvm_sta = sta; +- +- sta_id = mvm_sta->deflink.sta_id; +- tfd_queue_msk = mvm_sta->tfd_queue_msk; +- } +- + if (iwl_mvm_has_new_tx_api(mvm)) + return iwl_mvm_flush_sta_tids(mvm, sta_id, 0xffff); + +- return iwl_mvm_flush_tx_path(mvm, tfd_queue_msk); ++ return iwl_mvm_flush_tx_path(mvm, tfd_queue_mask); + } +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-mvm-correctly-set-link-configuration.patch b/queue-6.6/wifi-iwlwifi-mvm-correctly-set-link-configuration.patch new file mode 100644 index 00000000000..865771a86cc --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-mvm-correctly-set-link-configuration.patch @@ -0,0 +1,67 @@ +From ff9ee1498f889fe3234edf4b347ec1cc5a9d0c9f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 12:36:34 +0300 +Subject: wifi: iwlwifi: mvm: Correctly set link configuration + +From: Ilan Peer + +[ Upstream commit 35b9281fb710ea9fa47dca56774f4a9606fe9154 ] + +In case the link puncturing is changed such that the channel +is no longer punctured, configure the FW correctly indicating +the EHT parameters changed (with a 0 punctured map). + +Allow EHT parameters configuration only when the link really +supports EHT. + +Fixes: 55eb1c5fa4b2 ("wifi: iwlwifi: mvm: add support for the new LINK command") +Signed-off-by: Ilan Peer +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20231004123422.2666ef86e032.I4b0e95722660acc5345ceefba7e8866a69572e8e@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/link.c | 13 ++++++++----- + .../net/wireless/intel/iwlwifi/mvm/mld-mac80211.c | 2 +- + 2 files changed, 9 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c +index ace82e2c5bd91..4f8d2a3191ec7 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c +@@ -194,11 +194,14 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + flags_mask |= LINK_FLG_MU_EDCA_CW; + } + +- if (link_conf->eht_puncturing && !iwlwifi_mod_params.disable_11be) +- cmd.puncture_mask = cpu_to_le16(link_conf->eht_puncturing); +- else +- /* This flag can be set only if the MAC has eht support */ +- changes &= ~LINK_CONTEXT_MODIFY_EHT_PARAMS; ++ if (changes & LINK_CONTEXT_MODIFY_EHT_PARAMS) { ++ if (iwlwifi_mod_params.disable_11be || ++ !link_conf->eht_support) ++ changes &= ~LINK_CONTEXT_MODIFY_EHT_PARAMS; ++ else ++ cmd.puncture_mask = ++ cpu_to_le16(link_conf->eht_puncturing); ++ } + + cmd.bss_color = link_conf->he_bss_color.color; + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +index 778a311b500bc..a3a2e9a1fa7bd 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +@@ -653,7 +653,7 @@ iwl_mvm_mld_link_info_changed_station(struct iwl_mvm *mvm, + } + + /* Update EHT Puncturing info */ +- if (changes & BSS_CHANGED_EHT_PUNCTURING && vif->cfg.assoc && has_eht) ++ if (changes & BSS_CHANGED_EHT_PUNCTURING && vif->cfg.assoc) + link_changes |= LINK_CONTEXT_MODIFY_EHT_PARAMS; + + if (link_changes) { +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-mvm-don-t-always-bind-link-the-p2p-devi.patch b/queue-6.6/wifi-iwlwifi-mvm-don-t-always-bind-link-the-p2p-devi.patch new file mode 100644 index 00000000000..689b991e3f7 --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-mvm-don-t-always-bind-link-the-p2p-devi.patch @@ -0,0 +1,552 @@ +From be94682ba5ff93bb152f4bc502a2c731f54ba192 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 12:36:30 +0300 +Subject: wifi: iwlwifi: mvm: Don't always bind/link the P2P Device interface + +From: Ilan Peer + +[ Upstream commit 84ef7cbe90e9e54c71c1da4e645ba34e1b33da77 ] + +It is not necessary to keep the P2P Device bound/linked to a PHY +context when there is no active ROC. + +Modify the P2P Device flows so the binding/linking would be done +only while ROC is active. With this change the switch_phy_ctxt() +is no longer needed so remove it. + +Signed-off-by: Ilan Peer +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20231004123422.c5b83b4bf9de.Ia80daf3ba0b5fec7d0919247fcbdbdb58bddf02b@changeid +Signed-off-by: Johannes Berg +Stable-dep-of: 43874283ce6c ("wifi: iwlwifi: mvm: fix iwl_mvm_mac_flush_sta()") +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/link.c | 9 +- + .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 8 +- + .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 152 ++++++------------ + .../wireless/intel/iwlwifi/mvm/mld-mac80211.c | 100 ++++-------- + drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 7 +- + .../wireless/intel/iwlwifi/mvm/time-event.c | 24 ++- + 6 files changed, 111 insertions(+), 189 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c +index 4f8d2a3191ec7..6e1ad65527d12 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c +@@ -53,7 +53,6 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + unsigned int link_id = link_conf->link_id; + struct iwl_mvm_vif_link_info *link_info = mvmvif->link[link_id]; + struct iwl_link_config_cmd cmd = {}; +- struct iwl_mvm_phy_ctxt *phyctxt; + + if (WARN_ON_ONCE(!link_info)) + return -EINVAL; +@@ -77,12 +76,8 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + cmd.link_id = cpu_to_le32(link_info->fw_link_id); + cmd.mac_id = cpu_to_le32(mvmvif->id); + cmd.spec_link_id = link_conf->link_id; +- /* P2P-Device already has a valid PHY context during add */ +- phyctxt = link_info->phy_ctxt; +- if (phyctxt) +- cmd.phy_id = cpu_to_le32(phyctxt->id); +- else +- cmd.phy_id = cpu_to_le32(FW_CTXT_INVALID); ++ WARN_ON_ONCE(link_info->phy_ctxt); ++ cmd.phy_id = cpu_to_le32(FW_CTXT_INVALID); + + memcpy(cmd.local_link_addr, link_conf->addr, ETH_ALEN); + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +index 7369a45f7f2bd..9c97691e60384 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +@@ -286,6 +286,10 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif) + INIT_LIST_HEAD(&mvmvif->time_event_data.list); + mvmvif->time_event_data.id = TE_MAX; + ++ mvmvif->deflink.bcast_sta.sta_id = IWL_MVM_INVALID_STA; ++ mvmvif->deflink.mcast_sta.sta_id = IWL_MVM_INVALID_STA; ++ mvmvif->deflink.ap_sta_id = IWL_MVM_INVALID_STA; ++ + /* No need to allocate data queues to P2P Device MAC and NAN.*/ + if (vif->type == NL80211_IFTYPE_P2P_DEVICE) + return 0; +@@ -300,10 +304,6 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif) + mvmvif->deflink.cab_queue = IWL_MVM_DQA_GCAST_QUEUE; + } + +- mvmvif->deflink.bcast_sta.sta_id = IWL_MVM_INVALID_STA; +- mvmvif->deflink.mcast_sta.sta_id = IWL_MVM_INVALID_STA; +- mvmvif->deflink.ap_sta_id = IWL_MVM_INVALID_STA; +- + for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) + mvmvif->deflink.smps_requests[i] = IEEE80211_SMPS_AUTOMATIC; + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +index f852e5d770d9b..a3058d7c77574 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +@@ -1589,32 +1589,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, + IEEE80211_VIF_SUPPORTS_CQM_RSSI; + } + +- /* +- * P2P_DEVICE interface does not have a channel context assigned to it, +- * so a dedicated PHY context is allocated to it and the corresponding +- * MAC context is bound to it at this stage. +- */ +- if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { +- +- mvmvif->deflink.phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm); +- if (!mvmvif->deflink.phy_ctxt) { +- ret = -ENOSPC; +- goto out_free_bf; +- } +- +- iwl_mvm_phy_ctxt_ref(mvm, mvmvif->deflink.phy_ctxt); +- ret = iwl_mvm_binding_add_vif(mvm, vif); +- if (ret) +- goto out_unref_phy; +- +- ret = iwl_mvm_add_p2p_bcast_sta(mvm, vif); +- if (ret) +- goto out_unbind; +- +- /* Save a pointer to p2p device vif, so it can later be used to +- * update the p2p device MAC when a GO is started/stopped */ ++ if (vif->type == NL80211_IFTYPE_P2P_DEVICE) + mvm->p2p_device_vif = vif; +- } + + iwl_mvm_tcm_add_vif(mvm, vif); + INIT_DELAYED_WORK(&mvmvif->csa_work, +@@ -1643,11 +1619,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, + + goto out_unlock; + +- out_unbind: +- iwl_mvm_binding_remove_vif(mvm, vif); +- out_unref_phy: +- iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt); +- out_free_bf: + if (mvm->bf_allowed_vif == mvmvif) { + mvm->bf_allowed_vif = NULL; + vif->driver_flags &= ~(IEEE80211_VIF_BEACON_FILTER | +@@ -1744,12 +1715,17 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, + if (iwl_mvm_mac_remove_interface_common(hw, vif)) + goto out; + ++ /* Before the interface removal, mac80211 would cancel the ROC, and the ++ * ROC worker would be scheduled if needed. The worker would be flushed ++ * in iwl_mvm_prepare_mac_removal() and thus at this point there is no ++ * binding etc. so nothing needs to be done here. ++ */ + if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { ++ if (mvmvif->deflink.phy_ctxt) { ++ iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt); ++ mvmvif->deflink.phy_ctxt = NULL; ++ } + mvm->p2p_device_vif = NULL; +- iwl_mvm_rm_p2p_bcast_sta(mvm, vif); +- iwl_mvm_binding_remove_vif(mvm, vif); +- iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt); +- mvmvif->deflink.phy_ctxt = NULL; + } + + iwl_mvm_mac_ctxt_remove(mvm, vif); +@@ -4537,30 +4513,20 @@ static int iwl_mvm_add_aux_sta_for_hs20(struct iwl_mvm *mvm, u32 lmac_id) + return ret; + } + +-static int iwl_mvm_roc_switch_binding(struct iwl_mvm *mvm, +- struct ieee80211_vif *vif, +- struct iwl_mvm_phy_ctxt *new_phy_ctxt) ++static int iwl_mvm_roc_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif) + { +- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); +- int ret = 0; ++ int ret; + + lockdep_assert_held(&mvm->mutex); + +- /* Unbind the P2P_DEVICE from the current PHY context, +- * and if the PHY context is not used remove it. +- */ +- ret = iwl_mvm_binding_remove_vif(mvm, vif); +- if (WARN(ret, "Failed unbinding P2P_DEVICE\n")) ++ ret = iwl_mvm_binding_add_vif(mvm, vif); ++ if (WARN(ret, "Failed binding P2P_DEVICE\n")) + return ret; + +- iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt); +- +- /* Bind the P2P_DEVICE to the current PHY Context */ +- mvmvif->deflink.phy_ctxt = new_phy_ctxt; +- +- ret = iwl_mvm_binding_add_vif(mvm, vif); +- WARN(ret, "Failed binding P2P_DEVICE\n"); +- return ret; ++ /* The station and queue allocation must be done only after the binding ++ * is done, as otherwise the FW might incorrectly configure its state. ++ */ ++ return iwl_mvm_add_p2p_bcast_sta(mvm, vif); + } + + static int iwl_mvm_roc(struct ieee80211_hw *hw, +@@ -4571,7 +4537,7 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw, + { + static const struct iwl_mvm_roc_ops ops = { + .add_aux_sta_for_hs20 = iwl_mvm_add_aux_sta_for_hs20, +- .switch_phy_ctxt = iwl_mvm_roc_switch_binding, ++ .link = iwl_mvm_roc_link, + }; + + return iwl_mvm_roc_common(hw, vif, channel, duration, type, &ops); +@@ -4587,7 +4553,6 @@ int iwl_mvm_roc_common(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct cfg80211_chan_def chandef; + struct iwl_mvm_phy_ctxt *phy_ctxt; +- bool band_change_removal; + int ret, i; + u32 lmac_id; + +@@ -4616,82 +4581,61 @@ int iwl_mvm_roc_common(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + /* handle below */ + break; + default: +- IWL_ERR(mvm, "vif isn't P2P_DEVICE: %d\n", vif->type); ++ IWL_ERR(mvm, "ROC: Invalid vif type=%u\n", vif->type); + ret = -EINVAL; + goto out_unlock; + } + ++ /* Try using a PHY context that is already in use */ + for (i = 0; i < NUM_PHY_CTX; i++) { + phy_ctxt = &mvm->phy_ctxts[i]; +- if (phy_ctxt->ref == 0 || mvmvif->deflink.phy_ctxt == phy_ctxt) ++ if (!phy_ctxt->ref || mvmvif->deflink.phy_ctxt == phy_ctxt) + continue; + +- if (phy_ctxt->ref && channel == phy_ctxt->channel) { +- ret = ops->switch_phy_ctxt(mvm, vif, phy_ctxt); +- if (ret) +- goto out_unlock; ++ if (channel == phy_ctxt->channel) { ++ if (mvmvif->deflink.phy_ctxt) ++ iwl_mvm_phy_ctxt_unref(mvm, ++ mvmvif->deflink.phy_ctxt); + ++ mvmvif->deflink.phy_ctxt = phy_ctxt; + iwl_mvm_phy_ctxt_ref(mvm, mvmvif->deflink.phy_ctxt); +- goto schedule_time_event; ++ goto link_and_start_p2p_roc; + } + } + +- /* Need to update the PHY context only if the ROC channel changed */ +- if (channel == mvmvif->deflink.phy_ctxt->channel) +- goto schedule_time_event; +- +- cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT); +- +- /* +- * Check if the remain-on-channel is on a different band and that +- * requires context removal, see iwl_mvm_phy_ctxt_changed(). If +- * so, we'll need to release and then re-configure here, since we +- * must not remove a PHY context that's part of a binding. ++ /* If the currently used PHY context is configured with a matching ++ * channel use it + */ +- band_change_removal = +- fw_has_capa(&mvm->fw->ucode_capa, +- IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT) && +- mvmvif->deflink.phy_ctxt->channel->band != chandef.chan->band; +- +- if (mvmvif->deflink.phy_ctxt->ref == 1 && !band_change_removal) { +- /* +- * Change the PHY context configuration as it is currently +- * referenced only by the P2P Device MAC (and we can modify it) +- */ +- ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->deflink.phy_ctxt, +- &chandef, 1, 1); +- if (ret) +- goto out_unlock; ++ if (mvmvif->deflink.phy_ctxt) { ++ if (channel == mvmvif->deflink.phy_ctxt->channel) ++ goto link_and_start_p2p_roc; + } else { +- /* +- * The PHY context is shared with other MACs (or we're trying to +- * switch bands), so remove the P2P Device from the binding, +- * allocate an new PHY context and create a new binding. +- */ + phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm); + if (!phy_ctxt) { + ret = -ENOSPC; + goto out_unlock; + } + +- ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &chandef, +- 1, 1); +- if (ret) { +- IWL_ERR(mvm, "Failed to change PHY context\n"); +- goto out_unlock; +- } ++ mvmvif->deflink.phy_ctxt = phy_ctxt; ++ iwl_mvm_phy_ctxt_ref(mvm, mvmvif->deflink.phy_ctxt); ++ } + +- ret = ops->switch_phy_ctxt(mvm, vif, phy_ctxt); +- if (ret) +- goto out_unlock; ++ /* Configure the PHY context */ ++ cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT); + +- iwl_mvm_phy_ctxt_ref(mvm, mvmvif->deflink.phy_ctxt); ++ ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &chandef, ++ 1, 1); ++ if (ret) { ++ IWL_ERR(mvm, "Failed to change PHY context\n"); ++ goto out_unlock; + } + +-schedule_time_event: +- /* Schedule the time events */ +- ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type); ++link_and_start_p2p_roc: ++ ret = ops->link(mvm, vif); ++ if (ret) ++ goto out_unlock; + ++ ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type); + out_unlock: + mutex_unlock(&mvm->mutex); + IWL_DEBUG_MAC80211(mvm, "leave\n"); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +index a3a2e9a1fa7bd..2ddb6f763a0b3 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +@@ -56,43 +56,15 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw, + IEEE80211_VIF_SUPPORTS_CQM_RSSI; + } + +- /* +- * P2P_DEVICE interface does not have a channel context assigned to it, +- * so a dedicated PHY context is allocated to it and the corresponding +- * MAC context is bound to it at this stage. +- */ +- if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { +- mvmvif->deflink.phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm); +- if (!mvmvif->deflink.phy_ctxt) { +- ret = -ENOSPC; +- goto out_free_bf; +- } +- +- iwl_mvm_phy_ctxt_ref(mvm, mvmvif->deflink.phy_ctxt); +- ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf); +- if (ret) +- goto out_unref_phy; +- +- ret = iwl_mvm_link_changed(mvm, vif, &vif->bss_conf, +- LINK_CONTEXT_MODIFY_ACTIVE | +- LINK_CONTEXT_MODIFY_RATES_INFO, +- true); +- if (ret) +- goto out_remove_link; +- +- ret = iwl_mvm_mld_add_bcast_sta(mvm, vif, &vif->bss_conf); +- if (ret) +- goto out_remove_link; ++ ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf); ++ if (ret) ++ goto out_free_bf; + +- /* Save a pointer to p2p device vif, so it can later be used to +- * update the p2p device MAC when a GO is started/stopped +- */ ++ /* Save a pointer to p2p device vif, so it can later be used to ++ * update the p2p device MAC when a GO is started/stopped ++ */ ++ if (vif->type == NL80211_IFTYPE_P2P_DEVICE) + mvm->p2p_device_vif = vif; +- } else { +- ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf); +- if (ret) +- goto out_free_bf; +- } + + ret = iwl_mvm_power_update_mac(mvm); + if (ret) +@@ -119,10 +91,6 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw, + + goto out_unlock; + +- out_remove_link: +- iwl_mvm_disable_link(mvm, vif, &vif->bss_conf); +- out_unref_phy: +- iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt); + out_free_bf: + if (mvm->bf_allowed_vif == mvmvif) { + mvm->bf_allowed_vif = NULL; +@@ -130,7 +98,6 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw, + IEEE80211_VIF_SUPPORTS_CQM_RSSI); + } + out_remove_mac: +- mvmvif->deflink.phy_ctxt = NULL; + mvmvif->link[0] = NULL; + iwl_mvm_mld_mac_ctxt_remove(mvm, vif); + out_unlock: +@@ -185,14 +152,18 @@ static void iwl_mvm_mld_mac_remove_interface(struct ieee80211_hw *hw, + + iwl_mvm_power_update_mac(mvm); + ++ /* Before the interface removal, mac80211 would cancel the ROC, and the ++ * ROC worker would be scheduled if needed. The worker would be flushed ++ * in iwl_mvm_prepare_mac_removal() and thus at this point the link is ++ * not active. So need only to remove the link. ++ */ + if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { ++ if (mvmvif->deflink.phy_ctxt) { ++ iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt); ++ mvmvif->deflink.phy_ctxt = NULL; ++ } + mvm->p2p_device_vif = NULL; +- +- /* P2P device uses only one link */ +- iwl_mvm_mld_rm_bcast_sta(mvm, vif, &vif->bss_conf); +- iwl_mvm_disable_link(mvm, vif, &vif->bss_conf); +- iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt); +- mvmvif->deflink.phy_ctxt = NULL; ++ iwl_mvm_remove_link(mvm, vif, &vif->bss_conf); + } else { + iwl_mvm_disable_link(mvm, vif, &vif->bss_conf); + } +@@ -968,36 +939,29 @@ iwl_mvm_mld_mac_conf_tx(struct ieee80211_hw *hw, + return 0; + } + +-static int iwl_mvm_link_switch_phy_ctx(struct iwl_mvm *mvm, +- struct ieee80211_vif *vif, +- struct iwl_mvm_phy_ctxt *new_phy_ctxt) ++static int iwl_mvm_mld_roc_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif) + { +- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); +- int ret = 0; ++ int ret; + + lockdep_assert_held(&mvm->mutex); + +- /* Inorder to change the phy_ctx of a link, the link needs to be +- * inactive. Therefore, first deactivate the link, then change its +- * phy_ctx, and then activate it again. +- */ +- ret = iwl_mvm_link_changed(mvm, vif, &vif->bss_conf, +- LINK_CONTEXT_MODIFY_ACTIVE, false); +- if (WARN(ret, "Failed to deactivate link\n")) ++ /* The PHY context ID might have changed so need to set it */ ++ ret = iwl_mvm_link_changed(mvm, vif, &vif->bss_conf, 0, false); ++ if (WARN(ret, "Failed to set PHY context ID\n")) + return ret; + +- iwl_mvm_phy_ctxt_unref(mvm, mvmvif->deflink.phy_ctxt); +- +- mvmvif->deflink.phy_ctxt = new_phy_ctxt; ++ ret = iwl_mvm_link_changed(mvm, vif, &vif->bss_conf, ++ LINK_CONTEXT_MODIFY_ACTIVE | ++ LINK_CONTEXT_MODIFY_RATES_INFO, ++ true); + +- ret = iwl_mvm_link_changed(mvm, vif, &vif->bss_conf, 0, false); +- if (WARN(ret, "Failed to deactivate link\n")) ++ if (WARN(ret, "Failed linking P2P_DEVICE\n")) + return ret; + +- ret = iwl_mvm_link_changed(mvm, vif, &vif->bss_conf, +- LINK_CONTEXT_MODIFY_ACTIVE, true); +- WARN(ret, "Failed binding P2P_DEVICE\n"); +- return ret; ++ /* The station and queue allocation must be done only after the linking ++ * is done, as otherwise the FW might incorrectly configure its state. ++ */ ++ return iwl_mvm_mld_add_bcast_sta(mvm, vif, &vif->bss_conf); + } + + static int iwl_mvm_mld_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +@@ -1006,7 +970,7 @@ static int iwl_mvm_mld_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + { + static const struct iwl_mvm_roc_ops ops = { + .add_aux_sta_for_hs20 = iwl_mvm_mld_add_aux_sta, +- .switch_phy_ctxt = iwl_mvm_link_switch_phy_ctx, ++ .link = iwl_mvm_mld_roc_link, + }; + + return iwl_mvm_roc_common(hw, vif, channel, duration, type, &ops); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +index b18c91c5dd5d1..b596eca562166 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +@@ -1942,13 +1942,12 @@ void iwl_mvm_bss_info_changed_station_assoc(struct iwl_mvm *mvm, + * + * @add_aux_sta_for_hs20: pointer to the function that adds an aux sta + * for Hot Spot 2.0 +- * @switch_phy_ctxt: pointer to the function that switches a vif from one +- * phy_ctx to another ++ * @link: For a P2P Device interface, pointer to a function that links the ++ * MAC/Link to the PHY context + */ + struct iwl_mvm_roc_ops { + int (*add_aux_sta_for_hs20)(struct iwl_mvm *mvm, u32 lmac_id); +- int (*switch_phy_ctxt)(struct iwl_mvm *mvm, struct ieee80211_vif *vif, +- struct iwl_mvm_phy_ctxt *new_phy_ctxt); ++ int (*link)(struct iwl_mvm *mvm, struct ieee80211_vif *vif); + }; + + int iwl_mvm_roc_common(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +index 5f0e7144a951c..ff213247569a7 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +@@ -78,9 +78,29 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk) + */ + + if (!WARN_ON(!mvm->p2p_device_vif)) { +- mvmvif = iwl_mvm_vif_from_mac80211(mvm->p2p_device_vif); ++ struct ieee80211_vif *vif = mvm->p2p_device_vif; ++ ++ mvmvif = iwl_mvm_vif_from_mac80211(vif); + iwl_mvm_flush_sta(mvm, &mvmvif->deflink.bcast_sta, + true); ++ ++ if (mvm->mld_api_is_used) { ++ iwl_mvm_mld_rm_bcast_sta(mvm, vif, ++ &vif->bss_conf); ++ ++ iwl_mvm_link_changed(mvm, vif, &vif->bss_conf, ++ LINK_CONTEXT_MODIFY_ACTIVE, ++ false); ++ } else { ++ iwl_mvm_rm_p2p_bcast_sta(mvm, vif); ++ iwl_mvm_binding_remove_vif(mvm, vif); ++ } ++ ++ /* Do not remove the PHY context as removing and adding ++ * a PHY context has timing overheads. Leaving it ++ * configured in FW would be useful in case the next ROC ++ * is with the same channel. ++ */ + } + } + +@@ -880,8 +900,8 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm, + if (!le32_to_cpu(notif->status) || !le32_to_cpu(notif->start)) { + /* End TE, notify mac80211 */ + mvmvif->time_event_data.id = SESSION_PROTECT_CONF_MAX_ID; +- ieee80211_remain_on_channel_expired(mvm->hw); + iwl_mvm_p2p_roc_finished(mvm); ++ ieee80211_remain_on_channel_expired(mvm->hw); + } else if (le32_to_cpu(notif->start)) { + if (WARN_ON(mvmvif->time_event_data.id != + le32_to_cpu(notif->conf_id))) +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-mvm-fix-iwl_mvm_mac_flush_sta.patch b/queue-6.6/wifi-iwlwifi-mvm-fix-iwl_mvm_mac_flush_sta.patch new file mode 100644 index 00000000000..56127f5dc08 --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-mvm-fix-iwl_mvm_mac_flush_sta.patch @@ -0,0 +1,67 @@ +From 9db9f7dc65fc03428995a11bb8e2d32d503607be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 13:07:29 +0300 +Subject: wifi: iwlwifi: mvm: fix iwl_mvm_mac_flush_sta() + +From: Johannes Berg + +[ Upstream commit 43874283ce6c5bd32ac9d30878b2c96a974357cb ] + +When I implemented iwl_mvm_mac_flush_sta() I completely botched it; +it basically always happens after the iwl_mvm_sta_pre_rcu_remove() +call, and that already clears mvm->fw_id_to_mac_id[] entries, so we +cannot rely on those at iwl_mvm_mac_flush_sta() time. This means it +never did anything. + +Fix this by just going through the station IDs and now with the new +API for iwl_mvm_flush_sta(), call those. + +Fixes: a6cc6ccb1c8a ("wifi: iwlwifi: mvm: support new flush_sta method") +Signed-off-by: Johannes Berg +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20231011130030.0b5878e93118.I1093e60163052e7be64d2b01424097cd6a272979@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 20 +++++++++---------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +index e68026a657059..a25ea638229b0 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +@@ -5602,22 +5602,20 @@ void iwl_mvm_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + void iwl_mvm_mac_flush_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) + { ++ struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); +- int i; ++ struct iwl_mvm_link_sta *mvm_link_sta; ++ struct ieee80211_link_sta *link_sta; ++ int link_id; + + mutex_lock(&mvm->mutex); +- for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) { +- struct iwl_mvm_sta *mvmsta; +- struct ieee80211_sta *tmp; +- +- tmp = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], +- lockdep_is_held(&mvm->mutex)); +- if (tmp != sta) ++ for_each_sta_active_link(vif, sta, link_sta, link_id) { ++ mvm_link_sta = rcu_dereference_protected(mvmsta->link[link_id], ++ lockdep_is_held(&mvm->mutex)); ++ if (!mvm_link_sta) + continue; + +- mvmsta = iwl_mvm_sta_from_mac80211(sta); +- +- if (iwl_mvm_flush_sta(mvm, mvmsta->deflink.sta_id, ++ if (iwl_mvm_flush_sta(mvm, mvm_link_sta->sta_id, + mvmsta->tfd_queue_msk)) + IWL_ERR(mvm, "flush request fail\n"); + } +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-mvm-fix-key-flags-for-igtk-on-ap-interf.patch b/queue-6.6/wifi-iwlwifi-mvm-fix-key-flags-for-igtk-on-ap-interf.patch new file mode 100644 index 00000000000..9b1c96cadc0 --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-mvm-fix-key-flags-for-igtk-on-ap-interf.patch @@ -0,0 +1,47 @@ +From 1a677e309924bb6a7e0e253b1ff82ee21d2fa08c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 13:07:20 +0300 +Subject: wifi: iwlwifi: mvm: Fix key flags for IGTK on AP interface + +From: Ilan Peer + +[ Upstream commit 8f9a791a8edd87fa64b35037d9c3bce89a1b8d21 ] + +When an IGTK is installed for an AP interface, there is no station +associated with it. However, the MFP flag must be set for the installed +key as otherwise the FW wouldn't use it. + +Fix the security key flag to set the MFP flag also when the AP is +an AP interface and the key index matches that of an IGTK. + +Fixes: 5c75a208c244 ("wifi: iwlwifi: mvm: support new key API") +Signed-off-by: Ilan Peer +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20231011130030.f67005e2d4d2.I6832c6e87f3c79fff00689eb10a3a30810e1ee83@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c +index f498206470410..ea3e9e9c6e26c 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c +@@ -96,7 +96,12 @@ u32 iwl_mvm_get_sec_flags(struct iwl_mvm *mvm, + if (!sta && vif->type == NL80211_IFTYPE_STATION) + sta = mvmvif->ap_sta; + +- if (!IS_ERR_OR_NULL(sta) && sta->mfp) ++ /* Set the MFP flag also for an AP interface where the key is an IGTK ++ * key as in such a case the station would always be NULL ++ */ ++ if ((!IS_ERR_OR_NULL(sta) && sta->mfp) || ++ (vif->type == NL80211_IFTYPE_AP && ++ (keyconf->keyidx == 4 || keyconf->keyidx == 5))) + flags |= IWL_SEC_KEY_FLAG_MFP; + + return flags; +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-mvm-fix-netif-csum-flags.patch b/queue-6.6/wifi-iwlwifi-mvm-fix-netif-csum-flags.patch new file mode 100644 index 00000000000..ae3496812a9 --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-mvm-fix-netif-csum-flags.patch @@ -0,0 +1,78 @@ +From 67f6405ff72448f0c32ee5d18bbee34f65a87ca9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 12:16:41 +0300 +Subject: wifi: iwlwifi: mvm: fix netif csum flags + +From: Johannes Berg + +[ Upstream commit 08365d3b9140c751a84f8027ac7d2e662958f768 ] + +We shouldn't advertise arbitrary checksum flags since we had +to remove support for it due to broken hardware. + +Fixes: ec18e7d4d20d ("wifi: iwlwifi: mvm: use old checksum for Bz A-step") +Signed-off-by: Johannes Berg +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20231017115047.e37327f1a129.Iaee86b00db4db791cd90adaf15384b8c87d2ad49@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/cfg/bz.c | 4 ++-- + drivers/net/wireless/intel/iwlwifi/cfg/sc.c | 2 +- + drivers/net/wireless/intel/iwlwifi/iwl-config.h | 5 +---- + 3 files changed, 4 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c +index 3d223014cfe6d..42e765fe3cfe1 100644 +--- a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c ++++ b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c +@@ -158,7 +158,7 @@ const struct iwl_cfg iwl_cfg_bz = { + .fw_name_mac = "bz", + .uhb_supported = true, + IWL_DEVICE_BZ, +- .features = IWL_TX_CSUM_NETIF_FLAGS_BZ | NETIF_F_RXCSUM, ++ .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, + .num_rbds = IWL_NUM_RBDS_BZ_EHT, + }; + +@@ -166,7 +166,7 @@ const struct iwl_cfg iwl_cfg_gl = { + .fw_name_mac = "gl", + .uhb_supported = true, + IWL_DEVICE_BZ, +- .features = IWL_TX_CSUM_NETIF_FLAGS_BZ | NETIF_F_RXCSUM, ++ .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, + .num_rbds = IWL_NUM_RBDS_BZ_EHT, + }; + +diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c +index d6243025993ea..604e9cef6baac 100644 +--- a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c ++++ b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c +@@ -151,7 +151,7 @@ const struct iwl_cfg iwl_cfg_sc = { + .fw_name_mac = "sc", + .uhb_supported = true, + IWL_DEVICE_SC, +- .features = IWL_TX_CSUM_NETIF_FLAGS_BZ | NETIF_F_RXCSUM, ++ .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, + .num_rbds = IWL_NUM_RBDS_SC_EHT, + }; + +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h +index 241a9e3f2a1a7..f45f645ca6485 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h +@@ -86,10 +86,7 @@ enum iwl_nvm_type { + #define IWL_DEFAULT_MAX_TX_POWER 22 + #define IWL_TX_CSUM_NETIF_FLAGS (NETIF_F_IPV6_CSUM | NETIF_F_IP_CSUM |\ + NETIF_F_TSO | NETIF_F_TSO6) +-#define IWL_TX_CSUM_NETIF_FLAGS_BZ (NETIF_F_HW_CSUM | NETIF_F_TSO | NETIF_F_TSO6) +-#define IWL_CSUM_NETIF_FLAGS_MASK (IWL_TX_CSUM_NETIF_FLAGS | \ +- IWL_TX_CSUM_NETIF_FLAGS_BZ | \ +- NETIF_F_RXCSUM) ++#define IWL_CSUM_NETIF_FLAGS_MASK (IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM) + + /* Antenna presence definitions */ + #define ANT_NONE 0x0 +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-mvm-fix-removing-pasn-station-for-respo.patch b/queue-6.6/wifi-iwlwifi-mvm-fix-removing-pasn-station-for-respo.patch new file mode 100644 index 00000000000..6beed9c1e19 --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-mvm-fix-removing-pasn-station-for-respo.patch @@ -0,0 +1,52 @@ +From 10f0fe19d08bfb0dd1d23b3b7ea2d92b6c964d87 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Sep 2023 11:07:18 +0300 +Subject: wifi: iwlwifi: mvm: fix removing pasn station for responder + +From: Avraham Stern + +[ Upstream commit ff2687612c21a87a58c76099f3d59f8db376b995 ] + +In case of MLD operation the station should be removed using the +mld api. + +Fixes: fd940de72d49 ("wifi: iwlwifi: mvm: FTM responder MLO support") +Signed-off-by: Avraham Stern +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20230926110319.7eb353abb95c.I2b30be09b99f5a2379956e010bafaa465ff053ba@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c +index b49781d1a07a7..10b9219b3bfd3 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + /* + * Copyright (C) 2015-2017 Intel Deutschland GmbH +- * Copyright (C) 2018-2022 Intel Corporation ++ * Copyright (C) 2018-2023 Intel Corporation + */ + #include + #include +@@ -302,7 +302,12 @@ static void iwl_mvm_resp_del_pasn_sta(struct iwl_mvm *mvm, + struct iwl_mvm_pasn_sta *sta) + { + list_del(&sta->list); +- iwl_mvm_rm_sta_id(mvm, vif, sta->int_sta.sta_id); ++ ++ if (iwl_mvm_has_mld_api(mvm->fw)) ++ iwl_mvm_mld_rm_sta_id(mvm, sta->int_sta.sta_id); ++ else ++ iwl_mvm_rm_sta_id(mvm, vif, sta->int_sta.sta_id); ++ + iwl_mvm_dealloc_int_sta(mvm, &sta->int_sta); + kfree(sta); + } +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-mvm-remove-tdls-stations-from-fw.patch b/queue-6.6/wifi-iwlwifi-mvm-remove-tdls-stations-from-fw.patch new file mode 100644 index 00000000000..ea6c27ac8b5 --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-mvm-remove-tdls-stations-from-fw.patch @@ -0,0 +1,40 @@ +From 2336b1b6d489a303c79ee64a2526089957ae7d20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 13:07:30 +0300 +Subject: wifi: iwlwifi: mvm: remove TDLS stations from FW + +From: Johannes Berg + +[ Upstream commit 7b404c5cff3d4270fcd5212b6776c8484623ac74 ] + +When we remove TDLS stations, we need to remove them from FW +immediately, even while associated. Some previous refactoring +here lost the sta ID condition, add it back. + +Fixes: 57974a55d995 ("wifi: iwlwifi: mvm: refactor iwl_mvm_mac_sta_state_common()") +Signed-off-by: Johannes Berg +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20231011130030.933011e710a9.I77c069c781e8b2b698b86cc3f43fc3c7e2dde114@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +index ebbe165510587..2c231f4623893 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +@@ -2059,7 +2059,8 @@ bool iwl_mvm_sta_del(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + *status = IWL_MVM_QUEUE_FREE; + } + +- if (vif->type == NL80211_IFTYPE_STATION) { ++ if (vif->type == NL80211_IFTYPE_STATION && ++ mvm_link->ap_sta_id == sta_id) { + /* if associated - we can't remove the AP STA now */ + if (vif->cfg.assoc) + return true; +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-mvm-update-igtk-in-mvmvif-upon-d3-resum.patch b/queue-6.6/wifi-iwlwifi-mvm-update-igtk-in-mvmvif-upon-d3-resum.patch new file mode 100644 index 00000000000..6ddef91b745 --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-mvm-update-igtk-in-mvmvif-upon-d3-resum.patch @@ -0,0 +1,49 @@ +From 293adb8c8e90cdab881ab10950b568bfcfb04e71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 12:16:48 +0300 +Subject: wifi: iwlwifi: mvm: update IGTK in mvmvif upon D3 resume + +From: Yedidya Benshimol + +[ Upstream commit ac0c6fdc4c56b669abc1c4a323f1c7a3a1422dd2 ] + +During the D3 resume flow, all new rekeys are passed from the FW. +Because the FW supports only one IGTK at a time, every IGTK rekey +update should be done by removing the last IGTK. The mvmvif holds a +pointer to the last IGTK for that reason and thus should be updated +when a new IGTK is passed upon resume. + +Fixes: 04f78e242fff ("wifi: iwlwifi: mvm: Add support for IGTK in D3 resume flow") +Signed-off-by: Yedidya Benshimol +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20231017115047.8ceaf7e5ece7.Ief444f6a2703ed76648b4d414f12bb4130bab36e@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +index f6488b4bbe68b..be2602d8c5bfa 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +@@ -2012,6 +2012,16 @@ iwl_mvm_d3_igtk_bigtk_rekey_add(struct iwl_wowlan_status_data *status, + if (IS_ERR(key_config)) + return false; + ieee80211_set_key_rx_seq(key_config, 0, &seq); ++ ++ if (key_config->keyidx == 4 || key_config->keyidx == 5) { ++ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); ++ int link_id = vif->active_links ? __ffs(vif->active_links) : 0; ++ struct iwl_mvm_vif_link_info *mvm_link = ++ mvmvif->link[link_id]; ++ ++ mvm_link->igtk = key_config; ++ } ++ + return true; + } + +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-mvm-update-station-s-mfp-flag-after-ass.patch b/queue-6.6/wifi-iwlwifi-mvm-update-station-s-mfp-flag-after-ass.patch new file mode 100644 index 00000000000..327c2fedb55 --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-mvm-update-station-s-mfp-flag-after-ass.patch @@ -0,0 +1,46 @@ +From e1b06a7046ad9f88805bc7016e2c28622c3c7f2e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Sep 2023 11:07:13 +0300 +Subject: wifi: iwlwifi: mvm: update station's MFP flag after association + +From: Avraham Stern + +[ Upstream commit 5a86dcb4a908845e6b7ff39b78fb1141b895408f ] + +The management frames protection flag is always set when the station +is not yet authorized. However, it was not cleared after association +even if the association did not use MFP. As a result, all public +action frames are not parsed by fw (which will cause FTM to fail, +for example). Update the station MFP flag after the station is +authorized. + +Fixes: 4c8d5c8d079e ("wifi: iwlwifi: mvm: tell firmware about per-STA MFP enablement") +Signed-off-by: Avraham Stern +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20230926110319.2488cbd01bde.Ic0f08b7d3efcbdce27ec897f84d740fec8d169ef@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +index 5918c1f2b10c3..f852e5d770d9b 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +@@ -3791,6 +3791,12 @@ iwl_mvm_sta_state_assoc_to_authorized(struct iwl_mvm *mvm, + + iwl_mvm_rs_rate_init_all_links(mvm, vif, sta); + ++ /* MFP is set by default before the station is authorized. ++ * Clear it here in case it's not used. ++ */ ++ if (!sta->mfp) ++ return callbacks->update_sta(mvm, vif, sta); ++ + return 0; + } + +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-mvm-use-correct-sta-id-for-igtk-bigtk.patch b/queue-6.6/wifi-iwlwifi-mvm-use-correct-sta-id-for-igtk-bigtk.patch new file mode 100644 index 00000000000..843a2eeb12b --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-mvm-use-correct-sta-id-for-igtk-bigtk.patch @@ -0,0 +1,49 @@ +From a7b6aef4e79307bb04087d7ea534ba5de232f50e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Sep 2023 11:07:20 +0300 +Subject: wifi: iwlwifi: mvm: use correct sta ID for IGTK/BIGTK + +From: Johannes Berg + +[ Upstream commit 63ef576c9facf5d92702e249ad213fa73eb434bf ] + +We don't (yet) send the IGTK down to the firmware, but when +we do it needs to be with the broadcast station ID, not the +multicast station ID. Same for the BIGTK, which we may send +already if firmware advertises it (but it doesn't yet.) + +Fixes: a5de7de7e78e ("wifi: iwlwifi: mvm: enable TX beacon protection") +Signed-off-by: Johannes Berg +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20230926110319.dbc653913353.I82e90c86010f0b9588a180d9835fd11f666f5196@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c +index 2c9f2f71b083a..f498206470410 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c +@@ -24,10 +24,15 @@ static u32 iwl_mvm_get_sec_sta_mask(struct iwl_mvm *mvm, + return 0; + } + +- /* AP group keys are per link and should be on the mcast STA */ ++ /* AP group keys are per link and should be on the mcast/bcast STA */ + if (vif->type == NL80211_IFTYPE_AP && +- !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) ++ !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { ++ /* IGTK/BIGTK to bcast STA */ ++ if (keyconf->keyidx >= 4) ++ return BIT(link_info->bcast_sta.sta_id); ++ /* GTK for data to mcast STA */ + return BIT(link_info->mcast_sta.sta_id); ++ } + + /* for client mode use the AP STA also for group keys */ + if (!sta && vif->type == NL80211_IFTYPE_STATION) +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-pcie-synchronize-irqs-before-napi.patch b/queue-6.6/wifi-iwlwifi-pcie-synchronize-irqs-before-napi.patch new file mode 100644 index 00000000000..95adf619e0c --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-pcie-synchronize-irqs-before-napi.patch @@ -0,0 +1,55 @@ +From f5d2433e4042ea15cb8a3e0e57d8833b1508ef3c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 12:16:43 +0300 +Subject: wifi: iwlwifi: pcie: synchronize IRQs before NAPI + +From: Johannes Berg + +[ Upstream commit 37fb29bd1f90f16d1abc95c0e9f0ff8eec9829ad ] + +When we want to synchronize the NAPI, which was added in +commit 5af2bb3168db ("wifi: iwlwifi: call napi_synchronize() +before freeing rx/tx queues"), we also need to make sure we +can't actually reschedule the NAPI. Yes, this happens while +interrupts are disabled, but interrupts may still be running +or pending. Also call iwl_pcie_synchronize_irqs() to ensure +we won't reschedule the NAPI. + +Fixes: 4cf2f5904d97 ("iwlwifi: queue: avoid memory leak in reset flow") +Signed-off-by: Johannes Berg +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20231017115047.a0f4104b479a.Id5c50a944f709092aa6256e32d8c63b2b8d8d3ac@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 1 + + drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +index fa46dad5fd680..2ecf6db95fb31 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +@@ -161,6 +161,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) + if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) { + IWL_DEBUG_INFO(trans, + "DEVICE_ENABLED bit was set and is now cleared\n"); ++ iwl_pcie_synchronize_irqs(trans); + iwl_pcie_rx_napi_sync(trans); + iwl_txq_gen2_tx_free(trans); + iwl_pcie_rx_stop(trans); +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +index 198933f853c55..583d1011963ec 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +@@ -1263,6 +1263,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans) + if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) { + IWL_DEBUG_INFO(trans, + "DEVICE_ENABLED bit was set and is now cleared\n"); ++ iwl_pcie_synchronize_irqs(trans); + iwl_pcie_rx_napi_sync(trans); + iwl_pcie_tx_stop(trans); + iwl_pcie_rx_stop(trans); +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch b/queue-6.6/wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch new file mode 100644 index 00000000000..c8649ee706d --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch @@ -0,0 +1,64 @@ +From c4b10f971eb9fd5bf98497d593714976d30c4c29 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 14:56:45 +0300 +Subject: wifi: iwlwifi: Use FW rate for non-data frames + +From: Miri Korenblit + +[ Upstream commit 499d02790495958506a64f37ceda7e97345a50a8 ] + +Currently we are setting the rate in the tx cmd for +mgmt frames (e.g. during connection establishment). +This was problematic when sending mgmt frames in eSR mode, +as we don't know what link this frame will be sent on +(This is decided by the FW), so we don't know what is the +lowest rate. +Fix this by not setting the rate in tx cmd and rely +on FW to choose the right one. +Set rate only for injected frames with fixed rate, +or when no sta is given. +Also set for important frames (EAPOL etc.) the High Priority flag. + +Fixes: 055b22e770dd ("iwlwifi: mvm: Set Tx rate and flags when there is not station") +Signed-off-by: Miri Korenblit +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20230913145231.6c7e59620ee0.I6eaed3ccdd6dd62b9e664facc484081fc5275843@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index 898dca3936435..8158e6d9ef190 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -536,16 +536,20 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, + flags |= IWL_TX_FLAGS_ENCRYPT_DIS; + + /* +- * For data packets rate info comes from the fw. Only +- * set rate/antenna during connection establishment or in case +- * no station is given. ++ * For data and mgmt packets rate info comes from the fw. Only ++ * set rate/antenna for injected frames with fixed rate, or ++ * when no sta is given. + */ +- if (!sta || !ieee80211_is_data(hdr->frame_control) || +- mvmsta->sta_state < IEEE80211_STA_AUTHORIZED) { ++ if (unlikely(!sta || ++ info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)) { + flags |= IWL_TX_FLAGS_CMD_RATE; + rate_n_flags = + iwl_mvm_get_tx_rate_n_flags(mvm, info, sta, + hdr->frame_control); ++ } else if (!ieee80211_is_data(hdr->frame_control) || ++ mvmsta->sta_state < IEEE80211_STA_AUTHORIZED) { ++ /* These are important frames */ ++ flags |= IWL_TX_FLAGS_HIGH_PRI; + } + + if (mvm->trans->trans_cfg->device_family >= +-- +2.42.0 + diff --git a/queue-6.6/wifi-iwlwifi-yoyo-swap-cdb-and-jacket-bits-values.patch b/queue-6.6/wifi-iwlwifi-yoyo-swap-cdb-and-jacket-bits-values.patch new file mode 100644 index 00000000000..5f8c2c8b845 --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-yoyo-swap-cdb-and-jacket-bits-values.patch @@ -0,0 +1,40 @@ +From c4e2dea088be7831e45ab4b637260cb68129ffc7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 12:36:22 +0300 +Subject: wifi: iwlwifi: yoyo: swap cdb and jacket bits values + +From: Rotem Saado + +[ Upstream commit 65008777b9dcd2002414ddb2c2158293a6e2fd6f ] + +The bits are wrong, the jacket bit should be 5 and cdb bit 4. +Fix it. + +Fixes: 1f171f4f1437 ("iwlwifi: Add support for getting rf id with blank otp") +Signed-off-by: Rotem Saado +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20231004123422.356d8dacda2f.I349ab888b43a11baa2453a1d6978a6a703e422f0@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h +index 6dd381ff0f9e7..2a63968b0e55b 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h +@@ -348,8 +348,8 @@ + #define RFIC_REG_RD 0xAD0470 + #define WFPM_CTRL_REG 0xA03030 + #define WFPM_OTP_CFG1_ADDR 0x00a03098 +-#define WFPM_OTP_CFG1_IS_JACKET_BIT BIT(4) +-#define WFPM_OTP_CFG1_IS_CDB_BIT BIT(5) ++#define WFPM_OTP_CFG1_IS_JACKET_BIT BIT(5) ++#define WFPM_OTP_CFG1_IS_CDB_BIT BIT(4) + #define WFPM_OTP_BZ_BNJ_JACKET_BIT 5 + #define WFPM_OTP_BZ_BNJ_CDB_BIT 4 + #define WFPM_OTP_CFG1_IS_JACKET(_val) (((_val) & 0x00000020) >> WFPM_OTP_BZ_BNJ_JACKET_BIT) +-- +2.42.0 + diff --git a/queue-6.6/wifi-mac80211-don-t-recreate-driver-link-debugfs-in-.patch b/queue-6.6/wifi-mac80211-don-t-recreate-driver-link-debugfs-in-.patch new file mode 100644 index 00000000000..0e78b224bba --- /dev/null +++ b/queue-6.6/wifi-mac80211-don-t-recreate-driver-link-debugfs-in-.patch @@ -0,0 +1,46 @@ +From d304d467aeb7c98bab329ebf348f1d71d91e8f61 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Sep 2023 17:35:24 +0300 +Subject: wifi: mac80211: don't recreate driver link debugfs in reconfig + +From: Johannes Berg + +[ Upstream commit 822cab1987a0e028e38b60aecd98af0289b46e7b ] + +We can delete any that we want to remove, but we can't +recreate the links as they already exist. + +Fixes: 170cd6a66d9a ("wifi: mac80211: add netdev per-link debugfs data and driver hook") +Signed-off-by: Johannes Berg +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20230928172905.3d0214838421.I512a0ff86f631ff42bf25ea0cb2e8e8616794a94@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/driver-ops.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c +index 30cd0c905a24f..aa37a1410f377 100644 +--- a/net/mac80211/driver-ops.c ++++ b/net/mac80211/driver-ops.c +@@ -510,10 +510,13 @@ int drv_change_vif_links(struct ieee80211_local *local, + if (ret) + return ret; + +- for_each_set_bit(link_id, &links_to_add, IEEE80211_MLD_MAX_NUM_LINKS) { +- link = rcu_access_pointer(sdata->link[link_id]); ++ if (!local->in_reconfig) { ++ for_each_set_bit(link_id, &links_to_add, ++ IEEE80211_MLD_MAX_NUM_LINKS) { ++ link = rcu_access_pointer(sdata->link[link_id]); + +- ieee80211_link_debugfs_drv_add(link); ++ ieee80211_link_debugfs_drv_add(link); ++ } + } + + return 0; +-- +2.42.0 + diff --git a/queue-6.6/wifi-mac80211-fix-check-for-unusable-rx-result.patch b/queue-6.6/wifi-mac80211-fix-check-for-unusable-rx-result.patch new file mode 100644 index 00000000000..2d8b7f09bd8 --- /dev/null +++ b/queue-6.6/wifi-mac80211-fix-check-for-unusable-rx-result.patch @@ -0,0 +1,52 @@ +From 33d9fde70c6a92f1b35335eed80cd78800c3e6fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Sep 2023 17:24:39 +0200 +Subject: wifi: mac80211: fix check for unusable RX result + +From: Johannes Berg + +[ Upstream commit 583058542f46e3e2b0c536316fbd641f62d91dc6 ] + +If we just check "result & RX_DROP_UNUSABLE", this really only works +by accident, because SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE got to +have the value 1, and SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR is 2. + +Fix this to really check the entire subsys mask for the value, so it +doesn't matter what the subsystem value is. + +Fixes: 7f4e09700bdc ("wifi: mac80211: report all unusable beacon frames") +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/drop.h | 3 +++ + net/mac80211/rx.c | 2 +- + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/net/mac80211/drop.h b/net/mac80211/drop.h +index 49dc809cab290..1570fac8411f4 100644 +--- a/net/mac80211/drop.h ++++ b/net/mac80211/drop.h +@@ -53,4 +53,7 @@ enum mac80211_drop_reason { + #undef DEF + }; + ++#define RX_RES_IS_UNUSABLE(result) \ ++ (((__force u32)(result) & SKB_DROP_REASON_SUBSYS_MASK) == ___RX_DROP_UNUSABLE) ++ + #endif /* MAC80211_DROP_H */ +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 8f6b6f56b65b4..26ca2f5dc52b2 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2112,7 +2112,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) + /* either the frame has been decrypted or will be dropped */ + status->flag |= RX_FLAG_DECRYPTED; + +- if (unlikely(ieee80211_is_beacon(fc) && (result & RX_DROP_UNUSABLE) && ++ if (unlikely(ieee80211_is_beacon(fc) && RX_RES_IS_UNUSABLE(result) && + rx->sdata->dev)) + cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, + skb->data, skb->len); +-- +2.42.0 + diff --git a/queue-6.6/wifi-mac80211-fix-of-msdu-in-a-msdu-calculation.patch b/queue-6.6/wifi-mac80211-fix-of-msdu-in-a-msdu-calculation.patch new file mode 100644 index 00000000000..a22a939b959 --- /dev/null +++ b/queue-6.6/wifi-mac80211-fix-of-msdu-in-a-msdu-calculation.patch @@ -0,0 +1,39 @@ +From b5a8c455ce2240e25183ad5495e0bafb1095196c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 27 Aug 2023 14:05:28 +0300 +Subject: wifi: mac80211: fix # of MSDU in A-MSDU calculation + +From: Johannes Berg + +[ Upstream commit 428e8976a15f849ad92b1c1e38dda2a684350ff7 ] + +During my refactoring I wanted to get rid of the switch, +but replaced it with the wrong calculation. Fix that. + +Fixes: 175ad2ec89fe ("wifi: mac80211: limit A-MSDU subframes for client too") +Reported-by: Emmanuel Grumbach +Signed-off-by: Johannes Berg +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20230827135854.51bf1b8b0adb.Iffbd337fdad2b86ae12f5a39c69fb82b517f7486@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/sta_info.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c +index 7751f8ba960ee..0c5cc75857e4f 100644 +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -2990,7 +2990,7 @@ void ieee80211_sta_set_max_amsdu_subframes(struct sta_info *sta, + WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB) << 1; + + if (val) +- sta->sta.max_amsdu_subframes = 4 << val; ++ sta->sta.max_amsdu_subframes = 4 << (4 - val); + } + + #ifdef CONFIG_LOCKDEP +-- +2.42.0 + diff --git a/queue-6.6/wifi-mac80211-fix-rcu-usage-warning-in-mesh-fast-xmi.patch b/queue-6.6/wifi-mac80211-fix-rcu-usage-warning-in-mesh-fast-xmi.patch new file mode 100644 index 00000000000..70da45d8052 --- /dev/null +++ b/queue-6.6/wifi-mac80211-fix-rcu-usage-warning-in-mesh-fast-xmi.patch @@ -0,0 +1,37 @@ +From 4dda23f93758ba16b39400af1d22768c7b124fdb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Sep 2023 11:57:52 +0200 +Subject: wifi: mac80211: fix RCU usage warning in mesh fast-xmit + +From: Johannes Berg + +[ Upstream commit 5ea82df1f50e42416d0a8a7c42d37cc1df1545fe ] + +In mesh_fast_tx_flush_addr() we already hold the lock, so +don't need additional hashtable RCU protection. Use the +rhashtable_lookup_fast() variant to avoid RCU protection +warnings. + +Fixes: d5edb9ae8d56 ("wifi: mac80211: mesh fast xmit support") +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/mesh_pathtbl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c +index d32e304eeb4ba..3e52aaa57b1fc 100644 +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -648,7 +648,7 @@ void mesh_fast_tx_flush_addr(struct ieee80211_sub_if_data *sdata, + + cache = &sdata->u.mesh.tx_cache; + spin_lock_bh(&cache->walk_lock); +- entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params); ++ entry = rhashtable_lookup_fast(&cache->rht, addr, fast_tx_rht_params); + if (entry) + mesh_fast_tx_entry_free(cache, entry); + spin_unlock_bh(&cache->walk_lock); +-- +2.42.0 + diff --git a/queue-6.6/wifi-mac80211-fix-setting-vif-links.patch b/queue-6.6/wifi-mac80211-fix-setting-vif-links.patch new file mode 100644 index 00000000000..6ad47eb5a85 --- /dev/null +++ b/queue-6.6/wifi-mac80211-fix-setting-vif-links.patch @@ -0,0 +1,40 @@ +From 6282a8bfe5ae0f163a462f324dd8e13ff4c4990b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Sep 2023 17:35:31 +0300 +Subject: wifi: mac80211: Fix setting vif links + +From: Ilan Peer + +[ Upstream commit e7182c4e6bbeafa272612e6c06fa92b42ad107ad ] + +When setting the interface links, ignore the change iff both the +valid links and the dormant links did not change. This is needed +to support cases where the valid links didn't change but the dormant +links did. + +Fixes: 6d543b34dbcf ("wifi: mac80211: Support disabled links during association") +Signed-off-by: Ilan Peer +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20230928172905.0357b6306587.I7dbfec347949b629fea680d246a650d6207ff217@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/link.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/mac80211/link.c b/net/mac80211/link.c +index 6148208b320e3..16cbaea93fc32 100644 +--- a/net/mac80211/link.c ++++ b/net/mac80211/link.c +@@ -195,7 +195,7 @@ static int ieee80211_vif_update_links(struct ieee80211_sub_if_data *sdata, + + memset(to_free, 0, sizeof(links)); + +- if (old_links == new_links) ++ if (old_links == new_links && dormant_links == sdata->vif.dormant_links) + return 0; + + /* if there were no old links, need to clear the pointers to deflink */ +-- +2.42.0 + diff --git a/queue-6.6/wifi-mac80211-move-offchannel-works-to-wiphy-work.patch b/queue-6.6/wifi-mac80211-move-offchannel-works-to-wiphy-work.patch new file mode 100644 index 00000000000..e842a22c39c --- /dev/null +++ b/queue-6.6/wifi-mac80211-move-offchannel-works-to-wiphy-work.patch @@ -0,0 +1,199 @@ +From 82fc4501dd70c1ba66a306368026a1857d38a86d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Aug 2023 13:59:42 +0200 +Subject: wifi: mac80211: move offchannel works to wiphy work + +From: Johannes Berg + +[ Upstream commit 97c19e42b264e6b71a9ff9deea04c19f621805b9 ] + +Make the offchannel works wiphy works to have the +wiphy locked for executing them. + +Signed-off-by: Johannes Berg +Stable-dep-of: eadfb54756ae ("wifi: mac80211: move sched-scan stop work to wiphy work") +Signed-off-by: Sasha Levin +--- + net/mac80211/ieee80211_i.h | 4 ++-- + net/mac80211/main.c | 6 +++--- + net/mac80211/offchannel.c | 36 ++++++++++++++++++------------------ + 3 files changed, 23 insertions(+), 23 deletions(-) + +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index 4e98e03e5de64..5321f75d0c6f3 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1583,9 +1583,9 @@ struct ieee80211_local { + /* + * Remain-on-channel support + */ +- struct delayed_work roc_work; ++ struct wiphy_delayed_work roc_work; + struct list_head roc_list; +- struct work_struct hw_roc_start, hw_roc_done; ++ struct wiphy_work hw_roc_start, hw_roc_done; + unsigned long hw_roc_start_time; + u64 roc_cookie_counter; + +diff --git a/net/mac80211/main.c b/net/mac80211/main.c +index adb8637a37445..f1cbb7c5d4ac3 100644 +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -376,8 +376,8 @@ static void ieee80211_restart_work(struct work_struct *work) + ieee80211_scan_cancel(local); + + /* make sure any new ROC will consider local->in_reconfig */ +- flush_delayed_work(&local->roc_work); +- flush_work(&local->hw_roc_done); ++ wiphy_delayed_work_flush(local->hw.wiphy, &local->roc_work); ++ wiphy_work_flush(local->hw.wiphy, &local->hw_roc_done); + + /* wait for all packet processing to be done */ + synchronize_net(); +@@ -1480,11 +1480,11 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) + ieee80211_remove_interfaces(local); + + wiphy_lock(local->hw.wiphy); ++ wiphy_delayed_work_cancel(local->hw.wiphy, &local->roc_work); + wiphy_work_cancel(local->hw.wiphy, &local->radar_detected_work); + wiphy_unlock(local->hw.wiphy); + rtnl_unlock(); + +- cancel_delayed_work_sync(&local->roc_work); + cancel_work_sync(&local->restart_work); + cancel_work_sync(&local->reconfig_filter); + flush_work(&local->sched_scan_stopped_work); +diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c +index cdf991e74ab99..5bedd9cef414d 100644 +--- a/net/mac80211/offchannel.c ++++ b/net/mac80211/offchannel.c +@@ -230,7 +230,7 @@ static bool ieee80211_recalc_sw_work(struct ieee80211_local *local, + if (dur == LONG_MAX) + return false; + +- mod_delayed_work(local->workqueue, &local->roc_work, dur); ++ wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work, dur); + return true; + } + +@@ -258,7 +258,7 @@ static void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc, + roc->notified = true; + } + +-static void ieee80211_hw_roc_start(struct work_struct *work) ++static void ieee80211_hw_roc_start(struct wiphy *wiphy, struct wiphy_work *work) + { + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, hw_roc_start); +@@ -285,7 +285,7 @@ void ieee80211_ready_on_channel(struct ieee80211_hw *hw) + + trace_api_ready_on_channel(local); + +- ieee80211_queue_work(hw, &local->hw_roc_start); ++ wiphy_work_queue(hw->wiphy, &local->hw_roc_start); + } + EXPORT_SYMBOL_GPL(ieee80211_ready_on_channel); + +@@ -338,7 +338,7 @@ static void _ieee80211_start_next_roc(struct ieee80211_local *local) + tmp->started = true; + tmp->abort = true; + } +- ieee80211_queue_work(&local->hw, &local->hw_roc_done); ++ wiphy_work_queue(local->hw.wiphy, &local->hw_roc_done); + return; + } + +@@ -368,8 +368,8 @@ static void _ieee80211_start_next_roc(struct ieee80211_local *local) + ieee80211_hw_config(local, 0); + } + +- ieee80211_queue_delayed_work(&local->hw, &local->roc_work, +- msecs_to_jiffies(min_dur)); ++ wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work, ++ msecs_to_jiffies(min_dur)); + + /* tell userspace or send frame(s) */ + list_for_each_entry(tmp, &local->roc_list, list) { +@@ -407,8 +407,8 @@ void ieee80211_start_next_roc(struct ieee80211_local *local) + _ieee80211_start_next_roc(local); + } else { + /* delay it a bit */ +- ieee80211_queue_delayed_work(&local->hw, &local->roc_work, +- round_jiffies_relative(HZ/2)); ++ wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work, ++ round_jiffies_relative(HZ / 2)); + } + } + +@@ -451,7 +451,7 @@ static void __ieee80211_roc_work(struct ieee80211_local *local) + } + } + +-static void ieee80211_roc_work(struct work_struct *work) ++static void ieee80211_roc_work(struct wiphy *wiphy, struct wiphy_work *work) + { + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, roc_work.work); +@@ -461,7 +461,7 @@ static void ieee80211_roc_work(struct work_struct *work) + mutex_unlock(&local->mtx); + } + +-static void ieee80211_hw_roc_done(struct work_struct *work) ++static void ieee80211_hw_roc_done(struct wiphy *wiphy, struct wiphy_work *work) + { + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, hw_roc_done); +@@ -482,7 +482,7 @@ void ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw) + + trace_api_remain_on_channel_expired(local); + +- ieee80211_queue_work(hw, &local->hw_roc_done); ++ wiphy_work_queue(hw->wiphy, &local->hw_roc_done); + } + EXPORT_SYMBOL_GPL(ieee80211_remain_on_channel_expired); + +@@ -586,8 +586,8 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, + /* if not HW assist, just queue & schedule work */ + if (!local->ops->remain_on_channel) { + list_add_tail(&roc->list, &local->roc_list); +- ieee80211_queue_delayed_work(&local->hw, +- &local->roc_work, 0); ++ wiphy_delayed_work_queue(local->hw.wiphy, ++ &local->roc_work, 0); + } else { + /* otherwise actually kick it off here + * (for error handling) +@@ -695,7 +695,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, + if (!cookie) + return -ENOENT; + +- flush_work(&local->hw_roc_start); ++ wiphy_work_flush(local->hw.wiphy, &local->hw_roc_start); + + mutex_lock(&local->mtx); + list_for_each_entry_safe(roc, tmp, &local->roc_list, list) { +@@ -745,7 +745,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, + } else { + /* go through work struct to return to the operating channel */ + found->abort = true; +- mod_delayed_work(local->workqueue, &local->roc_work, 0); ++ wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work, 0); + } + + out_unlock: +@@ -994,9 +994,9 @@ int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, + + void ieee80211_roc_setup(struct ieee80211_local *local) + { +- INIT_WORK(&local->hw_roc_start, ieee80211_hw_roc_start); +- INIT_WORK(&local->hw_roc_done, ieee80211_hw_roc_done); +- INIT_DELAYED_WORK(&local->roc_work, ieee80211_roc_work); ++ wiphy_work_init(&local->hw_roc_start, ieee80211_hw_roc_start); ++ wiphy_work_init(&local->hw_roc_done, ieee80211_hw_roc_done); ++ wiphy_delayed_work_init(&local->roc_work, ieee80211_roc_work); + INIT_LIST_HEAD(&local->roc_list); + } + +-- +2.42.0 + diff --git a/queue-6.6/wifi-mac80211-move-radar-detect-work-to-wiphy-work.patch b/queue-6.6/wifi-mac80211-move-radar-detect-work-to-wiphy-work.patch new file mode 100644 index 00000000000..db20da9bf07 --- /dev/null +++ b/queue-6.6/wifi-mac80211-move-radar-detect-work-to-wiphy-work.patch @@ -0,0 +1,121 @@ +From a17e63173537902943d619d115bf6c2108f307e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Aug 2023 13:59:38 +0200 +Subject: wifi: mac80211: move radar detect work to wiphy work + +From: Johannes Berg + +[ Upstream commit 228e4f931b0e630dacca8dd867ddd863aea53913 ] + +Move the radar detect work to wiphy work in order +to lock the wiphy for it without doing it manually. + +Reviewed-by: Emmanuel Grumbach +Signed-off-by: Johannes Berg +Stable-dep-of: eadfb54756ae ("wifi: mac80211: move sched-scan stop work to wiphy work") +Signed-off-by: Sasha Levin +--- + net/mac80211/ieee80211_i.h | 5 +++-- + net/mac80211/main.c | 9 +++++---- + net/mac80211/util.c | 7 +++---- + 3 files changed, 11 insertions(+), 10 deletions(-) + +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index 98ef1fe1226e7..358c8865f909a 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1406,7 +1406,7 @@ struct ieee80211_local { + /* wowlan is enabled -- don't reconfig on resume */ + bool wowlan; + +- struct work_struct radar_detected_work; ++ struct wiphy_work radar_detected_work; + + /* number of RX chains the hardware has */ + u8 rx_chains; +@@ -2566,7 +2566,8 @@ bool ieee80211_is_radar_required(struct ieee80211_local *local); + + void ieee80211_dfs_cac_timer_work(struct work_struct *work); + void ieee80211_dfs_cac_cancel(struct ieee80211_local *local); +-void ieee80211_dfs_radar_detected_work(struct work_struct *work); ++void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy, ++ struct wiphy_work *work); + int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, + struct cfg80211_csa_settings *csa_settings); + +diff --git a/net/mac80211/main.c b/net/mac80211/main.c +index 24315d7b31263..3bbd66e5a0df0 100644 +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -338,7 +338,6 @@ static void ieee80211_restart_work(struct work_struct *work) + /* wait for scan work complete */ + flush_workqueue(local->workqueue); + flush_work(&local->sched_scan_stopped_work); +- flush_work(&local->radar_detected_work); + + rtnl_lock(); + /* we might do interface manipulations, so need both */ +@@ -813,8 +812,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, + + INIT_WORK(&local->restart_work, ieee80211_restart_work); + +- INIT_WORK(&local->radar_detected_work, +- ieee80211_dfs_radar_detected_work); ++ wiphy_work_init(&local->radar_detected_work, ++ ieee80211_dfs_radar_detected_work); + + INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); + local->smps_mode = IEEE80211_SMPS_OFF; +@@ -1482,13 +1481,15 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) + */ + ieee80211_remove_interfaces(local); + ++ wiphy_lock(local->hw.wiphy); ++ wiphy_work_cancel(local->hw.wiphy, &local->radar_detected_work); ++ wiphy_unlock(local->hw.wiphy); + rtnl_unlock(); + + cancel_delayed_work_sync(&local->roc_work); + cancel_work_sync(&local->restart_work); + cancel_work_sync(&local->reconfig_filter); + flush_work(&local->sched_scan_stopped_work); +- flush_work(&local->radar_detected_work); + + ieee80211_clear_tx_pending(local); + rate_control_deinitialize(local); +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index 8a6917cf63cf9..e878b6a27651a 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -4356,7 +4356,8 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local) + mutex_unlock(&local->mtx); + } + +-void ieee80211_dfs_radar_detected_work(struct work_struct *work) ++void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy, ++ struct wiphy_work *work) + { + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, radar_detected_work); +@@ -4374,9 +4375,7 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work) + } + mutex_unlock(&local->chanctx_mtx); + +- wiphy_lock(local->hw.wiphy); + ieee80211_dfs_cac_cancel(local); +- wiphy_unlock(local->hw.wiphy); + + if (num_chanctx > 1) + /* XXX: multi-channel is not supported yet */ +@@ -4391,7 +4390,7 @@ void ieee80211_radar_detected(struct ieee80211_hw *hw) + + trace_api_radar_detected(local); + +- schedule_work(&local->radar_detected_work); ++ wiphy_work_queue(hw->wiphy, &local->radar_detected_work); + } + EXPORT_SYMBOL(ieee80211_radar_detected); + +-- +2.42.0 + diff --git a/queue-6.6/wifi-mac80211-move-scan-work-to-wiphy-work.patch b/queue-6.6/wifi-mac80211-move-scan-work-to-wiphy-work.patch new file mode 100644 index 00000000000..d4ee2f1b51d --- /dev/null +++ b/queue-6.6/wifi-mac80211-move-scan-work-to-wiphy-work.patch @@ -0,0 +1,189 @@ +From 4ae7eebc7ae436846c54724c7d6db4c80706738b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Aug 2023 13:59:39 +0200 +Subject: wifi: mac80211: move scan work to wiphy work + +From: Johannes Berg + +[ Upstream commit 201712512cbbda360f62c222a4bab260350462a0 ] + +Move the scan work to wiphy work, which also simplifies +the way we handle the work vs. the scan configuration. + +Reviewed-by: Emmanuel Grumbach +Signed-off-by: Johannes Berg +Stable-dep-of: eadfb54756ae ("wifi: mac80211: move sched-scan stop work to wiphy work") +Signed-off-by: Sasha Levin +--- + net/mac80211/ieee80211_i.h | 4 ++-- + net/mac80211/iface.c | 2 +- + net/mac80211/main.c | 4 +--- + net/mac80211/scan.c | 29 ++++++++++++----------------- + net/mac80211/util.c | 4 ++-- + 5 files changed, 18 insertions(+), 25 deletions(-) + +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index 358c8865f909a..4e98e03e5de64 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1490,7 +1490,7 @@ struct ieee80211_local { + + unsigned long leave_oper_channel_time; + enum mac80211_scan_state next_scan_state; +- struct delayed_work scan_work; ++ struct wiphy_delayed_work scan_work; + struct ieee80211_sub_if_data __rcu *scan_sdata; + /* For backward compatibility only -- do not use */ + struct cfg80211_chan_def _oper_chandef; +@@ -1929,7 +1929,7 @@ int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata, + u64 *changed); + + /* scan/BSS handling */ +-void ieee80211_scan_work(struct work_struct *work); ++void ieee80211_scan_work(struct wiphy *wiphy, struct wiphy_work *work); + int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, + const u8 *ssid, u8 ssid_len, + struct ieee80211_channel **channels, +diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c +index be586bc0b5b7d..6e3bfb46af44d 100644 +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -691,7 +691,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do + ieee80211_recalc_ps(local); + + if (cancel_scan) +- flush_delayed_work(&local->scan_work); ++ wiphy_delayed_work_flush(local->hw.wiphy, &local->scan_work); + + if (local->open_count == 0) { + ieee80211_stop_device(local); +diff --git a/net/mac80211/main.c b/net/mac80211/main.c +index 3bbd66e5a0df0..adb8637a37445 100644 +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -335,9 +335,7 @@ static void ieee80211_restart_work(struct work_struct *work) + struct ieee80211_sub_if_data *sdata; + int ret; + +- /* wait for scan work complete */ + flush_workqueue(local->workqueue); +- flush_work(&local->sched_scan_stopped_work); + + rtnl_lock(); + /* we might do interface manipulations, so need both */ +@@ -808,7 +806,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, + INIT_LIST_HEAD(&local->chanctx_list); + mutex_init(&local->chanctx_mtx); + +- INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); ++ wiphy_delayed_work_init(&local->scan_work, ieee80211_scan_work); + + INIT_WORK(&local->restart_work, ieee80211_restart_work); + +diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c +index 0805aa8603c61..2117cb2a916ac 100644 +--- a/net/mac80211/scan.c ++++ b/net/mac80211/scan.c +@@ -274,8 +274,8 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb) + * the beacon/proberesp rx gives us an opportunity to upgrade + * to active scan + */ +- set_bit(SCAN_BEACON_DONE, &local->scanning); +- ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); ++ set_bit(SCAN_BEACON_DONE, &local->scanning); ++ wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, 0); + } + + if (ieee80211_is_probe_resp(mgmt->frame_control)) { +@@ -505,7 +505,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, + + memcpy(&local->scan_info, info, sizeof(*info)); + +- ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); ++ wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, 0); + } + EXPORT_SYMBOL(ieee80211_scan_completed); + +@@ -545,8 +545,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local, + /* We need to set power level at maximum rate for scanning. */ + ieee80211_hw_config(local, 0); + +- ieee80211_queue_delayed_work(&local->hw, +- &local->scan_work, 0); ++ wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, 0); + + return 0; + } +@@ -603,8 +602,8 @@ void ieee80211_run_deferred_scan(struct ieee80211_local *local) + lockdep_is_held(&local->mtx)))) + return; + +- ieee80211_queue_delayed_work(&local->hw, &local->scan_work, +- round_jiffies_relative(0)); ++ wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, ++ round_jiffies_relative(0)); + } + + static void ieee80211_send_scan_probe_req(struct ieee80211_sub_if_data *sdata, +@@ -795,8 +794,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, + } + + /* Now, just wait a bit and we are all done! */ +- ieee80211_queue_delayed_work(&local->hw, &local->scan_work, +- next_delay); ++ wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, ++ next_delay); + return 0; + } else { + /* Do normal software scan */ +@@ -1043,7 +1042,7 @@ static void ieee80211_scan_state_resume(struct ieee80211_local *local, + local->next_scan_state = SCAN_SET_CHANNEL; + } + +-void ieee80211_scan_work(struct work_struct *work) ++void ieee80211_scan_work(struct wiphy *wiphy, struct wiphy_work *work) + { + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, scan_work.work); +@@ -1137,7 +1136,8 @@ void ieee80211_scan_work(struct work_struct *work) + } + } while (next_delay == 0); + +- ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay); ++ wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, ++ next_delay); + goto out; + + out_complete: +@@ -1280,12 +1280,7 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) + goto out; + } + +- /* +- * If the work is currently running, it must be blocked on +- * the mutex, but we'll set scan_sdata = NULL and it'll +- * simply exit once it acquires the mutex. +- */ +- cancel_delayed_work(&local->scan_work); ++ wiphy_delayed_work_cancel(local->hw.wiphy, &local->scan_work); + /* and clean up */ + memset(&local->scan_info, 0, sizeof(local->scan_info)); + __ieee80211_scan_completed(&local->hw, true); +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index e878b6a27651a..172173b2a9eb8 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -2340,8 +2340,8 @@ static void ieee80211_flush_completed_scan(struct ieee80211_local *local, + */ + if (aborted) + set_bit(SCAN_ABORTED, &local->scanning); +- ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); +- flush_delayed_work(&local->scan_work); ++ wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, 0); ++ wiphy_delayed_work_flush(local->hw.wiphy, &local->scan_work); + } + } + +-- +2.42.0 + diff --git a/queue-6.6/wifi-mac80211-move-sched-scan-stop-work-to-wiphy-wor.patch b/queue-6.6/wifi-mac80211-move-sched-scan-stop-work-to-wiphy-wor.patch new file mode 100644 index 00000000000..575f0b289b6 --- /dev/null +++ b/queue-6.6/wifi-mac80211-move-sched-scan-stop-work-to-wiphy-wor.patch @@ -0,0 +1,105 @@ +From 9eda9f9fb799e536bf326066f0698bfc1799ff6d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Aug 2023 13:59:45 +0200 +Subject: wifi: mac80211: move sched-scan stop work to wiphy work + +From: Johannes Berg + +[ Upstream commit eadfb54756aea5610d8d0a467f66305f777c85dd ] + +This also has the wiphy locked here then. We need to use +the _locked version of cfg80211_sched_scan_stopped() now, +which also fixes an old deadlock there. + +Fixes: a05829a7222e ("cfg80211: avoid holding the RTNL when calling the driver") +Reviewed-by: Emmanuel Grumbach +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/ieee80211_i.h | 5 +++-- + net/mac80211/main.c | 6 +++--- + net/mac80211/scan.c | 7 ++++--- + 3 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index 5321f75d0c6f3..07beb72ddd25a 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1483,7 +1483,7 @@ struct ieee80211_local { + int hw_scan_ies_bufsize; + struct cfg80211_scan_info scan_info; + +- struct work_struct sched_scan_stopped_work; ++ struct wiphy_work sched_scan_stopped_work; + struct ieee80211_sub_if_data __rcu *sched_scan_sdata; + struct cfg80211_sched_scan_request __rcu *sched_scan_req; + u8 scan_addr[ETH_ALEN]; +@@ -1962,7 +1962,8 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, + struct cfg80211_sched_scan_request *req); + int ieee80211_request_sched_scan_stop(struct ieee80211_local *local); + void ieee80211_sched_scan_end(struct ieee80211_local *local); +-void ieee80211_sched_scan_stopped_work(struct work_struct *work); ++void ieee80211_sched_scan_stopped_work(struct wiphy *wiphy, ++ struct wiphy_work *work); + + /* off-channel/mgmt-tx */ + void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local); +diff --git a/net/mac80211/main.c b/net/mac80211/main.c +index f1cbb7c5d4ac3..4548f84451095 100644 +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -822,8 +822,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, + ieee80211_dynamic_ps_disable_work); + timer_setup(&local->dynamic_ps_timer, ieee80211_dynamic_ps_timer, 0); + +- INIT_WORK(&local->sched_scan_stopped_work, +- ieee80211_sched_scan_stopped_work); ++ wiphy_work_init(&local->sched_scan_stopped_work, ++ ieee80211_sched_scan_stopped_work); + + spin_lock_init(&local->ack_status_lock); + idr_init(&local->ack_status_frames); +@@ -1481,13 +1481,13 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) + + wiphy_lock(local->hw.wiphy); + wiphy_delayed_work_cancel(local->hw.wiphy, &local->roc_work); ++ wiphy_work_cancel(local->hw.wiphy, &local->sched_scan_stopped_work); + wiphy_work_cancel(local->hw.wiphy, &local->radar_detected_work); + wiphy_unlock(local->hw.wiphy); + rtnl_unlock(); + + cancel_work_sync(&local->restart_work); + cancel_work_sync(&local->reconfig_filter); +- flush_work(&local->sched_scan_stopped_work); + + ieee80211_clear_tx_pending(local); + rate_control_deinitialize(local); +diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c +index 2117cb2a916ac..68ec2124c3db5 100644 +--- a/net/mac80211/scan.c ++++ b/net/mac80211/scan.c +@@ -1422,10 +1422,11 @@ void ieee80211_sched_scan_end(struct ieee80211_local *local) + + mutex_unlock(&local->mtx); + +- cfg80211_sched_scan_stopped(local->hw.wiphy, 0); ++ cfg80211_sched_scan_stopped_locked(local->hw.wiphy, 0); + } + +-void ieee80211_sched_scan_stopped_work(struct work_struct *work) ++void ieee80211_sched_scan_stopped_work(struct wiphy *wiphy, ++ struct wiphy_work *work) + { + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, +@@ -1448,6 +1449,6 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw) + if (local->in_reconfig) + return; + +- schedule_work(&local->sched_scan_stopped_work); ++ wiphy_work_queue(hw->wiphy, &local->sched_scan_stopped_work); + } + EXPORT_SYMBOL(ieee80211_sched_scan_stopped); +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-fix-per-band-ieee80211_conf_monitor-flag-c.patch b/queue-6.6/wifi-mt76-fix-per-band-ieee80211_conf_monitor-flag-c.patch new file mode 100644 index 00000000000..239667716b4 --- /dev/null +++ b/queue-6.6/wifi-mt76-fix-per-band-ieee80211_conf_monitor-flag-c.patch @@ -0,0 +1,65 @@ +From 579bdce69b618ffea7bbeb97f0b519cfc40a9a74 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 31 Aug 2023 14:22:18 +0800 +Subject: wifi: mt76: fix per-band IEEE80211_CONF_MONITOR flag comparison + +From: Shayne Chen + +[ Upstream commit c685034cabc574dbdf16fa675010e202083cb4c2 ] + +Use the correct ieee80211_conf of each band for IEEE80211_CONF_MONITOR +comparison. + +Fixes: 24e69f6bc3ca ("mt76: fix monitor rx FCS error in DFS channel") +Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices") +Signed-off-by: Shayne Chen +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 2 +- + drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 2 +- + drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +index 8d745c9730c72..955974a82180f 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +@@ -2147,7 +2147,7 @@ int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd) + }; + + if (cmd == MCU_EXT_CMD(SET_RX_PATH) || +- dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR) ++ phy->mt76->hw->conf.flags & IEEE80211_CONF_MONITOR) + req.switch_reason = CH_SWITCH_NORMAL; + else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) + req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +index acdb54a8bcc6c..92a341aa58228 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +@@ -2740,7 +2740,7 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd) + if (mt76_connac_spe_idx(phy->mt76->antenna_mask)) + req.tx_path_num = fls(phy->mt76->antenna_mask); + +- if (dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR) ++ if (phy->mt76->hw->conf.flags & IEEE80211_CONF_MONITOR) + req.switch_reason = CH_SWITCH_NORMAL; + else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL || + phy->mt76->hw->conf.flags & IEEE80211_CONF_IDLE) +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +index f80ba8f1f5de1..7575d3506ea4e 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +@@ -2972,7 +2972,7 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag) + .channel_band = ch_band[chandef->chan->band], + }; + +- if (dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR) ++ if (phy->mt76->hw->conf.flags & IEEE80211_CONF_MONITOR) + req.switch_reason = CH_SWITCH_NORMAL; + else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL || + phy->mt76->hw->conf.flags & IEEE80211_CONF_IDLE) +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-fix-potential-memory-leak-of-beacon-comman.patch b/queue-6.6/wifi-mt76-fix-potential-memory-leak-of-beacon-comman.patch new file mode 100644 index 00000000000..2da7affc05e --- /dev/null +++ b/queue-6.6/wifi-mt76-fix-potential-memory-leak-of-beacon-comman.patch @@ -0,0 +1,102 @@ +From 7fb11325ff3f1ca5571728a5d6cc0a9301eb3303 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 31 Aug 2023 14:22:16 +0800 +Subject: wifi: mt76: fix potential memory leak of beacon commands + +From: Bo Jiao + +[ Upstream commit d6a2f91741d9f43b31cb16c82da37f35117a6d1c ] + +Fix potential memory leak when setting beacon and inband discovery +commands. + +Fixes: e57b7901469f ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets") +Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices") +Signed-off-by: Bo Jiao +Signed-off-by: Shayne Chen +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 10 ++++++++-- + drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 10 ++++++++-- + 2 files changed, 16 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +index 5cf45c5ce5e13..44d5aad6c3cc0 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +@@ -1925,8 +1925,10 @@ mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif, + skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(hw, vif); + } + +- if (!skb) ++ if (!skb) { ++ dev_kfree_skb(rskb); + return -EINVAL; ++ } + + info = IEEE80211_SKB_CB(skb); + info->control.vif = vif; +@@ -1938,6 +1940,7 @@ mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif, + + if (skb->len > MT7915_MAX_BEACON_SIZE) { + dev_err(dev->mt76.dev, "inband discovery size limit exceed\n"); ++ dev_kfree_skb(rskb); + dev_kfree_skb(skb); + return -EINVAL; + } +@@ -1994,11 +1997,14 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + goto out; + + skb = ieee80211_beacon_get_template(hw, vif, &offs, 0); +- if (!skb) ++ if (!skb) { ++ dev_kfree_skb(rskb); + return -EINVAL; ++ } + + if (skb->len > MT7915_MAX_BEACON_SIZE) { + dev_err(dev->mt76.dev, "Bcn size limit exceed\n"); ++ dev_kfree_skb(rskb); + dev_kfree_skb(skb); + return -EINVAL; + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +index 44a7c5af43e06..f4545342018f5 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +@@ -2042,11 +2042,14 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw, + return PTR_ERR(rskb); + + skb = ieee80211_beacon_get_template(hw, vif, &offs, 0); +- if (!skb) ++ if (!skb) { ++ dev_kfree_skb(rskb); + return -EINVAL; ++ } + + if (skb->len > MT7996_MAX_BEACON_SIZE) { + dev_err(dev->mt76.dev, "Bcn size limit exceed\n"); ++ dev_kfree_skb(rskb); + dev_kfree_skb(skb); + return -EINVAL; + } +@@ -2106,11 +2109,14 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev, + skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(hw, vif); + } + +- if (!skb) ++ if (!skb) { ++ dev_kfree_skb(rskb); + return -EINVAL; ++ } + + if (skb->len > MT7996_MAX_BEACON_SIZE) { + dev_err(dev->mt76.dev, "inband discovery size limit exceed\n"); ++ dev_kfree_skb(rskb); + dev_kfree_skb(skb); + return -EINVAL; + } +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-get-rid-of-false-alamrs-of-tx-emission-iss.patch b/queue-6.6/wifi-mt76-get-rid-of-false-alamrs-of-tx-emission-iss.patch new file mode 100644 index 00000000000..ca84afe6775 --- /dev/null +++ b/queue-6.6/wifi-mt76-get-rid-of-false-alamrs-of-tx-emission-iss.patch @@ -0,0 +1,65 @@ +From 039284a5f628aa823e1e2029a4d6da36457c1dd6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 31 Aug 2023 14:22:17 +0800 +Subject: wifi: mt76: get rid of false alamrs of tx emission issues + +From: StanleyYP Wang + +[ Upstream commit 413f05d68d11981f5984b49214d3a5a0d88079b1 ] + +When the set_chan_info command is set with CH_SWITCH_NORMAL reason, +even if the action is UNI_CHANNEL_RX_PATH, it'll still generate some +unexpected tones, which might confuse DFS CAC tests that there are some +tone leakages. To get rid of these kinds of false alarms, always bypass +DPD calibration when IEEE80211_CONF_IDLE is set. + +Reviewed-by: Evelyn Tsai +Signed-off-by: StanleyYP Wang +Signed-off-by: Shayne Chen +Signed-off-by: Felix Fietkau +Stable-dep-of: c685034cabc5 ("wifi: mt76: fix per-band IEEE80211_CONF_MONITOR flag comparison") +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 6 +++--- + drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 6 +++--- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +index 44d5aad6c3cc0..acdb54a8bcc6c 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +@@ -2740,10 +2740,10 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd) + if (mt76_connac_spe_idx(phy->mt76->antenna_mask)) + req.tx_path_num = fls(phy->mt76->antenna_mask); + +- if (cmd == MCU_EXT_CMD(SET_RX_PATH) || +- dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR) ++ if (dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR) + req.switch_reason = CH_SWITCH_NORMAL; +- else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) ++ else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL || ++ phy->mt76->hw->conf.flags & IEEE80211_CONF_IDLE) + req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD; + else if (!cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef, + NL80211_IFTYPE_AP)) +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +index f4545342018f5..f80ba8f1f5de1 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +@@ -2972,10 +2972,10 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag) + .channel_band = ch_band[chandef->chan->band], + }; + +- if (tag == UNI_CHANNEL_RX_PATH || +- dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR) ++ if (dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR) + req.switch_reason = CH_SWITCH_NORMAL; +- else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) ++ else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL || ++ phy->mt76->hw->conf.flags & IEEE80211_CONF_IDLE) + req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD; + else if (!cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef, + NL80211_IFTYPE_AP)) +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-move-struct-ieee80211_chanctx_conf-up-to-s.patch b/queue-6.6/wifi-mt76-move-struct-ieee80211_chanctx_conf-up-to-s.patch new file mode 100644 index 00000000000..f760fba9079 --- /dev/null +++ b/queue-6.6/wifi-mt76-move-struct-ieee80211_chanctx_conf-up-to-s.patch @@ -0,0 +1,134 @@ +From 653095582f71c50310c328a13713491c12c704fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Sep 2023 16:03:06 +0800 +Subject: wifi: mt76: move struct ieee80211_chanctx_conf up to struct mt76_vif + +From: Sean Wang + +[ Upstream commit f50206555992abb802cee4e3f951d1ea669cb8bc ] + +Move struct ieee80211_chanctx_conf up to struct mt76_vif to allow the +connac2 library can access the struct ieee80211_chanctx_conf * member in +struct mt76_vif. + +Signed-off-by: Sean Wang +Reviewed-by: David Ruth +Tested-by: David Ruth +Signed-off-by: Deren Wu +Signed-off-by: Felix Fietkau +Stable-dep-of: 32b1000db221 ("wifi: mt76: mt7921: fix the wrong rate pickup for the chanctx driver") +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt76.h | 1 + + drivers/net/wireless/mediatek/mt76/mt7921/main.c | 12 ++++++------ + drivers/net/wireless/mediatek/mt76/mt792x.h | 1 - + drivers/net/wireless/mediatek/mt76/mt792x_core.c | 4 ++-- + 4 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h +index e8757865a3d06..13ed07c5ccc60 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76.h +@@ -709,6 +709,7 @@ struct mt76_vif { + u8 basic_rates_idx; + u8 mcast_rates_idx; + u8 beacon_rates_idx; ++ struct ieee80211_chanctx_conf *ctx; + }; + + struct mt76_phy { +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c +index 0844d28b3223d..d8851cb5f400b 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c +@@ -756,7 +756,7 @@ void mt7921_mac_sta_assoc(struct mt76_dev *mdev, struct ieee80211_vif *vif, + + if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) + mt76_connac_mcu_uni_add_bss(&dev->mphy, vif, &mvif->sta.wcid, +- true, mvif->ctx); ++ true, mvif->mt76.ctx); + + ewma_avg_signal_init(&msta->avg_ack_signal); + +@@ -791,7 +791,7 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, + if (!sta->tdls) + mt76_connac_mcu_uni_add_bss(&dev->mphy, vif, + &mvif->sta.wcid, false, +- mvif->ctx); ++ mvif->mt76.ctx); + } + + spin_lock_bh(&dev->mt76.sta_poll_lock); +@@ -1208,7 +1208,7 @@ mt7921_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + mt792x_mutex_acquire(dev); + + err = mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid, +- true, mvif->ctx); ++ true, mvif->mt76.ctx); + if (err) + goto out; + +@@ -1240,7 +1240,7 @@ mt7921_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + goto out; + + mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid, false, +- mvif->ctx); ++ mvif->mt76.ctx); + + out: + mt792x_mutex_release(dev); +@@ -1265,7 +1265,7 @@ static void mt7921_ctx_iter(void *priv, u8 *mac, + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct ieee80211_chanctx_conf *ctx = priv; + +- if (ctx != mvif->ctx) ++ if (ctx != mvif->mt76.ctx) + return; + + if (vif->type == NL80211_IFTYPE_MONITOR) +@@ -1298,7 +1298,7 @@ static void mt7921_mgd_prepare_tx(struct ieee80211_hw *hw, + jiffies_to_msecs(HZ); + + mt792x_mutex_acquire(dev); +- mt7921_set_roc(mvif->phy, mvif, mvif->ctx->def.chan, duration, ++ mt7921_set_roc(mvif->phy, mvif, mvif->mt76.ctx->def.chan, duration, + MT7921_ROC_REQ_JOIN); + mt792x_mutex_release(dev); + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h +index 5d5ab8630041b..6c347495e1185 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt792x.h ++++ b/drivers/net/wireless/mediatek/mt76/mt792x.h +@@ -91,7 +91,6 @@ struct mt792x_vif { + struct ewma_rssi rssi; + + struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; +- struct ieee80211_chanctx_conf *ctx; + }; + + struct mt792x_phy { +diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net/wireless/mediatek/mt76/mt792x_core.c +index 46be7f996c7e1..ec98450a938ff 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt792x_core.c ++++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c +@@ -243,7 +243,7 @@ int mt792x_assign_vif_chanctx(struct ieee80211_hw *hw, + struct mt792x_dev *dev = mt792x_hw_dev(hw); + + mutex_lock(&dev->mt76.mutex); +- mvif->ctx = ctx; ++ mvif->mt76.ctx = ctx; + mutex_unlock(&dev->mt76.mutex); + + return 0; +@@ -259,7 +259,7 @@ void mt792x_unassign_vif_chanctx(struct ieee80211_hw *hw, + struct mt792x_dev *dev = mt792x_hw_dev(hw); + + mutex_lock(&dev->mt76.mutex); +- mvif->ctx = NULL; ++ mvif->mt76.ctx = NULL; + mutex_unlock(&dev->mt76.mutex); + } + EXPORT_SYMBOL_GPL(mt792x_unassign_vif_chanctx); +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-mt7603-improve-stuck-beacon-handling.patch b/queue-6.6/wifi-mt76-mt7603-improve-stuck-beacon-handling.patch new file mode 100644 index 00000000000..eb9b2488e28 --- /dev/null +++ b/queue-6.6/wifi-mt76-mt7603-improve-stuck-beacon-handling.patch @@ -0,0 +1,177 @@ +From e52fe37b0c860d47de1cbb4d4c5c30a52bea58f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Jul 2023 16:21:18 +0200 +Subject: wifi: mt76: mt7603: improve stuck beacon handling + +From: Felix Fietkau + +[ Upstream commit 3176205933494bd184c6acd70e796c382bc729b5 ] + +Before preparing the new beacon, check the queue status, flush out all +previous beacons and buffered multicast packets, then (if necessary) +try to recover more gracefully from a stuck beacon condition by making a +less invasive attempt at getting the MAC un-stuck. + +Fixes: c8846e101502 ("mt76: add driver for MT7603E and MT7628/7688") +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + .../wireless/mediatek/mt76/mt7603/beacon.c | 76 ++++++++++++++----- + .../net/wireless/mediatek/mt76/mt7603/regs.h | 5 ++ + 2 files changed, 60 insertions(+), 21 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c +index 888678732f290..c223f7c19e6da 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c +@@ -9,6 +9,23 @@ struct beacon_bc_data { + int count[MT7603_MAX_INTERFACES]; + }; + ++static void ++mt7603_mac_stuck_beacon_recovery(struct mt7603_dev *dev) ++{ ++ if (dev->beacon_check % 5 != 4) ++ return; ++ ++ mt76_clear(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_EN); ++ mt76_set(dev, MT_SCH_4, MT_SCH_4_RESET); ++ mt76_clear(dev, MT_SCH_4, MT_SCH_4_RESET); ++ mt76_set(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_EN); ++ ++ mt76_set(dev, MT_WF_CFG_OFF_WOCCR, MT_WF_CFG_OFF_WOCCR_TMAC_GC_DIS); ++ mt76_set(dev, MT_ARB_SCR, MT_ARB_SCR_TX_DISABLE); ++ mt76_clear(dev, MT_ARB_SCR, MT_ARB_SCR_TX_DISABLE); ++ mt76_clear(dev, MT_WF_CFG_OFF_WOCCR, MT_WF_CFG_OFF_WOCCR_TMAC_GC_DIS); ++} ++ + static void + mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) + { +@@ -16,6 +33,8 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) + struct mt76_dev *mdev = &dev->mt76; + struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv; + struct sk_buff *skb = NULL; ++ u32 om_idx = mvif->idx; ++ u32 val; + + if (!(mdev->beacon_mask & BIT(mvif->idx))) + return; +@@ -24,20 +43,33 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) + if (!skb) + return; + +- mt76_tx_queue_skb(dev, dev->mphy.q_tx[MT_TXQ_BEACON], +- MT_TXQ_BEACON, skb, &mvif->sta.wcid, NULL); ++ if (om_idx) ++ om_idx |= 0x10; ++ val = MT_DMA_FQCR0_BUSY | MT_DMA_FQCR0_MODE | ++ FIELD_PREP(MT_DMA_FQCR0_TARGET_BSS, om_idx) | ++ FIELD_PREP(MT_DMA_FQCR0_DEST_PORT_ID, 3) | ++ FIELD_PREP(MT_DMA_FQCR0_DEST_QUEUE_ID, 8); + + spin_lock_bh(&dev->ps_lock); +- mt76_wr(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY | +- FIELD_PREP(MT_DMA_FQCR0_TARGET_WCID, mvif->sta.wcid.idx) | +- FIELD_PREP(MT_DMA_FQCR0_TARGET_QID, +- dev->mphy.q_tx[MT_TXQ_CAB]->hw_idx) | +- FIELD_PREP(MT_DMA_FQCR0_DEST_PORT_ID, 3) | +- FIELD_PREP(MT_DMA_FQCR0_DEST_QUEUE_ID, 8)); + +- if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000)) ++ mt76_wr(dev, MT_DMA_FQCR0, val | ++ FIELD_PREP(MT_DMA_FQCR0_TARGET_QID, MT_TX_HW_QUEUE_BCN)); ++ if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000)) { + dev->beacon_check = MT7603_WATCHDOG_TIMEOUT; ++ goto out; ++ } ++ ++ mt76_wr(dev, MT_DMA_FQCR0, val | ++ FIELD_PREP(MT_DMA_FQCR0_TARGET_QID, MT_TX_HW_QUEUE_BMC)); ++ if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000)) { ++ dev->beacon_check = MT7603_WATCHDOG_TIMEOUT; ++ goto out; ++ } + ++ mt76_tx_queue_skb(dev, dev->mphy.q_tx[MT_TXQ_BEACON], ++ MT_TXQ_BEACON, skb, &mvif->sta.wcid, NULL); ++ ++out: + spin_unlock_bh(&dev->ps_lock); + } + +@@ -81,6 +113,18 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t) + data.dev = dev; + __skb_queue_head_init(&data.q); + ++ /* Flush all previous CAB queue packets and beacons */ ++ mt76_wr(dev, MT_WF_ARB_CAB_FLUSH, GENMASK(30, 16) | BIT(0)); ++ ++ mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_CAB], false); ++ mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_BEACON], false); ++ ++ if (dev->mphy.q_tx[MT_TXQ_BEACON]->queued > 0) ++ dev->beacon_check++; ++ else ++ dev->beacon_check = 0; ++ mt7603_mac_stuck_beacon_recovery(dev); ++ + q = dev->mphy.q_tx[MT_TXQ_BEACON]; + spin_lock(&q->lock); + ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev), +@@ -89,14 +133,9 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t) + mt76_queue_kick(dev, q); + spin_unlock(&q->lock); + +- /* Flush all previous CAB queue packets */ +- mt76_wr(dev, MT_WF_ARB_CAB_FLUSH, GENMASK(30, 16) | BIT(0)); +- +- mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_CAB], false); +- + mt76_csa_check(mdev); + if (mdev->csa_complete) +- goto out; ++ return; + + q = dev->mphy.q_tx[MT_TXQ_CAB]; + do { +@@ -108,7 +147,7 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t) + skb_queue_len(&data.q) < 8); + + if (skb_queue_empty(&data.q)) +- goto out; ++ return; + + for (i = 0; i < ARRAY_SIZE(data.tail); i++) { + if (!data.tail[i]) +@@ -136,11 +175,6 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t) + MT_WF_ARB_CAB_START_BSSn(0) | + (MT_WF_ARB_CAB_START_BSS0n(1) * + ((1 << (MT7603_MAX_INTERFACES - 1)) - 1))); +- +-out: +- mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_BEACON], false); +- if (dev->mphy.q_tx[MT_TXQ_BEACON]->queued > hweight8(mdev->beacon_mask)) +- dev->beacon_check++; + } + + void mt7603_beacon_set_timer(struct mt7603_dev *dev, int idx, int intval) +diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/regs.h b/drivers/net/wireless/mediatek/mt76/mt7603/regs.h +index a39c9a0fcb1cb..524bceb8e9581 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7603/regs.h ++++ b/drivers/net/wireless/mediatek/mt76/mt7603/regs.h +@@ -469,6 +469,11 @@ enum { + #define MT_WF_SEC_BASE 0x21a00 + #define MT_WF_SEC(ofs) (MT_WF_SEC_BASE + (ofs)) + ++#define MT_WF_CFG_OFF_BASE 0x21e00 ++#define MT_WF_CFG_OFF(ofs) (MT_WF_CFG_OFF_BASE + (ofs)) ++#define MT_WF_CFG_OFF_WOCCR MT_WF_CFG_OFF(0x004) ++#define MT_WF_CFG_OFF_WOCCR_TMAC_GC_DIS BIT(4) ++ + #define MT_SEC_SCR MT_WF_SEC(0x004) + #define MT_SEC_SCR_MASK_ORDER GENMASK(1, 0) + +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-mt7603-improve-watchdog-reset-reliablity.patch b/queue-6.6/wifi-mt76-mt7603-improve-watchdog-reset-reliablity.patch new file mode 100644 index 00000000000..5599b4df54b --- /dev/null +++ b/queue-6.6/wifi-mt76-mt7603-improve-watchdog-reset-reliablity.patch @@ -0,0 +1,84 @@ +From 92a385d825e973c83aa0cef45b582beb29f779a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Jul 2023 16:04:40 +0200 +Subject: wifi: mt76: mt7603: improve watchdog reset reliablity + +From: Felix Fietkau + +[ Upstream commit c677dda165231c3efffb9de4bace249d5d2a51b9 ] + +Only trigger PSE reset if PSE was stuck, otherwise it can cause DMA issues. +Trigger the PSE reset while DMA is fully stopped in order to improve +reliabilty. + +Fixes: c8846e101502 ("mt76: add driver for MT7603E and MT7628/7688") +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + .../net/wireless/mediatek/mt76/mt7603/mac.c | 29 ++++++++----------- + 1 file changed, 12 insertions(+), 17 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c +index 7a506a0c46e2b..cf21d06257e53 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c +@@ -1441,15 +1441,6 @@ static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev) + + mt7603_beacon_set_timer(dev, -1, 0); + +- if (dev->reset_cause[RESET_CAUSE_RESET_FAILED] || +- dev->cur_reset_cause == RESET_CAUSE_RX_PSE_BUSY || +- dev->cur_reset_cause == RESET_CAUSE_BEACON_STUCK || +- dev->cur_reset_cause == RESET_CAUSE_TX_HANG) +- mt7603_pse_reset(dev); +- +- if (dev->reset_cause[RESET_CAUSE_RESET_FAILED]) +- goto skip_dma_reset; +- + mt7603_mac_stop(dev); + + mt76_clear(dev, MT_WPDMA_GLO_CFG, +@@ -1459,28 +1450,32 @@ static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev) + + mt7603_irq_disable(dev, mask); + +- mt76_set(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_FORCE_TX_EOF); +- + mt7603_pse_client_reset(dev); + + mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], true); + for (i = 0; i < __MT_TXQ_MAX; i++) + mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[i], true); + ++ mt7603_dma_sched_reset(dev); ++ ++ mt76_tx_status_check(&dev->mt76, true); ++ + mt76_for_each_q_rx(&dev->mt76, i) { + mt76_queue_rx_reset(dev, i); + } + +- mt76_tx_status_check(&dev->mt76, true); ++ if (dev->reset_cause[RESET_CAUSE_RESET_FAILED] || ++ dev->cur_reset_cause == RESET_CAUSE_RX_PSE_BUSY) ++ mt7603_pse_reset(dev); + +- mt7603_dma_sched_reset(dev); ++ if (!dev->reset_cause[RESET_CAUSE_RESET_FAILED]) { ++ mt7603_mac_dma_start(dev); + +- mt7603_mac_dma_start(dev); ++ mt7603_irq_enable(dev, mask); + +- mt7603_irq_enable(dev, mask); ++ clear_bit(MT76_RESET, &dev->mphy.state); ++ } + +-skip_dma_reset: +- clear_bit(MT76_RESET, &dev->mphy.state); + mutex_unlock(&dev->mt76.mutex); + + mt76_worker_enable(&dev->mt76.tx_worker); +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-mt7603-rework-fix-rx-pse-hang-check.patch b/queue-6.6/wifi-mt76-mt7603-rework-fix-rx-pse-hang-check.patch new file mode 100644 index 00000000000..319edf151fb --- /dev/null +++ b/queue-6.6/wifi-mt76-mt7603-rework-fix-rx-pse-hang-check.patch @@ -0,0 +1,87 @@ +From 2be21c3bc9d0b5433426722b966eed994cc278da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Jul 2023 09:51:01 +0200 +Subject: wifi: mt76: mt7603: rework/fix rx pse hang check + +From: Felix Fietkau + +[ Upstream commit baa19b2e4b7bbb509a7ca7939c8785477dcd40ee ] + +It turns out that the code in mt7603_rx_pse_busy() does not detect actual +hardware hangs, it only checks for busy conditions in PSE. +A reset should only be performed if these conditions are true and if there +is no rx activity as well. +Reset the counter whenever a rx interrupt occurs. In order to also deal with +a fully loaded CPU that leaves interrupts disabled with continuous NAPI +polling, also check for pending rx interrupts in the function itself. + +Fixes: c8846e101502 ("mt76: add driver for MT7603E and MT7628/7688") +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + .../net/wireless/mediatek/mt76/mt7603/core.c | 2 ++ + .../net/wireless/mediatek/mt76/mt7603/mac.c | 23 +++++++++++++------ + 2 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/core.c b/drivers/net/wireless/mediatek/mt76/mt7603/core.c +index 60a996b63c0c0..915b8349146af 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7603/core.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7603/core.c +@@ -42,11 +42,13 @@ irqreturn_t mt7603_irq_handler(int irq, void *dev_instance) + } + + if (intr & MT_INT_RX_DONE(0)) { ++ dev->rx_pse_check = 0; + mt7603_irq_disable(dev, MT_INT_RX_DONE(0)); + napi_schedule(&dev->mt76.napi[0]); + } + + if (intr & MT_INT_RX_DONE(1)) { ++ dev->rx_pse_check = 0; + mt7603_irq_disable(dev, MT_INT_RX_DONE(1)); + napi_schedule(&dev->mt76.napi[1]); + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c +index 99ae080502d80..7a506a0c46e2b 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c +@@ -1570,20 +1570,29 @@ static bool mt7603_rx_pse_busy(struct mt7603_dev *dev) + { + u32 addr, val; + +- if (mt76_rr(dev, MT_MCU_DEBUG_RESET) & MT_MCU_DEBUG_RESET_QUEUES) +- return true; +- + if (mt7603_rx_fifo_busy(dev)) +- return false; ++ goto out; + + addr = mt7603_reg_map(dev, MT_CLIENT_BASE_PHYS_ADDR + MT_CLIENT_STATUS); + mt76_wr(dev, addr, 3); + val = mt76_rr(dev, addr) >> 16; + +- if (is_mt7628(dev) && (val & 0x4001) == 0x4001) +- return true; ++ if (!(val & BIT(0))) ++ return false; ++ ++ if (is_mt7628(dev)) ++ val &= 0xa000; ++ else ++ val &= 0x8000; ++ if (!val) ++ return false; ++ ++out: ++ if (mt76_rr(dev, MT_INT_SOURCE_CSR) & ++ (MT_INT_RX_DONE(0) | MT_INT_RX_DONE(1))) ++ return false; + +- return (val & 0x8001) == 0x8001 || (val & 0xe001) == 0xe001; ++ return true; + } + + static bool +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-mt7915-fix-beamforming-availability-check.patch b/queue-6.6/wifi-mt76-mt7915-fix-beamforming-availability-check.patch new file mode 100644 index 00000000000..5828d8e1435 --- /dev/null +++ b/queue-6.6/wifi-mt76-mt7915-fix-beamforming-availability-check.patch @@ -0,0 +1,44 @@ +From 517d083eb9aaf46e822118c056f5c5ad7c772c4d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 31 Aug 2023 14:22:21 +0800 +Subject: wifi: mt76: mt7915: fix beamforming availability check + +From: MeiChia Chiu + +[ Upstream commit ced1a0b8f3944e44e7f4eb3772dea1bada25d38a ] + +Without this patch, when ap sets the tx stream number to 2, +ap won't send any beamforming packet. + +Fixes: f89f297aef28 ("mt76: mt7915: fix txbf starec TLV issues") +Signed-off-by: MeiChia Chiu +Signed-off-by: Shayne Chen +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +index 92a341aa58228..5d8e985cd7d45 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +@@ -1015,13 +1015,13 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, bool bfee) + { + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; +- int tx_ant = hweight8(phy->mt76->chainmask) - 1; ++ int sts = hweight16(phy->mt76->chainmask); + + if (vif->type != NL80211_IFTYPE_STATION && + vif->type != NL80211_IFTYPE_AP) + return false; + +- if (!bfee && tx_ant < 2) ++ if (!bfee && sts < 2) + return false; + + if (sta->deflink.he_cap.has_he) { +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-mt7921-fix-the-wrong-rate-pickup-for-the-c.patch b/queue-6.6/wifi-mt76-mt7921-fix-the-wrong-rate-pickup-for-the-c.patch new file mode 100644 index 00000000000..602899f7769 --- /dev/null +++ b/queue-6.6/wifi-mt76-mt7921-fix-the-wrong-rate-pickup-for-the-c.patch @@ -0,0 +1,92 @@ +From 54205874ccff097b451fdd095e0638e55350320b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Sep 2023 16:03:07 +0800 +Subject: wifi: mt76: mt7921: fix the wrong rate pickup for the chanctx driver + +From: Sean Wang + +[ Upstream commit 32b1000db221df33ec8b57794a091ba6075b6c28 ] + +The variable band should be determined by the ieee80211_chanctx_conf when +the driver is a kind of chanctx one e.g mt7921 and mt7922 driver so we +added the extension to mt76_connac2_mac_tx_rate_val by distinguishing if +it can support chanctx to fix the incorrect rate pickup. + +Fixes: 41ac53c899bd ("wifi: mt76: mt7921: introduce chanctx support") +Signed-off-by: Sean Wang +Reviewed-by: David Ruth +Tested-by: David Ruth +Signed-off-by: Deren Wu +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mac80211.c | 9 +++++++-- + drivers/net/wireless/mediatek/mt76/mt76.h | 3 ++- + drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c | 7 +++++-- + 3 files changed, 14 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c +index d158320bc15db..dbab400969202 100644 +--- a/drivers/net/wireless/mediatek/mt76/mac80211.c ++++ b/drivers/net/wireless/mediatek/mt76/mac80211.c +@@ -1697,11 +1697,16 @@ mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc, + } + EXPORT_SYMBOL_GPL(mt76_init_queue); + +-u16 mt76_calculate_default_rate(struct mt76_phy *phy, int rateidx) ++u16 mt76_calculate_default_rate(struct mt76_phy *phy, ++ struct ieee80211_vif *vif, int rateidx) + { ++ struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; ++ struct cfg80211_chan_def *chandef = mvif->ctx ? ++ &mvif->ctx->def : ++ &phy->chandef; + int offset = 0; + +- if (phy->chandef.chan->band != NL80211_BAND_2GHZ) ++ if (chandef->chan->band != NL80211_BAND_2GHZ) + offset = 4; + + /* pick the lowest rate for hidden nodes */ +diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h +index 13ed07c5ccc60..dae5410d67e83 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76.h +@@ -1101,7 +1101,8 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *data, int offset, int len); + struct mt76_queue * + mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc, + int ring_base, u32 flags); +-u16 mt76_calculate_default_rate(struct mt76_phy *phy, int rateidx); ++u16 mt76_calculate_default_rate(struct mt76_phy *phy, ++ struct ieee80211_vif *vif, int rateidx); + static inline int mt76_init_tx_queue(struct mt76_phy *phy, int qid, int idx, + int n_desc, int ring_base, u32 flags) + { +diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +index 73db9e14db06c..87479c6c2b505 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +@@ -293,7 +293,10 @@ u16 mt76_connac2_mac_tx_rate_val(struct mt76_phy *mphy, + struct ieee80211_vif *vif, + bool beacon, bool mcast) + { +- u8 nss = 0, mode = 0, band = mphy->chandef.chan->band; ++ struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; ++ struct cfg80211_chan_def *chandef = mvif->ctx ? ++ &mvif->ctx->def : &mphy->chandef; ++ u8 nss = 0, mode = 0, band = chandef->chan->band; + int rateidx = 0, mcast_rate; + + if (!vif) +@@ -326,7 +329,7 @@ u16 mt76_connac2_mac_tx_rate_val(struct mt76_phy *mphy, + rateidx = ffs(vif->bss_conf.basic_rates) - 1; + + legacy: +- rateidx = mt76_calculate_default_rate(mphy, rateidx); ++ rateidx = mt76_calculate_default_rate(mphy, vif, rateidx); + mode = rateidx >> 8; + rateidx &= GENMASK(7, 0); + out: +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-mt7921-fix-the-wrong-rate-selected-in-fw-f.patch b/queue-6.6/wifi-mt76-mt7921-fix-the-wrong-rate-selected-in-fw-f.patch new file mode 100644 index 00000000000..44d0af5eb05 --- /dev/null +++ b/queue-6.6/wifi-mt76-mt7921-fix-the-wrong-rate-selected-in-fw-f.patch @@ -0,0 +1,55 @@ +From 1082fe832c729dbf344e3f0cc034b1c966ef93f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Sep 2023 16:03:08 +0800 +Subject: wifi: mt76: mt7921: fix the wrong rate selected in fw for the chanctx + driver + +From: Sean Wang + +[ Upstream commit c558d22e7a93affeb18aae1dcd777ddd1ad18da1 ] + +The variable band should be determined by the ieee80211_chanctx_conf when +the driver is a kind of chanctx one e.g mt7921 and mt7922 driver so we +added the extension to mt76_connac2_mac_tx_rate_val and +mt76_connac_get_he_phy_cap for the firmware can select the proper rate. + +Fixes: 41ac53c899bd ("wifi: mt76: mt7921: introduce chanctx support") +Signed-off-by: Sean Wang +Tested-by: David Ruth +Signed-off-by: Deren Wu +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +index 0f0a519f956f8..8274a57e1f0fb 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +@@ -829,7 +829,9 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb, + struct ieee80211_vif *vif, + u8 rcpi, u8 sta_state) + { +- struct cfg80211_chan_def *chandef = &mphy->chandef; ++ struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; ++ struct cfg80211_chan_def *chandef = mvif->ctx ? ++ &mvif->ctx->def : &mphy->chandef; + enum nl80211_band band = chandef->chan->band; + struct mt76_dev *dev = mphy->dev; + struct sta_rec_ra_info *ra_info; +@@ -1369,7 +1371,10 @@ EXPORT_SYMBOL_GPL(mt76_connac_get_phy_mode_ext); + const struct ieee80211_sta_he_cap * + mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif) + { +- enum nl80211_band band = phy->chandef.chan->band; ++ struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; ++ struct cfg80211_chan_def *chandef = mvif->ctx ? ++ &mvif->ctx->def : &phy->chandef; ++ enum nl80211_band band = chandef->chan->band; + struct ieee80211_supported_band *sband; + + sband = phy->hw->wiphy->bands[band]; +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-mt7996-fix-beamform-mcu-cmd-configuration.patch b/queue-6.6/wifi-mt76-mt7996-fix-beamform-mcu-cmd-configuration.patch new file mode 100644 index 00000000000..81c20f02130 --- /dev/null +++ b/queue-6.6/wifi-mt76-mt7996-fix-beamform-mcu-cmd-configuration.patch @@ -0,0 +1,39 @@ +From 9f393df7a632bbf659e6da175d12c51837ffb11f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Aug 2023 16:01:47 +0800 +Subject: wifi: mt76: mt7996: fix beamform mcu cmd configuration + +From: Howard Hsu + +[ Upstream commit d40fd59b7267d2e7722d3edf3935a9a9f03c0115 ] + +The bf_num field represents how many bands can support beamform, so set +the value to 3, and bf_bitmap represents the bitmap of bf_num. + +Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices") +Signed-off-by: Howard Hsu +Signed-off-by: Shayne Chen +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +index 4a30db49ef33f..4ed1643818980 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +@@ -3307,8 +3307,8 @@ int mt7996_mcu_set_txbf(struct mt7996_dev *dev, u8 action) + + tlv = mt7996_mcu_add_uni_tlv(skb, action, sizeof(*req_mod_en)); + req_mod_en = (struct bf_mod_en_ctrl *)tlv; +- req_mod_en->bf_num = 2; +- req_mod_en->bf_bitmap = GENMASK(0, 0); ++ req_mod_en->bf_num = 3; ++ req_mod_en->bf_bitmap = GENMASK(2, 0); + break; + } + default: +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-mt7996-fix-beamformee-ss-subfield-in-eht-p.patch b/queue-6.6/wifi-mt76-mt7996-fix-beamformee-ss-subfield-in-eht-p.patch new file mode 100644 index 00000000000..f1b697a442c --- /dev/null +++ b/queue-6.6/wifi-mt76-mt7996-fix-beamformee-ss-subfield-in-eht-p.patch @@ -0,0 +1,50 @@ +From 83d0b5e68f2251e44c4ea345f7a76daa3de4e699 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Aug 2023 16:01:48 +0800 +Subject: wifi: mt76: mt7996: fix beamformee ss subfield in EHT PHY cap + +From: Howard Hsu + +[ Upstream commit e19028104b2de5510b43282f632c4b6453568c41 ] + +According to P802.11be_D3.2 Table 9-404m, the minimum value of +Beamformee SS field shall be 3. Fix the values to follow the spec. + +Fixes: 348533eb968d ("wifi: mt76: mt7996: add EHT capability init") +Signed-off-by: Howard Hsu +Signed-off-by: Shayne Chen +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/init.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c +index 26e03b28935f2..66d8cc0eeabee 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c +@@ -733,16 +733,17 @@ mt7996_init_eht_caps(struct mt7996_phy *phy, enum nl80211_band band, + IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER | + IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE; + ++ val = max_t(u8, sts - 1, 3); + eht_cap_elem->phy_cap_info[0] |= +- u8_encode_bits(u8_get_bits(sts - 1, BIT(0)), ++ u8_encode_bits(u8_get_bits(val, BIT(0)), + IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK); + + eht_cap_elem->phy_cap_info[1] = +- u8_encode_bits(u8_get_bits(sts - 1, GENMASK(2, 1)), ++ u8_encode_bits(u8_get_bits(val, GENMASK(2, 1)), + IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_80MHZ_MASK) | +- u8_encode_bits(sts - 1, ++ u8_encode_bits(val, + IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK) | +- u8_encode_bits(sts - 1, ++ u8_encode_bits(val, + IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK); + + eht_cap_elem->phy_cap_info[2] = +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-mt7996-fix-rx-rate-report-for-cbw320-2.patch b/queue-6.6/wifi-mt76-mt7996-fix-rx-rate-report-for-cbw320-2.patch new file mode 100644 index 00000000000..d784991c19d --- /dev/null +++ b/queue-6.6/wifi-mt76-mt7996-fix-rx-rate-report-for-cbw320-2.patch @@ -0,0 +1,38 @@ +From 7a616bf1d75c2f33cbccdbe60ba9633eb7f810ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Aug 2023 16:01:50 +0800 +Subject: wifi: mt76: mt7996: fix rx rate report for CBW320-2 + +From: Peter Chiu + +[ Upstream commit 0197923ecf5eb4dbd785f5576040d49611f591a4 ] + +RX vector reports channel bandwidth 320-1 and 320-2 with different +values. Fix it to correctly report rx rate when using CBW320-2. + +Fixes: 80f5a31d2856 ("wifi: mt76: mt7996: add support for EHT rate report") +Signed-off-by: Peter Chiu +Signed-off-by: Shayne Chen +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +index 269e023e43113..c43839a205088 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +@@ -433,7 +433,9 @@ mt7996_mac_fill_rx_rate(struct mt7996_dev *dev, + case IEEE80211_STA_RX_BW_160: + status->bw = RATE_INFO_BW_160; + break; ++ /* rxv reports bw 320-1 and 320-2 separately */ + case IEEE80211_STA_RX_BW_320: ++ case IEEE80211_STA_RX_BW_320 + 1: + status->bw = RATE_INFO_BW_320; + break; + default: +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-mt7996-fix-twt-command-format.patch b/queue-6.6/wifi-mt76-mt7996-fix-twt-command-format.patch new file mode 100644 index 00000000000..b6b1192d94c --- /dev/null +++ b/queue-6.6/wifi-mt76-mt7996-fix-twt-command-format.patch @@ -0,0 +1,55 @@ +From 42f1a109b2ed4de8d0bd7d7bbaf822c4cf6b1f2b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Aug 2023 16:01:51 +0800 +Subject: wifi: mt76: mt7996: fix TWT command format + +From: Peter Chiu + +[ Upstream commit 84f313b7392f6501f05d8981105d79859b1252cb ] + +Align the command format of UNI_CMD_TWT_ARGT_UPDATE to firmware. + +Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices") +Signed-off-by: Peter Chiu +Signed-off-by: Shayne Chen +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +index cf443748ef7cc..b0e6f51041fdd 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +@@ -3548,7 +3548,9 @@ int mt7996_mcu_twt_agrt_update(struct mt7996_dev *dev, + int cmd) + { + struct { +- u8 _rsv[4]; ++ /* fixed field */ ++ u8 bss; ++ u8 _rsv[3]; + + __le16 tag; + __le16 len; +@@ -3566,7 +3568,7 @@ int mt7996_mcu_twt_agrt_update(struct mt7996_dev *dev, + u8 exponent; + u8 is_ap; + u8 agrt_params; +- u8 __rsv2[135]; ++ u8 __rsv2[23]; + } __packed req = { + .tag = cpu_to_le16(UNI_CMD_TWT_ARGT_UPDATE), + .len = cpu_to_le16(sizeof(req) - 4), +@@ -3576,6 +3578,7 @@ int mt7996_mcu_twt_agrt_update(struct mt7996_dev *dev, + .flowid = flow->id, + .peer_id = cpu_to_le16(flow->wcid), + .duration = flow->duration, ++ .bss = mvif->mt76.idx, + .bss_idx = mvif->mt76.idx, + .start_tsf = cpu_to_le64(flow->tsf), + .mantissa = flow->mantissa, +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-mt7996-fix-wmm-queue-mapping.patch b/queue-6.6/wifi-mt76-mt7996-fix-wmm-queue-mapping.patch new file mode 100644 index 00000000000..befeff3f5a7 --- /dev/null +++ b/queue-6.6/wifi-mt76-mt7996-fix-wmm-queue-mapping.patch @@ -0,0 +1,70 @@ +From 06b753d1568af710fdd68c5ce515f154a59afc3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Aug 2023 16:01:49 +0800 +Subject: wifi: mt76: mt7996: fix wmm queue mapping + +From: Peter Chiu + +[ Upstream commit 9b11696e5c5bf6030a32571f3f88845226d8b662 ] + +Firmware uses access class index (ACI) for wmm parameters update, so +convert mac80211 queue to ACI in mt7996_conf_tx(). + +Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices") +Signed-off-by: Peter Chiu +Signed-off-by: Shayne Chen +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/main.c | 12 +++++++++--- + drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 2 +- + 2 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index c3a479dc3f533..600010cdb94e6 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -190,7 +190,7 @@ static int mt7996_add_interface(struct ieee80211_hw *hw, + mvif->mt76.omac_idx = idx; + mvif->phy = phy; + mvif->mt76.band_idx = band_idx; +- mvif->mt76.wmm_idx = band_idx; ++ mvif->mt76.wmm_idx = vif->type != NL80211_IFTYPE_AP; + + ret = mt7996_mcu_add_dev_info(phy, vif, true); + if (ret) +@@ -414,10 +414,16 @@ mt7996_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + const struct ieee80211_tx_queue_params *params) + { + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; ++ const u8 mq_to_aci[] = { ++ [IEEE80211_AC_VO] = 3, ++ [IEEE80211_AC_VI] = 2, ++ [IEEE80211_AC_BE] = 0, ++ [IEEE80211_AC_BK] = 1, ++ }; + ++ /* firmware uses access class index */ ++ mvif->queue_params[mq_to_aci[queue]] = *params; + /* no need to update right away, we'll get BSS_CHANGED_QOS */ +- queue = mt76_connac_lmac_mapping(queue); +- mvif->queue_params[queue] = *params; + + return 0; + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +index 4ed1643818980..cf443748ef7cc 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +@@ -2679,7 +2679,7 @@ int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif) + + e = (struct edca *)tlv; + e->set = WMM_PARAM_SET; +- e->queue = ac + mvif->mt76.wmm_idx * MT7996_MAX_WMM_SETS; ++ e->queue = ac; + e->aifs = q->aifs; + e->txop = cpu_to_le16(q->txop); + +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-mt7996-set-correct-wcid-in-txp.patch b/queue-6.6/wifi-mt76-mt7996-set-correct-wcid-in-txp.patch new file mode 100644 index 00000000000..e7ed022bc15 --- /dev/null +++ b/queue-6.6/wifi-mt76-mt7996-set-correct-wcid-in-txp.patch @@ -0,0 +1,68 @@ +From 4c95b0771cbb9039dc8345fb877ada63f9d96bf0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Aug 2023 16:01:46 +0800 +Subject: wifi: mt76: mt7996: set correct wcid in txp + +From: Peter Chiu + +[ Upstream commit bde2e77f76266fbd81ff74cb12b3d87f9460b1e0 ] + +Set correct wcid in txp to let the SDO hw module look into the correct +wtbl, otherwise the tx descriptor may be wrongly fiiled. This patch also +fixed the issue that driver could not correctly report sta statistics, +especially in WDS mode, which misled AQL. + +Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices") +Co-developed-by: Michael-CY Lee +Signed-off-by: Michael-CY Lee +Signed-off-by: Peter Chiu +Signed-off-by: Shayne Chen +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h | 2 ++ + drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 8 +++----- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +index 68ca0844cbbfa..87bfa441a9374 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +@@ -257,6 +257,8 @@ enum tx_mgnt_type { + #define MT_TXD7_UDP_TCP_SUM BIT(15) + #define MT_TXD7_TX_TIME GENMASK(9, 0) + ++#define MT_TXD9_WLAN_IDX GENMASK(23, 8) ++ + #define MT_TX_RATE_STBC BIT(14) + #define MT_TX_RATE_NSS GENMASK(13, 10) + #define MT_TX_RATE_MODE GENMASK(9, 6) +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +index 0eebf915df265..269e023e43113 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +@@ -991,10 +991,8 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, + } + + txp->fw.token = cpu_to_le16(id); +- if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags)) +- txp->fw.rept_wds_wcid = cpu_to_le16(wcid->idx); +- else +- txp->fw.rept_wds_wcid = cpu_to_le16(0xfff); ++ txp->fw.rept_wds_wcid = cpu_to_le16(sta ? wcid->idx : 0xfff); ++ + tx_info->skb = NULL; + + /* pass partial skb header to fw */ +@@ -1051,7 +1049,7 @@ mt7996_txwi_free(struct mt7996_dev *dev, struct mt76_txwi_cache *t, + if (likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE))) + mt7996_tx_check_aggr(sta, txwi); + } else { +- wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX); ++ wcid_idx = le32_get_bits(txwi[9], MT_TXD9_WLAN_IDX); + } + + __mt76_tx_complete_skb(mdev, wcid_idx, t->skb, free_list); +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-remove-unused-error-path-in-mt76_connac_tx.patch b/queue-6.6/wifi-mt76-remove-unused-error-path-in-mt76_connac_tx.patch new file mode 100644 index 00000000000..7e51c2efa9e --- /dev/null +++ b/queue-6.6/wifi-mt76-remove-unused-error-path-in-mt76_connac_tx.patch @@ -0,0 +1,122 @@ +From 4512c1c09808bb0efb2751c2c317a6a4ceb15db7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Sep 2023 15:15:18 +0200 +Subject: wifi: mt76: remove unused error path in mt76_connac_tx_complete_skb + +From: Felix Fietkau + +[ Upstream commit 832f42699791e7a90e81c15da0ce886b4f8300b8 ] + +The error handling code was added in order to allow tx enqueue to fail after +calling .tx_prepare_skb. Since this can no longer happen, the error handling +code is unused. + +Signed-off-by: Felix Fietkau +Stable-dep-of: bde2e77f7626 ("wifi: mt76: mt7996: set correct wcid in txp") +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/dma.c | 3 --- + .../net/wireless/mediatek/mt76/mt7615/pci_mac.c | 2 +- + .../wireless/mediatek/mt76/mt76_connac_mac.c | 17 ----------------- + drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 2 +- + .../net/wireless/mediatek/mt76/mt7921/pci_mac.c | 2 +- + drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 2 +- + 6 files changed, 4 insertions(+), 24 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c +index dc8f4e157eb29..6ca7b494c2c26 100644 +--- a/drivers/net/wireless/mediatek/mt76/dma.c ++++ b/drivers/net/wireless/mediatek/mt76/dma.c +@@ -330,9 +330,6 @@ mt76_dma_tx_cleanup_idx(struct mt76_dev *dev, struct mt76_queue *q, int idx, + if (e->txwi == DMA_DUMMY_DATA) + e->txwi = NULL; + +- if (e->skb == DMA_DUMMY_DATA) +- e->skb = NULL; +- + *prev_e = *e; + memset(e, 0, sizeof(*e)); + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c +index 0019890fdb784..fbb1181c58ff3 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c +@@ -106,7 +106,7 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, + else + mt76_connac_write_hw_txp(mdev, tx_info, txp, id); + +- tx_info->skb = DMA_DUMMY_DATA; ++ tx_info->skb = NULL; + + return 0; + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +index ee5177fd6ddea..73db9e14db06c 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +@@ -151,23 +151,6 @@ void mt76_connac_tx_complete_skb(struct mt76_dev *mdev, + return; + } + +- /* error path */ +- if (e->skb == DMA_DUMMY_DATA) { +- struct mt76_connac_txp_common *txp; +- struct mt76_txwi_cache *t; +- u16 token; +- +- txp = mt76_connac_txwi_to_txp(mdev, e->txwi); +- if (is_mt76_fw_txp(mdev)) +- token = le16_to_cpu(txp->fw.token); +- else +- token = le16_to_cpu(txp->hw.msdu_id[0]) & +- ~MT_MSDU_ID_VALID; +- +- t = mt76_token_put(mdev, token); +- e->skb = t ? t->skb : NULL; +- } +- + if (e->skb) + mt76_tx_complete_skb(mdev, e->wcid, e->skb); + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +index b8b0c0fda7522..2222fb9aa103e 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +@@ -809,7 +809,7 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, + txp->rept_wds_wcid = cpu_to_le16(wcid->idx); + else + txp->rept_wds_wcid = cpu_to_le16(0x3ff); +- tx_info->skb = DMA_DUMMY_DATA; ++ tx_info->skb = NULL; + + /* pass partial skb header to fw */ + tx_info->buf[1].len = MT_CT_PARSE_LEN; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c +index e7a995e7e70a3..c866144ff0613 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c +@@ -48,7 +48,7 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, + memset(txp, 0, sizeof(struct mt76_connac_hw_txp)); + mt76_connac_write_hw_txp(mdev, tx_info, txp, id); + +- tx_info->skb = DMA_DUMMY_DATA; ++ tx_info->skb = NULL; + + return 0; + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +index ac8759febe485..0eebf915df265 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +@@ -995,7 +995,7 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, + txp->fw.rept_wds_wcid = cpu_to_le16(wcid->idx); + else + txp->fw.rept_wds_wcid = cpu_to_le16(0xfff); +- tx_info->skb = DMA_DUMMY_DATA; ++ tx_info->skb = NULL; + + /* pass partial skb header to fw */ + tx_info->buf[1].len = MT_CT_PARSE_LEN; +-- +2.42.0 + diff --git a/queue-6.6/wifi-mt76-update-beacon-size-limitation.patch b/queue-6.6/wifi-mt76-update-beacon-size-limitation.patch new file mode 100644 index 00000000000..19186143080 --- /dev/null +++ b/queue-6.6/wifi-mt76-update-beacon-size-limitation.patch @@ -0,0 +1,385 @@ +From 8a80966deb6d2ed79c5b69afa4e9f0ac01ea9c32 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 31 Aug 2023 14:22:14 +0800 +Subject: wifi: mt76: update beacon size limitation + +From: MeiChia Chiu + +[ Upstream commit de869f81f994c4a4dea0d70921ac5ab78858b224 ] + +To accommodate 11v MBSSID IE and support maximum 16 MBSSIDs, expand the +beacon size limitation for beacon and inband discovery commands. + +Co-developed-by: Peter Chiu +Signed-off-by: Peter Chiu +Co-developed-by: Money Wang +Signed-off-by: Money Wang +Signed-off-by: MeiChia Chiu +Signed-off-by: Shayne Chen +Signed-off-by: Felix Fietkau +Stable-dep-of: d6a2f91741d9 ("wifi: mt76: fix potential memory leak of beacon commands") +Signed-off-by: Sasha Levin +--- + .../net/wireless/mediatek/mt76/mt7915/main.c | 8 +-- + .../net/wireless/mediatek/mt76/mt7915/mcu.c | 49 +++++++++++-------- + .../net/wireless/mediatek/mt76/mt7915/mcu.h | 18 +++---- + .../wireless/mediatek/mt76/mt7915/mt7915.h | 2 + + .../net/wireless/mediatek/mt76/mt7996/main.c | 4 +- + .../net/wireless/mediatek/mt76/mt7996/mcu.c | 38 ++++++++------ + .../net/wireless/mediatek/mt76/mt7996/mcu.h | 11 ++--- + 7 files changed, 72 insertions(+), 58 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c +index 8ebbf186fab23..d06c25dda325e 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c +@@ -646,11 +646,13 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw, + mt7915_update_bss_color(hw, vif, &info->he_bss_color); + + if (changed & (BSS_CHANGED_BEACON | +- BSS_CHANGED_BEACON_ENABLED | +- BSS_CHANGED_UNSOL_BCAST_PROBE_RESP | +- BSS_CHANGED_FILS_DISCOVERY)) ++ BSS_CHANGED_BEACON_ENABLED)) + mt7915_mcu_add_beacon(hw, vif, info->enable_beacon, changed); + ++ if (changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP | ++ BSS_CHANGED_FILS_DISCOVERY)) ++ mt7915_mcu_add_inband_discov(dev, vif, changed); ++ + if (set_bss_info == 0) + mt7915_mcu_add_bss_info(phy, vif, false); + if (set_sta == 0) +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +index 50ae7bf3af91c..5cf45c5ce5e13 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +@@ -1882,10 +1882,9 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif, + memcpy(buf + MT_TXD_SIZE, skb->data, skb->len); + } + +-static void +-mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif, +- struct sk_buff *rskb, struct bss_info_bcn *bcn, +- u32 changed) ++int ++mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif, ++ u32 changed) + { + #define OFFLOAD_TX_MODE_SU BIT(0) + #define OFFLOAD_TX_MODE_MU BIT(1) +@@ -1895,14 +1894,27 @@ mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vi + struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef; + enum nl80211_band band = chandef->chan->band; + struct mt76_wcid *wcid = &dev->mt76.global_wcid; ++ struct bss_info_bcn *bcn; + struct bss_info_inband_discovery *discov; + struct ieee80211_tx_info *info; +- struct sk_buff *skb = NULL; +- struct tlv *tlv; ++ struct sk_buff *rskb, *skb = NULL; ++ struct tlv *tlv, *sub_tlv; + bool ext_phy = phy != &dev->phy; + u8 *buf, interval; + int len; + ++ if (vif->bss_conf.nontransmitted) ++ return 0; ++ ++ rskb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, NULL, ++ MT7915_MAX_BSS_OFFLOAD_SIZE); ++ if (IS_ERR(rskb)) ++ return PTR_ERR(rskb); ++ ++ tlv = mt76_connac_mcu_add_tlv(rskb, BSS_INFO_OFFLOAD, sizeof(*bcn)); ++ bcn = (struct bss_info_bcn *)tlv; ++ bcn->enable = true; ++ + if (changed & BSS_CHANGED_FILS_DISCOVERY && + vif->bss_conf.fils_discovery.max_interval) { + interval = vif->bss_conf.fils_discovery.max_interval; +@@ -1914,26 +1926,25 @@ mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vi + } + + if (!skb) +- return; ++ return -EINVAL; + + info = IEEE80211_SKB_CB(skb); + info->control.vif = vif; + info->band = band; +- + info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, ext_phy); + + len = sizeof(*discov) + MT_TXD_SIZE + skb->len; + len = (len & 0x3) ? ((len | 0x3) + 1) : len; + +- if (len > (MT7915_MAX_BSS_OFFLOAD_SIZE - rskb->len)) { ++ if (skb->len > MT7915_MAX_BEACON_SIZE) { + dev_err(dev->mt76.dev, "inband discovery size limit exceed\n"); + dev_kfree_skb(skb); +- return; ++ return -EINVAL; + } + +- tlv = mt7915_mcu_add_nested_subtlv(rskb, BSS_INFO_BCN_DISCOV, +- len, &bcn->sub_ntlv, &bcn->len); +- discov = (struct bss_info_inband_discovery *)tlv; ++ sub_tlv = mt7915_mcu_add_nested_subtlv(rskb, BSS_INFO_BCN_DISCOV, ++ len, &bcn->sub_ntlv, &bcn->len); ++ discov = (struct bss_info_inband_discovery *)sub_tlv; + discov->tx_mode = OFFLOAD_TX_MODE_SU; + /* 0: UNSOL PROBE RESP, 1: FILS DISCOV */ + discov->tx_type = !!(changed & BSS_CHANGED_FILS_DISCOVERY); +@@ -1941,13 +1952,16 @@ mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vi + discov->prob_rsp_len = cpu_to_le16(MT_TXD_SIZE + skb->len); + discov->enable = true; + +- buf = (u8 *)tlv + sizeof(*discov); ++ buf = (u8 *)sub_tlv + sizeof(*discov); + + mt7915_mac_write_txwi(&dev->mt76, (__le32 *)buf, skb, wcid, 0, NULL, + 0, changed); + memcpy(buf + MT_TXD_SIZE, skb->data, skb->len); + + dev_kfree_skb(skb); ++ ++ return mt76_mcu_skb_send_msg(&phy->dev->mt76, rskb, ++ MCU_EXT_CMD(BSS_INFO_UPDATE), true); + } + + int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +@@ -1983,7 +1997,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + if (!skb) + return -EINVAL; + +- if (skb->len > MT7915_MAX_BEACON_SIZE - MT_TXD_SIZE) { ++ if (skb->len > MT7915_MAX_BEACON_SIZE) { + dev_err(dev->mt76.dev, "Bcn size limit exceed\n"); + dev_kfree_skb(skb); + return -EINVAL; +@@ -1997,11 +2011,6 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + mt7915_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs); + dev_kfree_skb(skb); + +- if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP || +- changed & BSS_CHANGED_FILS_DISCOVERY) +- mt7915_mcu_beacon_inband_discov(dev, vif, rskb, +- bcn, changed); +- + out: + return mt76_mcu_skb_send_msg(&phy->dev->mt76, rskb, + MCU_EXT_CMD(BSS_INFO_UPDATE), true); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +index b9ea297f382c3..1592b5d6751a0 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +@@ -495,10 +495,14 @@ enum { + SER_RECOVER + }; + +-#define MT7915_MAX_BEACON_SIZE 512 +-#define MT7915_MAX_INBAND_FRAME_SIZE 256 +-#define MT7915_MAX_BSS_OFFLOAD_SIZE (MT7915_MAX_BEACON_SIZE + \ +- MT7915_MAX_INBAND_FRAME_SIZE + \ ++#define MT7915_MAX_BEACON_SIZE 1308 ++#define MT7915_BEACON_UPDATE_SIZE (sizeof(struct sta_req_hdr) + \ ++ sizeof(struct bss_info_bcn) + \ ++ sizeof(struct bss_info_bcn_cntdwn) + \ ++ sizeof(struct bss_info_bcn_mbss) + \ ++ MT_TXD_SIZE + \ ++ sizeof(struct bss_info_bcn_cont)) ++#define MT7915_MAX_BSS_OFFLOAD_SIZE (MT7915_MAX_BEACON_SIZE + \ + MT7915_BEACON_UPDATE_SIZE) + + #define MT7915_BSS_UPDATE_MAX_SIZE (sizeof(struct sta_req_hdr) + \ +@@ -511,12 +515,6 @@ enum { + sizeof(struct bss_info_bmc_rate) +\ + sizeof(struct bss_info_ext_bss)) + +-#define MT7915_BEACON_UPDATE_SIZE (sizeof(struct sta_req_hdr) + \ +- sizeof(struct bss_info_bcn_cntdwn) + \ +- sizeof(struct bss_info_bcn_mbss) + \ +- sizeof(struct bss_info_bcn_cont) + \ +- sizeof(struct bss_info_inband_discovery)) +- + static inline s8 + mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower) + { +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +index 0456e56f63480..21984e9723709 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +@@ -447,6 +447,8 @@ int mt7915_mcu_add_rx_ba(struct mt7915_dev *dev, + bool add); + int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vif, + struct cfg80211_he_bss_color *he_bss_color); ++int mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif, ++ u32 changed); + int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + int enable, u32 changed); + int mt7915_mcu_add_obss_spr(struct mt7915_phy *phy, struct ieee80211_vif *vif, +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index 600010cdb94e6..6e0f0c100db84 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -624,8 +624,8 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw, + mt7996_mcu_add_beacon(hw, vif, info->enable_beacon); + } + +- if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP || +- changed & BSS_CHANGED_FILS_DISCOVERY) ++ if (changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP | ++ BSS_CHANGED_FILS_DISCOVERY)) + mt7996_mcu_beacon_inband_discov(dev, vif, changed); + + if (changed & BSS_CHANGED_MU_GROUPS) +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +index b0e6f51041fdd..44a7c5af43e06 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +@@ -2016,7 +2016,7 @@ mt7996_mcu_beacon_cont(struct mt7996_dev *dev, struct ieee80211_vif *vif, + bcn->bcc_ie_pos = cpu_to_le16(offset - 3); + } + +- buf = (u8 *)bcn + sizeof(*bcn) - MAX_BEACON_SIZE; ++ buf = (u8 *)bcn + sizeof(*bcn); + mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0, + BSS_CHANGED_BEACON); + +@@ -2034,25 +2034,18 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw, + struct sk_buff *skb, *rskb; + struct tlv *tlv; + struct bss_bcn_content_tlv *bcn; ++ int len; + + rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, +- MT7996_BEACON_UPDATE_SIZE); ++ MT7996_MAX_BSS_OFFLOAD_SIZE); + if (IS_ERR(rskb)) + return PTR_ERR(rskb); + +- tlv = mt7996_mcu_add_uni_tlv(rskb, +- UNI_BSS_INFO_BCN_CONTENT, sizeof(*bcn)); +- bcn = (struct bss_bcn_content_tlv *)tlv; +- bcn->enable = en; +- +- if (!en) +- goto out; +- + skb = ieee80211_beacon_get_template(hw, vif, &offs, 0); + if (!skb) + return -EINVAL; + +- if (skb->len > MAX_BEACON_SIZE - MT_TXD_SIZE) { ++ if (skb->len > MT7996_MAX_BEACON_SIZE) { + dev_err(dev->mt76.dev, "Bcn size limit exceed\n"); + dev_kfree_skb(skb); + return -EINVAL; +@@ -2061,11 +2054,18 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw, + info = IEEE80211_SKB_CB(skb); + info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx); + ++ len = sizeof(*bcn) + MT_TXD_SIZE + skb->len; ++ tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_BCN_CONTENT, len); ++ bcn = (struct bss_bcn_content_tlv *)tlv; ++ bcn->enable = en; ++ if (!en) ++ goto out; ++ + mt7996_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs); + /* TODO: subtag - 11v MBSSID */ + mt7996_mcu_beacon_cntdwn(vif, rskb, skb, &offs); +- dev_kfree_skb(skb); + out: ++ dev_kfree_skb(skb); + return mt76_mcu_skb_send_msg(&phy->dev->mt76, rskb, + MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true); + } +@@ -2086,9 +2086,13 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev, + struct sk_buff *rskb, *skb = NULL; + struct tlv *tlv; + u8 *buf, interval; ++ int len; ++ ++ if (vif->bss_conf.nontransmitted) ++ return 0; + + rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, +- MT7996_INBAND_FRAME_SIZE); ++ MT7996_MAX_BSS_OFFLOAD_SIZE); + if (IS_ERR(rskb)) + return PTR_ERR(rskb); + +@@ -2105,7 +2109,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev, + if (!skb) + return -EINVAL; + +- if (skb->len > MAX_INBAND_FRAME_SIZE - MT_TXD_SIZE) { ++ if (skb->len > MT7996_MAX_BEACON_SIZE) { + dev_err(dev->mt76.dev, "inband discovery size limit exceed\n"); + dev_kfree_skb(skb); + return -EINVAL; +@@ -2116,7 +2120,9 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev, + info->band = band; + info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx); + +- tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_OFFLOAD, sizeof(*discov)); ++ len = sizeof(*discov) + MT_TXD_SIZE + skb->len; ++ ++ tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_OFFLOAD, len); + + discov = (struct bss_inband_discovery_tlv *)tlv; + discov->tx_mode = OFFLOAD_TX_MODE_SU; +@@ -2127,7 +2133,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev, + discov->enable = true; + discov->wcid = cpu_to_le16(MT7996_WTBL_RESERVED); + +- buf = (u8 *)tlv + sizeof(*discov) - MAX_INBAND_FRAME_SIZE; ++ buf = (u8 *)tlv + sizeof(*discov); + + mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0, changed); + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h +index 078f828586212..e4b31228ba0d2 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h +@@ -270,8 +270,6 @@ struct bss_inband_discovery_tlv { + u8 enable; + __le16 wcid; + __le16 prob_rsp_len; +-#define MAX_INBAND_FRAME_SIZE 512 +- u8 pkt[MAX_INBAND_FRAME_SIZE]; + } __packed; + + struct bss_bcn_content_tlv { +@@ -283,8 +281,6 @@ struct bss_bcn_content_tlv { + u8 enable; + u8 type; + __le16 pkt_len; +-#define MAX_BEACON_SIZE 512 +- u8 pkt[MAX_BEACON_SIZE]; + } __packed; + + struct bss_bcn_cntdwn_tlv { +@@ -591,13 +587,14 @@ enum { + sizeof(struct sta_rec_hdr_trans) + \ + sizeof(struct tlv)) + ++#define MT7996_MAX_BEACON_SIZE 1342 + #define MT7996_BEACON_UPDATE_SIZE (sizeof(struct bss_req_hdr) + \ + sizeof(struct bss_bcn_content_tlv) + \ ++ MT_TXD_SIZE + \ + sizeof(struct bss_bcn_cntdwn_tlv) + \ + sizeof(struct bss_bcn_mbss_tlv)) +- +-#define MT7996_INBAND_FRAME_SIZE (sizeof(struct bss_req_hdr) + \ +- sizeof(struct bss_inband_discovery_tlv)) ++#define MT7996_MAX_BSS_OFFLOAD_SIZE (MT7996_MAX_BEACON_SIZE + \ ++ MT7996_BEACON_UPDATE_SIZE) + + enum { + UNI_BAND_CONFIG_RADIO_ENABLE, +-- +2.42.0 + diff --git a/queue-6.6/wifi-rtlwifi-fix-edca-limit-set-by-bt-coexistence.patch b/queue-6.6/wifi-rtlwifi-fix-edca-limit-set-by-bt-coexistence.patch new file mode 100644 index 00000000000..da59e26aebd --- /dev/null +++ b/queue-6.6/wifi-rtlwifi-fix-edca-limit-set-by-bt-coexistence.patch @@ -0,0 +1,70 @@ +From 1468c7c510bedc2d63dc7b2ad07eb98e0b99a953 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Sep 2023 08:23:19 +0300 +Subject: wifi: rtlwifi: fix EDCA limit set by BT coexistence + +From: Dmitry Antipov + +[ Upstream commit 3391ee7f9ea508c375d443cd712c2e699be235b4 ] + +In 'rtl92c_dm_check_edca_turbo()', 'rtl88e_dm_check_edca_turbo()', +and 'rtl8723e_dm_check_edca_turbo()', the DL limit should be set +from the corresponding field of 'rtlpriv->btcoexist' rather than +UL. Compile tested only. + +Fixes: 0529c6b81761 ("rtlwifi: rtl8723ae: Update driver to match 06/28/14 Realtek version") +Fixes: c151aed6aa14 ("rtlwifi: rtl8188ee: Update driver to match Realtek release of 06282014") +Fixes: beb5bc402043 ("rtlwifi: rtl8192c-common: Convert common dynamic management routines for addition of rtl8192se and rtl8192de") +Signed-off-by: Dmitry Antipov +Acked-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230928052327.120178-1-dmantipov@yandex.ru +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c | 2 +- + drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c | 2 +- + drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c +index 6f61d6a106272..5a34894a533be 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c +@@ -799,7 +799,7 @@ static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw *hw) + } + + if (rtlpriv->btcoexist.bt_edca_dl != 0) { +- edca_be_ul = rtlpriv->btcoexist.bt_edca_dl; ++ edca_be_dl = rtlpriv->btcoexist.bt_edca_dl; + bt_change_edca = true; + } + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c +index 0b6a15c2e5ccd..d92aad60edfe9 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c +@@ -640,7 +640,7 @@ static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) + } + + if (rtlpriv->btcoexist.bt_edca_dl != 0) { +- edca_be_ul = rtlpriv->btcoexist.bt_edca_dl; ++ edca_be_dl = rtlpriv->btcoexist.bt_edca_dl; + bt_change_edca = true; + } + +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c +index 8ada31380efa4..0ff8e355c23a4 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c +@@ -466,7 +466,7 @@ static void rtl8723e_dm_check_edca_turbo(struct ieee80211_hw *hw) + } + + if (rtlpriv->btcoexist.bt_edca_dl != 0) { +- edca_be_ul = rtlpriv->btcoexist.bt_edca_dl; ++ edca_be_dl = rtlpriv->btcoexist.bt_edca_dl; + bt_change_edca = true; + } + +-- +2.42.0 + diff --git a/queue-6.6/wifi-rtw88-debug-fix-the-null-vs-is_err-bug-for-debu.patch b/queue-6.6/wifi-rtw88-debug-fix-the-null-vs-is_err-bug-for-debu.patch new file mode 100644 index 00000000000..872e0d70c73 --- /dev/null +++ b/queue-6.6/wifi-rtw88-debug-fix-the-null-vs-is_err-bug-for-debu.patch @@ -0,0 +1,42 @@ +From f66ce98e54a554639f544db71c7ca770d54ec048 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 13:06:50 +0800 +Subject: wifi: rtw88: debug: Fix the NULL vs IS_ERR() bug for + debugfs_create_file() + +From: Jinjie Ruan + +[ Upstream commit 74f7957c9b1b95553faaf146a2553e023a9d1720 ] + +Since debugfs_create_file() return ERR_PTR and never return NULL, so use +IS_ERR() to check it instead of checking NULL. + +Fixes: e3037485c68e ("rtw88: new Realtek 802.11ac driver") +Signed-off-by: Jinjie Ruan +Acked-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230919050651.962694-1-ruanjinjie@huawei.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtw88/debug.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c +index f8ba133baff06..35bc37a3c469d 100644 +--- a/drivers/net/wireless/realtek/rtw88/debug.c ++++ b/drivers/net/wireless/realtek/rtw88/debug.c +@@ -1233,9 +1233,9 @@ static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = { + #define rtw_debugfs_add_core(name, mode, fopname, parent) \ + do { \ + rtw_debug_priv_ ##name.rtwdev = rtwdev; \ +- if (!debugfs_create_file(#name, mode, \ ++ if (IS_ERR(debugfs_create_file(#name, mode, \ + parent, &rtw_debug_priv_ ##name,\ +- &file_ops_ ##fopname)) \ ++ &file_ops_ ##fopname))) \ + pr_debug("Unable to initialize debugfs:%s\n", \ + #name); \ + } while (0) +-- +2.42.0 + diff --git a/queue-6.6/wifi-rtw88-remove-duplicate-null-check-before-callin.patch b/queue-6.6/wifi-rtw88-remove-duplicate-null-check-before-callin.patch new file mode 100644 index 00000000000..43bf63605ef --- /dev/null +++ b/queue-6.6/wifi-rtw88-remove-duplicate-null-check-before-callin.patch @@ -0,0 +1,54 @@ +From 3b32db4dc298f3fd841134e449cad451e75516a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Oct 2023 10:58:52 +0800 +Subject: wifi: rtw88: Remove duplicate NULL check before calling + usb_kill/free_urb() + +From: Jinjie Ruan + +[ Upstream commit de8dd096949820ce5656d41ce409a67603e79327 ] + +Both usb_kill_urb() and usb_free_urb() do the NULL check itself, so there +is no need to duplicate it prior to calling. + +Fixes: a82dfd33d123 ("wifi: rtw88: Add common USB chip support") +Signed-off-by: Jinjie Ruan +Acked-by: Sascha Hauer +Acked-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20231008025852.1239450-1-ruanjinjie@huawei.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtw88/usb.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +index d879d7e3dc81f..e6ab1ac6d7093 100644 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -611,8 +611,7 @@ static void rtw_usb_cancel_rx_bufs(struct rtw_usb *rtwusb) + + for (i = 0; i < RTW_USB_RXCB_NUM; i++) { + rxcb = &rtwusb->rx_cb[i]; +- if (rxcb->rx_urb) +- usb_kill_urb(rxcb->rx_urb); ++ usb_kill_urb(rxcb->rx_urb); + } + } + +@@ -623,10 +622,8 @@ static void rtw_usb_free_rx_bufs(struct rtw_usb *rtwusb) + + for (i = 0; i < RTW_USB_RXCB_NUM; i++) { + rxcb = &rtwusb->rx_cb[i]; +- if (rxcb->rx_urb) { +- usb_kill_urb(rxcb->rx_urb); +- usb_free_urb(rxcb->rx_urb); +- } ++ usb_kill_urb(rxcb->rx_urb); ++ usb_free_urb(rxcb->rx_urb); + } + } + +-- +2.42.0 + diff --git a/queue-6.6/wifi-wfx-fix-case-where-rates-are-out-of-order.patch b/queue-6.6/wifi-wfx-fix-case-where-rates-are-out-of-order.patch new file mode 100644 index 00000000000..cc41cba10f9 --- /dev/null +++ b/queue-6.6/wifi-wfx-fix-case-where-rates-are-out-of-order.patch @@ -0,0 +1,161 @@ +From e190c44288bca73c65fd75711c722e953418d55e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 14:30:39 +0200 +Subject: wifi: wfx: fix case where rates are out of order +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Felipe Negrelli Wolter + +[ Upstream commit ea2274ab0b18549dbf0e755e41d8c5e8b5232dc3 ] + +When frames are sent over the air, the device always applies the data +rates in descending order. The driver assumed Minstrel also provided +rate in descending order. + +However, in some cases, Minstrel can a choose a fallback rate greater +than the primary rate. In this case, the two rates was inverted, the +device try highest rate first and we get many retries. + +Since the device always applies rates in descending order, the +workaround is to drop the rate when it higher than its predecessor in +the rate list. Thus [ 4, 5, 3 ] becomes [ 4, 3 ]. + +This patch has been tested in isolated room with a series of +attenuators. Here are the Minstrel statistics with 80dBm of attenuation: + + Without the fix: + + best ____________rate__________ ____statistics___ _____last____ ______sum-of________ + mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts] + HT20 LGI 1 S MCS0 0 1477 5.6 5.2 82.7 3 0 0 3 4 + HT20 LGI 1 MCS1 1 738 10.6 0.0 0.0 0 0 0 0 1 + HT20 LGI 1 D MCS2 2 492 14.9 13.5 81.5 5 0 0 5 9 + HT20 LGI 1 C MCS3 3 369 18.8 17.6 84.3 5 0 0 76 96 + HT20 LGI 1 A P MCS4 4 246 25.4 22.4 79.5 5 0 0 11268 14026 + HT20 LGI 1 B S MCS5 5 185 30.7 19.7 57.7 5 8 9 3918 9793 + HT20 LGI 1 MCS6 6 164 33.0 0.0 0.0 5 0 0 6 102 + HT20 LGI 1 MCS7 7 148 35.1 0.0 0.0 0 0 0 0 44 + + With the fix: + + best ____________rate__________ ____statistics___ _____last____ ______sum-of________ + mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts] + HT20 LGI 1 S MCS0 0 1477 5.6 1.8 28.6 1 0 0 1 5 + HT20 LGI 1 DP MCS1 1 738 10.6 9.7 82.6 4 0 0 14 34 + HT20 LGI 1 MCS2 2 492 14.9 9.2 55.4 5 0 0 52 77 + HT20 LGI 1 B S MCS3 3 369 18.8 15.6 74.9 5 1 1 417 554 + HT20 LGI 1 A MCS4 4 246 25.4 16.7 59.2 5 1 1 13812 17951 + HT20 LGI 1 C S MCS5 5 185 30.7 14.0 41.0 5 1 5 57 640 + HT20 LGI 1 MCS6 6 164 33.0 0.0 0.0 0 0 1 0 48 + HT20 LGI 1 S MCS7 7 148 35.1 0.0 0.0 0 0 0 0 36 + +We can notice the device try now to send with lower rates (and high +success rates). At the end, we measured 20-25% better throughput with +this patch. + +Fixes: 9bca45f3d692 ("staging: wfx: allow to send 802.11 frames") +Tested-by: Olivier Souloumiac +Tested-by: Alexandr Suslenko +Reported-by: Alexandr Suslenko +Co-developed-by: Jérôme Pouiller +Signed-off-by: Jérôme Pouiller +Signed-off-by: Felipe Negrelli Wolter +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20231004123039.157112-1-jerome.pouiller@silabs.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/silabs/wfx/data_tx.c | 71 +++++++++-------------- + 1 file changed, 29 insertions(+), 42 deletions(-) + +diff --git a/drivers/net/wireless/silabs/wfx/data_tx.c b/drivers/net/wireless/silabs/wfx/data_tx.c +index 6a5e52a96d183..caa22226b01bc 100644 +--- a/drivers/net/wireless/silabs/wfx/data_tx.c ++++ b/drivers/net/wireless/silabs/wfx/data_tx.c +@@ -226,53 +226,40 @@ static u8 wfx_tx_get_link_id(struct wfx_vif *wvif, struct ieee80211_sta *sta, + + static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates) + { +- int i; +- bool finished; ++ bool has_rate0 = false; ++ int i, j; + +- /* Firmware is not able to mix rates with different flags */ +- for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { +- if (rates[0].flags & IEEE80211_TX_RC_SHORT_GI) +- rates[i].flags |= IEEE80211_TX_RC_SHORT_GI; +- if (!(rates[0].flags & IEEE80211_TX_RC_SHORT_GI)) ++ for (i = 1, j = 1; j < IEEE80211_TX_MAX_RATES; j++) { ++ if (rates[j].idx == -1) ++ break; ++ /* The device use the rates in descending order, whatever the request from minstrel. ++ * We have to trade off here. Most important is to respect the primary rate ++ * requested by minstrel. So, we drops the entries with rate higher than the ++ * previous. ++ */ ++ if (rates[j].idx >= rates[i - 1].idx) { ++ rates[i - 1].count += rates[j].count; ++ rates[i - 1].count = min_t(u16, 15, rates[i - 1].count); ++ } else { ++ memcpy(rates + i, rates + j, sizeof(rates[i])); ++ if (rates[i].idx == 0) ++ has_rate0 = true; ++ /* The device apply Short GI only on the first rate */ + rates[i].flags &= ~IEEE80211_TX_RC_SHORT_GI; +- if (!(rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)) +- rates[i].flags &= ~IEEE80211_TX_RC_USE_RTS_CTS; +- } +- +- /* Sort rates and remove duplicates */ +- do { +- finished = true; +- for (i = 0; i < IEEE80211_TX_MAX_RATES - 1; i++) { +- if (rates[i + 1].idx == rates[i].idx && +- rates[i].idx != -1) { +- rates[i].count += rates[i + 1].count; +- if (rates[i].count > 15) +- rates[i].count = 15; +- rates[i + 1].idx = -1; +- rates[i + 1].count = 0; +- +- finished = false; +- } +- if (rates[i + 1].idx > rates[i].idx) { +- swap(rates[i + 1], rates[i]); +- finished = false; +- } ++ i++; + } +- } while (!finished); ++ } + /* Ensure that MCS0 or 1Mbps is present at the end of the retry list */ +- for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { +- if (rates[i].idx == 0) +- break; +- if (rates[i].idx == -1) { +- rates[i].idx = 0; +- rates[i].count = 8; /* == hw->max_rate_tries */ +- rates[i].flags = rates[i - 1].flags & IEEE80211_TX_RC_MCS; +- break; +- } ++ if (!has_rate0 && i < IEEE80211_TX_MAX_RATES) { ++ rates[i].idx = 0; ++ rates[i].count = 8; /* == hw->max_rate_tries */ ++ rates[i].flags = rates[0].flags & IEEE80211_TX_RC_MCS; ++ i++; ++ } ++ for (; i < IEEE80211_TX_MAX_RATES; i++) { ++ memset(rates + i, 0, sizeof(rates[i])); ++ rates[i].idx = -1; + } +- /* All retries use long GI */ +- for (i = 1; i < IEEE80211_TX_MAX_RATES; i++) +- rates[i].flags &= ~IEEE80211_TX_RC_SHORT_GI; + } + + static u8 wfx_tx_get_retry_policy_id(struct wfx_vif *wvif, struct ieee80211_tx_info *tx_info) +-- +2.42.0 + diff --git a/queue-6.6/writeback-cgroup-switch-inodes-with-dirty-timestamps.patch b/queue-6.6/writeback-cgroup-switch-inodes-with-dirty-timestamps.patch new file mode 100644 index 00000000000..a1765864967 --- /dev/null +++ b/queue-6.6/writeback-cgroup-switch-inodes-with-dirty-timestamps.patch @@ -0,0 +1,103 @@ +From 7fab468bfa7f6e6a8adec4eb892b90be34f6a903 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Oct 2023 20:55:11 +0800 +Subject: writeback, cgroup: switch inodes with dirty timestamps to release + dying cgwbs + +From: Jingbo Xu + +[ Upstream commit 6654408a33e6297d8e1d2773409431d487399b95 ] + +The cgwb cleanup routine will try to release the dying cgwb by switching +the attached inodes. It fetches the attached inodes from wb->b_attached +list, omitting the fact that inodes only with dirty timestamps reside in +wb->b_dirty_time list, which is the case when lazytime is enabled. This +causes enormous zombie memory cgroup when lazytime is enabled, as inodes +with dirty timestamps can not be switched to a live cgwb for a long time. + +It is reasonable not to switch cgwb for inodes with dirty data, as +otherwise it may break the bandwidth restrictions. However since the +writeback of inode metadata is not accounted for, let's also switch +inodes with dirty timestamps to avoid zombie memory and block cgroups +when laztytime is enabled. + +Fixes: c22d70a162d3 ("writeback, cgroup: release dying cgwbs by switching attached inodes") +Reviewed-by: Jan Kara +Signed-off-by: Jingbo Xu +Link: https://lore.kernel.org/r/20231014125511.102978-1-jefflexu@linux.alibaba.com +Acked-by: Tejun Heo +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/fs-writeback.c | 41 +++++++++++++++++++++++++++++------------ + 1 file changed, 29 insertions(+), 12 deletions(-) + +diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c +index c1af01b2c42d7..1767493dffda7 100644 +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -613,6 +613,24 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id) + kfree(isw); + } + ++static bool isw_prepare_wbs_switch(struct inode_switch_wbs_context *isw, ++ struct list_head *list, int *nr) ++{ ++ struct inode *inode; ++ ++ list_for_each_entry(inode, list, i_io_list) { ++ if (!inode_prepare_wbs_switch(inode, isw->new_wb)) ++ continue; ++ ++ isw->inodes[*nr] = inode; ++ (*nr)++; ++ ++ if (*nr >= WB_MAX_INODES_PER_ISW - 1) ++ return true; ++ } ++ return false; ++} ++ + /** + * cleanup_offline_cgwb - detach associated inodes + * @wb: target wb +@@ -625,7 +643,6 @@ bool cleanup_offline_cgwb(struct bdi_writeback *wb) + { + struct cgroup_subsys_state *memcg_css; + struct inode_switch_wbs_context *isw; +- struct inode *inode; + int nr; + bool restart = false; + +@@ -647,17 +664,17 @@ bool cleanup_offline_cgwb(struct bdi_writeback *wb) + + nr = 0; + spin_lock(&wb->list_lock); +- list_for_each_entry(inode, &wb->b_attached, i_io_list) { +- if (!inode_prepare_wbs_switch(inode, isw->new_wb)) +- continue; +- +- isw->inodes[nr++] = inode; +- +- if (nr >= WB_MAX_INODES_PER_ISW - 1) { +- restart = true; +- break; +- } +- } ++ /* ++ * In addition to the inodes that have completed writeback, also switch ++ * cgwbs for those inodes only with dirty timestamps. Otherwise, those ++ * inodes won't be written back for a long time when lazytime is ++ * enabled, and thus pinning the dying cgwbs. It won't break the ++ * bandwidth restrictions, as writeback of inode metadata is not ++ * accounted for. ++ */ ++ restart = isw_prepare_wbs_switch(isw, &wb->b_attached, &nr); ++ if (!restart) ++ restart = isw_prepare_wbs_switch(isw, &wb->b_dirty_time, &nr); + spin_unlock(&wb->list_lock); + + /* no attached inodes? bail out */ +-- +2.42.0 + diff --git a/queue-6.6/x86-apic-fake-primary-thread-mask-for-xen-pv.patch b/queue-6.6/x86-apic-fake-primary-thread-mask-for-xen-pv.patch new file mode 100644 index 00000000000..0884c5b2f7b --- /dev/null +++ b/queue-6.6/x86-apic-fake-primary-thread-mask-for-xen-pv.patch @@ -0,0 +1,86 @@ +From a3fd29a57cd7a5cc4db742613ad6c1c986a84581 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Aug 2023 10:18:28 +0200 +Subject: x86/apic: Fake primary thread mask for XEN/PV + +From: Thomas Gleixner + +[ Upstream commit 965e05ff8af98c44f9937366715c512000373164 ] + +The SMT control mechanism got added as speculation attack vector +mitigation. The implemented logic relies on the primary thread mask to +be set up properly. + +This turns out to be an issue with XEN/PV guests because their CPU hotplug +mechanics do not enumerate APICs and therefore the mask is never correctly +populated. + +This went unnoticed so far because by chance XEN/PV ends up with +smp_num_siblings == 2. So cpu_smt_control stays at its default value +CPU_SMT_ENABLED and the primary thread mask is never evaluated in the +context of CPU hotplug. + +This stopped "working" with the upcoming overhaul of the topology +evaluation which legitimately provides a fake topology for XEN/PV. That +sets smp_num_siblings to 1, which causes the core CPU hot-plug core to +refuse to bring up the APs. + +This happens because cpu_smt_control is set to CPU_SMT_NOT_SUPPORTED which +causes cpu_bootable() to evaluate the unpopulated primary thread mask with +the conclusion that all non-boot CPUs are not valid to be plugged. + +The core code has already been made more robust against this kind of fail, +but the primary thread mask really wants to be populated to avoid other +issues all over the place. + +Just fake the mask by pretending that all XEN/PV vCPUs are primary threads, +which is consistent because all of XEN/PVs topology is fake or non-existent. + +Fixes: 6a4d2657e048 ("x86/smp: Provide topology_is_primary_thread()") +Fixes: f54d4434c281 ("x86/apic: Provide cpu_primary_thread mask") +Reported-by: Juergen Gross +Signed-off-by: Thomas Gleixner +Tested-by: Juergen Gross +Tested-by: Sohil Mehta +Tested-by: Michael Kelley +Tested-by: Peter Zijlstra (Intel) +Tested-by: Zhang Rui +Acked-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/r/20230814085112.210011520@linutronix.de +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/apic/apic.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c +index 760adac3d1a82..3cdf48493546d 100644 +--- a/arch/x86/kernel/apic/apic.c ++++ b/arch/x86/kernel/apic/apic.c +@@ -36,6 +36,8 @@ + #include + #include + ++#include ++ + #include + #include + #include +@@ -2344,6 +2346,15 @@ static int __init smp_init_primary_thread_mask(void) + { + unsigned int cpu; + ++ /* ++ * XEN/PV provides either none or useless topology information. ++ * Pretend that all vCPUs are primary threads. ++ */ ++ if (xen_pv_domain()) { ++ cpumask_copy(&__cpu_primary_thread_mask, cpu_possible_mask); ++ return 0; ++ } ++ + for (cpu = 0; cpu < nr_logical_cpuids; cpu++) + cpu_mark_primary_thread(cpu, cpuid_to_apicid[cpu]); + return 0; +-- +2.42.0 + diff --git a/queue-6.6/x86-boot-fix-incorrect-startup_gdt_descr.size.patch b/queue-6.6/x86-boot-fix-incorrect-startup_gdt_descr.size.patch new file mode 100644 index 00000000000..91526598041 --- /dev/null +++ b/queue-6.6/x86-boot-fix-incorrect-startup_gdt_descr.size.patch @@ -0,0 +1,42 @@ +From 175c3b4e12ae1c878b708b27a8dbda21a35e7471 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Aug 2023 16:45:47 +0800 +Subject: x86/boot: Fix incorrect startup_gdt_descr.size + +From: Yuntao Wang + +[ Upstream commit 001470fed5959d01faecbd57fcf2f60294da0de1 ] + +Since the size value is added to the base address to yield the last valid +byte address of the GDT, the current size value of startup_gdt_descr is +incorrect (too large by one), fix it. + +[ mingo: This probably never mattered, because startup_gdt[] is only used + in a very controlled fashion - but make it consistent nevertheless. ] + +Fixes: 866b556efa12 ("x86/head/64: Install startup GDT") +Signed-off-by: Yuntao Wang +Signed-off-by: Ingo Molnar +Cc: "H. Peter Anvin" +Link: https://lore.kernel.org/r/20230807084547.217390-1-ytcoode@gmail.com +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/head64.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c +index 49f7629b17f73..bbc21798df10e 100644 +--- a/arch/x86/kernel/head64.c ++++ b/arch/x86/kernel/head64.c +@@ -80,7 +80,7 @@ static struct desc_struct startup_gdt[GDT_ENTRIES] = { + * while the kernel still uses a direct mapping. + */ + static struct desc_ptr startup_gdt_descr = { +- .size = sizeof(startup_gdt), ++ .size = sizeof(startup_gdt)-1, + .address = 0, + }; + +-- +2.42.0 + diff --git a/queue-6.6/x86-nmi-fix-out-of-order-nmi-nesting-checks-false-po.patch b/queue-6.6/x86-nmi-fix-out-of-order-nmi-nesting-checks-false-po.patch new file mode 100644 index 00000000000..122626ea88b --- /dev/null +++ b/queue-6.6/x86-nmi-fix-out-of-order-nmi-nesting-checks-false-po.patch @@ -0,0 +1,100 @@ +From 278ccb53f53b5ecd868cb980b55bc30aca53e97d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 11:40:16 -0700 +Subject: x86/nmi: Fix out-of-order NMI nesting checks & false positive warning + +From: Paul E. McKenney + +[ Upstream commit f44075ecafb726830e63d33fbca29413149eeeb8 ] + +The ->idt_seq and ->recv_jiffies variables added by: + + 1a3ea611fc10 ("x86/nmi: Accumulate NMI-progress evidence in exc_nmi()") + +... place the exit-time check of the bottom bit of ->idt_seq after the +this_cpu_dec_return() that re-enables NMI nesting. This can result in +the following sequence of events on a given CPU in kernels built with +CONFIG_NMI_CHECK_CPU=y: + + o An NMI arrives, and ->idt_seq is incremented to an odd number. + In addition, nmi_state is set to NMI_EXECUTING==1. + + o The NMI is processed. + + o The this_cpu_dec_return(nmi_state) zeroes nmi_state and returns + NMI_EXECUTING==1, thus opting out of the "goto nmi_restart". + + o Another NMI arrives and ->idt_seq is incremented to an even + number, triggering the warning. But all is just fine, at least + assuming we don't get so many closely spaced NMIs that the stack + overflows or some such. + +Experience on the fleet indicates that the MTBF of this false positive +is about 70 years. Or, for those who are not quite that patient, the +MTBF appears to be about one per week per 4,000 systems. + +Fix this false-positive warning by moving the "nmi_restart" label before +the initial ->idt_seq increment/check and moving the this_cpu_dec_return() +to follow the final ->idt_seq increment/check. This way, all nested NMIs +that get past the NMI_NOT_RUNNING check get a clean ->idt_seq slate. +And if they don't get past that check, they will set nmi_state to +NMI_LATCHED, which will cause the this_cpu_dec_return(nmi_state) +to restart. + +Fixes: 1a3ea611fc10 ("x86/nmi: Accumulate NMI-progress evidence in exc_nmi()") +Reported-by: Chris Mason +Signed-off-by: Paul E. McKenney +Signed-off-by: Ingo Molnar +Cc: Linus Torvalds +Cc: Andy Lutomirski +Cc: "H. Peter Anvin" +Link: https://lore.kernel.org/r/0cbff831-6e3d-431c-9830-ee65ee7787ff@paulmck-laptop +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/nmi.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c +index a0c551846b35f..4766b6bed4439 100644 +--- a/arch/x86/kernel/nmi.c ++++ b/arch/x86/kernel/nmi.c +@@ -507,12 +507,13 @@ DEFINE_IDTENTRY_RAW(exc_nmi) + } + this_cpu_write(nmi_state, NMI_EXECUTING); + this_cpu_write(nmi_cr2, read_cr2()); ++ ++nmi_restart: + if (IS_ENABLED(CONFIG_NMI_CHECK_CPU)) { + WRITE_ONCE(nsp->idt_seq, nsp->idt_seq + 1); + WARN_ON_ONCE(!(nsp->idt_seq & 0x1)); + WRITE_ONCE(nsp->recv_jiffies, jiffies); + } +-nmi_restart: + + /* + * Needs to happen before DR7 is accessed, because the hypervisor can +@@ -548,16 +549,16 @@ DEFINE_IDTENTRY_RAW(exc_nmi) + + if (unlikely(this_cpu_read(nmi_cr2) != read_cr2())) + write_cr2(this_cpu_read(nmi_cr2)); +- if (this_cpu_dec_return(nmi_state)) +- goto nmi_restart; +- +- if (user_mode(regs)) +- mds_user_clear_cpu_buffers(); + if (IS_ENABLED(CONFIG_NMI_CHECK_CPU)) { + WRITE_ONCE(nsp->idt_seq, nsp->idt_seq + 1); + WARN_ON_ONCE(nsp->idt_seq & 0x1); + WRITE_ONCE(nsp->recv_jiffies, jiffies); + } ++ if (this_cpu_dec_return(nmi_state)) ++ goto nmi_restart; ++ ++ if (user_mode(regs)) ++ mds_user_clear_cpu_buffers(); + } + + #if IS_ENABLED(CONFIG_KVM_INTEL) +-- +2.42.0 + diff --git a/queue-6.6/x86-numa-introduce-numa_fill_memblks.patch b/queue-6.6/x86-numa-introduce-numa_fill_memblks.patch new file mode 100644 index 00000000000..636c1c8b491 --- /dev/null +++ b/queue-6.6/x86-numa-introduce-numa_fill_memblks.patch @@ -0,0 +1,195 @@ +From ab55bea6f132e59b35901a41a476d6e5115c0b79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Jul 2023 13:02:58 -0700 +Subject: x86/numa: Introduce numa_fill_memblks() + +From: Alison Schofield + +[ Upstream commit 8f012db27c9516be1a7aca93ea4a6ca9c75056c9 ] + +numa_fill_memblks() fills in the gaps in numa_meminfo memblks +over an physical address range. + +The ACPI driver will use numa_fill_memblks() to implement a new Linux +policy that prescribes extending proximity domains in a portion of a +CFMWS window to the entire window. + +Dan Williams offered this explanation of the policy: +A CFWMS is an ACPI data structure that indicates *potential* locations +where CXL memory can be placed. It is the playground where the CXL +driver has free reign to establish regions. That space can be populated +by BIOS created regions, or driver created regions, after hotplug or +other reconfiguration. + +When BIOS creates a region in a CXL Window it additionally describes +that subset of the Window range in the other typical ACPI tables SRAT, +SLIT, and HMAT. The rationale for BIOS not pre-describing the entire +CXL Window in SRAT, SLIT, and HMAT is that it can not predict the +future. I.e. there is nothing stopping higher or lower performance +devices being placed in the same Window. Compare that to ACPI memory +hotplug that just onlines additional capacity in the proximity domain +with little freedom for dynamic performance differentiation. + +That leaves the OS with a choice, should unpopulated window capacity +match the proximity domain of an existing region, or should it allocate +a new one? This patch takes the simple position of minimizing proximity +domain proliferation by reusing any proximity domain intersection for +the entire Window. If the Window has no intersections then allocate a +new proximity domain. Note that SRAT, SLIT and HMAT information can be +enumerated dynamically in a standard way from device provided data. +Think of CXL as the end of ACPI needing to describe memory attributes, +CXL offers a standard discovery model for performance attributes, but +Linux still needs to interoperate with the old regime. + +Reported-by: Derick Marks +Suggested-by: Dan Williams +Signed-off-by: Alison Schofield +Signed-off-by: Dave Hansen +Reviewed-by: Dan Williams +Tested-by: Derick Marks +Link: https://lore.kernel.org/all/ef078a6f056ca974e5af85997013c0fda9e3326d.1689018477.git.alison.schofield%40intel.com +Stable-dep-of: 8f1004679987 ("ACPI/NUMA: Apply SRAT proximity domain to entire CFMWS window") +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/sparsemem.h | 2 + + arch/x86/mm/numa.c | 80 ++++++++++++++++++++++++++++++++ + include/linux/numa.h | 7 +++ + 3 files changed, 89 insertions(+) + +diff --git a/arch/x86/include/asm/sparsemem.h b/arch/x86/include/asm/sparsemem.h +index 64df897c0ee30..1be13b2dfe8bf 100644 +--- a/arch/x86/include/asm/sparsemem.h ++++ b/arch/x86/include/asm/sparsemem.h +@@ -37,6 +37,8 @@ extern int phys_to_target_node(phys_addr_t start); + #define phys_to_target_node phys_to_target_node + extern int memory_add_physaddr_to_nid(u64 start); + #define memory_add_physaddr_to_nid memory_add_physaddr_to_nid ++extern int numa_fill_memblks(u64 start, u64 end); ++#define numa_fill_memblks numa_fill_memblks + #endif + #endif /* __ASSEMBLY__ */ + +diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c +index 2aadb2019b4f2..c01c5506fd4ae 100644 +--- a/arch/x86/mm/numa.c ++++ b/arch/x86/mm/numa.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -961,4 +962,83 @@ int memory_add_physaddr_to_nid(u64 start) + return nid; + } + EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); ++ ++static int __init cmp_memblk(const void *a, const void *b) ++{ ++ const struct numa_memblk *ma = *(const struct numa_memblk **)a; ++ const struct numa_memblk *mb = *(const struct numa_memblk **)b; ++ ++ return ma->start - mb->start; ++} ++ ++static struct numa_memblk *numa_memblk_list[NR_NODE_MEMBLKS] __initdata; ++ ++/** ++ * numa_fill_memblks - Fill gaps in numa_meminfo memblks ++ * @start: address to begin fill ++ * @end: address to end fill ++ * ++ * Find and extend numa_meminfo memblks to cover the @start-@end ++ * physical address range, such that the first memblk includes ++ * @start, the last memblk includes @end, and any gaps in between ++ * are filled. ++ * ++ * RETURNS: ++ * 0 : Success ++ * NUMA_NO_MEMBLK : No memblk exists in @start-@end range ++ */ ++ ++int __init numa_fill_memblks(u64 start, u64 end) ++{ ++ struct numa_memblk **blk = &numa_memblk_list[0]; ++ struct numa_meminfo *mi = &numa_meminfo; ++ int count = 0; ++ u64 prev_end; ++ ++ /* ++ * Create a list of pointers to numa_meminfo memblks that ++ * overlap start, end. Exclude (start == bi->end) since ++ * end addresses in both a CFMWS range and a memblk range ++ * are exclusive. ++ * ++ * This list of pointers is used to make in-place changes ++ * that fill out the numa_meminfo memblks. ++ */ ++ for (int i = 0; i < mi->nr_blks; i++) { ++ struct numa_memblk *bi = &mi->blk[i]; ++ ++ if (start < bi->end && end >= bi->start) { ++ blk[count] = &mi->blk[i]; ++ count++; ++ } ++ } ++ if (!count) ++ return NUMA_NO_MEMBLK; ++ ++ /* Sort the list of pointers in memblk->start order */ ++ sort(&blk[0], count, sizeof(blk[0]), cmp_memblk, NULL); ++ ++ /* Make sure the first/last memblks include start/end */ ++ blk[0]->start = min(blk[0]->start, start); ++ blk[count - 1]->end = max(blk[count - 1]->end, end); ++ ++ /* ++ * Fill any gaps by tracking the previous memblks ++ * end address and backfilling to it if needed. ++ */ ++ prev_end = blk[0]->end; ++ for (int i = 1; i < count; i++) { ++ struct numa_memblk *curr = blk[i]; ++ ++ if (prev_end >= curr->start) { ++ if (prev_end < curr->end) ++ prev_end = curr->end; ++ } else { ++ curr->start = prev_end; ++ prev_end = curr->end; ++ } ++ } ++ return 0; ++} ++ + #endif +diff --git a/include/linux/numa.h b/include/linux/numa.h +index fb30a42f0700d..a904861de8000 100644 +--- a/include/linux/numa.h ++++ b/include/linux/numa.h +@@ -12,6 +12,7 @@ + #define MAX_NUMNODES (1 << NODES_SHIFT) + + #define NUMA_NO_NODE (-1) ++#define NUMA_NO_MEMBLK (-1) + + /* optionally keep NUMA memory info available post init */ + #ifdef CONFIG_NUMA_KEEP_MEMINFO +@@ -43,6 +44,12 @@ static inline int phys_to_target_node(u64 start) + return 0; + } + #endif ++#ifndef numa_fill_memblks ++static inline int __init numa_fill_memblks(u64 start, u64 end) ++{ ++ return NUMA_NO_MEMBLK; ++} ++#endif + #else /* !CONFIG_NUMA */ + static inline int numa_nearest_node(int node, unsigned int state) + { +-- +2.42.0 + diff --git a/queue-6.6/x86-sev-es-allow-copy_from_kernel_nofault-in-earlier.patch b/queue-6.6/x86-sev-es-allow-copy_from_kernel_nofault-in-earlier.patch new file mode 100644 index 00000000000..8e9948e807b --- /dev/null +++ b/queue-6.6/x86-sev-es-allow-copy_from_kernel_nofault-in-earlier.patch @@ -0,0 +1,64 @@ +From 4e9d4e2997f54f897fc4b1fdb5636d90ca2d2a1a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Sep 2023 17:27:02 -0700 +Subject: x86/sev-es: Allow copy_from_kernel_nofault() in earlier boot + +From: Adam Dunlap + +[ Upstream commit f79936545fb122856bd78b189d3c7ee59928c751 ] + +Previously, if copy_from_kernel_nofault() was called before +boot_cpu_data.x86_virt_bits was set up, then it would trigger undefined +behavior due to a shift by 64. + +This ended up causing boot failures in the latest version of ubuntu2204 +in the gcp project when using SEV-SNP. + +Specifically, this function is called during an early #VC handler which +is triggered by a CPUID to check if NX is implemented. + +Fixes: 1aa9aa8ee517 ("x86/sev-es: Setup GHCB-based boot #VC handler") +Suggested-by: Dave Hansen +Signed-off-by: Adam Dunlap +Signed-off-by: Ingo Molnar +Tested-by: Jacob Xu +Link: https://lore.kernel.org/r/20230912002703.3924521-2-acdunlap@google.com +Signed-off-by: Sasha Levin +--- + arch/x86/mm/maccess.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +diff --git a/arch/x86/mm/maccess.c b/arch/x86/mm/maccess.c +index 5a53c2cc169cc..6993f026adec9 100644 +--- a/arch/x86/mm/maccess.c ++++ b/arch/x86/mm/maccess.c +@@ -9,12 +9,21 @@ bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) + unsigned long vaddr = (unsigned long)unsafe_src; + + /* +- * Range covering the highest possible canonical userspace address +- * as well as non-canonical address range. For the canonical range +- * we also need to include the userspace guard page. ++ * Do not allow userspace addresses. This disallows ++ * normal userspace and the userspace guard page: + */ +- return vaddr >= TASK_SIZE_MAX + PAGE_SIZE && +- __is_canonical_address(vaddr, boot_cpu_data.x86_virt_bits); ++ if (vaddr < TASK_SIZE_MAX + PAGE_SIZE) ++ return false; ++ ++ /* ++ * Allow everything during early boot before 'x86_virt_bits' ++ * is initialized. Needed for instruction decoding in early ++ * exception handlers. ++ */ ++ if (!boot_cpu_data.x86_virt_bits) ++ return true; ++ ++ return __is_canonical_address(vaddr, boot_cpu_data.x86_virt_bits); + } + #else + bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) +-- +2.42.0 + diff --git a/queue-6.6/x86-srso-fix-sbpb-enablement-for-possible-future-fix.patch b/queue-6.6/x86-srso-fix-sbpb-enablement-for-possible-future-fix.patch new file mode 100644 index 00000000000..730971ae626 --- /dev/null +++ b/queue-6.6/x86-srso-fix-sbpb-enablement-for-possible-future-fix.patch @@ -0,0 +1,39 @@ +From dea2b8553a6171115024beafa42e135abbdd0c5e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 22:04:49 -0700 +Subject: x86/srso: Fix SBPB enablement for (possible) future fixed HW + +From: Josh Poimboeuf + +[ Upstream commit 1d1142ac51307145dbb256ac3535a1d43a1c9800 ] + +Make the SBPB check more robust against the (possible) case where future +HW has SRSO fixed but doesn't have the SRSO_NO bit set. + +Fixes: 1b5277c0ea0b ("x86/srso: Add SRSO_NO support") +Signed-off-by: Josh Poimboeuf +Signed-off-by: Ingo Molnar +Signed-off-by: Borislav Petkov (AMD) +Acked-by: Borislav Petkov (AMD) +Link: https://lore.kernel.org/r/cee5050db750b391c9f35f5334f8ff40e66c01b9.1693889988.git.jpoimboe@kernel.org +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/cpu/bugs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c +index 10499bcd4e396..2859a54660a28 100644 +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -2496,7 +2496,7 @@ static void __init srso_select_mitigation(void) + pr_info("%s%s\n", srso_strings[srso_mitigation], (has_microcode ? "" : ", no microcode")); + + pred_cmd: +- if ((boot_cpu_has(X86_FEATURE_SRSO_NO) || srso_cmd == SRSO_CMD_OFF) && ++ if ((!boot_cpu_has_bug(X86_BUG_SRSO) || srso_cmd == SRSO_CMD_OFF) && + boot_cpu_has(X86_FEATURE_SBPB)) + x86_pred_cmd = PRED_CMD_SBPB; + } +-- +2.42.0 + diff --git a/queue-6.6/x86-srso-fix-unret-validation-dependencies.patch b/queue-6.6/x86-srso-fix-unret-validation-dependencies.patch new file mode 100644 index 00000000000..30426cf9818 --- /dev/null +++ b/queue-6.6/x86-srso-fix-unret-validation-dependencies.patch @@ -0,0 +1,80 @@ +From 78834636d3214595b038fac394fa5e4711090d3d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 22:04:53 -0700 +Subject: x86/srso: Fix unret validation dependencies + +From: Josh Poimboeuf + +[ Upstream commit eeb9f34df065f42f0c9195b322ba6df420c9fc92 ] + +CONFIG_CPU_SRSO isn't dependent on CONFIG_CPU_UNRET_ENTRY (AMD +Retbleed), so the two features are independently configurable. Fix +several issues for the (presumably rare) case where CONFIG_CPU_SRSO is +enabled but CONFIG_CPU_UNRET_ENTRY isn't. + +Fixes: fb3bd914b3ec ("x86/srso: Add a Speculative RAS Overflow mitigation") +Signed-off-by: Josh Poimboeuf +Signed-off-by: Ingo Molnar +Signed-off-by: Borislav Petkov (AMD) +Acked-by: Borislav Petkov (AMD) +Link: https://lore.kernel.org/r/299fb7740174d0f2335e91c58af0e9c242b4bac1.1693889988.git.jpoimboe@kernel.org +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/nospec-branch.h | 4 ++-- + include/linux/objtool.h | 3 ++- + scripts/Makefile.vmlinux_o | 3 ++- + 3 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h +index c55cc243592e9..197ff4f4d1ceb 100644 +--- a/arch/x86/include/asm/nospec-branch.h ++++ b/arch/x86/include/asm/nospec-branch.h +@@ -271,7 +271,7 @@ + .Lskip_rsb_\@: + .endm + +-#ifdef CONFIG_CPU_UNRET_ENTRY ++#if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_SRSO) + #define CALL_UNTRAIN_RET "call entry_untrain_ret" + #else + #define CALL_UNTRAIN_RET "" +@@ -312,7 +312,7 @@ + + .macro UNTRAIN_RET_FROM_CALL + #if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_IBPB_ENTRY) || \ +- defined(CONFIG_CALL_DEPTH_TRACKING) ++ defined(CONFIG_CALL_DEPTH_TRACKING) || defined(CONFIG_CPU_SRSO) + VALIDATE_UNRET_END + ALTERNATIVE_3 "", \ + CALL_UNTRAIN_RET, X86_FEATURE_UNRET, \ +diff --git a/include/linux/objtool.h b/include/linux/objtool.h +index 03f82c2c2ebf6..b5440e7da55bf 100644 +--- a/include/linux/objtool.h ++++ b/include/linux/objtool.h +@@ -130,7 +130,8 @@ + * it will be ignored. + */ + .macro VALIDATE_UNRET_BEGIN +-#if defined(CONFIG_NOINSTR_VALIDATION) && defined(CONFIG_CPU_UNRET_ENTRY) ++#if defined(CONFIG_NOINSTR_VALIDATION) && \ ++ (defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_SRSO)) + .Lhere_\@: + .pushsection .discard.validate_unret + .long .Lhere_\@ - . +diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o +index 0edfdb40364b8..25b3b587d37c0 100644 +--- a/scripts/Makefile.vmlinux_o ++++ b/scripts/Makefile.vmlinux_o +@@ -37,7 +37,8 @@ objtool-enabled := $(or $(delay-objtool),$(CONFIG_NOINSTR_VALIDATION)) + + vmlinux-objtool-args-$(delay-objtool) += $(objtool-args-y) + vmlinux-objtool-args-$(CONFIG_GCOV_KERNEL) += --no-unreachable +-vmlinux-objtool-args-$(CONFIG_NOINSTR_VALIDATION) += --noinstr $(if $(CONFIG_CPU_UNRET_ENTRY), --unret) ++vmlinux-objtool-args-$(CONFIG_NOINSTR_VALIDATION) += --noinstr \ ++ $(if $(or $(CONFIG_CPU_UNRET_ENTRY),$(CONFIG_CPU_SRSO)), --unret) + + objtool-args = $(vmlinux-objtool-args-y) --link + +-- +2.42.0 + diff --git a/queue-6.6/x86-srso-fix-vulnerability-reporting-for-missing-mic.patch b/queue-6.6/x86-srso-fix-vulnerability-reporting-for-missing-mic.patch new file mode 100644 index 00000000000..5320422bb74 --- /dev/null +++ b/queue-6.6/x86-srso-fix-vulnerability-reporting-for-missing-mic.patch @@ -0,0 +1,177 @@ +From bf07dd961d8d039dc89bc85b7c5e8a0920fa8ebe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 22:04:52 -0700 +Subject: x86/srso: Fix vulnerability reporting for missing microcode + +From: Josh Poimboeuf + +[ Upstream commit dc6306ad5b0dda040baf1fde3cfd458e6abfc4da ] + +The SRSO default safe-ret mitigation is reported as "mitigated" even if +microcode hasn't been updated. That's wrong because userspace may still +be vulnerable to SRSO attacks due to IBPB not flushing branch type +predictions. + +Report the safe-ret + !microcode case as vulnerable. + +Also report the microcode-only case as vulnerable as it leaves the +kernel open to attacks. + +Fixes: fb3bd914b3ec ("x86/srso: Add a Speculative RAS Overflow mitigation") +Signed-off-by: Josh Poimboeuf +Signed-off-by: Ingo Molnar +Signed-off-by: Borislav Petkov (AMD) +Acked-by: Borislav Petkov (AMD) +Link: https://lore.kernel.org/r/a8a14f97d1b0e03ec255c81637afdf4cf0ae9c99.1693889988.git.jpoimboe@kernel.org +Signed-off-by: Sasha Levin +--- + Documentation/admin-guide/hw-vuln/srso.rst | 24 ++++++++++----- + arch/x86/kernel/cpu/bugs.c | 36 +++++++++++++--------- + 2 files changed, 39 insertions(+), 21 deletions(-) + +diff --git a/Documentation/admin-guide/hw-vuln/srso.rst b/Documentation/admin-guide/hw-vuln/srso.rst +index b6cfb51cb0b46..e715bfc09879a 100644 +--- a/Documentation/admin-guide/hw-vuln/srso.rst ++++ b/Documentation/admin-guide/hw-vuln/srso.rst +@@ -46,12 +46,22 @@ The possible values in this file are: + + The processor is not vulnerable + +- * 'Vulnerable: no microcode': ++* 'Vulnerable': ++ ++ The processor is vulnerable and no mitigations have been applied. ++ ++ * 'Vulnerable: No microcode': + + The processor is vulnerable, no microcode extending IBPB + functionality to address the vulnerability has been applied. + +- * 'Mitigation: microcode': ++ * 'Vulnerable: Safe RET, no microcode': ++ ++ The "Safe RET" mitigation (see below) has been applied to protect the ++ kernel, but the IBPB-extending microcode has not been applied. User ++ space tasks may still be vulnerable. ++ ++ * 'Vulnerable: Microcode, no safe RET': + + Extended IBPB functionality microcode patch has been applied. It does + not address User->Kernel and Guest->Host transitions protection but it +@@ -72,11 +82,11 @@ The possible values in this file are: + + (spec_rstack_overflow=microcode) + +- * 'Mitigation: safe RET': ++ * 'Mitigation: Safe RET': + +- Software-only mitigation. It complements the extended IBPB microcode +- patch functionality by addressing User->Kernel and Guest->Host +- transitions protection. ++ Combined microcode/software mitigation. It complements the ++ extended IBPB microcode patch functionality by addressing ++ User->Kernel and Guest->Host transitions protection. + + Selected by default or by spec_rstack_overflow=safe-ret + +@@ -129,7 +139,7 @@ an indrect branch prediction barrier after having applied the required + microcode patch for one's system. This mitigation comes also at + a performance cost. + +-Mitigation: safe RET ++Mitigation: Safe RET + -------------------- + + The mitigation works by ensuring all RET instructions speculate to +diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c +index d5db0baca2f14..a55a3864df1c9 100644 +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -2353,6 +2353,8 @@ early_param("l1tf", l1tf_cmdline); + + enum srso_mitigation { + SRSO_MITIGATION_NONE, ++ SRSO_MITIGATION_UCODE_NEEDED, ++ SRSO_MITIGATION_SAFE_RET_UCODE_NEEDED, + SRSO_MITIGATION_MICROCODE, + SRSO_MITIGATION_SAFE_RET, + SRSO_MITIGATION_IBPB, +@@ -2368,11 +2370,13 @@ enum srso_mitigation_cmd { + }; + + static const char * const srso_strings[] = { +- [SRSO_MITIGATION_NONE] = "Vulnerable", +- [SRSO_MITIGATION_MICROCODE] = "Mitigation: microcode", +- [SRSO_MITIGATION_SAFE_RET] = "Mitigation: safe RET", +- [SRSO_MITIGATION_IBPB] = "Mitigation: IBPB", +- [SRSO_MITIGATION_IBPB_ON_VMEXIT] = "Mitigation: IBPB on VMEXIT only" ++ [SRSO_MITIGATION_NONE] = "Vulnerable", ++ [SRSO_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode", ++ [SRSO_MITIGATION_SAFE_RET_UCODE_NEEDED] = "Vulnerable: Safe RET, no microcode", ++ [SRSO_MITIGATION_MICROCODE] = "Vulnerable: Microcode, no safe RET", ++ [SRSO_MITIGATION_SAFE_RET] = "Mitigation: Safe RET", ++ [SRSO_MITIGATION_IBPB] = "Mitigation: IBPB", ++ [SRSO_MITIGATION_IBPB_ON_VMEXIT] = "Mitigation: IBPB on VMEXIT only" + }; + + static enum srso_mitigation srso_mitigation __ro_after_init = SRSO_MITIGATION_NONE; +@@ -2409,10 +2413,7 @@ static void __init srso_select_mitigation(void) + if (!boot_cpu_has_bug(X86_BUG_SRSO) || cpu_mitigations_off()) + goto pred_cmd; + +- if (!has_microcode) { +- pr_warn("IBPB-extending microcode not applied!\n"); +- pr_warn(SRSO_NOTICE); +- } else { ++ if (has_microcode) { + /* + * Zen1/2 with SMT off aren't vulnerable after the right + * IBPB microcode has been applied. +@@ -2428,6 +2429,12 @@ static void __init srso_select_mitigation(void) + srso_mitigation = SRSO_MITIGATION_IBPB; + goto out; + } ++ } else { ++ pr_warn("IBPB-extending microcode not applied!\n"); ++ pr_warn(SRSO_NOTICE); ++ ++ /* may be overwritten by SRSO_CMD_SAFE_RET below */ ++ srso_mitigation = SRSO_MITIGATION_UCODE_NEEDED; + } + + switch (srso_cmd) { +@@ -2457,7 +2464,10 @@ static void __init srso_select_mitigation(void) + setup_force_cpu_cap(X86_FEATURE_SRSO); + x86_return_thunk = srso_return_thunk; + } +- srso_mitigation = SRSO_MITIGATION_SAFE_RET; ++ if (has_microcode) ++ srso_mitigation = SRSO_MITIGATION_SAFE_RET; ++ else ++ srso_mitigation = SRSO_MITIGATION_SAFE_RET_UCODE_NEEDED; + } else { + pr_err("WARNING: kernel not compiled with CPU_SRSO.\n"); + goto pred_cmd; +@@ -2493,7 +2503,7 @@ static void __init srso_select_mitigation(void) + } + + out: +- pr_info("%s%s\n", srso_strings[srso_mitigation], has_microcode ? "" : ", no microcode"); ++ pr_info("%s\n", srso_strings[srso_mitigation]); + + pred_cmd: + if ((!boot_cpu_has_bug(X86_BUG_SRSO) || srso_cmd == SRSO_CMD_OFF) && +@@ -2704,9 +2714,7 @@ static ssize_t srso_show_state(char *buf) + if (boot_cpu_has(X86_FEATURE_SRSO_NO)) + return sysfs_emit(buf, "Mitigation: SMT disabled\n"); + +- return sysfs_emit(buf, "%s%s\n", +- srso_strings[srso_mitigation], +- boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) ? "" : ", no microcode"); ++ return sysfs_emit(buf, "%s\n", srso_strings[srso_mitigation]); + } + + static ssize_t gds_show_state(char *buf) +-- +2.42.0 + diff --git a/queue-6.6/x86-srso-print-mitigation-for-retbleed-ibpb-case.patch b/queue-6.6/x86-srso-print-mitigation-for-retbleed-ibpb-case.patch new file mode 100644 index 00000000000..5e5e839aa7d --- /dev/null +++ b/queue-6.6/x86-srso-print-mitigation-for-retbleed-ibpb-case.patch @@ -0,0 +1,52 @@ +From 50167617ec644dbfe6517b70173814e4302b2be3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 22:04:51 -0700 +Subject: x86/srso: Print mitigation for retbleed IBPB case + +From: Josh Poimboeuf + +[ Upstream commit de9f5f7b06a5b7adbfdd8016f011120a4e928add ] + +When overriding the requested mitigation with IBPB due to retbleed=ibpb, +print the mitigation in the usual format instead of a custom error +message. + +Signed-off-by: Josh Poimboeuf +Signed-off-by: Ingo Molnar +Signed-off-by: Borislav Petkov (AMD) +Acked-by: Borislav Petkov (AMD) +Link: https://lore.kernel.org/r/ec3af919e267773d896c240faf30bfc6a1fd6304.1693889988.git.jpoimboe@kernel.org +Stable-dep-of: dc6306ad5b0d ("x86/srso: Fix vulnerability reporting for missing microcode") +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/cpu/bugs.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c +index 2859a54660a28..d5db0baca2f14 100644 +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -2425,9 +2425,8 @@ static void __init srso_select_mitigation(void) + + if (retbleed_mitigation == RETBLEED_MITIGATION_IBPB) { + if (has_microcode) { +- pr_err("Retbleed IBPB mitigation enabled, using same for SRSO\n"); + srso_mitigation = SRSO_MITIGATION_IBPB; +- goto pred_cmd; ++ goto out; + } + } + +@@ -2493,7 +2492,8 @@ static void __init srso_select_mitigation(void) + break; + } + +- pr_info("%s%s\n", srso_strings[srso_mitigation], (has_microcode ? "" : ", no microcode")); ++out: ++ pr_info("%s%s\n", srso_strings[srso_mitigation], has_microcode ? "" : ", no microcode"); + + pred_cmd: + if ((!boot_cpu_has_bug(X86_BUG_SRSO) || srso_cmd == SRSO_CMD_OFF) && +-- +2.42.0 + diff --git a/queue-6.6/x86-tdx-zero-out-the-missing-rsi-in-tdx_hypercall-ma.patch b/queue-6.6/x86-tdx-zero-out-the-missing-rsi-in-tdx_hypercall-ma.patch new file mode 100644 index 00000000000..9e65315f9c4 --- /dev/null +++ b/queue-6.6/x86-tdx-zero-out-the-missing-rsi-in-tdx_hypercall-ma.patch @@ -0,0 +1,53 @@ +From b78401b80da53298eaf4f02110bd720eddff3f96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Aug 2023 23:01:55 +1200 +Subject: x86/tdx: Zero out the missing RSI in TDX_HYPERCALL macro + +From: Kai Huang + +[ Upstream commit 5d092b66119d774853cc9308522620299048a662 ] + +In the TDX_HYPERCALL asm, after the TDCALL instruction returns from the +untrusted VMM, the registers that the TDX guest shares to the VMM need +to be cleared to avoid speculative execution of VMM-provided values. + +RSI is specified in the bitmap of those registers, but it is missing +when zeroing out those registers in the current TDX_HYPERCALL. + +It was there when it was originally added in commit 752d13305c78 +("x86/tdx: Expand __tdx_hypercall() to handle more arguments"), but was +later removed in commit 1e70c680375a ("x86/tdx: Do not corrupt +frame-pointer in __tdx_hypercall()"), which was correct because %rsi is +later restored in the "pop %rsi". However a later commit 7a3a401874be +("x86/tdx: Drop flags from __tdx_hypercall()") removed that "pop %rsi" +but forgot to add the "xor %rsi, %rsi" back. + +Fix by adding it back. + +Fixes: 7a3a401874be ("x86/tdx: Drop flags from __tdx_hypercall()") +Signed-off-by: Kai Huang +Signed-off-by: Dave Hansen +Reviewed-by: Kuppuswamy Sathyanarayanan +Reviewed-by: Kirill A. Shutemov +Acked-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/all/e7d1157074a0b45d34564d5f17f3e0ffee8115e9.1692096753.git.kai.huang%40intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/coco/tdx/tdcall.S | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/x86/coco/tdx/tdcall.S b/arch/x86/coco/tdx/tdcall.S +index b193c0a1d8db3..2eca5f43734fe 100644 +--- a/arch/x86/coco/tdx/tdcall.S ++++ b/arch/x86/coco/tdx/tdcall.S +@@ -195,6 +195,7 @@ SYM_FUNC_END(__tdx_module_call) + xor %r10d, %r10d + xor %r11d, %r11d + xor %rdi, %rdi ++ xor %rsi, %rsi + xor %rdx, %rdx + + /* Restore callee-saved GPRs as mandated by the x86_64 ABI */ +-- +2.42.0 + diff --git a/queue-6.6/xen-irqfd-use-_iow-instead-of-the-internal-_ioc-macr.patch b/queue-6.6/xen-irqfd-use-_iow-instead-of-the-internal-_ioc-macr.patch new file mode 100644 index 00000000000..f45f018fc38 --- /dev/null +++ b/queue-6.6/xen-irqfd-use-_iow-instead-of-the-internal-_ioc-macr.patch @@ -0,0 +1,43 @@ +From 5b21487ac074610bb26f5563b008051756e85a9c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Oct 2023 12:41:25 +0530 +Subject: xen: irqfd: Use _IOW instead of the internal _IOC() macro + +From: Viresh Kumar + +[ Upstream commit 767e33ca47dd8ace7769e0b0c19d7b0c38b2f72d ] + +_IOC() an internal helper that we should not use in driver code. In +particular, we got the data direction wrong here, which breaks a number +of tools, as having "_IOC_NONE" should never be paired with a nonzero +size. + +Use _IOW() instead. + +Fixes: f8941e6c4c71 ("xen: privcmd: Add support for irqfd") +Reported-by: Arnd Bergmann +Closes: https://lore.kernel.org/all/268a2031-63b8-4c7d-b1e5-8ab83ca80b4a@app.fastmail.com/ +Signed-off-by: Viresh Kumar +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/599ca6f1b9dd2f0e6247ea37bee3ea6827404b6d.1697439990.git.viresh.kumar@linaro.org +Signed-off-by: Juergen Gross +Signed-off-by: Sasha Levin +--- + include/uapi/xen/privcmd.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/uapi/xen/privcmd.h b/include/uapi/xen/privcmd.h +index b143fafce84db..e145bca5105c5 100644 +--- a/include/uapi/xen/privcmd.h ++++ b/include/uapi/xen/privcmd.h +@@ -138,6 +138,6 @@ struct privcmd_irqfd { + #define IOCTL_PRIVCMD_MMAP_RESOURCE \ + _IOC(_IOC_NONE, 'P', 7, sizeof(struct privcmd_mmap_resource)) + #define IOCTL_PRIVCMD_IRQFD \ +- _IOC(_IOC_NONE, 'P', 8, sizeof(struct privcmd_irqfd)) ++ _IOW('P', 8, struct privcmd_irqfd) + + #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */ +-- +2.42.0 + diff --git a/queue-6.6/xen-make-struct-privcmd_irqfd-s-layout-architecture-.patch b/queue-6.6/xen-make-struct-privcmd_irqfd-s-layout-architecture-.patch new file mode 100644 index 00000000000..e660b71135a --- /dev/null +++ b/queue-6.6/xen-make-struct-privcmd_irqfd-s-layout-architecture-.patch @@ -0,0 +1,57 @@ +From 96c36db91ec56440ead2425281c12c6dcaffff2e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Oct 2023 12:41:24 +0530 +Subject: xen: Make struct privcmd_irqfd's layout architecture independent + +From: Viresh Kumar + +[ Upstream commit 8dd765a5d769c521d73931850d1c8708fbc490cb ] + +Using indirect pointers in an ioctl command argument means that the +layout is architecture specific, in particular we can't use the same one +from 32-bit compat tasks. The general recommendation is to have __u64 +members and use u64_to_user_ptr() to access it from the kernel if we are +unable to avoid the pointers altogether. + +Fixes: f8941e6c4c71 ("xen: privcmd: Add support for irqfd") +Reported-by: Arnd Bergmann +Closes: https://lore.kernel.org/all/268a2031-63b8-4c7d-b1e5-8ab83ca80b4a@app.fastmail.com/ +Signed-off-by: Viresh Kumar +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/a4ef0d4a68fc858b34a81fd3f9877d9b6898eb77.1697439990.git.viresh.kumar@linaro.org +Signed-off-by: Juergen Gross +Signed-off-by: Sasha Levin +--- + drivers/xen/privcmd.c | 2 +- + include/uapi/xen/privcmd.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c +index f00ad5f5f1d4a..da88173bac432 100644 +--- a/drivers/xen/privcmd.c ++++ b/drivers/xen/privcmd.c +@@ -935,7 +935,7 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd) + return -ENOMEM; + dm_op = kirqfd + 1; + +- if (copy_from_user(dm_op, irqfd->dm_op, irqfd->size)) { ++ if (copy_from_user(dm_op, u64_to_user_ptr(irqfd->dm_op), irqfd->size)) { + ret = -EFAULT; + goto error_kfree; + } +diff --git a/include/uapi/xen/privcmd.h b/include/uapi/xen/privcmd.h +index 375718ba4ab62..b143fafce84db 100644 +--- a/include/uapi/xen/privcmd.h ++++ b/include/uapi/xen/privcmd.h +@@ -102,7 +102,7 @@ struct privcmd_mmap_resource { + #define PRIVCMD_IRQFD_FLAG_DEASSIGN (1 << 0) + + struct privcmd_irqfd { +- void __user *dm_op; ++ __u64 dm_op; + __u32 size; /* Size of structure pointed by dm_op */ + __u32 fd; + __u32 flags; +-- +2.42.0 + diff --git a/queue-6.6/xen-pciback-consider-intx-disabled-when-msi-msi-x-is.patch b/queue-6.6/xen-pciback-consider-intx-disabled-when-msi-msi-x-is.patch new file mode 100644 index 00000000000..eee7fc6e046 --- /dev/null +++ b/queue-6.6/xen-pciback-consider-intx-disabled-when-msi-msi-x-is.patch @@ -0,0 +1,131 @@ +From 1b0219e9be0ec9e100ee09701a34ef41abea771e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Oct 2023 15:13:25 +0200 +Subject: xen-pciback: Consider INTx disabled when MSI/MSI-X is enabled +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Marek Marczykowski-Górecki + +[ Upstream commit 2c269f42d0f382743ab230308b836ffe5ae9b2ae ] + +Linux enables MSI-X before disabling INTx, but keeps MSI-X masked until +the table is filled. Then it disables INTx just before clearing MASKALL +bit. Currently this approach is rejected by xen-pciback. +According to the PCIe spec, device cannot use INTx when MSI/MSI-X is +enabled (in other words: enabling MSI/MSI-X implicitly disables INTx). + +Change the logic to consider INTx disabled if MSI/MSI-X is enabled. This +applies to three places: + - checking currently enabled interrupts type, + - transition to MSI/MSI-X - where INTx would be implicitly disabled, + - clearing INTx disable bit - which can be allowed even if MSI/MSI-X is + enabled, as device should consider INTx disabled anyway in that case + +Fixes: 5e29500eba2a ("xen-pciback: Allow setting PCI_MSIX_FLAGS_MASKALL too") +Signed-off-by: Marek Marczykowski-Górecki +Acked-by: Juergen Gross +Link: https://lore.kernel.org/r/20231016131348.1734721-1-marmarek@invisiblethingslab.com +Signed-off-by: Juergen Gross +Signed-off-by: Sasha Levin +--- + drivers/xen/xen-pciback/conf_space.c | 19 +++++++++++------ + .../xen/xen-pciback/conf_space_capability.c | 8 ++++++- + drivers/xen/xen-pciback/conf_space_header.c | 21 +++---------------- + 3 files changed, 23 insertions(+), 25 deletions(-) + +diff --git a/drivers/xen/xen-pciback/conf_space.c b/drivers/xen/xen-pciback/conf_space.c +index 059de92aea7d0..d47eee6c51435 100644 +--- a/drivers/xen/xen-pciback/conf_space.c ++++ b/drivers/xen/xen-pciback/conf_space.c +@@ -288,12 +288,6 @@ int xen_pcibk_get_interrupt_type(struct pci_dev *dev) + u16 val; + int ret = 0; + +- err = pci_read_config_word(dev, PCI_COMMAND, &val); +- if (err) +- return err; +- if (!(val & PCI_COMMAND_INTX_DISABLE)) +- ret |= INTERRUPT_TYPE_INTX; +- + /* + * Do not trust dev->msi(x)_enabled here, as enabling could be done + * bypassing the pci_*msi* functions, by the qemu. +@@ -316,6 +310,19 @@ int xen_pcibk_get_interrupt_type(struct pci_dev *dev) + if (val & PCI_MSIX_FLAGS_ENABLE) + ret |= INTERRUPT_TYPE_MSIX; + } ++ ++ /* ++ * PCIe spec says device cannot use INTx if MSI/MSI-X is enabled, ++ * so check for INTx only when both are disabled. ++ */ ++ if (!ret) { ++ err = pci_read_config_word(dev, PCI_COMMAND, &val); ++ if (err) ++ return err; ++ if (!(val & PCI_COMMAND_INTX_DISABLE)) ++ ret |= INTERRUPT_TYPE_INTX; ++ } ++ + return ret ?: INTERRUPT_TYPE_NONE; + } + +diff --git a/drivers/xen/xen-pciback/conf_space_capability.c b/drivers/xen/xen-pciback/conf_space_capability.c +index 097316a741268..1948a9700c8fa 100644 +--- a/drivers/xen/xen-pciback/conf_space_capability.c ++++ b/drivers/xen/xen-pciback/conf_space_capability.c +@@ -236,10 +236,16 @@ static int msi_msix_flags_write(struct pci_dev *dev, int offset, u16 new_value, + return PCIBIOS_SET_FAILED; + + if (new_value & field_config->enable_bit) { +- /* don't allow enabling together with other interrupt types */ ++ /* ++ * Don't allow enabling together with other interrupt type, but do ++ * allow enabling MSI(-X) while INTx is still active to please Linuxes ++ * MSI(-X) startup sequence. It is safe to do, as according to PCI ++ * spec, device with enabled MSI(-X) shouldn't use INTx. ++ */ + int int_type = xen_pcibk_get_interrupt_type(dev); + + if (int_type == INTERRUPT_TYPE_NONE || ++ int_type == INTERRUPT_TYPE_INTX || + int_type == field_config->int_type) + goto write; + return PCIBIOS_SET_FAILED; +diff --git a/drivers/xen/xen-pciback/conf_space_header.c b/drivers/xen/xen-pciback/conf_space_header.c +index 981435103af1a..fc03326459664 100644 +--- a/drivers/xen/xen-pciback/conf_space_header.c ++++ b/drivers/xen/xen-pciback/conf_space_header.c +@@ -104,24 +104,9 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data) + pci_clear_mwi(dev); + } + +- if (dev_data && dev_data->allow_interrupt_control) { +- if ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE) { +- if (value & PCI_COMMAND_INTX_DISABLE) { +- pci_intx(dev, 0); +- } else { +- /* Do not allow enabling INTx together with MSI or MSI-X. */ +- switch (xen_pcibk_get_interrupt_type(dev)) { +- case INTERRUPT_TYPE_NONE: +- pci_intx(dev, 1); +- break; +- case INTERRUPT_TYPE_INTX: +- break; +- default: +- return PCIBIOS_SET_FAILED; +- } +- } +- } +- } ++ if (dev_data && dev_data->allow_interrupt_control && ++ ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE)) ++ pci_intx(dev, !(value & PCI_COMMAND_INTX_DISABLE)); + + cmd->val = value; + +-- +2.42.0 + diff --git a/queue-6.6/xenbus-fix-error-exit-in-xenbus_init.patch b/queue-6.6/xenbus-fix-error-exit-in-xenbus_init.patch new file mode 100644 index 00000000000..e28c7756892 --- /dev/null +++ b/queue-6.6/xenbus-fix-error-exit-in-xenbus_init.patch @@ -0,0 +1,43 @@ +From bf7dd28823e07eaec0dda1a71b9694ebba700153 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Aug 2023 11:11:38 +0200 +Subject: xenbus: fix error exit in xenbus_init() + +From: Juergen Gross + +[ Upstream commit 44961b81a9e9059b5c0443643915386db7035227 ] + +In case an error occurs in xenbus_init(), xen_store_domain_type should +be set to XS_UNKNOWN. + +Fix one instance where this action is missing. + +Fixes: 5b3353949e89 ("xen: add support for initializing xenstore later as HVM domain") +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Link: https://lore.kernel.org/r/202304200845.w7m4kXZr-lkp@intel.com/ +Signed-off-by: Juergen Gross +Reviewed-by: Oleksandr Tyshchenko +Link: https://lore.kernel.org/r/20230822091138.4765-1-jgross@suse.com +Signed-off-by: Juergen Gross +Signed-off-by: Sasha Levin +--- + drivers/xen/xenbus/xenbus_probe.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c +index 639bf628389ba..3205e5d724c8c 100644 +--- a/drivers/xen/xenbus/xenbus_probe.c ++++ b/drivers/xen/xenbus/xenbus_probe.c +@@ -1025,7 +1025,7 @@ static int __init xenbus_init(void) + if (err < 0) { + pr_err("xenstore_late_init couldn't bind irq err=%d\n", + err); +- return err; ++ goto out_error; + } + + xs_init_irq = err; +-- +2.42.0 + diff --git a/queue-6.6/xhci-loosen-rpm-as-default-policy-to-cover-for-amd-x.patch b/queue-6.6/xhci-loosen-rpm-as-default-policy-to-cover-for-amd-x.patch new file mode 100644 index 00000000000..29f8bc81beb --- /dev/null +++ b/queue-6.6/xhci-loosen-rpm-as-default-policy-to-cover-for-amd-x.patch @@ -0,0 +1,47 @@ +From ddd4b753f2fa5cb49474203d10e39cbcdbaac8e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Oct 2023 13:29:19 +0300 +Subject: xhci: Loosen RPM as default policy to cover for AMD xHC 1.1 + +From: Basavaraj Natikar + +[ Upstream commit 4baf1218150985ee3ab0a27220456a1f027ea0ac ] + +The AMD USB host controller (1022:43f7) isn't going into PCI D3 by default +without anything connected. This is because the policy that was introduced +by commit a611bf473d1f ("xhci-pci: Set runtime PM as default policy on all +xHC 1.2 or later devices") only covered 1.2 or later. + +The 1.1 specification also has the same requirement as the 1.2 +specification for D3 support. So expand the runtime PM as default policy +to all AMD 1.1 devices as well. + +Fixes: a611bf473d1f ("xhci-pci: Set runtime PM as default policy on all xHC 1.2 or later devices") +Link: https://composter.com.ua/documents/xHCI_Specification_for_USB.pdf +Co-developed-by: Mario Limonciello +Signed-off-by: Mario Limonciello +Signed-off-by: Basavaraj Natikar +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20231019102924.2797346-15-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/host/xhci-pci.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index b9ae5c2a25275..bde43cef8846c 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -535,6 +535,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + /* xHC spec requires PCI devices to support D3hot and D3cold */ + if (xhci->hci_version >= 0x120) + xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; ++ else if (pdev->vendor == PCI_VENDOR_ID_AMD && xhci->hci_version >= 0x110) ++ xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; + + if (xhci->quirks & XHCI_RESET_ON_RESUME) + xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, +-- +2.42.0 +