From: Sasha Levin Date: Sun, 25 Dec 2022 03:33:07 +0000 (-0500) Subject: Fixes for 6.0 X-Git-Tag: v5.15.86~81 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ef51eca5ab7e3fda4b65dc55f1b6f9ee0919bba3;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.0 Signed-off-by: Sasha Levin --- diff --git a/queue-6.0/acct-fix-potential-integer-overflow-in-encode_comp_t.patch b/queue-6.0/acct-fix-potential-integer-overflow-in-encode_comp_t.patch new file mode 100644 index 00000000000..a32f0579b7c --- /dev/null +++ b/queue-6.0/acct-fix-potential-integer-overflow-in-encode_comp_t.patch @@ -0,0 +1,51 @@ +From 1ef37deda985778884417708a3fe680eb45d7682 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 May 2021 22:06:31 +0800 +Subject: acct: fix potential integer overflow in encode_comp_t() + +From: Zheng Yejian + +[ Upstream commit c5f31c655bcc01b6da53b836ac951c1556245305 ] + +The integer overflow is descripted with following codes: + > 317 static comp_t encode_comp_t(u64 value) + > 318 { + > 319 int exp, rnd; + ...... + > 341 exp <<= MANTSIZE; + > 342 exp += value; + > 343 return exp; + > 344 } + +Currently comp_t is defined as type of '__u16', but the variable 'exp' is +type of 'int', so overflow would happen when variable 'exp' in line 343 is +greater than 65535. + +Link: https://lkml.kernel.org/r/20210515140631.369106-3-zhengyejian1@huawei.com +Signed-off-by: Zheng Yejian +Cc: Hanjun Guo +Cc: Randy Dunlap +Cc: Vlastimil Babka +Cc: Zhang Jinhao +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + kernel/acct.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/kernel/acct.c b/kernel/acct.c +index 13706356ec54..67bde1633d8f 100644 +--- a/kernel/acct.c ++++ b/kernel/acct.c +@@ -350,6 +350,8 @@ static comp_t encode_comp_t(unsigned long value) + exp++; + } + ++ if (exp > (((comp_t) ~0U) >> MANTSIZE)) ++ return (comp_t) ~0U; + /* + * Clean it up and polish it off. + */ +-- +2.35.1 + diff --git a/queue-6.0/acpi-ec-add-quirk-for-the-hp-pavilion-gaming-15-cx00.patch b/queue-6.0/acpi-ec-add-quirk-for-the-hp-pavilion-gaming-15-cx00.patch new file mode 100644 index 00000000000..bc9556ce0c4 --- /dev/null +++ b/queue-6.0/acpi-ec-add-quirk-for-the-hp-pavilion-gaming-15-cx00.patch @@ -0,0 +1,46 @@ +From a6b61f8ffe0a55e0ca548f4d2d24824ce792dff3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 30 Oct 2022 01:20:08 +0300 +Subject: ACPI: EC: Add quirk for the HP Pavilion Gaming 15-cx0041ur + +From: Mia Kanashi + +[ Upstream commit b423f240a66ad928c4cb5ec6055dfc90ce8d894e ] + +Added GPE quirk entry for the HP Pavilion Gaming 15-cx0041ur. +There is a quirk entry for the 15-cx0xxx laptops, but this one has +different DMI_PRODUCT_NAME. + +Notably backlight keys and other ACPI events now function correctly. + +Signed-off-by: Mia Kanashi +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/ec.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c +index c95e535035a0..fdc760e1e09e 100644 +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -1879,6 +1879,16 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = { + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-cx0xxx"), + }, + }, ++ { ++ /* ++ * HP Pavilion Gaming Laptop 15-cx0041ur ++ */ ++ .callback = ec_honor_dsdt_gpe, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "HP"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "HP 15-cx0041ur"), ++ }, ++ }, + { + /* + * Samsung hardware +-- +2.35.1 + diff --git a/queue-6.0/acpi-irq-fix-some-kernel-doc-issues.patch b/queue-6.0/acpi-irq-fix-some-kernel-doc-issues.patch new file mode 100644 index 00000000000..1c7948bd561 --- /dev/null +++ b/queue-6.0/acpi-irq-fix-some-kernel-doc-issues.patch @@ -0,0 +1,53 @@ +From 2d9d366372e0737a7d79681dffc47286850cd38f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Nov 2022 09:46:23 +0800 +Subject: ACPI: irq: Fix some kernel-doc issues + +From: Xiongfeng Wang + +[ Upstream commit ebb92d58b90753e658059f5d8590d9048395491a ] + +The following commit change the second parameter of acpi_set_irq_model() +but forgot to update the function description. Let's fix it. + + commit 7327b16f5f56 ("APCI: irq: Add support for multiple GSI domains") + +Also add description of parameter 'gsi' for +acpi_get_irq_source_fwhandle() to avoid the following build W=1 warning. + + drivers/acpi/irq.c:108: warning: Function parameter or member 'gsi' not described in 'acpi_get_irq_source_fwhandle' + +Fixes: 7327b16f5f56 ("APCI: irq: Add support for multiple GSI domains") +Signed-off-by: Xiongfeng Wang +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/irq.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c +index dabe45eba055..0d9a17fdd83e 100644 +--- a/drivers/acpi/irq.c ++++ b/drivers/acpi/irq.c +@@ -94,6 +94,7 @@ EXPORT_SYMBOL_GPL(acpi_unregister_gsi); + /** + * acpi_get_irq_source_fwhandle() - Retrieve fwhandle from IRQ resource source. + * @source: acpi_resource_source to use for the lookup. ++ * @gsi: GSI IRQ number + * + * Description: + * Retrieve the fwhandle of the device referenced by the given IRQ resource +@@ -295,8 +296,8 @@ EXPORT_SYMBOL_GPL(acpi_irq_get); + /** + * acpi_set_irq_model - Setup the GSI irqdomain information + * @model: the value assigned to acpi_irq_model +- * @fwnode: the irq_domain identifier for mapping and looking up +- * GSI interrupts ++ * @fn: a dispatcher function that will return the domain fwnode ++ * for a given GSI + */ + void __init acpi_set_irq_model(enum acpi_irq_model_id model, + struct fwnode_handle *(*fn)(u32)) +-- +2.35.1 + diff --git a/queue-6.0/acpi-pfr_telemetry-use-acpi_free-to-free-acpi_object.patch b/queue-6.0/acpi-pfr_telemetry-use-acpi_free-to-free-acpi_object.patch new file mode 100644 index 00000000000..6a210860f33 --- /dev/null +++ b/queue-6.0/acpi-pfr_telemetry-use-acpi_free-to-free-acpi_object.patch @@ -0,0 +1,57 @@ +From 188a1e4ae5b9ad6ddd3d1913fa66c4691193f394 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Nov 2022 14:32:18 +0800 +Subject: ACPI: pfr_telemetry: use ACPI_FREE() to free acpi_object + +From: Wang ShaoBo + +[ Upstream commit 0f2aa7fc2a9aee05bafb965d5b1638d3e74b4c61 ] + +acpi_evaluate_dsm_typed()/acpi_evaluate_dsm() should be coupled +with ACPI_FREE() to free the ACPI memory, because we need to +track the allocation of acpi_object when ACPI_DBG_TRACK_ALLOCATIONS +enabled, so use ACPI_FREE() instead of kfree(). + +Fixes: b0013e037a8b ("ACPI: Introduce Platform Firmware Runtime Telemetry driver") +Signed-off-by: Wang ShaoBo +Reviewed-by: Chen Yu +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/pfr_telemetry.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/acpi/pfr_telemetry.c b/drivers/acpi/pfr_telemetry.c +index 9abf350bd7a5..27fb6cdad75f 100644 +--- a/drivers/acpi/pfr_telemetry.c ++++ b/drivers/acpi/pfr_telemetry.c +@@ -144,7 +144,7 @@ static int get_pfrt_log_data_info(struct pfrt_log_data_info *data_info, + ret = 0; + + free_acpi_buffer: +- kfree(out_obj); ++ ACPI_FREE(out_obj); + + return ret; + } +@@ -180,7 +180,7 @@ static int set_pfrt_log_level(int level, struct pfrt_log_device *pfrt_log_dev) + ret = -EBUSY; + } + +- kfree(out_obj); ++ ACPI_FREE(out_obj); + + return ret; + } +@@ -218,7 +218,7 @@ static int get_pfrt_log_level(struct pfrt_log_device *pfrt_log_dev) + ret = obj->integer.value; + + free_acpi_buffer: +- kfree(out_obj); ++ ACPI_FREE(out_obj); + + return ret; + } +-- +2.35.1 + diff --git a/queue-6.0/acpi-pfr_update-use-acpi_free-to-free-acpi_object.patch b/queue-6.0/acpi-pfr_update-use-acpi_free-to-free-acpi_object.patch new file mode 100644 index 00000000000..e485ac2e47d --- /dev/null +++ b/queue-6.0/acpi-pfr_update-use-acpi_free-to-free-acpi_object.patch @@ -0,0 +1,57 @@ +From a212f71f06873c04bb75328c56be29536592dc1f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Nov 2022 14:32:19 +0800 +Subject: ACPI: pfr_update: use ACPI_FREE() to free acpi_object + +From: Wang ShaoBo + +[ Upstream commit e335beed78ec82656dcb554f9fe560709f0dc408 ] + +acpi_evaluate_dsm_typed()/acpi_evaluate_dsm() should be coupled with +ACPI_FREE() to free the ACPI memory, because we need to track the +allocation of acpi_object when ACPI_DBG_TRACK_ALLOCATIONS enabled, +so use ACPI_FREE() instead of kfree(). + +Fixes: 0db89fa243e5 ("ACPI: Introduce Platform Firmware Runtime Update device driver") +Signed-off-by: Wang ShaoBo +Reviewed-by: Chen Yu +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/pfr_update.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/acpi/pfr_update.c b/drivers/acpi/pfr_update.c +index 6bb0b778b5da..9d2bdc13253a 100644 +--- a/drivers/acpi/pfr_update.c ++++ b/drivers/acpi/pfr_update.c +@@ -178,7 +178,7 @@ static int query_capability(struct pfru_update_cap_info *cap_hdr, + ret = 0; + + free_acpi_buffer: +- kfree(out_obj); ++ ACPI_FREE(out_obj); + + return ret; + } +@@ -224,7 +224,7 @@ static int query_buffer(struct pfru_com_buf_info *info, + ret = 0; + + free_acpi_buffer: +- kfree(out_obj); ++ ACPI_FREE(out_obj); + + return ret; + } +@@ -385,7 +385,7 @@ static int start_update(int action, struct pfru_device *pfru_dev) + ret = 0; + + free_acpi_buffer: +- kfree(out_obj); ++ ACPI_FREE(out_obj); + + return ret; + } +-- +2.35.1 + diff --git a/queue-6.0/acpi-processor-idle-check-acpi_fetch_acpi_dev-return.patch b/queue-6.0/acpi-processor-idle-check-acpi_fetch_acpi_dev-return.patch new file mode 100644 index 00000000000..770bb04b948 --- /dev/null +++ b/queue-6.0/acpi-processor-idle-check-acpi_fetch_acpi_dev-return.patch @@ -0,0 +1,37 @@ +From 4d4d6652d3a41a23e87447ba3b13deb4a581b581 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Sep 2022 00:37:30 -0700 +Subject: ACPI: processor: idle: Check acpi_fetch_acpi_dev() return value + +From: Li Zhong + +[ Upstream commit 2437513a814b3e93bd02879740a8a06e52e2cf7d ] + +The return value of acpi_fetch_acpi_dev() could be NULL, which would +cause a NULL pointer dereference to occur in acpi_device_hid(). + +Signed-off-by: Li Zhong +[ rjw: Subject and changelog edits, added empty line after if () ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/processor_idle.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c +index 9f40917c49ef..4d1dd255c122 100644 +--- a/drivers/acpi/processor_idle.c ++++ b/drivers/acpi/processor_idle.c +@@ -1134,6 +1134,9 @@ static int acpi_processor_get_lpi_info(struct acpi_processor *pr) + status = acpi_get_parent(handle, &pr_ahandle); + while (ACPI_SUCCESS(status)) { + d = acpi_fetch_acpi_dev(pr_ahandle); ++ if (!d) ++ break; ++ + handle = pr_ahandle; + + if (strcmp(acpi_device_hid(d), ACPI_PROCESSOR_CONTAINER_HID)) +-- +2.35.1 + diff --git a/queue-6.0/acpi-x86-add-skip-i2c-clients-quirk-for-lenovo-yoga-.patch b/queue-6.0/acpi-x86-add-skip-i2c-clients-quirk-for-lenovo-yoga-.patch new file mode 100644 index 00000000000..3ca46128549 --- /dev/null +++ b/queue-6.0/acpi-x86-add-skip-i2c-clients-quirk-for-lenovo-yoga-.patch @@ -0,0 +1,72 @@ +From 90e40d23c734df91cedaa911f06b0a86eaa2ee16 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 27 Nov 2022 19:24:03 +0100 +Subject: ACPI: x86: Add skip i2c clients quirk for Lenovo Yoga Tab 3 Pro + (YT3-X90F) + +From: Hans de Goede + +[ Upstream commit fe820db35275561d8bf86ad19044d40ffc95bc04 ] + +The Lenovo Yoga Tab 3 Pro (YT3-X90F) is a x86 (Cherry Trail) tablet which +ships with Android x86 as factory OS. The Android x86 kernel fork ignores +I2C devices described in the DSDT, except for the PMIC and Audio codecs. + +As usual the Lenovo Yoga Tab 3 Pro's DSDT contains a bunch of extra I2C +devices which are not actually there, causing various resource conflicts. +Add an ACPI_QUIRK_SKIP_I2C_CLIENTS quirk for the Lenovo Yoga Tab 3 Pro to +the acpi_quirk_skip_dmi_ids table to woraround this. + +ACPI_QUIRK_SKIP_I2C_CLIENTS handling uses i2c_acpi_known_good_ids[], +so that PMICs and Audio codecs will still be enumerated properly. +The Lenovo Yoga Tab 3 Pro uses a Whiskey Cove PMIC, add the INT34D3 HID +for this PMIC to the i2c_acpi_known_good_ids[] list. + +Signed-off-by: Hans de Goede +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/x86/utils.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c +index 950a93922ca8..fb999597a3f0 100644 +--- a/drivers/acpi/x86/utils.c ++++ b/drivers/acpi/x86/utils.c +@@ -308,7 +308,7 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = { + ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), + }, + { +- /* Lenovo Yoga Tablet 1050F/L */ ++ /* Lenovo Yoga Tablet 2 1050F/L */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."), + DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"), +@@ -319,6 +319,16 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = { + .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | + ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), + }, ++ { ++ /* Lenovo Yoga Tab 3 Pro X90F */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"), ++ }, ++ .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | ++ ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), ++ }, + { + /* Nextbook Ares 8 */ + .matches = { +@@ -348,6 +358,7 @@ static const struct acpi_device_id i2c_acpi_known_good_ids[] = { + { "10EC5640", 0 }, /* RealTek ALC5640 audio codec */ + { "INT33F4", 0 }, /* X-Powers AXP288 PMIC */ + { "INT33FD", 0 }, /* Intel Crystal Cove PMIC */ ++ { "INT34D3", 0 }, /* Intel Whiskey Cove PMIC */ + { "NPCE69A", 0 }, /* Asus Transformer keyboard dock */ + {} + }; +-- +2.35.1 + diff --git a/queue-6.0/acpi-x86-add-skip-i2c-clients-quirk-for-medion-lifet.patch b/queue-6.0/acpi-x86-add-skip-i2c-clients-quirk-for-medion-lifet.patch new file mode 100644 index 00000000000..6049abed891 --- /dev/null +++ b/queue-6.0/acpi-x86-add-skip-i2c-clients-quirk-for-medion-lifet.patch @@ -0,0 +1,51 @@ +From 15be295b9d34aa69d052d63920b20240f361c707 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Dec 2022 12:02:02 +0100 +Subject: ACPI: x86: Add skip i2c clients quirk for Medion Lifetab S10346 + +From: Hans de Goede + +[ Upstream commit ecc6aaabcedc276128315f57755364106017c606 ] + +The Medion Lifetab S10346 is a x86 tablet which ships with Android x86 as +factory OS. The Android x86 kernel fork ignores I2C devices described in +the DSDT, except for the PMIC and Audio codecs. + +As usual the Medion Lifetab S10346's DSDT contains a bunch of extra I2C +devices which are not actually there, causing various resource conflicts. +Add an ACPI_QUIRK_SKIP_I2C_CLIENTS quirk for the Medion Lifetab S10346 to +the acpi_quirk_skip_dmi_ids table to woraround this. + +Signed-off-by: Hans de Goede +Reviewed-by: Andy Shevchenko +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/x86/utils.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c +index fb999597a3f0..ae60e4aae0ee 100644 +--- a/drivers/acpi/x86/utils.c ++++ b/drivers/acpi/x86/utils.c +@@ -329,6 +329,17 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = { + .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | + ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), + }, ++ { ++ /* Medion Lifetab S10346 */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), ++ DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), ++ /* Way too generic, also match on BIOS data */ ++ DMI_MATCH(DMI_BIOS_DATE, "10/22/2015"), ++ }, ++ .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | ++ ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), ++ }, + { + /* Nextbook Ares 8 */ + .matches = { +-- +2.35.1 + diff --git a/queue-6.0/acpica-fix-error-code-path-in-acpi_ds_call_control_m.patch b/queue-6.0/acpica-fix-error-code-path-in-acpi_ds_call_control_m.patch new file mode 100644 index 00000000000..484f8bb1eb2 --- /dev/null +++ b/queue-6.0/acpica-fix-error-code-path-in-acpi_ds_call_control_m.patch @@ -0,0 +1,68 @@ +From 7d1503f178bd7becb0fb9268cd4bebc7f895290e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Nov 2022 18:42:36 +0100 +Subject: ACPICA: Fix error code path in acpi_ds_call_control_method() + +From: Rafael J. Wysocki + +[ Upstream commit 404ec60438add1afadaffaed34bb5fe4ddcadd40 ] + +A use-after-free in acpi_ps_parse_aml() after a failing invocaion of +acpi_ds_call_control_method() is reported by KASAN [1] and code +inspection reveals that next_walk_state pushed to the thread by +acpi_ds_create_walk_state() is freed on errors, but it is not popped +from the thread beforehand. Thus acpi_ds_get_current_walk_state() +called by acpi_ps_parse_aml() subsequently returns it as the new +walk state which is incorrect. + +To address this, make acpi_ds_call_control_method() call +acpi_ds_pop_walk_state() to pop next_walk_state from the thread before +returning an error. + +Link: https://lore.kernel.org/linux-acpi/20221019073443.248215-1-chenzhongjin@huawei.com/ # [1] +Reported-by: Chen Zhongjin +Signed-off-by: Rafael J. Wysocki +Reviewed-by: Chen Zhongjin +Signed-off-by: Sasha Levin +--- + drivers/acpi/acpica/dsmethod.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c +index ae2e768830bf..9332bc688713 100644 +--- a/drivers/acpi/acpica/dsmethod.c ++++ b/drivers/acpi/acpica/dsmethod.c +@@ -517,7 +517,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, + info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); + if (!info) { + status = AE_NO_MEMORY; +- goto cleanup; ++ goto pop_walk_state; + } + + info->parameters = &this_walk_state->operands[0]; +@@ -529,7 +529,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, + + ACPI_FREE(info); + if (ACPI_FAILURE(status)) { +- goto cleanup; ++ goto pop_walk_state; + } + + next_walk_state->method_nesting_depth = +@@ -575,6 +575,12 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, + + return_ACPI_STATUS(status); + ++pop_walk_state: ++ ++ /* On error, pop the walk state to be deleted from thread */ ++ ++ acpi_ds_pop_walk_state(thread); ++ + cleanup: + + /* On error, we must terminate the method properly */ +-- +2.35.1 + diff --git a/queue-6.0/acpica-fix-use-after-free-in-acpi_ut_copy_ipackage_t.patch b/queue-6.0/acpica-fix-use-after-free-in-acpi_ut_copy_ipackage_t.patch new file mode 100644 index 00000000000..52c67a5c44d --- /dev/null +++ b/queue-6.0/acpica-fix-use-after-free-in-acpi_ut_copy_ipackage_t.patch @@ -0,0 +1,70 @@ +From 5278ccbbacef3a97ca9b08805bc49fc30c8224a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Dec 2022 16:05:14 +0800 +Subject: ACPICA: Fix use-after-free in acpi_ut_copy_ipackage_to_ipackage() + +From: Li Zetao + +[ Upstream commit 470188b09e92d83c5a997f25f0e8fb8cd2bc3469 ] + +There is an use-after-free reported by KASAN: + + BUG: KASAN: use-after-free in acpi_ut_remove_reference+0x3b/0x82 + Read of size 1 at addr ffff888112afc460 by task modprobe/2111 + CPU: 0 PID: 2111 Comm: modprobe Not tainted 6.1.0-rc7-dirty + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), + Call Trace: + + kasan_report+0xae/0xe0 + acpi_ut_remove_reference+0x3b/0x82 + acpi_ut_copy_iobject_to_iobject+0x3be/0x3d5 + acpi_ds_store_object_to_local+0x15d/0x3a0 + acpi_ex_store+0x78d/0x7fd + acpi_ex_opcode_1A_1T_1R+0xbe4/0xf9b + acpi_ps_parse_aml+0x217/0x8d5 + ... + + +The root cause of the problem is that the acpi_operand_object +is freed when acpi_ut_walk_package_tree() fails in +acpi_ut_copy_ipackage_to_ipackage(), lead to repeated release in +acpi_ut_copy_iobject_to_iobject(). The problem was introduced +by "8aa5e56eeb61" commit, this commit is to fix memory leak in +acpi_ut_copy_iobject_to_iobject(), repeatedly adding remove +operation, lead to "acpi_operand_object" used after free. + +Fix it by removing acpi_ut_remove_reference() in +acpi_ut_copy_ipackage_to_ipackage(). acpi_ut_copy_ipackage_to_ipackage() +is called to copy an internal package object into another internal +package object, when it fails, the memory of acpi_operand_object +should be freed by the caller. + +Fixes: 8aa5e56eeb61 ("ACPICA: Utilities: Fix memory leak in acpi_ut_copy_iobject_to_iobject") +Signed-off-by: Li Zetao +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/acpica/utcopy.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c +index 400b9e15a709..63c17f420fb8 100644 +--- a/drivers/acpi/acpica/utcopy.c ++++ b/drivers/acpi/acpica/utcopy.c +@@ -916,13 +916,6 @@ acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj, + status = acpi_ut_walk_package_tree(source_obj, dest_obj, + acpi_ut_copy_ielement_to_ielement, + walk_state); +- if (ACPI_FAILURE(status)) { +- +- /* On failure, delete the destination package object */ +- +- acpi_ut_remove_reference(dest_obj); +- } +- + return_ACPI_STATUS(status); + } + +-- +2.35.1 + diff --git a/queue-6.0/af_unix-call-proto_unregister-in-the-error-path-in-a.patch b/queue-6.0/af_unix-call-proto_unregister-in-the-error-path-in-a.patch new file mode 100644 index 00000000000..bd4d91920d6 --- /dev/null +++ b/queue-6.0/af_unix-call-proto_unregister-in-the-error-path-in-a.patch @@ -0,0 +1,37 @@ +From ad4af94e9662991e626efb0d45138d2a8786be8d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Dec 2022 23:01:58 +0800 +Subject: af_unix: call proto_unregister() in the error path in af_unix_init() + +From: Yang Yingliang + +[ Upstream commit 73e341e0281a35274629e9be27eae2f9b1b492bf ] + +If register unix_stream_proto returns error, unix_dgram_proto needs +be unregistered. + +Fixes: 94531cfcbe79 ("af_unix: Add unix_stream_proto for sockmap") +Signed-off-by: Yang Yingliang +Reviewed-by: Simon Horman +Reviewed-by: Kuniyuki Iwashima +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index d686804119c9..02fad8e8f4cd 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -3724,6 +3724,7 @@ static int __init af_unix_init(void) + rc = proto_register(&unix_stream_proto, 1); + if (rc != 0) { + pr_crit("%s: Cannot create unix_sock SLAB cache!\n", __func__); ++ proto_unregister(&unix_dgram_proto); + goto out; + } + +-- +2.35.1 + diff --git a/queue-6.0/alpha-fix-syscall-entry-in-audut_syscall-case.patch b/queue-6.0/alpha-fix-syscall-entry-in-audut_syscall-case.patch new file mode 100644 index 00000000000..7fbdf9af98a --- /dev/null +++ b/queue-6.0/alpha-fix-syscall-entry-in-audut_syscall-case.patch @@ -0,0 +1,40 @@ +From b91924432d94c499f2ac13aaebea40eea4ccd964 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Sep 2021 18:18:48 -0400 +Subject: alpha: fix syscall entry in !AUDUT_SYSCALL case + +From: Al Viro + +[ Upstream commit f7b2431a6d22f7a91c567708e071dfcd6d66db14 ] + +We only want to take the slow path if SYSCALL_TRACE or SYSCALL_AUDIT is +set; on !AUDIT_SYSCALL configs the current tree hits it whenever _any_ +thread flag (including NEED_RESCHED, NOTIFY_SIGNAL, etc.) happens to +be set. + +Fixes: a9302e843944 "alpha: Enable system-call auditing support" +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + arch/alpha/kernel/entry.S | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S +index e227f3a29a43..c41a5a9c3b9f 100644 +--- a/arch/alpha/kernel/entry.S ++++ b/arch/alpha/kernel/entry.S +@@ -469,8 +469,10 @@ entSys: + #ifdef CONFIG_AUDITSYSCALL + lda $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT + and $3, $6, $3 +-#endif + bne $3, strace ++#else ++ blbs $3, strace /* check for SYSCALL_TRACE in disguise */ ++#endif + beq $4, 1f + ldq $27, 0($5) + 1: jsr $26, ($27), sys_ni_syscall +-- +2.35.1 + diff --git a/queue-6.0/alpha-fix-tif_notify_signal-handling.patch b/queue-6.0/alpha-fix-tif_notify_signal-handling.patch new file mode 100644 index 00000000000..1f99824d589 --- /dev/null +++ b/queue-6.0/alpha-fix-tif_notify_signal-handling.patch @@ -0,0 +1,35 @@ +From c6141e464589b0ea68571d7feec2cd009dbd7c7e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Sep 2021 18:08:56 -0400 +Subject: alpha: fix TIF_NOTIFY_SIGNAL handling + +From: Al Viro + +[ Upstream commit e2c7554cc6d85f95e3c6635f270ec839ab9fe05e ] + +it needs to be added to _TIF_WORK_MASK, or we might not reach +do_work_pending() in the first place... + +Fixes: 5a9a8897c253a "alpha: add support for TIF_NOTIFY_SIGNAL" +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + arch/alpha/include/asm/thread_info.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h +index fdc485d7787a..084c27cb0c70 100644 +--- a/arch/alpha/include/asm/thread_info.h ++++ b/arch/alpha/include/asm/thread_info.h +@@ -75,7 +75,7 @@ register struct thread_info *__current_thread_info __asm__("$8"); + + /* Work to do on interrupt/exception return. */ + #define _TIF_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ +- _TIF_NOTIFY_RESUME) ++ _TIF_NOTIFY_RESUME | _TIF_NOTIFY_SIGNAL) + + /* Work to do on any return to userspace. */ + #define _TIF_ALLWORK_MASK (_TIF_WORK_MASK \ +-- +2.35.1 + diff --git a/queue-6.0/alsa-asihpi-fix-missing-pci_disable_device.patch b/queue-6.0/alsa-asihpi-fix-missing-pci_disable_device.patch new file mode 100644 index 00000000000..084c84ece7e --- /dev/null +++ b/queue-6.0/alsa-asihpi-fix-missing-pci_disable_device.patch @@ -0,0 +1,37 @@ +From e2fa2c13978843f6452e40991ec9296a3d27999f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Nov 2022 10:14:29 +0800 +Subject: ALSA: asihpi: fix missing pci_disable_device() + +From: Liu Shixin + +[ Upstream commit 9d86515c3d4c0564a0c31a2df87d735353a1971e ] + +pci_disable_device() need be called while module exiting, switch to use +pcim_enable(), pci_disable_device() will be called in pcim_release(). + +Fixes: 3285ea10e9b0 ("ALSA: asihpi - Interrelated HPI tidy up.") +Signed-off-by: Liu Shixin +Link: https://lore.kernel.org/r/20221126021429.3029562-1-liushixin2@huawei.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/asihpi/hpioctl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c +index bb31b7fe867d..477a5b4b50bc 100644 +--- a/sound/pci/asihpi/hpioctl.c ++++ b/sound/pci/asihpi/hpioctl.c +@@ -361,7 +361,7 @@ int asihpi_adapter_probe(struct pci_dev *pci_dev, + pci_dev->device, pci_dev->subsystem_vendor, + pci_dev->subsystem_device, pci_dev->devfn); + +- if (pci_enable_device(pci_dev) < 0) { ++ if (pcim_enable_device(pci_dev) < 0) { + dev_err(&pci_dev->dev, + "pci_enable_device failed, disabling device\n"); + return -EIO; +-- +2.35.1 + diff --git a/queue-6.0/alsa-mts64-fix-possible-null-ptr-defer-in-snd_mts64_.patch b/queue-6.0/alsa-mts64-fix-possible-null-ptr-defer-in-snd_mts64_.patch new file mode 100644 index 00000000000..0076f02c7c0 --- /dev/null +++ b/queue-6.0/alsa-mts64-fix-possible-null-ptr-defer-in-snd_mts64_.patch @@ -0,0 +1,103 @@ +From 54d56a952bdee2629f30b758be052e5979eea9f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Dec 2022 14:10:04 +0800 +Subject: ALSA: mts64: fix possible null-ptr-defer in snd_mts64_interrupt + +From: Gaosheng Cui + +[ Upstream commit cf2ea3c86ad90d63d1c572b43e1ca9276b0357ad ] + +I got a null-ptr-defer error report when I do the following tests +on the qemu platform: + +make defconfig and CONFIG_PARPORT=m, CONFIG_PARPORT_PC=m, +CONFIG_SND_MTS64=m + +Then making test scripts: +cat>test_mod1.sh< + snd_mts64_interrupt+0x24/0xa0 [snd_mts64] + parport_irq_handler+0x37/0x50 [parport] + __handle_irq_event_percpu+0x39/0x190 + handle_irq_event_percpu+0xa/0x30 + handle_irq_event+0x2f/0x50 + handle_edge_irq+0x99/0x1b0 + __common_interrupt+0x5d/0x100 + common_interrupt+0xa0/0xc0 + + + asm_common_interrupt+0x22/0x40 + RIP: 0010:_raw_write_unlock_irqrestore+0x11/0x30 + parport_claim+0xbd/0x230 [parport] + snd_mts64_probe+0x14a/0x465 [snd_mts64] + platform_probe+0x3f/0xa0 + really_probe+0x129/0x2c0 + __driver_probe_device+0x6d/0xc0 + driver_probe_device+0x1a/0xa0 + __device_attach_driver+0x7a/0xb0 + bus_for_each_drv+0x62/0xb0 + __device_attach+0xe4/0x180 + bus_probe_device+0x82/0xa0 + device_add+0x550/0x920 + platform_device_add+0x106/0x220 + snd_mts64_attach+0x2e/0x80 [snd_mts64] + port_check+0x14/0x20 [parport] + bus_for_each_dev+0x6e/0xc0 + __parport_register_driver+0x7c/0xb0 [parport] + snd_mts64_module_init+0x31/0x1000 [snd_mts64] + do_one_initcall+0x3c/0x1f0 + do_init_module+0x46/0x1c6 + load_module+0x1d8d/0x1e10 + __do_sys_finit_module+0xa2/0xf0 + do_syscall_64+0x37/0x90 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + + Kernel panic - not syncing: Fatal exception in interrupt + Rebooting in 1 seconds.. + +The mts wa not initialized during interrupt, we add check for +mts to fix this bug. + +Fixes: 68ab801e32bb ("[ALSA] Add snd-mts64 driver for ESI Miditerminal 4140") +Signed-off-by: Gaosheng Cui +Link: https://lore.kernel.org/r/20221206061004.1222966-1-cuigaosheng1@huawei.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/drivers/mts64.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c +index d3bc9e8c407d..f0d34cf70c3e 100644 +--- a/sound/drivers/mts64.c ++++ b/sound/drivers/mts64.c +@@ -815,6 +815,9 @@ static void snd_mts64_interrupt(void *private) + u8 status, data; + struct snd_rawmidi_substream *substream; + ++ if (!mts) ++ return; ++ + spin_lock(&mts->lock); + ret = mts64_read(mts->pardev->port); + data = ret & 0x00ff; +-- +2.35.1 + diff --git a/queue-6.0/alsa-pcm-fix-undefined-behavior-in-bit-shift-for-snd.patch b/queue-6.0/alsa-pcm-fix-undefined-behavior-in-bit-shift-for-snd.patch new file mode 100644 index 00000000000..323ee276f0f --- /dev/null +++ b/queue-6.0/alsa-pcm-fix-undefined-behavior-in-bit-shift-for-snd.patch @@ -0,0 +1,92 @@ +From 6c11107421e8f445870ed734b6f0f6259032684a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Nov 2022 19:00:44 +0800 +Subject: ALSA: pcm: fix undefined behavior in bit shift for + SNDRV_PCM_RATE_KNOT + +From: Baisong Zhong + +[ Upstream commit b5172e62458f8e6ff359e5f096044a488db90ac5 ] + +Shifting signed 32-bit value by 31 bits is undefined, so changing +significant bit to unsigned. The UBSAN warning calltrace like below: + +UBSAN: shift-out-of-bounds in sound/core/pcm_native.c:2676:21 +left shift of 1 by 31 places cannot be represented in type 'int' +... +Call Trace: + + dump_stack_lvl+0x8d/0xcf + ubsan_epilogue+0xa/0x44 + __ubsan_handle_shift_out_of_bounds+0x1e7/0x208 + snd_pcm_open_substream+0x9f0/0xa90 + snd_pcm_oss_open.part.26+0x313/0x670 + snd_pcm_oss_open+0x30/0x40 + soundcore_open+0x18b/0x2e0 + chrdev_open+0xe2/0x270 + do_dentry_open+0x2f7/0x620 + path_openat+0xd66/0xe70 + do_filp_open+0xe3/0x170 + do_sys_openat2+0x357/0x4a0 + do_sys_open+0x87/0xd0 + do_syscall_64+0x34/0x80 + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Baisong Zhong +Link: https://lore.kernel.org/r/20221121110044.3115686-1-zhongbaisong@huawei.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + include/sound/pcm.h | 36 ++++++++++++++++++------------------ + 1 file changed, 18 insertions(+), 18 deletions(-) + +diff --git a/include/sound/pcm.h b/include/sound/pcm.h +index 8c48a5bce88c..25695f5f795a 100644 +--- a/include/sound/pcm.h ++++ b/include/sound/pcm.h +@@ -106,24 +106,24 @@ struct snd_pcm_ops { + #define SNDRV_PCM_POS_XRUN ((snd_pcm_uframes_t)-1) + + /* If you change this don't forget to change rates[] table in pcm_native.c */ +-#define SNDRV_PCM_RATE_5512 (1<<0) /* 5512Hz */ +-#define SNDRV_PCM_RATE_8000 (1<<1) /* 8000Hz */ +-#define SNDRV_PCM_RATE_11025 (1<<2) /* 11025Hz */ +-#define SNDRV_PCM_RATE_16000 (1<<3) /* 16000Hz */ +-#define SNDRV_PCM_RATE_22050 (1<<4) /* 22050Hz */ +-#define SNDRV_PCM_RATE_32000 (1<<5) /* 32000Hz */ +-#define SNDRV_PCM_RATE_44100 (1<<6) /* 44100Hz */ +-#define SNDRV_PCM_RATE_48000 (1<<7) /* 48000Hz */ +-#define SNDRV_PCM_RATE_64000 (1<<8) /* 64000Hz */ +-#define SNDRV_PCM_RATE_88200 (1<<9) /* 88200Hz */ +-#define SNDRV_PCM_RATE_96000 (1<<10) /* 96000Hz */ +-#define SNDRV_PCM_RATE_176400 (1<<11) /* 176400Hz */ +-#define SNDRV_PCM_RATE_192000 (1<<12) /* 192000Hz */ +-#define SNDRV_PCM_RATE_352800 (1<<13) /* 352800Hz */ +-#define SNDRV_PCM_RATE_384000 (1<<14) /* 384000Hz */ +- +-#define SNDRV_PCM_RATE_CONTINUOUS (1<<30) /* continuous range */ +-#define SNDRV_PCM_RATE_KNOT (1<<31) /* supports more non-continuos rates */ ++#define SNDRV_PCM_RATE_5512 (1U<<0) /* 5512Hz */ ++#define SNDRV_PCM_RATE_8000 (1U<<1) /* 8000Hz */ ++#define SNDRV_PCM_RATE_11025 (1U<<2) /* 11025Hz */ ++#define SNDRV_PCM_RATE_16000 (1U<<3) /* 16000Hz */ ++#define SNDRV_PCM_RATE_22050 (1U<<4) /* 22050Hz */ ++#define SNDRV_PCM_RATE_32000 (1U<<5) /* 32000Hz */ ++#define SNDRV_PCM_RATE_44100 (1U<<6) /* 44100Hz */ ++#define SNDRV_PCM_RATE_48000 (1U<<7) /* 48000Hz */ ++#define SNDRV_PCM_RATE_64000 (1U<<8) /* 64000Hz */ ++#define SNDRV_PCM_RATE_88200 (1U<<9) /* 88200Hz */ ++#define SNDRV_PCM_RATE_96000 (1U<<10) /* 96000Hz */ ++#define SNDRV_PCM_RATE_176400 (1U<<11) /* 176400Hz */ ++#define SNDRV_PCM_RATE_192000 (1U<<12) /* 192000Hz */ ++#define SNDRV_PCM_RATE_352800 (1U<<13) /* 352800Hz */ ++#define SNDRV_PCM_RATE_384000 (1U<<14) /* 384000Hz */ ++ ++#define SNDRV_PCM_RATE_CONTINUOUS (1U<<30) /* continuous range */ ++#define SNDRV_PCM_RATE_KNOT (1U<<31) /* supports more non-continuos rates */ + + #define SNDRV_PCM_RATE_8000_44100 (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\ + SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|\ +-- +2.35.1 + diff --git a/queue-6.0/alsa-pcm-set-missing-stop_operating-flag-at-undoing-.patch b/queue-6.0/alsa-pcm-set-missing-stop_operating-flag-at-undoing-.patch new file mode 100644 index 00000000000..314cdfda273 --- /dev/null +++ b/queue-6.0/alsa-pcm-set-missing-stop_operating-flag-at-undoing-.patch @@ -0,0 +1,46 @@ +From ff57c342d6e4fcaad791762ddabef3d82294c1a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Dec 2022 14:21:22 +0100 +Subject: ALSA: pcm: Set missing stop_operating flag at undoing trigger start + +From: Takashi Iwai + +[ Upstream commit 5c8cc93b06d1ff860327a273abf3ac006290d242 ] + +When a PCM trigger-start fails at snd_pcm_do_start(), PCM core tries +to undo the action at snd_pcm_undo_start() by issuing the trigger STOP +manually. At that point, we forgot to set the stop_operating flag, +hence the sync-stop won't be issued at the next prepare or other +calls. + +This patch adds the missing stop_operating flag at +snd_pcm_undo_start(). + +Fixes: 1e850beea278 ("ALSA: pcm: Add the support for sync-stop operation") +Link: https://lore.kernel.org/r/b4e71631-4a94-613-27b2-fb595792630@carlh.net +Link: https://lore.kernel.org/r/20221205132124.11585-2-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/core/pcm_native.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c +index ad0541e9e888..ac985cec5c16 100644 +--- a/sound/core/pcm_native.c ++++ b/sound/core/pcm_native.c +@@ -1432,8 +1432,10 @@ static int snd_pcm_do_start(struct snd_pcm_substream *substream, + static void snd_pcm_undo_start(struct snd_pcm_substream *substream, + snd_pcm_state_t state) + { +- if (substream->runtime->trigger_master == substream) ++ if (substream->runtime->trigger_master == substream) { + substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP); ++ substream->runtime->stop_operating = true; ++ } + } + + static void snd_pcm_post_start(struct snd_pcm_substream *substream, +-- +2.35.1 + diff --git a/queue-6.0/alsa-seq-fix-undefined-behavior-in-bit-shift-for-snd.patch b/queue-6.0/alsa-seq-fix-undefined-behavior-in-bit-shift-for-snd.patch new file mode 100644 index 00000000000..0f966849a11 --- /dev/null +++ b/queue-6.0/alsa-seq-fix-undefined-behavior-in-bit-shift-for-snd.patch @@ -0,0 +1,66 @@ +From 61d10460b4b32ce3b2c5182cb1742dd6d9710423 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Nov 2022 19:16:30 +0800 +Subject: ALSA: seq: fix undefined behavior in bit shift for + SNDRV_SEQ_FILTER_USE_EVENT + +From: Baisong Zhong + +[ Upstream commit cf59e1e4c79bf741905484cdb13c130b53576a16 ] + +Shifting signed 32-bit value by 31 bits is undefined, so changing +significant bit to unsigned. The UBSAN warning calltrace like below: + +UBSAN: shift-out-of-bounds in sound/core/seq/seq_clientmgr.c:509:22 +left shift of 1 by 31 places cannot be represented in type 'int' +... +Call Trace: + + dump_stack_lvl+0x8d/0xcf + ubsan_epilogue+0xa/0x44 + __ubsan_handle_shift_out_of_bounds+0x1e7/0x208 + snd_seq_deliver_single_event.constprop.21+0x191/0x2f0 + snd_seq_deliver_event+0x1a2/0x350 + snd_seq_kernel_client_dispatch+0x8b/0xb0 + snd_seq_client_notify_subscription+0x72/0xa0 + snd_seq_ioctl_subscribe_port+0x128/0x160 + snd_seq_kernel_client_ctl+0xce/0xf0 + snd_seq_oss_create_client+0x109/0x15b + alsa_seq_oss_init+0x11c/0x1aa + do_one_initcall+0x80/0x440 + kernel_init_freeable+0x370/0x3c3 + kernel_init+0x1b/0x190 + ret_from_fork+0x1f/0x30 + + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Baisong Zhong +Link: https://lore.kernel.org/r/20221121111630.3119259-1-zhongbaisong@huawei.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + include/uapi/sound/asequencer.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/include/uapi/sound/asequencer.h b/include/uapi/sound/asequencer.h +index a75e14edc957..dbd60f48b4b0 100644 +--- a/include/uapi/sound/asequencer.h ++++ b/include/uapi/sound/asequencer.h +@@ -344,10 +344,10 @@ typedef int __bitwise snd_seq_client_type_t; + #define KERNEL_CLIENT ((__force snd_seq_client_type_t) 2) + + /* event filter flags */ +-#define SNDRV_SEQ_FILTER_BROADCAST (1<<0) /* accept broadcast messages */ +-#define SNDRV_SEQ_FILTER_MULTICAST (1<<1) /* accept multicast messages */ +-#define SNDRV_SEQ_FILTER_BOUNCE (1<<2) /* accept bounce event in error */ +-#define SNDRV_SEQ_FILTER_USE_EVENT (1<<31) /* use event filter */ ++#define SNDRV_SEQ_FILTER_BROADCAST (1U<<0) /* accept broadcast messages */ ++#define SNDRV_SEQ_FILTER_MULTICAST (1U<<1) /* accept multicast messages */ ++#define SNDRV_SEQ_FILTER_BOUNCE (1U<<2) /* accept bounce event in error */ ++#define SNDRV_SEQ_FILTER_USE_EVENT (1U<<31) /* use event filter */ + + struct snd_seq_client_info { + int client; /* client number to inquire */ +-- +2.35.1 + diff --git a/queue-6.0/amdgpu-nv.c-corrected-typo-in-the-video-capabilities.patch b/queue-6.0/amdgpu-nv.c-corrected-typo-in-the-video-capabilities.patch new file mode 100644 index 00000000000..02990d2819f --- /dev/null +++ b/queue-6.0/amdgpu-nv.c-corrected-typo-in-the-video-capabilities.patch @@ -0,0 +1,161 @@ +From 58c33fe08fe075e3b6ef980c7f98cfa60dd16e2c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Nov 2022 20:10:32 +0530 +Subject: amdgpu/nv.c: Corrected typo in the video capabilities resolution +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Veerabadhran Gopalakrishnan + +[ Upstream commit 65009bf2b4d287ef7ad7e6eb082b7c3d35eb611f ] + +Corrected the typo in the 4K resolution parameters. + +Fixes: b3a24461f9fb15 ("amdgpu/nv.c - Added codec query for Beige Goby") +Fixes: 9075096b09e590 ("amdgpu/nv.c - Optimize code for video codec support structure") +Fixes: 9ac0edaa0f8323 ("drm/amdgpu: add vcn_4_0_0 video codec query") + +Signed-off-by: Veerabadhran Gopalakrishnan +Acked-by: Luben Tuikov +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/nv.c | 28 ++++++++++++++-------------- + drivers/gpu/drm/amd/amdgpu/soc15.c | 24 ++++++++++++------------ + drivers/gpu/drm/amd/amdgpu/soc21.c | 2 +- + 3 files changed, 27 insertions(+), 27 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c +index b3fba8dea63c..6853b93ac82e 100644 +--- a/drivers/gpu/drm/amd/amdgpu/nv.c ++++ b/drivers/gpu/drm/amd/amdgpu/nv.c +@@ -82,10 +82,10 @@ static const struct amdgpu_video_codecs nv_video_codecs_encode = + /* Navi1x */ + static const struct amdgpu_video_codec_info nv_video_codecs_decode_array[] = + { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, +@@ -100,10 +100,10 @@ static const struct amdgpu_video_codecs nv_video_codecs_decode = + /* Sienna Cichlid */ + static const struct amdgpu_video_codec_info sc_video_codecs_decode_array[] = + { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, +@@ -125,10 +125,10 @@ static struct amdgpu_video_codec_info sriov_sc_video_codecs_encode_array[] = + + static struct amdgpu_video_codec_info sriov_sc_video_codecs_decode_array[] = + { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, +@@ -149,7 +149,7 @@ static struct amdgpu_video_codecs sriov_sc_video_codecs_decode = + + /* Beige Goby*/ + static const struct amdgpu_video_codec_info bg_video_codecs_decode_array[] = { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, + }; +@@ -166,7 +166,7 @@ static const struct amdgpu_video_codecs bg_video_codecs_encode = { + + /* Yellow Carp*/ + static const struct amdgpu_video_codec_info yc_video_codecs_decode_array[] = { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, +diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c +index e3b2b6b4f1a6..7cd17dda32ce 100644 +--- a/drivers/gpu/drm/amd/amdgpu/soc15.c ++++ b/drivers/gpu/drm/amd/amdgpu/soc15.c +@@ -103,10 +103,10 @@ static const struct amdgpu_video_codecs vega_video_codecs_encode = + /* Vega */ + static const struct amdgpu_video_codec_info vega_video_codecs_decode_array[] = + { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, + }; +@@ -120,10 +120,10 @@ static const struct amdgpu_video_codecs vega_video_codecs_decode = + /* Raven */ + static const struct amdgpu_video_codec_info rv_video_codecs_decode_array[] = + { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 4096, 4096, 0)}, +@@ -138,10 +138,10 @@ static const struct amdgpu_video_codecs rv_video_codecs_decode = + /* Renoir, Arcturus */ + static const struct amdgpu_video_codec_info rn_video_codecs_decode_array[] = + { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, +diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c +index 9c3463b48139..6d21c975b73d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/soc21.c ++++ b/drivers/gpu/drm/amd/amdgpu/soc21.c +@@ -61,7 +61,7 @@ static const struct amdgpu_video_codecs vcn_4_0_0_video_codecs_encode = + + static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_decode_array[] = + { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, +-- +2.35.1 + diff --git a/queue-6.0/amdgpu-pm-prevent-array-underflow-in-vega20_odn_edit.patch b/queue-6.0/amdgpu-pm-prevent-array-underflow-in-vega20_odn_edit.patch new file mode 100644 index 00000000000..dc003e6d77c --- /dev/null +++ b/queue-6.0/amdgpu-pm-prevent-array-underflow-in-vega20_odn_edit.patch @@ -0,0 +1,38 @@ +From 92386dfdb128ba4c0c4a0261294e0e68f06bc846 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Nov 2022 15:56:57 +0300 +Subject: amdgpu/pm: prevent array underflow in vega20_odn_edit_dpm_table() + +From: Dan Carpenter + +[ Upstream commit d27252b5706e51188aed7647126e44dcf9e940c1 ] + +In the PP_OD_EDIT_VDDC_CURVE case the "input_index" variable is capped at +2 but not checked for negative values so it results in an out of bounds +read. This value comes from the user via sysfs. + +Fixes: d5bf26539494 ("drm/amd/powerplay: added vega20 overdrive support V3") +Signed-off-by: Dan Carpenter +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +index 97b3ad369046..b30684c84e20 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +@@ -2961,7 +2961,8 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, + data->od8_settings.od8_settings_array; + OverDriveTable_t *od_table = + &(data->smc_state_table.overdrive_table); +- int32_t input_index, input_clk, input_vol, i; ++ int32_t input_clk, input_vol, i; ++ uint32_t input_index; + int od8_id; + int ret; + +-- +2.35.1 + diff --git a/queue-6.0/apparmor-fix-a-memleak-in-multi_transaction_new.patch b/queue-6.0/apparmor-fix-a-memleak-in-multi_transaction_new.patch new file mode 100644 index 00000000000..0d5173f0252 --- /dev/null +++ b/queue-6.0/apparmor-fix-a-memleak-in-multi_transaction_new.patch @@ -0,0 +1,42 @@ +From 84c4f473da89d69f1b5a8cac5ec808f943459b79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Aug 2022 09:15:03 +0800 +Subject: apparmor: fix a memleak in multi_transaction_new() + +From: Gaosheng Cui + +[ Upstream commit c73275cf6834787ca090317f1d20dbfa3b7f05aa ] + +In multi_transaction_new(), the variable t is not freed or passed out +on the failure of copy_from_user(t->data, buf, size), which could lead +to a memleak. + +Fix this bug by adding a put_multi_transaction(t) in the error path. + +Fixes: 1dea3b41e84c5 ("apparmor: speed up transactional queries") +Signed-off-by: Gaosheng Cui +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/apparmorfs.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c +index d066ccc219e2..7160e7aa58b9 100644 +--- a/security/apparmor/apparmorfs.c ++++ b/security/apparmor/apparmorfs.c +@@ -868,8 +868,10 @@ static struct multi_transaction *multi_transaction_new(struct file *file, + if (!t) + return ERR_PTR(-ENOMEM); + kref_init(&t->count); +- if (copy_from_user(t->data, buf, size)) ++ if (copy_from_user(t->data, buf, size)) { ++ put_multi_transaction(t); + return ERR_PTR(-EFAULT); ++ } + + return t; + } +-- +2.35.1 + diff --git a/queue-6.0/apparmor-fix-abi-check-to-include-v8-abi.patch b/queue-6.0/apparmor-fix-abi-check-to-include-v8-abi.patch new file mode 100644 index 00000000000..2d7d030947e --- /dev/null +++ b/queue-6.0/apparmor-fix-abi-check-to-include-v8-abi.patch @@ -0,0 +1,42 @@ +From 295da1e63c5559d04be9640d56afd6b254c3c390 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 May 2022 18:57:12 -0700 +Subject: apparmor: Fix abi check to include v8 abi + +From: John Johansen + +[ Upstream commit 1b5a6198f5a9d0aa5497da0dc4bcd4fc166ee516 ] + +The v8 abi is supported by the kernel but the userspace supported +version check does not allow for it. This was missed when v8 was added +due to a bug in the userspace compiler which was setting an older abi +version for v8 encoding (which is forward compatible except on the +network encoding). However it is possible to detect the network +encoding by checking the policydb network support which the code +does. The end result was that missing the abi flag worked until +userspace was fixed and began correctly checking for the v8 abi +version. + +Fixes: 56974a6fcfef ("apparmor: add base infastructure for socket mediation") +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/policy_unpack.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c +index 55d31bac4f35..9d26bbb90133 100644 +--- a/security/apparmor/policy_unpack.c ++++ b/security/apparmor/policy_unpack.c +@@ -972,7 +972,7 @@ static int verify_header(struct aa_ext *e, int required, const char **ns) + * if not specified use previous version + * Mask off everything that is not kernel abi version + */ +- if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v7)) { ++ if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v8)) { + audit_iface(NULL, NULL, NULL, "unsupported interface version", + e, error); + return error; +-- +2.35.1 + diff --git a/queue-6.0/apparmor-fix-lockdep-warning-when-removing-a-namespa.patch b/queue-6.0/apparmor-fix-lockdep-warning-when-removing-a-namespa.patch new file mode 100644 index 00000000000..7174cd53dde --- /dev/null +++ b/queue-6.0/apparmor-fix-lockdep-warning-when-removing-a-namespa.patch @@ -0,0 +1,56 @@ +From 9e947814d074c411885466c988cc3f4473242ce3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Sep 2022 03:39:55 -0700 +Subject: apparmor: fix lockdep warning when removing a namespace + +From: John Johansen + +[ Upstream commit 9c4557efc558a68e4cd973490fd936d6e3414db8 ] + +Fix the following lockdep warning + +[ 1119.158984] ============================================ +[ 1119.158988] WARNING: possible recursive locking detected +[ 1119.158996] 6.0.0-rc1+ #257 Tainted: G E N +[ 1119.158999] -------------------------------------------- +[ 1119.159001] bash/80100 is trying to acquire lock: +[ 1119.159007] ffff88803e79b4a0 (&ns->lock/1){+.+.}-{4:4}, at: destroy_ns.part.0+0x43/0x140 +[ 1119.159028] + but task is already holding lock: +[ 1119.159030] ffff8881009764a0 (&ns->lock/1){+.+.}-{4:4}, at: aa_remove_profiles+0x3f0/0x640 +[ 1119.159040] + other info that might help us debug this: +[ 1119.159042] Possible unsafe locking scenario: + +[ 1119.159043] CPU0 +[ 1119.159045] ---- +[ 1119.159047] lock(&ns->lock/1); +[ 1119.159051] lock(&ns->lock/1); +[ 1119.159055] + *** DEADLOCK *** + +Which is caused by an incorrect lockdep nesting notation + +Fixes: feb3c766a3ab ("apparmor: fix possible recursive lock warning in __aa_create_ns") +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/policy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c +index 499c0209b6a4..fbdfcef91c61 100644 +--- a/security/apparmor/policy.c ++++ b/security/apparmor/policy.c +@@ -1170,7 +1170,7 @@ ssize_t aa_remove_profiles(struct aa_ns *policy_ns, struct aa_label *subj, + + if (!name) { + /* remove namespace - can only happen if fqname[0] == ':' */ +- mutex_lock_nested(&ns->parent->lock, ns->level); ++ mutex_lock_nested(&ns->parent->lock, ns->parent->level); + __aa_bump_ns_revision(ns); + __aa_remove_ns(ns); + mutex_unlock(&ns->parent->lock); +-- +2.35.1 + diff --git a/queue-6.0/apparmor-fix-memleak-in-alloc_ns.patch b/queue-6.0/apparmor-fix-memleak-in-alloc_ns.patch new file mode 100644 index 00000000000..17d7a647664 --- /dev/null +++ b/queue-6.0/apparmor-fix-memleak-in-alloc_ns.patch @@ -0,0 +1,38 @@ +From 62f030714c8d7a91596348967fe3171e8a4624f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Oct 2022 20:33:20 +0800 +Subject: apparmor: Fix memleak in alloc_ns() + +From: Xiu Jianfeng + +[ Upstream commit e9e6fa49dbab6d84c676666f3fe7d360497fd65b ] + +After changes in commit a1bd627b46d1 ("apparmor: share profile name on +replacement"), the hname member of struct aa_policy is not valid slab +object, but a subset of that, it can not be freed by kfree_sensitive(), +use aa_policy_destroy() to fix it. + +Fixes: a1bd627b46d1 ("apparmor: share profile name on replacement") +Signed-off-by: Xiu Jianfeng +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/policy_ns.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c +index 43beaad083fe..78700d94b453 100644 +--- a/security/apparmor/policy_ns.c ++++ b/security/apparmor/policy_ns.c +@@ -134,7 +134,7 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name) + return ns; + + fail_unconfined: +- kfree_sensitive(ns->base.hname); ++ aa_policy_destroy(&ns->base); + fail_ns: + kfree_sensitive(ns); + return NULL; +-- +2.35.1 + diff --git a/queue-6.0/apparmor-fix-regression-in-stacking-due-to-label-fla.patch b/queue-6.0/apparmor-fix-regression-in-stacking-due-to-label-fla.patch new file mode 100644 index 00000000000..c8a0bb06b0a --- /dev/null +++ b/queue-6.0/apparmor-fix-regression-in-stacking-due-to-label-fla.patch @@ -0,0 +1,60 @@ +From 6a5bc45d0ef1a5bcfad8cd1fa77167dd38fb2bf0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Sep 2022 04:01:28 -0700 +Subject: apparmor: Fix regression in stacking due to label flags + +From: John Johansen + +[ Upstream commit 1f939c6bd1512d0b39b470396740added3cb403f ] + +The unconfined label flag is not being computed correctly. It +should only be set if all the profiles in the vector are set, which +is different than what is required for the debug and stale flag +that are set if any on the profile flags are set. + +Fixes: c1ed5da19765 ("apparmor: allow label to carry debug flags") +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/label.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/security/apparmor/label.c b/security/apparmor/label.c +index 0f36ee907438..a67c5897ee25 100644 +--- a/security/apparmor/label.c ++++ b/security/apparmor/label.c +@@ -197,15 +197,18 @@ static bool vec_is_stale(struct aa_profile **vec, int n) + return false; + } + +-static long union_vec_flags(struct aa_profile **vec, int n, long mask) ++static long accum_vec_flags(struct aa_profile **vec, int n) + { +- long u = 0; ++ long u = FLAG_UNCONFINED; + int i; + + AA_BUG(!vec); + + for (i = 0; i < n; i++) { +- u |= vec[i]->label.flags & mask; ++ u |= vec[i]->label.flags & (FLAG_DEBUG1 | FLAG_DEBUG2 | ++ FLAG_STALE); ++ if (!(u & vec[i]->label.flags & FLAG_UNCONFINED)) ++ u &= ~FLAG_UNCONFINED; + } + + return u; +@@ -1097,8 +1100,7 @@ static struct aa_label *label_merge_insert(struct aa_label *new, + else if (k == b->size) + return aa_get_label(b); + } +- new->flags |= union_vec_flags(new->vec, new->size, FLAG_UNCONFINED | +- FLAG_DEBUG1 | FLAG_DEBUG2); ++ new->flags |= accum_vec_flags(new->vec, new->size); + ls = labels_set(new); + write_lock_irqsave(&ls->lock, flags); + label = __label_insert(labels_set(new), new, false); +-- +2.35.1 + diff --git a/queue-6.0/apparmor-use-pointer-to-struct-aa_label-for-lbs_cred.patch b/queue-6.0/apparmor-use-pointer-to-struct-aa_label-for-lbs_cred.patch new file mode 100644 index 00000000000..f9b6c435333 --- /dev/null +++ b/queue-6.0/apparmor-use-pointer-to-struct-aa_label-for-lbs_cred.patch @@ -0,0 +1,41 @@ +From bd01307ed12cb2ad6f15b3556475f84b798eec70 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Oct 2022 08:46:04 +0800 +Subject: apparmor: Use pointer to struct aa_label for lbs_cred + +From: Xiu Jianfeng + +[ Upstream commit 37923d4321b1e38170086da2c117f78f2b0f49c6 ] + +According to the implementations of cred_label() and set_cred_label(), +we should use pointer to struct aa_label for lbs_cred instead of struct +aa_task_ctx, this patch fixes it. + +Fixes: bbd3662a8348 ("Infrastructure management of the cred security blob") +Signed-off-by: Xiu Jianfeng +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/lsm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index e29cade7b662..9eb7972e08e4 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -1194,10 +1194,10 @@ static int apparmor_inet_conn_request(const struct sock *sk, struct sk_buff *skb + #endif + + /* +- * The cred blob is a pointer to, not an instance of, an aa_task_ctx. ++ * The cred blob is a pointer to, not an instance of, an aa_label. + */ + struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = { +- .lbs_cred = sizeof(struct aa_task_ctx *), ++ .lbs_cred = sizeof(struct aa_label *), + .lbs_file = sizeof(struct aa_file_ctx), + .lbs_task = sizeof(struct aa_task_ctx), + }; +-- +2.35.1 + diff --git a/queue-6.0/arch-arm64-apple-t8103-use-standard-iommu-node-name.patch b/queue-6.0/arch-arm64-apple-t8103-use-standard-iommu-node-name.patch new file mode 100644 index 00000000000..817773c512c --- /dev/null +++ b/queue-6.0/arch-arm64-apple-t8103-use-standard-iommu-node-name.patch @@ -0,0 +1,55 @@ +From 495d945f8c1f6c40fe690161ef4fd4da5fadedf3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Dec 2022 23:57:36 +0100 +Subject: arch: arm64: apple: t8103: Use standard "iommu" node name + +From: Janne Grunau + +[ Upstream commit 56d32c51dffac8a431b472a4c31efb8563b048d1 ] + +The PCIe iommu nodes use "dart" as node names. Replace it with the +the standard "iommu" node name as all other iommu nodes. + +Fixes: 3c866bb79577 ("arm64: dts: apple: t8103: Add PCIe DARTs") +Signed-off-by: Janne Grunau +Reviewed-by: Mark Kettenis +Signed-off-by: Hector Martin +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/apple/t8103.dtsi | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi +index 51a63b29d404..a4d195e9eb8c 100644 +--- a/arch/arm64/boot/dts/apple/t8103.dtsi ++++ b/arch/arm64/boot/dts/apple/t8103.dtsi +@@ -412,7 +412,7 @@ nvme@27bcc0000 { + resets = <&ps_ans2>; + }; + +- pcie0_dart_0: dart@681008000 { ++ pcie0_dart_0: iommu@681008000 { + compatible = "apple,t8103-dart"; + reg = <0x6 0x81008000 0x0 0x4000>; + #iommu-cells = <1>; +@@ -421,7 +421,7 @@ pcie0_dart_0: dart@681008000 { + power-domains = <&ps_apcie_gp>; + }; + +- pcie0_dart_1: dart@682008000 { ++ pcie0_dart_1: iommu@682008000 { + compatible = "apple,t8103-dart"; + reg = <0x6 0x82008000 0x0 0x4000>; + #iommu-cells = <1>; +@@ -430,7 +430,7 @@ pcie0_dart_1: dart@682008000 { + power-domains = <&ps_apcie_gp>; + }; + +- pcie0_dart_2: dart@683008000 { ++ pcie0_dart_2: iommu@683008000 { + compatible = "apple,t8103-dart"; + reg = <0x6 0x83008000 0x0 0x4000>; + #iommu-cells = <1>; +-- +2.35.1 + diff --git a/queue-6.0/arm-dts-armada-370-fix-assigned-addresses-for-every-.patch b/queue-6.0/arm-dts-armada-370-fix-assigned-addresses-for-every-.patch new file mode 100644 index 00000000000..45b0699314b --- /dev/null +++ b/queue-6.0/arm-dts-armada-370-fix-assigned-addresses-for-every-.patch @@ -0,0 +1,40 @@ +From ecfc781996124a942b04d162416dd02c51aefa14 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Aug 2022 00:30:49 +0200 +Subject: ARM: dts: armada-370: Fix assigned-addresses for every PCIe Root Port +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit d9208b0fa2e803d16b28d91bf1d46b7ee9ea13c6 ] + +BDF of resource in DT assigned-addresses property of Marvell PCIe Root Port +(PCI-to-PCI bridge) should match BDF in address part in that DT node name +as specified resource belongs to Marvell PCIe Root Port itself. + +Fixes: a09a0b7c6ff1 ("arm: mvebu: add PCIe Device Tree informations for Armada 370") +Signed-off-by: Pali Rohár +Signed-off-by: Gregory CLEMENT +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/armada-370.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi +index 46e6d3ed8f35..c042c416a94a 100644 +--- a/arch/arm/boot/dts/armada-370.dtsi ++++ b/arch/arm/boot/dts/armada-370.dtsi +@@ -74,7 +74,7 @@ pcie0: pcie@1,0 { + + pcie2: pcie@2,0 { + device_type = "pci"; +- assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; ++ assigned-addresses = <0x82001000 0 0x80000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +-- +2.35.1 + diff --git a/queue-6.0/arm-dts-armada-375-fix-assigned-addresses-for-every-.patch b/queue-6.0/arm-dts-armada-375-fix-assigned-addresses-for-every-.patch new file mode 100644 index 00000000000..c0d803550af --- /dev/null +++ b/queue-6.0/arm-dts-armada-375-fix-assigned-addresses-for-every-.patch @@ -0,0 +1,40 @@ +From 50e8366a777ca93bf7030251825c7ff05a672a7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Aug 2022 00:30:51 +0200 +Subject: ARM: dts: armada-375: Fix assigned-addresses for every PCIe Root Port +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit 823956d2436f70ced74c0fe8ab99facd8abfc060 ] + +BDF of resource in DT assigned-addresses property of Marvell PCIe Root Port +(PCI-to-PCI bridge) should match BDF in address part in that DT node name +as specified resource belongs to Marvell PCIe Root Port itself. + +Fixes: 4de59085091f ("ARM: mvebu: add Device Tree description of the Armada 375 SoC") +Signed-off-by: Pali Rohár +Signed-off-by: Gregory CLEMENT +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/armada-375.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi +index 7f2f24a29e6c..352a2f7ba311 100644 +--- a/arch/arm/boot/dts/armada-375.dtsi ++++ b/arch/arm/boot/dts/armada-375.dtsi +@@ -582,7 +582,7 @@ pcie0: pcie@1,0 { + + pcie1: pcie@2,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; ++ assigned-addresses = <0x82001000 0 0x44000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +-- +2.35.1 + diff --git a/queue-6.0/arm-dts-armada-38x-fix-assigned-addresses-for-every-.patch b/queue-6.0/arm-dts-armada-38x-fix-assigned-addresses-for-every-.patch new file mode 100644 index 00000000000..54a494e471b --- /dev/null +++ b/queue-6.0/arm-dts-armada-38x-fix-assigned-addresses-for-every-.patch @@ -0,0 +1,81 @@ +From 4feb30295b59d81bfbc4741c14708aa85e98f7fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Aug 2022 00:30:52 +0200 +Subject: ARM: dts: armada-38x: Fix assigned-addresses for every PCIe Root Port +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit 44f47b7a8fa4678ce4c38ea74837e4996b9df6d6 ] + +BDF of resource in DT assigned-addresses property of Marvell PCIe Root Port +(PCI-to-PCI bridge) should match BDF in address part in that DT node name +as specified resource belongs to Marvell PCIe Root Port itself. + +Fixes: 0d3d96ab0059 ("ARM: mvebu: add Device Tree description of the Armada 380/385 SoCs") +Signed-off-by: Pali Rohár +Signed-off-by: Gregory CLEMENT +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/armada-380.dtsi | 4 ++-- + arch/arm/boot/dts/armada-385.dtsi | 6 +++--- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/arm/boot/dts/armada-380.dtsi b/arch/arm/boot/dts/armada-380.dtsi +index cff1269f3fbf..7146cc8f082a 100644 +--- a/arch/arm/boot/dts/armada-380.dtsi ++++ b/arch/arm/boot/dts/armada-380.dtsi +@@ -79,7 +79,7 @@ pcie@1,0 { + /* x1 port */ + pcie@2,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; ++ assigned-addresses = <0x82001000 0 0x40000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -98,7 +98,7 @@ pcie@2,0 { + /* x1 port */ + pcie@3,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; ++ assigned-addresses = <0x82001800 0 0x44000 0 0x2000>; + reg = <0x1800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +diff --git a/arch/arm/boot/dts/armada-385.dtsi b/arch/arm/boot/dts/armada-385.dtsi +index 83392b92dae2..be8d607c59b2 100644 +--- a/arch/arm/boot/dts/armada-385.dtsi ++++ b/arch/arm/boot/dts/armada-385.dtsi +@@ -93,7 +93,7 @@ pcie1_intc: interrupt-controller { + /* x1 port */ + pcie2: pcie@2,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; ++ assigned-addresses = <0x82001000 0 0x40000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -121,7 +121,7 @@ pcie2_intc: interrupt-controller { + /* x1 port */ + pcie3: pcie@3,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; ++ assigned-addresses = <0x82001800 0 0x44000 0 0x2000>; + reg = <0x1800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -152,7 +152,7 @@ pcie3_intc: interrupt-controller { + */ + pcie4: pcie@4,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; ++ assigned-addresses = <0x82002000 0 0x48000 0 0x2000>; + reg = <0x2000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +-- +2.35.1 + diff --git a/queue-6.0/arm-dts-armada-38x-fix-compatible-string-for-gpios.patch b/queue-6.0/arm-dts-armada-38x-fix-compatible-string-for-gpios.patch new file mode 100644 index 00000000000..6b9ec2117c4 --- /dev/null +++ b/queue-6.0/arm-dts-armada-38x-fix-compatible-string-for-gpios.patch @@ -0,0 +1,56 @@ +From 81f42ba5fcbc242b1755b08791b07c2c21599a5a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Jul 2022 20:33:27 +0200 +Subject: ARM: dts: armada-38x: Fix compatible string for gpios +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit c4de4667f15d04ef5920bacf41e514ec7d1ef03d ] + +Armada 38x supports per CPU interrupts for gpios, like Armada XP. Pre-XP +variants like Armada 370 do not support per CPU interrupts for gpios. + +So change compatible string for Armada 38x from "marvell,armada-370-gpio" +which indicates pre-XP variant to "marvell,armadaxp-gpio" which indicates +XP variant or new. + +Driver gpio-mvebu.c which handles both pre-XP and XP variants already +provides support for per CPU interrupts on XP and newer variants. + +Signed-off-by: Pali Rohár +Fixes: 7cb2acb3fbae ("ARM: dts: mvebu: Add PWM properties for armada-38x") +Acked-by: Uwe Kleine-König +Signed-off-by: Gregory CLEMENT +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/armada-38x.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi +index df3c8d1d8f64..9343de6947b3 100644 +--- a/arch/arm/boot/dts/armada-38x.dtsi ++++ b/arch/arm/boot/dts/armada-38x.dtsi +@@ -292,7 +292,7 @@ sata3_pins: sata-pins-3 { + }; + + gpio0: gpio@18100 { +- compatible = "marvell,armada-370-gpio", ++ compatible = "marvell,armadaxp-gpio", + "marvell,orion-gpio"; + reg = <0x18100 0x40>, <0x181c0 0x08>; + reg-names = "gpio", "pwm"; +@@ -310,7 +310,7 @@ gpio0: gpio@18100 { + }; + + gpio1: gpio@18140 { +- compatible = "marvell,armada-370-gpio", ++ compatible = "marvell,armadaxp-gpio", + "marvell,orion-gpio"; + reg = <0x18140 0x40>, <0x181c8 0x08>; + reg-names = "gpio", "pwm"; +-- +2.35.1 + diff --git a/queue-6.0/arm-dts-armada-39x-fix-assigned-addresses-for-every-.patch b/queue-6.0/arm-dts-armada-39x-fix-assigned-addresses-for-every-.patch new file mode 100644 index 00000000000..2290f8ca0c3 --- /dev/null +++ b/queue-6.0/arm-dts-armada-39x-fix-assigned-addresses-for-every-.patch @@ -0,0 +1,58 @@ +From e5c2169a03a1f68aa6fc7b0a6b0ccd1d17474404 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Aug 2022 00:30:53 +0200 +Subject: ARM: dts: armada-39x: Fix assigned-addresses for every PCIe Root Port +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit 69236d2391b4d7324b11c3252921571577892e7b ] + +BDF of resource in DT assigned-addresses property of Marvell PCIe Root Port +(PCI-to-PCI bridge) should match BDF in address part in that DT node name +as specified resource belongs to Marvell PCIe Root Port itself. + +Fixes: 538da83ddbea ("ARM: mvebu: add Device Tree files for Armada 39x SoC and board") +Signed-off-by: Pali Rohár +Signed-off-by: Gregory CLEMENT +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/armada-39x.dtsi | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/boot/dts/armada-39x.dtsi b/arch/arm/boot/dts/armada-39x.dtsi +index e0b7c2099831..9525e7b7f436 100644 +--- a/arch/arm/boot/dts/armada-39x.dtsi ++++ b/arch/arm/boot/dts/armada-39x.dtsi +@@ -453,7 +453,7 @@ pcie@1,0 { + /* x1 port */ + pcie@2,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; ++ assigned-addresses = <0x82001000 0 0x40000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -472,7 +472,7 @@ pcie@2,0 { + /* x1 port */ + pcie@3,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; ++ assigned-addresses = <0x82001800 0 0x44000 0 0x2000>; + reg = <0x1800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -494,7 +494,7 @@ pcie@3,0 { + */ + pcie@4,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; ++ assigned-addresses = <0x82002000 0 0x48000 0 0x2000>; + reg = <0x2000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +-- +2.35.1 + diff --git a/queue-6.0/arm-dts-armada-39x-fix-compatible-string-for-gpios.patch b/queue-6.0/arm-dts-armada-39x-fix-compatible-string-for-gpios.patch new file mode 100644 index 00000000000..f105ab732ae --- /dev/null +++ b/queue-6.0/arm-dts-armada-39x-fix-compatible-string-for-gpios.patch @@ -0,0 +1,52 @@ +From 582d7672f4704baaee0039fd242fee9b4b31af69 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Jul 2022 20:33:28 +0200 +Subject: ARM: dts: armada-39x: Fix compatible string for gpios +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit d10886a4e6f85ee18d47a1066a52168461370ded ] + +Armada 39x supports per CPU interrupts for gpios, like Armada XP. + +So add compatible string "marvell,armadaxp-gpio" for Armada 39x GPIO nodes. + +Driver gpio-mvebu.c which handles both pre-XP and XP variants already +provides support for per CPU interrupts on XP and newer variants. + +Signed-off-by: Pali Rohár +Fixes: d81a914fc630 ("ARM: dts: mvebu: armada-39x: add missing nodes describing GPIO's") +Signed-off-by: Gregory CLEMENT +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/armada-39x.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/armada-39x.dtsi b/arch/arm/boot/dts/armada-39x.dtsi +index 9525e7b7f436..9aad10fd3823 100644 +--- a/arch/arm/boot/dts/armada-39x.dtsi ++++ b/arch/arm/boot/dts/armada-39x.dtsi +@@ -213,7 +213,7 @@ nand_pins: nand-pins { + }; + + gpio0: gpio@18100 { +- compatible = "marvell,orion-gpio"; ++ compatible = "marvell,armadaxp-gpio", "marvell,orion-gpio"; + reg = <0x18100 0x40>; + ngpios = <32>; + gpio-controller; +@@ -227,7 +227,7 @@ gpio0: gpio@18100 { + }; + + gpio1: gpio@18140 { +- compatible = "marvell,orion-gpio"; ++ compatible = "marvell,armadaxp-gpio", "marvell,orion-gpio"; + reg = <0x18140 0x40>; + ngpios = <28>; + gpio-controller; +-- +2.35.1 + diff --git a/queue-6.0/arm-dts-armada-xp-fix-assigned-addresses-for-every-p.patch b/queue-6.0/arm-dts-armada-xp-fix-assigned-addresses-for-every-p.patch new file mode 100644 index 00000000000..e4c866c3506 --- /dev/null +++ b/queue-6.0/arm-dts-armada-xp-fix-assigned-addresses-for-every-p.patch @@ -0,0 +1,146 @@ +From 6aee516fde57dd7435a465dab86f6d3d0976f28d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Aug 2022 00:30:50 +0200 +Subject: ARM: dts: armada-xp: Fix assigned-addresses for every PCIe Root Port +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit eab276787f456cbea89fabea110fe0728673d308 ] + +BDF of resource in DT assigned-addresses property of Marvell PCIe Root Port +(PCI-to-PCI bridge) should match BDF in address part in that DT node name +as specified resource belongs to Marvell PCIe Root Port itself. + +Fixes: 9d8f44f02d4a ("arm: mvebu: add PCIe Device Tree informations for Armada XP") +Fixes: 12b69a599745 ("ARM: mvebu: second PCIe unit of Armada XP mv78230 is only x1 capable") +Fixes: 2163e61c92d9 ("ARM: mvebu: fix second and third PCIe unit of Armada XP mv78260") +Signed-off-by: Pali Rohár +Signed-off-by: Gregory CLEMENT +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/armada-xp-mv78230.dtsi | 8 ++++---- + arch/arm/boot/dts/armada-xp-mv78260.dtsi | 16 ++++++++-------- + 2 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi +index 8558bf6bb54c..d55fe162fc7f 100644 +--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi +@@ -97,7 +97,7 @@ pcie1: pcie@1,0 { + + pcie2: pcie@2,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; ++ assigned-addresses = <0x82001000 0 0x44000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -115,7 +115,7 @@ pcie2: pcie@2,0 { + + pcie3: pcie@3,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; ++ assigned-addresses = <0x82001800 0 0x48000 0 0x2000>; + reg = <0x1800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -133,7 +133,7 @@ pcie3: pcie@3,0 { + + pcie4: pcie@4,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>; ++ assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>; + reg = <0x2000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -151,7 +151,7 @@ pcie4: pcie@4,0 { + + pcie5: pcie@5,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x80000 0 0x2000>; ++ assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; + reg = <0x2800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi +index 2d85fe8ac327..fdcc81819940 100644 +--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi ++++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi +@@ -112,7 +112,7 @@ pcie1: pcie@1,0 { + + pcie2: pcie@2,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; ++ assigned-addresses = <0x82001000 0 0x44000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -130,7 +130,7 @@ pcie2: pcie@2,0 { + + pcie3: pcie@3,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; ++ assigned-addresses = <0x82001800 0 0x48000 0 0x2000>; + reg = <0x1800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -148,7 +148,7 @@ pcie3: pcie@3,0 { + + pcie4: pcie@4,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>; ++ assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>; + reg = <0x2000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -166,7 +166,7 @@ pcie4: pcie@4,0 { + + pcie5: pcie@5,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x80000 0 0x2000>; ++ assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; + reg = <0x2800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -184,7 +184,7 @@ pcie5: pcie@5,0 { + + pcie6: pcie@6,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x84000 0 0x2000>; ++ assigned-addresses = <0x82003000 0 0x84000 0 0x2000>; + reg = <0x3000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -202,7 +202,7 @@ pcie6: pcie@6,0 { + + pcie7: pcie@7,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x88000 0 0x2000>; ++ assigned-addresses = <0x82003800 0 0x88000 0 0x2000>; + reg = <0x3800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -220,7 +220,7 @@ pcie7: pcie@7,0 { + + pcie8: pcie@8,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x8c000 0 0x2000>; ++ assigned-addresses = <0x82004000 0 0x8c000 0 0x2000>; + reg = <0x4000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +@@ -238,7 +238,7 @@ pcie8: pcie@8,0 { + + pcie9: pcie@9,0 { + device_type = "pci"; +- assigned-addresses = <0x82000800 0 0x42000 0 0x2000>; ++ assigned-addresses = <0x82004800 0 0x42000 0 0x2000>; + reg = <0x4800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; +-- +2.35.1 + diff --git a/queue-6.0/arm-dts-aspeed-rainier-everest-move-reserved-memory-.patch b/queue-6.0/arm-dts-aspeed-rainier-everest-move-reserved-memory-.patch new file mode 100644 index 00000000000..e4c606a835f --- /dev/null +++ b/queue-6.0/arm-dts-aspeed-rainier-everest-move-reserved-memory-.patch @@ -0,0 +1,123 @@ +From 56c05ea3b973deed52f440342ef1e6a52620548b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Sep 2022 14:55:35 -0500 +Subject: ARM: dts: aspeed: rainier,everest: Move reserved memory regions + +From: Adriana Kobylak + +[ Upstream commit e184d42a6e085f95f5c4f1a4fbabebab2984cb68 ] + +Move the reserved regions to account for a decrease in DRAM when ECC is +enabled. ECC takes 1/9th of memory. + +Running on HW with ECC off, u-boot prints: +DRAM: already initialized, 1008 MiB (capacity:1024 MiB, VGA:16 MiB, ECC:off) + +And with ECC on, u-boot prints: +DRAM: already initialized, 896 MiB (capacity:1024 MiB, VGA:16 MiB, ECC:on, ECC size:896 MiB) + +This implies that MCR54 is configured for ECC to be bounded at the +bottom of a 16MiB VGA memory region: + +1024MiB - 16MiB (VGA) = 1008MiB +1008MiB / 9 (for ECC) = 112MiB +1008MiB - 112MiB = 896MiB (available DRAM) + +The flash_memory region currently starts at offset 896MiB: +0xb8000000 (flash_memory offset) - 0x80000000 (base memory address) = 0x38000000 = 896MiB + +This is the end of the available DRAM with ECC enabled and therefore it +needs to be moved. + +Since the flash_memory is 64MiB in size and needs to be 64MiB aligned, +it can just be moved up by 64MiB and would sit right at the end of the +available DRAM buffer. + +The ramoops region currently follows the flash_memory, but it can be +moved to sit above flash_memory which would minimize the address-space +fragmentation. + +Signed-off-by: Adriana Kobylak +Reviewed-by: Andrew Jeffery +Link: https://lore.kernel.org/r/20220916195535.1020185-1-anoo@linux.ibm.com +Signed-off-by: Joel Stanley +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts | 17 ++++++++--------- + arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts | 16 +++++++++------- + 2 files changed, 17 insertions(+), 16 deletions(-) + +diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts +index a6a2bc3b855c..fcc890e3ad73 100644 +--- a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts ++++ b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts +@@ -162,16 +162,9 @@ reserved-memory { + #size-cells = <1>; + ranges; + +- /* LPC FW cycle bridge region requires natural alignment */ +- flash_memory: region@b8000000 { +- no-map; +- reg = <0xb8000000 0x04000000>; /* 64M */ +- }; +- +- /* 48MB region from the end of flash to start of vga memory */ +- ramoops@bc000000 { ++ ramoops@b3e00000 { + compatible = "ramoops"; +- reg = <0xbc000000 0x200000>; /* 16 * (4 * 0x8000) */ ++ reg = <0xb3e00000 0x200000>; /* 16 * (4 * 0x8000) */ + record-size = <0x8000>; + console-size = <0x8000>; + ftrace-size = <0x8000>; +@@ -179,6 +172,12 @@ ramoops@bc000000 { + max-reason = <3>; /* KMSG_DUMP_EMERG */ + }; + ++ /* LPC FW cycle bridge region requires natural alignment */ ++ flash_memory: region@b4000000 { ++ no-map; ++ reg = <0xb4000000 0x04000000>; /* 64M */ ++ }; ++ + /* VGA region is dictated by hardware strapping */ + vga_memory: region@bf000000 { + no-map; +diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts +index bf59a9962379..4879da4cdbd2 100644 +--- a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts ++++ b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts +@@ -95,14 +95,9 @@ reserved-memory { + #size-cells = <1>; + ranges; + +- flash_memory: region@b8000000 { +- no-map; +- reg = <0xb8000000 0x04000000>; /* 64M */ +- }; +- +- ramoops@bc000000 { ++ ramoops@b3e00000 { + compatible = "ramoops"; +- reg = <0xbc000000 0x200000>; /* 16 * (4 * 0x8000) */ ++ reg = <0xb3e00000 0x200000>; /* 16 * (4 * 0x8000) */ + record-size = <0x8000>; + console-size = <0x8000>; + ftrace-size = <0x8000>; +@@ -110,6 +105,13 @@ ramoops@bc000000 { + max-reason = <3>; /* KMSG_DUMP_EMERG */ + }; + ++ /* LPC FW cycle bridge region requires natural alignment */ ++ flash_memory: region@b4000000 { ++ no-map; ++ reg = <0xb4000000 0x04000000>; /* 64M */ ++ }; ++ ++ /* VGA region is dictated by hardware strapping */ + vga_memory: region@bf000000 { + no-map; + compatible = "shared-dma-pool"; +-- +2.35.1 + diff --git a/queue-6.0/arm-dts-dove-fix-assigned-addresses-for-every-pcie-r.patch b/queue-6.0/arm-dts-dove-fix-assigned-addresses-for-every-pcie-r.patch new file mode 100644 index 00000000000..b394597951c --- /dev/null +++ b/queue-6.0/arm-dts-dove-fix-assigned-addresses-for-every-pcie-r.patch @@ -0,0 +1,40 @@ +From 69d834a0794770bdce08b9d7267f5e366184e885 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Aug 2022 00:30:48 +0200 +Subject: ARM: dts: dove: Fix assigned-addresses for every PCIe Root Port +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit dcc7d8c72b64a479b8017e4332d99179deb8802d ] + +BDF of resource in DT assigned-addresses property of Marvell PCIe Root Port +(PCI-to-PCI bridge) should match BDF in address part in that DT node name +as specified resource belongs to Marvell PCIe Root Port itself. + +Fixes: 74ecaa403a74 ("ARM: dove: add PCIe controllers to SoC DT") +Signed-off-by: Pali Rohár +Signed-off-by: Gregory CLEMENT +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/dove.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi +index 89e0bdaf3a85..726d353eda68 100644 +--- a/arch/arm/boot/dts/dove.dtsi ++++ b/arch/arm/boot/dts/dove.dtsi +@@ -129,7 +129,7 @@ pcie0: pcie@1 { + pcie1: pcie@2 { + device_type = "pci"; + status = "disabled"; +- assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; ++ assigned-addresses = <0x82001000 0 0x80000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + clocks = <&gate_clk 5>; + marvell,pcie-port = <1>; +-- +2.35.1 + diff --git a/queue-6.0/arm-dts-nuvoton-remove-bogus-unit-addresses-from-fix.patch b/queue-6.0/arm-dts-nuvoton-remove-bogus-unit-addresses-from-fix.patch new file mode 100644 index 00000000000..164f619e4aa --- /dev/null +++ b/queue-6.0/arm-dts-nuvoton-remove-bogus-unit-addresses-from-fix.patch @@ -0,0 +1,146 @@ +From cdcbb69c953ac2c0eb6e3f71ef1680f40505e63e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 31 Oct 2022 23:15:52 +0100 +Subject: ARM: dts: nuvoton: Remove bogus unit addresses from fixed-partition + nodes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jonathan Neuschäfer + +[ Upstream commit ea3ce4cf076ba11bb591c8013c5315136cae52c8 ] + +The unit addresses do not correspond to the nodes' reg properties, +because they don't have any. + +Fixes: e42b650f828d ("ARM: dts: nuvoton: Add new device nodes to NPCM750 EVB") +Fixes: ee33e2fb3d70 ("ARM: dts: nuvoton: Add Quanta GBS BMC Device Tree") +Fixes: 59f5abe09f0a ("ARM: dts: nuvoton: Add Quanta GSJ BMC") +Fixes: 14579c76f5ca ("ARM: dts: nuvoton: Add Fii Kudo system") +Signed-off-by: Jonathan Neuschäfer +Reviewed-by: Joel Stanley +Link: https://lore.kernel.org/r/20221031221553.163273-1-j.neuschaefer@gmx.net +Signed-off-by: Joel Stanley +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/nuvoton-npcm730-gbs.dts | 2 +- + arch/arm/boot/dts/nuvoton-npcm730-gsj.dts | 2 +- + arch/arm/boot/dts/nuvoton-npcm730-kudo.dts | 6 +++--- + arch/arm/boot/dts/nuvoton-npcm750-evb.dts | 4 ++-- + arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts | 6 +++--- + 5 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/arch/arm/boot/dts/nuvoton-npcm730-gbs.dts b/arch/arm/boot/dts/nuvoton-npcm730-gbs.dts +index d10669fcd527..9e9eba8bad5e 100644 +--- a/arch/arm/boot/dts/nuvoton-npcm730-gbs.dts ++++ b/arch/arm/boot/dts/nuvoton-npcm730-gbs.dts +@@ -366,7 +366,7 @@ flash@0 { + spi-max-frequency = <20000000>; + spi-rx-bus-width = <2>; + label = "bmc"; +- partitions@80000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +diff --git a/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts b/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts +index 491606c4f044..2a394cc15284 100644 +--- a/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts ++++ b/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts +@@ -142,7 +142,7 @@ flash@0 { + reg = <0>; + spi-rx-bus-width = <2>; + +- partitions@80000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +diff --git a/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts b/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts +index a0c2d7652625..f7b38bee039b 100644 +--- a/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts ++++ b/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts +@@ -388,7 +388,7 @@ flash@0 { + spi-max-frequency = <5000000>; + spi-rx-bus-width = <2>; + label = "bmc"; +- partitions@80000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +@@ -422,7 +422,7 @@ flash@1 { + reg = <1>; + spi-max-frequency = <5000000>; + spi-rx-bus-width = <2>; +- partitions@88000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +@@ -447,7 +447,7 @@ flash@0 { + reg = <0>; + spi-max-frequency = <5000000>; + spi-rx-bus-width = <2>; +- partitions@A0000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +diff --git a/arch/arm/boot/dts/nuvoton-npcm750-evb.dts b/arch/arm/boot/dts/nuvoton-npcm750-evb.dts +index 3dad32834e5e..f53d45fa1de8 100644 +--- a/arch/arm/boot/dts/nuvoton-npcm750-evb.dts ++++ b/arch/arm/boot/dts/nuvoton-npcm750-evb.dts +@@ -74,7 +74,7 @@ flash@0 { + spi-rx-bus-width = <2>; + reg = <0>; + spi-max-frequency = <5000000>; +- partitions@80000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +@@ -135,7 +135,7 @@ flash@0 { + spi-rx-bus-width = <2>; + reg = <0>; + spi-max-frequency = <5000000>; +- partitions@A0000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +diff --git a/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts b/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts +index 132e702281fc..87359ab05db3 100644 +--- a/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts ++++ b/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts +@@ -107,7 +107,7 @@ flash@0 { + reg = <0>; + spi-rx-bus-width = <2>; + +- partitions@80000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +@@ -146,7 +146,7 @@ flash@1 { + reg = <1>; + npcm,fiu-rx-bus-width = <2>; + +- partitions@88000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +@@ -173,7 +173,7 @@ flash@0 { + reg = <0>; + spi-rx-bus-width = <2>; + +- partitions@A0000000 { ++ partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +-- +2.35.1 + diff --git a/queue-6.0/arm-dts-qcom-apq8064-fix-coresight-compatible.patch b/queue-6.0/arm-dts-qcom-apq8064-fix-coresight-compatible.patch new file mode 100644 index 00000000000..06ae763cb93 --- /dev/null +++ b/queue-6.0/arm-dts-qcom-apq8064-fix-coresight-compatible.patch @@ -0,0 +1,39 @@ +From 2cf94951271331b9069219a6f31eb69f279e2f63 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Oct 2022 21:06:57 +0200 +Subject: ARM: dts: qcom: apq8064: fix coresight compatible + +From: Luca Weiss + +[ Upstream commit a42b1ee868361f1cb0492f1bdaefb43e0751e468 ] + +There's a typo missing the arm, prefix of arm,coresight-etb10. Fix it to +make devicetree validation happier. + +Signed-off-by: Luca Weiss +Fixes: 7a5c275fd821 ("ARM: dts: qcom: Add apq8064 CoreSight components") +Reviewed-by: Krzysztof Kozlowski +Reviewed-by: Konrad Dybcio +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221013190657.48499-3-luca@z3ntu.xyz +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/qcom-apq8064.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi +index ada4c828bf2f..095849423de1 100644 +--- a/arch/arm/boot/dts/qcom-apq8064.dtsi ++++ b/arch/arm/boot/dts/qcom-apq8064.dtsi +@@ -1580,7 +1580,7 @@ wifi { + }; + + etb@1a01000 { +- compatible = "coresight-etb10", "arm,primecell"; ++ compatible = "arm,coresight-etb10", "arm,primecell"; + reg = <0x1a01000 0x1000>; + + clocks = <&rpmcc RPM_QDSS_CLK>; +-- +2.35.1 + diff --git a/queue-6.0/arm-dts-spear600-fix-clcd-interrupt.patch b/queue-6.0/arm-dts-spear600-fix-clcd-interrupt.patch new file mode 100644 index 00000000000..15a466e6773 --- /dev/null +++ b/queue-6.0/arm-dts-spear600-fix-clcd-interrupt.patch @@ -0,0 +1,37 @@ +From 8171cb28b34dcfe01d4c8a3a78800473e86b170d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Nov 2022 18:10:06 +0100 +Subject: arm: dts: spear600: Fix clcd interrupt + +From: Kory Maincent + +[ Upstream commit 0336e2ce34e7a89832b6c214f924eb7bc58940be ] + +Interrupt 12 of the Interrupt controller belongs to the SMI controller, +the right one for the display controller is the interrupt 13. + +Fixes: 8113ba917dfa ("ARM: SPEAr: DT: Update device nodes") +Signed-off-by: Kory Maincent +Acked-by: Viresh Kumar +Signed-off-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/spear600.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi +index fd41243a0b2c..9d5a04a46b14 100644 +--- a/arch/arm/boot/dts/spear600.dtsi ++++ b/arch/arm/boot/dts/spear600.dtsi +@@ -47,7 +47,7 @@ clcd: clcd@fc200000 { + compatible = "arm,pl110", "arm,primecell"; + reg = <0xfc200000 0x1000>; + interrupt-parent = <&vic1>; +- interrupts = <12>; ++ interrupts = <13>; + status = "disabled"; + }; + +-- +2.35.1 + diff --git a/queue-6.0/arm-dts-stm32-drop-stm32mp15xc.dtsi-from-avenger96.patch b/queue-6.0/arm-dts-stm32-drop-stm32mp15xc.dtsi-from-avenger96.patch new file mode 100644 index 00000000000..e75f9d841e7 --- /dev/null +++ b/queue-6.0/arm-dts-stm32-drop-stm32mp15xc.dtsi-from-avenger96.patch @@ -0,0 +1,39 @@ +From 2b67118a7a520b3c808aaa299f35277dcc6d06b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Sep 2022 04:37:45 +0200 +Subject: ARM: dts: stm32: Drop stm32mp15xc.dtsi from Avenger96 + +From: Marek Vasut + +[ Upstream commit 3b835f1b8acef53c8882b25f40f48d7f5982c938 ] + +The Avenger96 is populated with STM32MP157A DHCOR SoM, drop the +stm32mp15xc.dtsi which should only be included in DTs of devices +which are populated with STM32MP15xC/F SoC as the stm32mp15xc.dtsi +enables CRYP block not present in the STM32MP15xA/D SoC . + +Fixes: 7e76f82acd9e1 ("ARM: dts: stm32: Split Avenger96 into DHCOR SoM and Avenger96 board") +Signed-off-by: Marek Vasut +Reviewed-by: Patrice Chotard +Reviewed-by: Manivannan Sadhasivam +Signed-off-by: Alexandre Torgue +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts b/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts +index 2e3c9fbb4eb3..275167f26fd9 100644 +--- a/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts ++++ b/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts +@@ -13,7 +13,6 @@ + /dts-v1/; + + #include "stm32mp157.dtsi" +-#include "stm32mp15xc.dtsi" + #include "stm32mp15xx-dhcor-som.dtsi" + #include "stm32mp15xx-dhcor-avenger96.dtsi" + +-- +2.35.1 + diff --git a/queue-6.0/arm-dts-stm32-fix-av96-wlan-regulator-gpio-property.patch b/queue-6.0/arm-dts-stm32-fix-av96-wlan-regulator-gpio-property.patch new file mode 100644 index 00000000000..6523e704890 --- /dev/null +++ b/queue-6.0/arm-dts-stm32-fix-av96-wlan-regulator-gpio-property.patch @@ -0,0 +1,38 @@ +From eb6bbd1b1f6669d5426e0f3de74d65c9739ce4cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Oct 2022 12:00:57 +0200 +Subject: ARM: dts: stm32: Fix AV96 WLAN regulator gpio property + +From: Marek Vasut + +[ Upstream commit d5d577e3d50713ad11d98dbdaa48bb494346c26d ] + +The WLAN regulator uses 'gpios' property instead of 'gpio' to specify +regulator enable GPIO. While the former is also currently handled by +the Linux kernel regulator-fixed driver, the later is the correct one +per DT bindings. Update the DT to use the later. + +Fixes: 7dd5cbba42c93 ("ARM: dts: stm32: Enable WiFi on AV96") +Signed-off-by: Marek Vasut +Signed-off-by: Alexandre Torgue +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi +index 90933077d66d..b6957cbdeff5 100644 +--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi ++++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi +@@ -100,7 +100,7 @@ wlan_pwr: regulator-wlan { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + +- gpios = <&gpioz 3 GPIO_ACTIVE_HIGH>; ++ gpio = <&gpioz 3 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; +-- +2.35.1 + diff --git a/queue-6.0/arm-dts-turris-omnia-add-ethernet-aliases.patch b/queue-6.0/arm-dts-turris-omnia-add-ethernet-aliases.patch new file mode 100644 index 00000000000..95fdecdda2f --- /dev/null +++ b/queue-6.0/arm-dts-turris-omnia-add-ethernet-aliases.patch @@ -0,0 +1,43 @@ +From 05979d8a003c18aafd4886a4bc1485ede2358d4b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Jul 2022 15:09:26 +0200 +Subject: ARM: dts: turris-omnia: Add ethernet aliases +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit f1f3e530c59a7e8c5f06172f4c28b945a6b4bfb8 ] + +This allows bootloader to correctly pass MAC addresses used by bootloader +to individual interfaces into kernel device tree. + +Signed-off-by: Pali Rohár +Fixes: 26ca8b52d6e1 ("ARM: dts: add support for Turris Omnia") +Signed-off-by: Gregory CLEMENT +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/armada-385-turris-omnia.dts | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts +index a41902e3815c..96bd40351c3b 100644 +--- a/arch/arm/boot/dts/armada-385-turris-omnia.dts ++++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts +@@ -23,6 +23,12 @@ chosen { + stdout-path = &uart0; + }; + ++ aliases { ++ ethernet0 = ð0; ++ ethernet1 = ð1; ++ ethernet2 = ð2; ++ }; ++ + memory { + device_type = "memory"; + reg = <0x00000000 0x40000000>; /* 1024 MB */ +-- +2.35.1 + diff --git a/queue-6.0/arm-dts-turris-omnia-add-switch-port-6-node.patch b/queue-6.0/arm-dts-turris-omnia-add-switch-port-6-node.patch new file mode 100644 index 00000000000..b8a96cf30e7 --- /dev/null +++ b/queue-6.0/arm-dts-turris-omnia-add-switch-port-6-node.patch @@ -0,0 +1,49 @@ +From 240b281be32917646d1b78a13a80a1055a678ec3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Aug 2022 14:21:02 +0200 +Subject: ARM: dts: turris-omnia: Add switch port 6 node +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit f87db2005f73876602211af0ee156817019b6bda ] + +Switch port 6 is connected to eth0, so add appropriate device tree node for it. + +Fixes: 26ca8b52d6e1 ("ARM: dts: add support for Turris Omnia") +Signed-off-by: Pali Rohár +Reviewed-by: Andrew Lunn +Signed-off-by: Gregory CLEMENT +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/armada-385-turris-omnia.dts | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts +index 96bd40351c3b..0b64d7505dca 100644 +--- a/arch/arm/boot/dts/armada-385-turris-omnia.dts ++++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts +@@ -461,7 +461,17 @@ fixed-link { + }; + }; + +- /* port 6 is connected to eth0 */ ++ ports@6 { ++ reg = <6>; ++ label = "cpu"; ++ ethernet = <ð0>; ++ phy-mode = "rgmii-id"; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++ }; + }; + }; + }; +-- +2.35.1 + diff --git a/queue-6.0/arm-mmp-fix-timer_read-delay.patch b/queue-6.0/arm-mmp-fix-timer_read-delay.patch new file mode 100644 index 00000000000..857ac72fc54 --- /dev/null +++ b/queue-6.0/arm-mmp-fix-timer_read-delay.patch @@ -0,0 +1,59 @@ +From b28558f025cc840e5a979affc08e41e5cd16dfdf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 3 Dec 2022 16:51:17 -0800 +Subject: ARM: mmp: fix timer_read delay + +From: Doug Brown + +[ Upstream commit e348b4014c31041e13ff370669ba3348c4d385e3 ] + +timer_read() was using an empty 100-iteration loop to wait for the +TMR_CVWR register to capture the latest timer counter value. The delay +wasn't long enough. This resulted in CPU idle time being extremely +underreported on PXA168 with CONFIG_NO_HZ_IDLE=y. + +Switch to the approach used in the vendor kernel, which implements the +capture delay by reading TMR_CVWR a few times instead. + +Fixes: 49cbe78637eb ("[ARM] pxa: add base support for Marvell's PXA168 processor line") +Signed-off-by: Doug Brown +Link: https://lore.kernel.org/r/20221204005117.53452-3-doug@schmorgal.com +Signed-off-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + arch/arm/mach-mmp/time.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c +index 41b2e8abc9e6..708816caf859 100644 +--- a/arch/arm/mach-mmp/time.c ++++ b/arch/arm/mach-mmp/time.c +@@ -43,18 +43,21 @@ + static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE; + + /* +- * FIXME: the timer needs some delay to stablize the counter capture ++ * Read the timer through the CVWR register. Delay is required after requesting ++ * a read. The CR register cannot be directly read due to metastability issues ++ * documented in the PXA168 software manual. + */ + static inline uint32_t timer_read(void) + { +- int delay = 100; ++ uint32_t val; ++ int delay = 3; + + __raw_writel(1, mmp_timer_base + TMR_CVWR(1)); + + while (delay--) +- cpu_relax(); ++ val = __raw_readl(mmp_timer_base + TMR_CVWR(1)); + +- return __raw_readl(mmp_timer_base + TMR_CVWR(1)); ++ return val; + } + + static u64 notrace mmp_read_sched_clock(void) +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-armada-3720-turris-mox-add-missing-interru.patch b/queue-6.0/arm64-dts-armada-3720-turris-mox-add-missing-interru.patch new file mode 100644 index 00000000000..cffb4e77e53 --- /dev/null +++ b/queue-6.0/arm64-dts-armada-3720-turris-mox-add-missing-interru.patch @@ -0,0 +1,43 @@ +From 06356cf7576228cf5fcba9c7a3dcdfc15d846be1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 24 Sep 2022 13:58:26 +0200 +Subject: arm64: dts: armada-3720-turris-mox: Add missing interrupt for RTC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit 21aad8ba615e9c39cee6c5d0b76726f63791926c ] + +MCP7940MT-I/MNY RTC has connected interrupt line to GPIO2_5. + +Fixes: 7109d817db2e ("arm64: dts: marvell: add DTS for Turris Mox") +Signed-off-by: Pali Rohár +Reviewed-by: Andrew Lunn +Signed-off-by: Gregory CLEMENT +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts +index ada164d423f3..200f97e1c4c9 100644 +--- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts ++++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts +@@ -125,9 +125,12 @@ &i2c0 { + /delete-property/ mrvl,i2c-fast-mode; + status = "okay"; + ++ /* MCP7940MT-I/MNY RTC */ + rtc@6f { + compatible = "microchip,mcp7940x"; + reg = <0x6f>; ++ interrupt-parent = <&gpiosb>; ++ interrupts = <5 0>; /* GPIO2_5 */ + }; + }; + +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-fsd-fix-drive-strength-macros-as-per-fsd-h.patch b/queue-6.0/arm64-dts-fsd-fix-drive-strength-macros-as-per-fsd-h.patch new file mode 100644 index 00000000000..d7b4b0e8113 --- /dev/null +++ b/queue-6.0/arm64-dts-fsd-fix-drive-strength-macros-as-per-fsd-h.patch @@ -0,0 +1,95 @@ +From dbdc60a9513cd92b7b178719cd73a03749f72560 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Oct 2022 16:10:21 +0530 +Subject: arm64: dts: fsd: fix drive strength macros as per FSD HW UM + +From: Padmanabhan Rajanbabu + +[ Upstream commit 574d6c59daefb51729b0640465f007f6c9600358 ] + +Drive strength macros defined for FSD platform is not reflecting actual +names and values as per HW UM. FSD SoC pinctrl has following four levels +of drive-strength and their corresponding values: +Level-1 <-> 0 +Level-2 <-> 1 +Level-4 <-> 2 +Level-6 <-> 3 + +The commit 684dac402f21 ("arm64: dts: fsd: Add initial pinctrl support") +used drive strength macros defined for Exynos4 SoC family. For some IPs +the macros values of Exynos4 matched and worked well, but Exynos4 SoC +family drive-strength (names and values) is not exactly matching with +FSD SoC. + +Fix the drive strength macros to reflect actual names and values given +in FSD HW UM. + +Fixes: 684dac402f21 ("arm64: dts: fsd: Add initial pinctrl support") +Signed-off-by: Padmanabhan Rajanbabu +Reviewed-by: Alim Akhtar +Link: https://lore.kernel.org/r/20221013104024.50179-2-p.rajanbabu@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi | 8 ++++---- + arch/arm64/boot/dts/tesla/fsd-pinctrl.h | 6 +++--- + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi +index d0abb9aa0e9e..4e151d419909 100644 +--- a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi ++++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi +@@ -55,14 +55,14 @@ ufs_rst_n: ufs-rst-n-pins { + samsung,pins = "gpf5-0"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + ufs_refclk_out: ufs-refclk-out-pins { + samsung,pins = "gpf5-1"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + }; + +@@ -239,14 +239,14 @@ pwm0_out: pwm0-out-pins { + samsung,pins = "gpb6-1"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + pwm1_out: pwm1-out-pins { + samsung,pins = "gpb6-5"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + hs_i2c0_bus: hs-i2c0-bus-pins { +diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.h b/arch/arm64/boot/dts/tesla/fsd-pinctrl.h +index 6ffbda362493..c397d02208a0 100644 +--- a/arch/arm64/boot/dts/tesla/fsd-pinctrl.h ++++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.h +@@ -16,9 +16,9 @@ + #define FSD_PIN_PULL_UP 3 + + #define FSD_PIN_DRV_LV1 0 +-#define FSD_PIN_DRV_LV2 2 +-#define FSD_PIN_DRV_LV3 1 +-#define FSD_PIN_DRV_LV4 3 ++#define FSD_PIN_DRV_LV2 1 ++#define FSD_PIN_DRV_LV4 2 ++#define FSD_PIN_DRV_LV6 3 + + #define FSD_PIN_FUNC_INPUT 0 + #define FSD_PIN_FUNC_OUTPUT 1 +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-fsd-fix-drive-strength-values-as-per-fsd-h.patch b/queue-6.0/arm64-dts-fsd-fix-drive-strength-values-as-per-fsd-h.patch new file mode 100644 index 00000000000..16a839c3ac9 --- /dev/null +++ b/queue-6.0/arm64-dts-fsd-fix-drive-strength-values-as-per-fsd-h.patch @@ -0,0 +1,134 @@ +From 6da1f575cc94abbc83f1a09190467eaa23112762 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Oct 2022 16:10:22 +0530 +Subject: arm64: dts: fsd: fix drive strength values as per FSD HW UM + +From: Padmanabhan Rajanbabu + +[ Upstream commit 21f6546e8bf68a847601e2710378e2224bf49704 ] + +Drive strength values used for HSI2C, SPI and UART are not reflecting +the default values recommended by FSD HW UM. + +Fixes: 684dac402f21 ("arm64: dts: fsd: Add initial pinctrl support") +Signed-off-by: Padmanabhan Rajanbabu +Reviewed-by: Alim Akhtar +Link: https://lore.kernel.org/r/20221013104024.50179-3-p.rajanbabu@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi | 26 +++++++++++----------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi +index 4e151d419909..e3852c946352 100644 +--- a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi ++++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi +@@ -253,91 +253,91 @@ hs_i2c0_bus: hs-i2c0-bus-pins { + samsung,pins = "gpb0-0", "gpb0-1"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + hs_i2c1_bus: hs-i2c1-bus-pins { + samsung,pins = "gpb0-2", "gpb0-3"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + hs_i2c2_bus: hs-i2c2-bus-pins { + samsung,pins = "gpb0-4", "gpb0-5"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + hs_i2c3_bus: hs-i2c3-bus-pins { + samsung,pins = "gpb0-6", "gpb0-7"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + hs_i2c4_bus: hs-i2c4-bus-pins { + samsung,pins = "gpb1-0", "gpb1-1"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + hs_i2c5_bus: hs-i2c5-bus-pins { + samsung,pins = "gpb1-2", "gpb1-3"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + hs_i2c6_bus: hs-i2c6-bus-pins { + samsung,pins = "gpb1-4", "gpb1-5"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + hs_i2c7_bus: hs-i2c7-bus-pins { + samsung,pins = "gpb1-6", "gpb1-7"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + uart0_data: uart0-data-pins { + samsung,pins = "gpb7-0", "gpb7-1"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + uart1_data: uart1-data-pins { + samsung,pins = "gpb7-4", "gpb7-5"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + spi0_bus: spi0-bus-pins { + samsung,pins = "gpb4-0", "gpb4-2", "gpb4-3"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + spi1_bus: spi1-bus-pins { + samsung,pins = "gpb4-4", "gpb4-6", "gpb4-7"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + + spi2_bus: spi2-bus-pins { + samsung,pins = "gpb5-0", "gpb5-2", "gpb5-3"; + samsung,pin-function = ; + samsung,pin-pud = ; +- samsung,pin-drv = ; ++ samsung,pin-drv = ; + }; + }; + +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-mediatek-mt6797-fix-26m-oscillator-unit-na.patch b/queue-6.0/arm64-dts-mediatek-mt6797-fix-26m-oscillator-unit-na.patch new file mode 100644 index 00000000000..e3ac674ef03 --- /dev/null +++ b/queue-6.0/arm64-dts-mediatek-mt6797-fix-26m-oscillator-unit-na.patch @@ -0,0 +1,37 @@ +From dee8101324880120867947d131a2a08c8c2bf54b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Oct 2022 17:22:12 +0200 +Subject: arm64: dts: mediatek: mt6797: Fix 26M oscillator unit name + +From: AngeloGioacchino Del Regno + +[ Upstream commit 5f535cc583759c9c60d4cc9b8d221762e2d75387 ] + +Update its unit name to oscillator-26m and remove the unneeded unit +address to fix a unit_address_vs_reg warning. + +Fixes: 464c510f60c6 ("arm64: dts: mediatek: add mt6797 support") +Signed-off-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221013152212.416661-9-angelogioacchino.delregno@collabora.com +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/mediatek/mt6797.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt6797.dtsi b/arch/arm64/boot/dts/mediatek/mt6797.dtsi +index 15616231022a..c3677d77e0a4 100644 +--- a/arch/arm64/boot/dts/mediatek/mt6797.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt6797.dtsi +@@ -95,7 +95,7 @@ cpu9: cpu@201 { + }; + }; + +- clk26m: oscillator@0 { ++ clk26m: oscillator-26m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-mediatek-mt8195-fix-cpus-capacity-dmips-mh.patch b/queue-6.0/arm64-dts-mediatek-mt8195-fix-cpus-capacity-dmips-mh.patch new file mode 100644 index 00000000000..d555ad97820 --- /dev/null +++ b/queue-6.0/arm64-dts-mediatek-mt8195-fix-cpus-capacity-dmips-mh.patch @@ -0,0 +1,83 @@ +From 49c16ef628f615e27c9120cb5cdaa1008d75a2d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Oct 2022 11:34:03 +0200 +Subject: arm64: dts: mediatek: mt8195: Fix CPUs capacity-dmips-mhz + +From: AngeloGioacchino Del Regno + +[ Upstream commit 513c43328b189874fdfee3ae99cac81e5502e7f7 ] + +The capacity-dmips-mhz parameter was miscalculated: this SoC runs +the first (Cortex-A55) cluster at a maximum of 2000MHz and the +second (Cortex-A78) cluster at a maximum of 3000MHz. + +In order to calculate the right capacity-dmips-mhz, the following +test was performed: +1. CPUFREQ governor was set to 'performance' on both clusters +2. Ran dhrystone with 500000000 iterations for 10 times on each cluster +3. Calculate the mean result for each cluster +4. Calculate DMIPS/MHz: dmips_mhz = dmips_per_second / cpu_mhz +5. Scale results to 1024: + result_c0 = (dmips_mhz_c0 - min_dmips_mhz(c0, c1)) / + (max_dmips_mhz(c0, c1) - min_dmips_mhz(c0, c1)) * 1024 + +The mean results for this SoC are: +Cluster 0 (LITTLE): 11990400 Dhry/s +Cluster 1 (BIG): 59809036 Dhry/s + +The calculated scaled results are: +Cluster 0: 307,934312801831 (rounded to 308) +Cluster 1: 1024 + +Fixes: 37f2582883be ("arm64: dts: Add mediatek SoC mt8195 and evaluation board") +Signed-off-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221005093404.33102-1-angelogioacchino.delregno@collabora.com +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/mediatek/mt8195.dtsi | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +index 066c14989708..e694ddb74f7d 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +@@ -27,7 +27,7 @@ cpu0: cpu@0 { + reg = <0x000>; + enable-method = "psci"; + clock-frequency = <1701000000>; +- capacity-dmips-mhz = <578>; ++ capacity-dmips-mhz = <308>; + cpu-idle-states = <&cpu_off_l &cluster_off_l>; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; +@@ -39,7 +39,7 @@ cpu1: cpu@100 { + reg = <0x100>; + enable-method = "psci"; + clock-frequency = <1701000000>; +- capacity-dmips-mhz = <578>; ++ capacity-dmips-mhz = <308>; + cpu-idle-states = <&cpu_off_l &cluster_off_l>; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; +@@ -51,7 +51,7 @@ cpu2: cpu@200 { + reg = <0x200>; + enable-method = "psci"; + clock-frequency = <1701000000>; +- capacity-dmips-mhz = <578>; ++ capacity-dmips-mhz = <308>; + cpu-idle-states = <&cpu_off_l &cluster_off_l>; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; +@@ -63,7 +63,7 @@ cpu3: cpu@300 { + reg = <0x300>; + enable-method = "psci"; + clock-frequency = <1701000000>; +- capacity-dmips-mhz = <578>; ++ capacity-dmips-mhz = <308>; + cpu-idle-states = <&cpu_off_l &cluster_off_l>; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-mediatek-pumpkin-common-fix-devicetree-war.patch b/queue-6.0/arm64-dts-mediatek-pumpkin-common-fix-devicetree-war.patch new file mode 100644 index 00000000000..e14fe7ca1c3 --- /dev/null +++ b/queue-6.0/arm64-dts-mediatek-pumpkin-common-fix-devicetree-war.patch @@ -0,0 +1,55 @@ +From 392374b38a6c8510f0ad76a53445ed6942c301cc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Oct 2022 17:22:11 +0200 +Subject: arm64: dts: mediatek: pumpkin-common: Fix devicetree warnings + +From: AngeloGioacchino Del Regno + +[ Upstream commit 509438336ce75c8b4e6ce8e8d507dc77d0783bdd ] + +Fix the pinctrl submodes and optee node to remove unneeded unit address, +fixing all unit_address_vs_reg warnings. + +Fixes: 9983822c8cf9 ("arm64: dts: mediatek: add pumpkin board dts") +Signed-off-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221013152212.416661-8-angelogioacchino.delregno@collabora.com +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi +index 8ee1529683a3..ec8dfb3d1c6d 100644 +--- a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi ++++ b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi +@@ -17,7 +17,7 @@ chosen { + }; + + firmware { +- optee: optee@4fd00000 { ++ optee: optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; +@@ -209,7 +209,7 @@ pins_cmd_dat { + }; + }; + +- i2c0_pins_a: i2c0@0 { ++ i2c0_pins_a: i2c0 { + pins1 { + pinmux = , + ; +@@ -217,7 +217,7 @@ pins1 { + }; + }; + +- i2c2_pins_a: i2c2@0 { ++ i2c2_pins_a: i2c2 { + pins1 { + pinmux = , + ; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-mt2712-evb-fix-usb-vbus-regulators-unit-na.patch b/queue-6.0/arm64-dts-mt2712-evb-fix-usb-vbus-regulators-unit-na.patch new file mode 100644 index 00000000000..ab5dd6c2cca --- /dev/null +++ b/queue-6.0/arm64-dts-mt2712-evb-fix-usb-vbus-regulators-unit-na.patch @@ -0,0 +1,64 @@ +From 9752891fb840e11c3f493891e71dc242814c387e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Oct 2022 17:22:10 +0200 +Subject: arm64: dts: mt2712-evb: Fix usb vbus regulators unit names + +From: AngeloGioacchino Del Regno + +[ Upstream commit ec1ae39a8d25cfb067b5459fac7c5b7b9bce6f6a ] + +Update the names to regulator-usb-p{0-3}-vbus to fix unit_address_vs_reg +warnings for those. + +Fixes: 1724f4cc5133 ("arm64: dts: Add USB3 related nodes for MT2712") +Signed-off-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221013152212.416661-7-angelogioacchino.delregno@collabora.com +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/mediatek/mt2712-evb.dts | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts +index 638908773706..d31a194124c9 100644 +--- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts ++++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts +@@ -50,7 +50,7 @@ extcon_usb1: extcon_iddig1 { + id-gpio = <&pio 14 GPIO_ACTIVE_HIGH>; + }; + +- usb_p0_vbus: regulator@2 { ++ usb_p0_vbus: regulator-usb-p0-vbus { + compatible = "regulator-fixed"; + regulator-name = "p0_vbus"; + regulator-min-microvolt = <5000000>; +@@ -59,7 +59,7 @@ usb_p0_vbus: regulator@2 { + enable-active-high; + }; + +- usb_p1_vbus: regulator@3 { ++ usb_p1_vbus: regulator-usb-p1-vbus { + compatible = "regulator-fixed"; + regulator-name = "p1_vbus"; + regulator-min-microvolt = <5000000>; +@@ -68,7 +68,7 @@ usb_p1_vbus: regulator@3 { + enable-active-high; + }; + +- usb_p2_vbus: regulator@4 { ++ usb_p2_vbus: regulator-usb-p2-vbus { + compatible = "regulator-fixed"; + regulator-name = "p2_vbus"; + regulator-min-microvolt = <5000000>; +@@ -77,7 +77,7 @@ usb_p2_vbus: regulator@4 { + enable-active-high; + }; + +- usb_p3_vbus: regulator@5 { ++ usb_p3_vbus: regulator-usb-p3-vbus { + compatible = "regulator-fixed"; + regulator-name = "p3_vbus"; + regulator-min-microvolt = <5000000>; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-mt2712-evb-fix-vproc-fixed-regulators-unit.patch b/queue-6.0/arm64-dts-mt2712-evb-fix-vproc-fixed-regulators-unit.patch new file mode 100644 index 00000000000..c4d12ac21e5 --- /dev/null +++ b/queue-6.0/arm64-dts-mt2712-evb-fix-vproc-fixed-regulators-unit.patch @@ -0,0 +1,45 @@ +From 57ae403a4c6864dd724483c3e1421240d1db257f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Oct 2022 17:22:09 +0200 +Subject: arm64: dts: mt2712-evb: Fix vproc fixed regulators unit names + +From: AngeloGioacchino Del Regno + +[ Upstream commit 377063156893bf6c088309ac799fe5c6dce2822d ] + +Update the names to regulator-vproc-buck{0,1} to fix unit_addres_vs_reg +warnings for those. + +Fixes: f75dd8bdd344 ("arm64: dts: mediatek: add mt2712 cpufreq related device nodes") +Signed-off-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221013152212.416661-6-angelogioacchino.delregno@collabora.com +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/mediatek/mt2712-evb.dts | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts +index 9b1af9c80130..638908773706 100644 +--- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts ++++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts +@@ -26,14 +26,14 @@ chosen { + stdout-path = "serial0:921600n8"; + }; + +- cpus_fixed_vproc0: fixedregulator@0 { ++ cpus_fixed_vproc0: regulator-vproc-buck0 { + compatible = "regulator-fixed"; + regulator-name = "vproc_buck0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + +- cpus_fixed_vproc1: fixedregulator@1 { ++ cpus_fixed_vproc1: regulator-vproc-buck1 { + compatible = "regulator-fixed"; + regulator-name = "vproc_buck1"; + regulator-min-microvolt = <1000000>; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-mt2712e-fix-unit-address-for-pinctrl-node.patch b/queue-6.0/arm64-dts-mt2712e-fix-unit-address-for-pinctrl-node.patch new file mode 100644 index 00000000000..a57a3393d29 --- /dev/null +++ b/queue-6.0/arm64-dts-mt2712e-fix-unit-address-for-pinctrl-node.patch @@ -0,0 +1,42 @@ +From 0f7abaf6693998168bfe7b282f1c47ca80a6f539 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Oct 2022 17:22:08 +0200 +Subject: arm64: dts: mt2712e: Fix unit address for pinctrl node + +From: AngeloGioacchino Del Regno + +[ Upstream commit 1d4516f53a611b362db7ba7a8889923d469f57e1 ] + +The unit address for the pinctrl node is (0x)1000b000 and not +(0x)10005000, which is the syscfg_pctl_a address instead. + +This fixes the following warning: +arch/arm64/boot/dts/mediatek/mt2712e.dtsi:264.40-267.4: Warning +(unique_unit_address): /syscfg_pctl_a@10005000: duplicate +unit-address (also used in node /pinctrl@10005000) + +Fixes: f0c64340b748 ("arm64: dts: mt2712: add pintcrl device node.") +Signed-off-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221013152212.416661-5-angelogioacchino.delregno@collabora.com +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/mediatek/mt2712e.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi +index dcd3df8eb4da..2ebefd144d6f 100644 +--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi +@@ -266,7 +266,7 @@ syscfg_pctl_a: syscfg_pctl_a@10005000 { + reg = <0 0x10005000 0 0x1000>; + }; + +- pio: pinctrl@10005000 { ++ pio: pinctrl@1000b000 { + compatible = "mediatek,mt2712-pinctrl"; + reg = <0 0x1000b000 0 0x1000>; + mediatek,pctl-regmap = <&syscfg_pctl_a>; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-mt2712e-fix-unit_address_vs_reg-warning-fo.patch b/queue-6.0/arm64-dts-mt2712e-fix-unit_address_vs_reg-warning-fo.patch new file mode 100644 index 00000000000..13f039e8372 --- /dev/null +++ b/queue-6.0/arm64-dts-mt2712e-fix-unit_address_vs_reg-warning-fo.patch @@ -0,0 +1,110 @@ +From 3d6a509277f96909a34ba96600003c32c5b9ff97 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Oct 2022 17:22:07 +0200 +Subject: arm64: dts: mt2712e: Fix unit_address_vs_reg warning for oscillators + +From: AngeloGioacchino Del Regno + +[ Upstream commit e4495a0a8b3d84816c9a46edf3ce060bbf267475 ] + +Rename the fixed-clock oscillators to remove the unit address. + +This solves unit_address_vs_reg warnings. + +Fixes: 5d4839709c8e ("arm64: dts: mt2712: Add clock controller device nodes") +Signed-off-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221013152212.416661-4-angelogioacchino.delregno@collabora.com +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/mediatek/mt2712e.dtsi | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi +index 4797537cb368..dcd3df8eb4da 100644 +--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi +@@ -160,70 +160,70 @@ sys_clk: dummyclk { + #clock-cells = <0>; + }; + +- clk26m: oscillator@0 { ++ clk26m: oscillator-26m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + clock-output-names = "clk26m"; + }; + +- clk32k: oscillator@1 { ++ clk32k: oscillator-32k { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "clk32k"; + }; + +- clkfpc: oscillator@2 { ++ clkfpc: oscillator-50m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + clock-output-names = "clkfpc"; + }; + +- clkaud_ext_i_0: oscillator@3 { ++ clkaud_ext_i_0: oscillator-aud0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <6500000>; + clock-output-names = "clkaud_ext_i_0"; + }; + +- clkaud_ext_i_1: oscillator@4 { ++ clkaud_ext_i_1: oscillator-aud1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <196608000>; + clock-output-names = "clkaud_ext_i_1"; + }; + +- clkaud_ext_i_2: oscillator@5 { ++ clkaud_ext_i_2: oscillator-aud2 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <180633600>; + clock-output-names = "clkaud_ext_i_2"; + }; + +- clki2si0_mck_i: oscillator@6 { ++ clki2si0_mck_i: oscillator-i2s0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <30000000>; + clock-output-names = "clki2si0_mck_i"; + }; + +- clki2si1_mck_i: oscillator@7 { ++ clki2si1_mck_i: oscillator-i2s1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <30000000>; + clock-output-names = "clki2si1_mck_i"; + }; + +- clki2si2_mck_i: oscillator@8 { ++ clki2si2_mck_i: oscillator-i2s2 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <30000000>; + clock-output-names = "clki2si2_mck_i"; + }; + +- clktdmin_mclk_i: oscillator@9 { ++ clktdmin_mclk_i: oscillator-mclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <30000000>; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-mt6779-fix-devicetree-build-warnings.patch b/queue-6.0/arm64-dts-mt6779-fix-devicetree-build-warnings.patch new file mode 100644 index 00000000000..db5c721b31d --- /dev/null +++ b/queue-6.0/arm64-dts-mt6779-fix-devicetree-build-warnings.patch @@ -0,0 +1,76 @@ +From 2b00143330409dc450062beb4bb002cbb00fc150 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Oct 2022 17:22:06 +0200 +Subject: arm64: dts: mt6779: Fix devicetree build warnings + +From: AngeloGioacchino Del Regno + +[ Upstream commit 4d759c524c15dc4151e40b9e3f368147fda7b789 ] + +Rename fixed-clock oscillators to oscillator-26m and oscillator-32k +and remove the unit address to fix the unit_address_vs_reg warning; +fix the unit address for interrupt and intpol controllers by +removing a leading zero in their unit address. + +This commit fixes the following warnings: + +(unit_address_vs_reg): /oscillator@0: node has a unit name, but +no reg or ranges property +(unit_address_vs_reg): /oscillator@1: node has a unit name, but +no reg or ranges property +(simple_bus_reg): /soc/interrupt-controller@0c000000: simple-bus +unit address format error, expected "c000000" +(simple_bus_reg): /soc/intpol-controller@0c53a650: simple-bus +unit address format error, expected "c53a650" + +Fixes: 4c7a6260775d ("arm64: dts: add dts nodes for MT6779") +Signed-off-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221013152212.416661-3-angelogioacchino.delregno@collabora.com +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/mediatek/mt6779.dtsi | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt6779.dtsi b/arch/arm64/boot/dts/mediatek/mt6779.dtsi +index 9bdf5145966c..dde9ce137b4f 100644 +--- a/arch/arm64/boot/dts/mediatek/mt6779.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt6779.dtsi +@@ -88,14 +88,14 @@ pmu { + interrupts = ; + }; + +- clk26m: oscillator@0 { ++ clk26m: oscillator-26m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + clock-output-names = "clk26m"; + }; + +- clk32k: oscillator@1 { ++ clk32k: oscillator-32k { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; +@@ -117,7 +117,7 @@ soc { + compatible = "simple-bus"; + ranges; + +- gic: interrupt-controller@0c000000 { ++ gic: interrupt-controller@c000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <4>; + interrupt-parent = <&gic>; +@@ -138,7 +138,7 @@ ppi_cluster1: interrupt-partition-1 { + + }; + +- sysirq: intpol-controller@0c53a650 { ++ sysirq: intpol-controller@c53a650 { + compatible = "mediatek,mt6779-sysirq", + "mediatek,mt6577-sysirq"; + interrupt-controller; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-mt7896a-fix-unit_address_vs_reg-warning-fo.patch b/queue-6.0/arm64-dts-mt7896a-fix-unit_address_vs_reg-warning-fo.patch new file mode 100644 index 00000000000..c148ec08d2b --- /dev/null +++ b/queue-6.0/arm64-dts-mt7896a-fix-unit_address_vs_reg-warning-fo.patch @@ -0,0 +1,41 @@ +From 36c5b331d60ecb23dc518db7e16594521f217202 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Oct 2022 17:22:05 +0200 +Subject: arm64: dts: mt7896a: Fix unit_address_vs_reg warning for oscillator + +From: AngeloGioacchino Del Regno + +[ Upstream commit 7898d047b1eb2bec2622668cd70181442a580c6d ] + +Rename the oscillator fixed-clock to oscillator-40m and remove +the unit address to fix warnings. + +arch/arm64/boot/dts/mediatek/mt7986a.dtsi:17.23-22.4: Warning +(unit_address_vs_reg): /oscillator@0: node has a unit name, +but no reg or ranges property + +Fixes: 1f9986b258c2 ("arm64: dts: mediatek: add clock support for mt7986a") +Signed-off-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221013152212.416661-2-angelogioacchino.delregno@collabora.com +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +index 12c259ec042e..25b297bbb1b0 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +@@ -13,7 +13,7 @@ / { + #address-cells = <2>; + #size-cells = <2>; + +- clk40m: oscillator@0 { ++ clk40m: oscillator-40m { + compatible = "fixed-clock"; + clock-frequency = <40000000>; + #clock-cells = <0>; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-mt7986-fix-trng-node-name.patch b/queue-6.0/arm64-dts-mt7986-fix-trng-node-name.patch new file mode 100644 index 00000000000..d84e901bab7 --- /dev/null +++ b/queue-6.0/arm64-dts-mt7986-fix-trng-node-name.patch @@ -0,0 +1,39 @@ +From 23231ebb8ba080774b9fc0ddb4a485609d57773c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Oct 2022 17:10:22 +0200 +Subject: arm64: dts: mt7986: fix trng node name + +From: Frank Wunderlich + +[ Upstream commit 07ce611c705217507c2a036bba8695cbd82c9e36 ] + +Binding requires node name to be rng not trng: + +trng@1020f000: $nodename:0: 'trng@1020f000' does not match '^rng@[0-9a-f]+$' + +Fixes: 50137c150f5f ("arm64: dts: mediatek: add basic mt7986 support") +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221027151022.5541-1-linux@fw-web.de +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +index e3a407d03551..12c259ec042e 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +@@ -162,7 +162,7 @@ sgmiisys1: syscon@10070000 { + #clock-cells = <1>; + }; + +- trng: trng@1020f000 { ++ trng: rng@1020f000 { + compatible = "mediatek,mt7986-rng", + "mediatek,mt7623-rng"; + reg = <0 0x1020f000 0 0x100>; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-mt8183-fix-mali-gpu-clock.patch b/queue-6.0/arm64-dts-mt8183-fix-mali-gpu-clock.patch new file mode 100644 index 00000000000..162ab38e9d9 --- /dev/null +++ b/queue-6.0/arm64-dts-mt8183-fix-mali-gpu-clock.patch @@ -0,0 +1,47 @@ +From 4770263d7360988f452c3d0f7f814fbf314c004d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Sep 2022 12:11:19 +0200 +Subject: arm64: dts: mt8183: Fix Mali GPU clock +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Chen-Yu Tsai + +[ Upstream commit ad2631b5645a1d0ca9bf6fecf71f77e3b0071ee5 ] + +The actual clock feeding into the Mali GPU on the MT8183 is from the +clock gate in the MFGCFG block, not CLK_TOP_MFGPLL_CK from the TOPCKGEN +block, which itself is simply a pass-through placeholder for the MFGPLL +in the APMIXEDSYS block. + +Fix the hardware description with the correct clock reference. + +Fixes: a8168cebf1bc ("arm64: dts: mt8183: Add node for the Mali GPU") +Signed-off-by: Chen-Yu Tsai +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: AngeloGioacchino Del Regno +Tested-by: Nícolas F. R. A. Prado +Link: https://lore.kernel.org/r/20220927101128.44758-2-angelogioacchino.delregno@collabora.com +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/mediatek/mt8183.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +index 9d32871973a2..85fb61324be8 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +@@ -1670,7 +1670,7 @@ gpu: gpu@13040000 { + ; + interrupt-names = "job", "mmu", "gpu"; + +- clocks = <&topckgen CLK_TOP_MFGPLL_CK>; ++ clocks = <&mfgcfg CLK_MFG_BG3D>; + + power-domains = + <&spm MT8183_POWER_DOMAIN_MFG_CORE0>, +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-ipq6018-cp01-c1-use-blspi1-pins.patch b/queue-6.0/arm64-dts-qcom-ipq6018-cp01-c1-use-blspi1-pins.patch new file mode 100644 index 00000000000..3a40fe50e1c --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-ipq6018-cp01-c1-use-blspi1-pins.patch @@ -0,0 +1,40 @@ +From 7d9e5a9587877671a944855f4657520ad1688e4b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Oct 2022 14:46:26 +0200 +Subject: arm64: dts: qcom: ipq6018-cp01-c1: use BLSPI1 pins + +From: Krzysztof Kozlowski + +[ Upstream commit 4871d3c38893c8a585e3e96364b7fb91cda8322e ] + +When BLSPI1 (originally SPI0, later renamed in commit f82c48d46852 +("arm64: dts: qcom: ipq6018: correct QUP peripheral labels")) was added, +the device node lacked respective pin configuration assignment. + +Fixes: 5bf635621245 ("arm64: dts: ipq6018: Add a few device nodes") +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Bjorn Andersson +Reviewed-by: Konrad Dybcio +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221006124659.217540-2-krzysztof.kozlowski@linaro.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts b/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts +index 1ba2eca33c7b..6a716c83e5f1 100644 +--- a/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts ++++ b/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts +@@ -37,6 +37,8 @@ &blsp1_i2c3 { + + &blsp1_spi1 { + cs-select = <0>; ++ pinctrl-0 = <&spi_0_pins>; ++ pinctrl-names = "default"; + status = "okay"; + + flash@0 { +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-msm8916-drop-mss-fallback-compatible.patch b/queue-6.0/arm64-dts-qcom-msm8916-drop-mss-fallback-compatible.patch new file mode 100644 index 00000000000..2649a608550 --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-msm8916-drop-mss-fallback-compatible.patch @@ -0,0 +1,52 @@ +From e12ef969db4b65e624eb25f27688ecbdc929b3ca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Jul 2022 16:03:40 +0200 +Subject: arm64: dts: qcom: msm8916: Drop MSS fallback compatible + +From: Stephan Gerhold + +[ Upstream commit ff02ac621634e82c0c34d02a79d402ae700cdfd0 ] + +MSM8916 was originally using the "qcom,q6v5-pil" compatible for the +MSS remoteproc. Later it was decided to use SoC-specific compatibles +instead, so "qcom,msm8916-mss-pil" is now the preferred compatible. + +Commit 60a05ed059a0 ("arm64: dts: qcom: msm8916: Add MSM8916-specific +compatibles to SCM/MSS") updated the MSM8916 device tree to make use of +the new compatible but still kept the old "qcom,q6v5-pil" as fallback. + +This is inconsistent with other SoCs and conflicts with the description +in the binding documentation (which says that only one compatible should +be present). Also, it has no functional advantage since older kernels +could not handle this DT anyway (e.g. "power-domains" in the MSS node is +only supported by kernels that also support "qcom,msm8916-mss-pil"). + +Make this consistent with other SoCs by using only the +"qcom,msm8916-mss-pil" compatible. + +Fixes: 60a05ed059a0 ("arm64: dts: qcom: msm8916: Add MSM8916-specific compatibles to SCM/MSS") +Signed-off-by: Stephan Gerhold +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220718140344.1831731-2-stephan.gerhold@kernkonzept.com +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 48bc2e09128d..863a60b63641 100644 +--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi +@@ -1331,7 +1331,7 @@ bam_dmux_dma: dma-controller@4044000 { + }; + + mpss: remoteproc@4080000 { +- compatible = "qcom,msm8916-mss-pil", "qcom,q6v5-pil"; ++ compatible = "qcom,msm8916-mss-pil"; + reg = <0x04080000 0x100>, + <0x04020000 0x040>; + +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-msm8996-add-msm8996-pro-support.patch b/queue-6.0/arm64-dts-qcom-msm8996-add-msm8996-pro-support.patch new file mode 100644 index 00000000000..5874539abe7 --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-msm8996-add-msm8996-pro-support.patch @@ -0,0 +1,567 @@ +From f83a05c8f0d41ed1521f8db0015f6365fcb3bab4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Jul 2022 17:04:16 +0300 +Subject: arm64: dts: qcom: msm8996: Add MSM8996 Pro support + +From: Yassine Oudjana + +[ Upstream commit 8898c9748a872866f8c2973e719b26bf7c6ab64e ] + +Qualcomm MSM8996 Pro is a variant of MSM8996 with higher frequencies +supported both on CPU and GPU. There are other minor hardware +differencies in the CPU and GPU regulators and bus fabrics. + +However this results in significant differences between 8996 and 8996 +Pro CPU OPP tables. Judging from msm-3.18 there are only few common +frequencies supported by both msm8996 and msm8996pro. Rather than +hacking the tables for msm8996, split msm8996pro support into a separate +file. Later this would allow having additional customizations for the +CBF, CPR, retulators, etc. + +[DB: dropped all non-CPU-OPP changes] + +Fixes: 90173a954a22 ("arm64: dts: qcom: msm8996: Add CPU opps") +Signed-off-by: Yassine Oudjana +[DB: Realigned supported-hw to keep compat with current cpufreq driver] +Signed-off-by: Dmitry Baryshkov +Acked-by: Krzysztof Kozlowski +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220724140421.1933004-3-dmitry.baryshkov@linaro.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/msm8996.dtsi | 82 +++---- + arch/arm64/boot/dts/qcom/msm8996pro.dtsi | 266 +++++++++++++++++++++++ + 2 files changed, 307 insertions(+), 41 deletions(-) + create mode 100644 arch/arm64/boot/dts/qcom/msm8996pro.dtsi + +diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi +index 742eac4ce9b3..41c09895268e 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi +@@ -143,82 +143,82 @@ cluster0_opp: opp-table-cluster0 { + /* Nominal fmax for now */ + opp-307200000 { + opp-hz = /bits/ 64 <307200000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-422400000 { + opp-hz = /bits/ 64 <422400000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-556800000 { + opp-hz = /bits/ 64 <556800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-652800000 { + opp-hz = /bits/ 64 <652800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-729600000 { + opp-hz = /bits/ 64 <729600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-844800000 { + opp-hz = /bits/ 64 <844800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-960000000 { + opp-hz = /bits/ 64 <960000000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1036800000 { + opp-hz = /bits/ 64 <1036800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1113600000 { + opp-hz = /bits/ 64 <1113600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1190400000 { + opp-hz = /bits/ 64 <1190400000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1228800000 { + opp-hz = /bits/ 64 <1228800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1324800000 { + opp-hz = /bits/ 64 <1324800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1401600000 { + opp-hz = /bits/ 64 <1401600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1478400000 { + opp-hz = /bits/ 64 <1478400000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1593600000 { + opp-hz = /bits/ 64 <1593600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + }; +@@ -231,127 +231,127 @@ cluster1_opp: opp-table-cluster1 { + /* Nominal fmax for now */ + opp-307200000 { + opp-hz = /bits/ 64 <307200000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-403200000 { + opp-hz = /bits/ 64 <403200000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-556800000 { + opp-hz = /bits/ 64 <556800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-652800000 { + opp-hz = /bits/ 64 <652800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-729600000 { + opp-hz = /bits/ 64 <729600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-806400000 { + opp-hz = /bits/ 64 <806400000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-883200000 { + opp-hz = /bits/ 64 <883200000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-940800000 { + opp-hz = /bits/ 64 <940800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1036800000 { + opp-hz = /bits/ 64 <1036800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1113600000 { + opp-hz = /bits/ 64 <1113600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1190400000 { + opp-hz = /bits/ 64 <1190400000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1248000000 { + opp-hz = /bits/ 64 <1248000000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1324800000 { + opp-hz = /bits/ 64 <1324800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1401600000 { + opp-hz = /bits/ 64 <1401600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1478400000 { + opp-hz = /bits/ 64 <1478400000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1555200000 { + opp-hz = /bits/ 64 <1555200000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1632000000 { + opp-hz = /bits/ 64 <1632000000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1708800000 { + opp-hz = /bits/ 64 <1708800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1785600000 { + opp-hz = /bits/ 64 <1785600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1824000000 { + opp-hz = /bits/ 64 <1824000000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1920000000 { + opp-hz = /bits/ 64 <1920000000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-1996800000 { + opp-hz = /bits/ 64 <1996800000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-2073600000 { + opp-hz = /bits/ 64 <2073600000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + opp-2150400000 { + opp-hz = /bits/ 64 <2150400000>; +- opp-supported-hw = <0x77>; ++ opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/msm8996pro.dtsi b/arch/arm64/boot/dts/qcom/msm8996pro.dtsi +new file mode 100644 +index 000000000000..63e1b4ec7a36 +--- /dev/null ++++ b/arch/arm64/boot/dts/qcom/msm8996pro.dtsi +@@ -0,0 +1,266 @@ ++// SPDX-License-Identifier: BSD-3-Clause ++/* ++ * Copyright (c) 2022, Linaro Limited ++ */ ++ ++#include "msm8996.dtsi" ++ ++/ { ++ /delete-node/ opp-table-cluster0; ++ /delete-node/ opp-table-cluster1; ++ ++ /* ++ * On MSM8996 Pro the cpufreq driver shifts speed bins into the high ++ * nibble of supported hw, so speed bin 0 becomes 0x10, speed bin 1 ++ * becomes 0x20, speed 2 becomes 0x40. ++ */ ++ ++ cluster0_opp: opp-table-cluster0 { ++ compatible = "operating-points-v2-kryo-cpu"; ++ nvmem-cells = <&speedbin_efuse>; ++ opp-shared; ++ ++ opp-307200000 { ++ opp-hz = /bits/ 64 <307200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-384000000 { ++ opp-hz = /bits/ 64 <384000000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-460800000 { ++ opp-hz = /bits/ 64 <460800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-537600000 { ++ opp-hz = /bits/ 64 <537600000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-614400000 { ++ opp-hz = /bits/ 64 <614400000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-691200000 { ++ opp-hz = /bits/ 64 <691200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-768000000 { ++ opp-hz = /bits/ 64 <768000000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-844800000 { ++ opp-hz = /bits/ 64 <844800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-902400000 { ++ opp-hz = /bits/ 64 <902400000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-979200000 { ++ opp-hz = /bits/ 64 <979200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1056000000 { ++ opp-hz = /bits/ 64 <1056000000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1132800000 { ++ opp-hz = /bits/ 64 <1132800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1209600000 { ++ opp-hz = /bits/ 64 <1209600000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1286400000 { ++ opp-hz = /bits/ 64 <1286400000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1363200000 { ++ opp-hz = /bits/ 64 <1363200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1440000000 { ++ opp-hz = /bits/ 64 <1440000000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1516800000 { ++ opp-hz = /bits/ 64 <1516800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1593600000 { ++ opp-hz = /bits/ 64 <1593600000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1996800000 { ++ opp-hz = /bits/ 64 <1996800000>; ++ opp-supported-hw = <0x20>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-2188800000 { ++ opp-hz = /bits/ 64 <2188800000>; ++ opp-supported-hw = <0x10>; ++ clock-latency-ns = <200000>; ++ }; ++ }; ++ ++ cluster1_opp: opp-table-cluster1 { ++ compatible = "operating-points-v2-kryo-cpu"; ++ nvmem-cells = <&speedbin_efuse>; ++ opp-shared; ++ ++ opp-307200000 { ++ opp-hz = /bits/ 64 <307200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-384000000 { ++ opp-hz = /bits/ 64 <384000000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-460800000 { ++ opp-hz = /bits/ 64 <460800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-537600000 { ++ opp-hz = /bits/ 64 <537600000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-614400000 { ++ opp-hz = /bits/ 64 <614400000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-691200000 { ++ opp-hz = /bits/ 64 <691200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-748800000 { ++ opp-hz = /bits/ 64 <748800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-825600000 { ++ opp-hz = /bits/ 64 <825600000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-902400000 { ++ opp-hz = /bits/ 64 <902400000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-979200000 { ++ opp-hz = /bits/ 64 <979200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1056000000 { ++ opp-hz = /bits/ 64 <1056000000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1132800000 { ++ opp-hz = /bits/ 64 <1132800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1209600000 { ++ opp-hz = /bits/ 64 <1209600000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1286400000 { ++ opp-hz = /bits/ 64 <1286400000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1363200000 { ++ opp-hz = /bits/ 64 <1363200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1440000000 { ++ opp-hz = /bits/ 64 <1440000000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1516800000 { ++ opp-hz = /bits/ 64 <1516800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1593600000 { ++ opp-hz = /bits/ 64 <1593600000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1670400000 { ++ opp-hz = /bits/ 64 <1670400000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1747200000 { ++ opp-hz = /bits/ 64 <1747200000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1824000000 { ++ opp-hz = /bits/ 64 <1824000000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1900800000 { ++ opp-hz = /bits/ 64 <1900800000>; ++ opp-supported-hw = <0x70>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1977600000 { ++ opp-hz = /bits/ 64 <1977600000>; ++ opp-supported-hw = <0x30>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-2054400000 { ++ opp-hz = /bits/ 64 <2054400000>; ++ opp-supported-hw = <0x30>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-2150400000 { ++ opp-hz = /bits/ 64 <2150400000>; ++ opp-supported-hw = <0x30>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-2246400000 { ++ opp-hz = /bits/ 64 <2246400000>; ++ opp-supported-hw = <0x10>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-2342400000 { ++ opp-hz = /bits/ 64 <2342400000>; ++ opp-supported-hw = <0x10>; ++ clock-latency-ns = <200000>; ++ }; ++ }; ++}; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-msm8996-fix-gpu-opp-table.patch b/queue-6.0/arm64-dts-qcom-msm8996-fix-gpu-opp-table.patch new file mode 100644 index 00000000000..59afb6e7646 --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-msm8996-fix-gpu-opp-table.patch @@ -0,0 +1,52 @@ +From e14a01a887dee26ec3beba0e9520e84fc958eecc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Jul 2022 17:04:20 +0300 +Subject: arm64: dts: qcom: msm8996: fix GPU OPP table + +From: Dmitry Baryshkov + +[ Upstream commit 0d440d811e6e2f37093e54db55bc27fe66678170 ] + +Fix Adreno OPP table according to the msm-3.18. Enable 624 MHz for the +speed bin 3 and 560 MHz for bins 2 and 3. + +Fixes: 69cc3114ab0f ("arm64: dts: Add Adreno GPU definitions") +Signed-off-by: Dmitry Baryshkov +Acked-by: Krzysztof Kozlowski +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220724140421.1933004-7-dmitry.baryshkov@linaro.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/msm8996.dtsi | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi +index 24791ed436c5..c8b9d7d60774 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi +@@ -1228,17 +1228,17 @@ gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* +- * 624Mhz and 560Mhz are only available on speed +- * bin (1 << 0). All the rest are available on +- * all bins of the hardware ++ * 624Mhz is only available on speed bins 0 and 3. ++ * 560Mhz is only available on speed bins 0, 2 and 3. ++ * All the rest are available on all bins of the hardware. + */ + opp-624000000 { + opp-hz = /bits/ 64 <624000000>; +- opp-supported-hw = <0x01>; ++ opp-supported-hw = <0x09>; + }; + opp-560000000 { + opp-hz = /bits/ 64 <560000000>; +- opp-supported-hw = <0x01>; ++ opp-supported-hw = <0x0d>; + }; + opp-510000000 { + opp-hz = /bits/ 64 <510000000>; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-msm8996-fix-sound-card-reset-line-pol.patch b/queue-6.0/arm64-dts-qcom-msm8996-fix-sound-card-reset-line-pol.patch new file mode 100644 index 00000000000..efa79ef8558 --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-msm8996-fix-sound-card-reset-line-pol.patch @@ -0,0 +1,39 @@ +From ae065a33886ef7bc6d5278b9f0d6ff21fa7ffe94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Oct 2022 00:46:47 -0700 +Subject: arm64: dts: qcom: msm8996: fix sound card reset line polarity + +From: Dmitry Torokhov + +[ Upstream commit 76d21ffc5d425bf7ea9888652c49d7dbda15f356 ] + +When resetting the block, the reset line is being driven low and then +high, which means that the line in DTS should be annotated as "active +low". It will become important when wcd9335 driver will be converted +to gpiod API that respects declared line polarities. + +Fixes: f3eb39a55a1f ("arm64: dts: db820c: Add sound card support") +Signed-off-by: Dmitry Torokhov +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221027074652.1044235-1-dmitry.torokhov@gmail.com +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/msm8996.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi +index d3cf0677ea28..5cf04c350a62 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi +@@ -3358,7 +3358,7 @@ wcd9335: codec@1{ + interrupt-names = "intr1", "intr2"; + interrupt-controller; + #interrupt-cells = <1>; +- reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>; ++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_LOW>; + + slim-ifc-dev = <&tasha_ifd>; + +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-msm8996-fix-supported-hw-in-cpufreq-o.patch b/queue-6.0/arm64-dts-qcom-msm8996-fix-supported-hw-in-cpufreq-o.patch new file mode 100644 index 00000000000..48b39722c89 --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-msm8996-fix-supported-hw-in-cpufreq-o.patch @@ -0,0 +1,113 @@ +From b91adb4760ad9fdc992f7879690bac1ea347c607 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Jul 2022 17:04:18 +0300 +Subject: arm64: dts: qcom: msm8996: fix supported-hw in cpufreq OPP tables + +From: Dmitry Baryshkov + +[ Upstream commit 0154caaa2b748e7414a4ec3c6ee60e8f483b2d4f ] + +Adjust MSM8996 cpufreq tables according to tables in msm-3.18. Some of +the frequencies are not supported on speed bins other than 0. Also other +speed bins support intermediate topmost frequencies, not supported on +speed bin 0. Implement all these differencies. + +Fixes: 90173a954a22 ("arm64: dts: qcom: msm8996: Add CPU opps") +Signed-off-by: Dmitry Baryshkov +Acked-by: Krzysztof Kozlowski +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220724140421.1933004-5-dmitry.baryshkov@linaro.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/msm8996.dtsi | 38 ++++++++++++++++++++------- + 1 file changed, 29 insertions(+), 9 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi +index 41c09895268e..24791ed436c5 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi +@@ -203,22 +203,32 @@ opp-1228800000 { + }; + opp-1324800000 { + opp-hz = /bits/ 64 <1324800000>; +- opp-supported-hw = <0x7>; ++ opp-supported-hw = <0x5>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1363200000 { ++ opp-hz = /bits/ 64 <1363200000>; ++ opp-supported-hw = <0x2>; + clock-latency-ns = <200000>; + }; + opp-1401600000 { + opp-hz = /bits/ 64 <1401600000>; +- opp-supported-hw = <0x7>; ++ opp-supported-hw = <0x5>; + clock-latency-ns = <200000>; + }; + opp-1478400000 { + opp-hz = /bits/ 64 <1478400000>; +- opp-supported-hw = <0x7>; ++ opp-supported-hw = <0x1>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1497600000 { ++ opp-hz = /bits/ 64 <1497600000>; ++ opp-supported-hw = <0x04>; + clock-latency-ns = <200000>; + }; + opp-1593600000 { + opp-hz = /bits/ 64 <1593600000>; +- opp-supported-hw = <0x7>; ++ opp-supported-hw = <0x1>; + clock-latency-ns = <200000>; + }; + }; +@@ -329,29 +339,39 @@ opp-1785600000 { + opp-supported-hw = <0x7>; + clock-latency-ns = <200000>; + }; ++ opp-1804800000 { ++ opp-hz = /bits/ 64 <1804800000>; ++ opp-supported-hw = <0x6>; ++ clock-latency-ns = <200000>; ++ }; + opp-1824000000 { + opp-hz = /bits/ 64 <1824000000>; +- opp-supported-hw = <0x7>; ++ opp-supported-hw = <0x1>; ++ clock-latency-ns = <200000>; ++ }; ++ opp-1900800000 { ++ opp-hz = /bits/ 64 <1900800000>; ++ opp-supported-hw = <0x4>; + clock-latency-ns = <200000>; + }; + opp-1920000000 { + opp-hz = /bits/ 64 <1920000000>; +- opp-supported-hw = <0x7>; ++ opp-supported-hw = <0x1>; + clock-latency-ns = <200000>; + }; + opp-1996800000 { + opp-hz = /bits/ 64 <1996800000>; +- opp-supported-hw = <0x7>; ++ opp-supported-hw = <0x1>; + clock-latency-ns = <200000>; + }; + opp-2073600000 { + opp-hz = /bits/ 64 <2073600000>; +- opp-supported-hw = <0x7>; ++ opp-supported-hw = <0x1>; + clock-latency-ns = <200000>; + }; + opp-2150400000 { + opp-hz = /bits/ 64 <2150400000>; +- opp-supported-hw = <0x7>; ++ opp-supported-hw = <0x1>; + clock-latency-ns = <200000>; + }; + }; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-pm6350-include-header-for-key_power.patch b/queue-6.0/arm64-dts-qcom-pm6350-include-header-for-key_power.patch new file mode 100644 index 00000000000..2e763065f3e --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-pm6350-include-header-for-key_power.patch @@ -0,0 +1,38 @@ +From 946cbab2f4a008d7080f09e918e407b9df6b8dc7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 30 Oct 2022 08:32:26 +0100 +Subject: arm64: dts: qcom: pm6350: Include header for KEY_POWER + +From: Marijn Suijten + +[ Upstream commit f6e2d6914c7c095660a9c7c503328eebab1e2557 ] + +Make pm6350.dtsi self-contained by including input.h, needed for the +KEY_POWER constant used to define the power key. + +Fixes: d8a3c775d7cd ("arm64: dts: qcom: Add PM6350 PMIC") +Signed-off-by: Marijn Suijten +Reviewed-by: Konrad Dybcio +Reviewed-by: Luca Weiss +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221030073232.22726-5-marijn.suijten@somainline.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/pm6350.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/qcom/pm6350.dtsi b/arch/arm64/boot/dts/qcom/pm6350.dtsi +index ecf9b9919182..68245d78d2b9 100644 +--- a/arch/arm64/boot/dts/qcom/pm6350.dtsi ++++ b/arch/arm64/boot/dts/qcom/pm6350.dtsi +@@ -3,6 +3,7 @@ + * Copyright (c) 2021, Luca Weiss + */ + ++#include + #include + + &spmi_bus { +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-pm660-use-unique-adc5_vcoin-address-i.patch b/queue-6.0/arm64-dts-qcom-pm660-use-unique-adc5_vcoin-address-i.patch new file mode 100644 index 00000000000..5391340a579 --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-pm660-use-unique-adc5_vcoin-address-i.patch @@ -0,0 +1,39 @@ +From b0aceb7317ce94b5f206ff9f5fe21430ff1247b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Sep 2022 21:01:45 +0200 +Subject: arm64: dts: qcom: pm660: Use unique ADC5_VCOIN address in node name + +From: Marijn Suijten + +[ Upstream commit 02549ba5de0a09a27616496c3512db5af4ad7862 ] + +The register address in the node name is shadowing vph_pwr@83, whereas +the ADC5_VCOIN register resolves to 0x85. Fix this copy-paste +discrepancy. + +Fixes: 4bf097540506 ("arm64: dts: qcom: pm660: Add VADC and temp alarm nodes") +Signed-off-by: Marijn Suijten +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220926190148.283805-3-marijn.suijten@somainline.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/pm660.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/pm660.dtsi b/arch/arm64/boot/dts/qcom/pm660.dtsi +index d0eefbb51663..d8c9ece20cd9 100644 +--- a/arch/arm64/boot/dts/qcom/pm660.dtsi ++++ b/arch/arm64/boot/dts/qcom/pm660.dtsi +@@ -163,7 +163,7 @@ vadc_vph_pwr: vph_pwr@83 { + qcom,pre-scaling = <1 3>; + }; + +- vcoin: vcoin@83 { ++ vcoin: vcoin@85 { + reg = ; + qcom,decimation = <1024>; + qcom,pre-scaling = <1 3>; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-sc7180-trogdor-homestar-fully-configu.patch b/queue-6.0/arm64-dts-qcom-sc7180-trogdor-homestar-fully-configu.patch new file mode 100644 index 00000000000..6803c0ce04b --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-sc7180-trogdor-homestar-fully-configu.patch @@ -0,0 +1,49 @@ +From f91321db48322311a1cf0e881efbc8e44a842cbf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Oct 2022 18:51:33 -0400 +Subject: arm64: dts: qcom: sc7180-trogdor-homestar: fully configure secondary + I2S pins + +From: Krzysztof Kozlowski + +[ Upstream commit 59e787935cfe6f562fbb9117e2df4076eaf810d8 ] + +The Trogdor Homestar DTSI adds additional GPIO52 pin to secondary I2S pins +("sec_mi2s_active") and configures it to "mi2s_1" function. + +The Trogdor DTSI (which is included by Homestar) configures drive +strength and bias for all "sec_mi2s_active" pins, thus the intention was +to apply this configuration also to GPIO52 on Homestar. + +Reported-by: Doug Anderson +Signed-off-by: Krzysztof Kozlowski +Fixes: be0416a3f917 ("arm64: dts: qcom: Add sc7180-trogdor-homestar") +Reviewed-by: Douglas Anderson +Reviewed-by: Stephen Boyd +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221020225135.31750-2-krzysztof.kozlowski@linaro.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi +index 1bd6c7dcd9e9..bfab67f4a7c9 100644 +--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi +@@ -194,6 +194,12 @@ pinmux { + pins = "gpio49", "gpio50", "gpio51", "gpio52"; + function = "mi2s_1"; + }; ++ ++ pinconf { ++ pins = "gpio49", "gpio50", "gpio51", "gpio52"; ++ drive-strength = <2>; ++ bias-pull-down; ++ }; + }; + + &ts_reset_l { +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-sdm630-fix-uart1-pin-bias.patch b/queue-6.0/arm64-dts-qcom-sdm630-fix-uart1-pin-bias.patch new file mode 100644 index 00000000000..f360f16613d --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-sdm630-fix-uart1-pin-bias.patch @@ -0,0 +1,38 @@ +From 21aef9ce0381507123b8639f38642ea8dfd9610a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 07:44:12 -0400 +Subject: arm64: dts: qcom: sdm630: fix UART1 pin bias + +From: Krzysztof Kozlowski + +[ Upstream commit 780f836fe071a9e8703fe6a05ae00129acf83391 ] + +There is no "bias-no-pull" property. Assume intentions were disabling +bias. + +Fixes: b190fb010664 ("arm64: dts: qcom: sdm630: Add sdm630 dts file") +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Douglas Anderson +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221010114417.29859-1-krzysztof.kozlowski@linaro.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdm630.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi +index 1bc9091cad2a..12f01815230b 100644 +--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi +@@ -773,7 +773,7 @@ rx-cts-rts { + pins = "gpio17", "gpio18", "gpio19"; + function = "gpio"; + drive-strength = <2>; +- bias-no-pull; ++ bias-disable; + }; + }; + +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-sdm845-cheza-fix-ap-suspend-pin-bias.patch b/queue-6.0/arm64-dts-qcom-sdm845-cheza-fix-ap-suspend-pin-bias.patch new file mode 100644 index 00000000000..cd0e9ae31ca --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-sdm845-cheza-fix-ap-suspend-pin-bias.patch @@ -0,0 +1,47 @@ +From 067ae70075977f547bf400541a714e6ecf426880 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 07:44:14 -0400 +Subject: arm64: dts: qcom: sdm845-cheza: fix AP suspend pin bias + +From: Krzysztof Kozlowski + +[ Upstream commit 9bce41fab14da8f21027dc9847535ef5e22cbe8b ] + +There is no "bias-no-pull" property. Assume intentions were disabling +bias. + +Fixes: 79e7739f7b87 ("arm64: dts: qcom: sdm845-cheza: add initial cheza dt") +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Douglas Anderson +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221010114417.29859-3-krzysztof.kozlowski@linaro.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi +index b5eb8f7eca1d..b5f11fbcc300 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi +@@ -1436,7 +1436,7 @@ ap_suspend_l_assert: ap_suspend_l_assert { + config { + pins = "gpio126"; + function = "gpio"; +- bias-no-pull; ++ bias-disable; + drive-strength = <2>; + output-low; + }; +@@ -1446,7 +1446,7 @@ ap_suspend_l_deassert: ap_suspend_l_deassert { + config { + pins = "gpio126"; + function = "gpio"; +- bias-no-pull; ++ bias-disable; + drive-strength = <2>; + output-high; + }; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-sdm845-xiaomi-polaris-fix-codec-pin-c.patch b/queue-6.0/arm64-dts-qcom-sdm845-xiaomi-polaris-fix-codec-pin-c.patch new file mode 100644 index 00000000000..79a787b53b1 --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-sdm845-xiaomi-polaris-fix-codec-pin-c.patch @@ -0,0 +1,39 @@ +From 0f53c84610d2e7d122cdf1c123762bb546584d13 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Sep 2022 21:20:39 +0200 +Subject: arm64: dts: qcom: sdm845-xiaomi-polaris: fix codec pin conf name + +From: Krzysztof Kozlowski + +[ Upstream commit 58c4a0b6f4bdf8c3c2b4aad7f980e4019cc0fc83 ] + +Fix typo in the codec's pin name to be configured. Mismatched name +caused the pin configuration to be ignored. + +Fixes: be497abe19bf ("arm64: dts: qcom: Add support for Xiaomi Mi Mix2s") +Signed-off-by: Krzysztof Kozlowski +Tested-by: Molly Sophia +Reviewed-by: Konrad Dybcio +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220930192039.240486-3-krzysztof.kozlowski@linaro.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts +index dba7c2693ff5..2611a5c40ba3 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts +@@ -628,7 +628,7 @@ sde_dsi_suspend: sde-dsi-suspend { + }; + + wcd_intr_default: wcd-intr-default { +- pins = "goui54"; ++ pins = "gpio54"; + function = "gpio"; + input-enable; + bias-pull-down; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-sm6125-fix-sdhci-cqe-reg-names.patch b/queue-6.0/arm64-dts-qcom-sm6125-fix-sdhci-cqe-reg-names.patch new file mode 100644 index 00000000000..e521f8591b3 --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-sm6125-fix-sdhci-cqe-reg-names.patch @@ -0,0 +1,39 @@ +From d2129faba085731f753087fa6c7a384babac353b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 12:36:46 -0400 +Subject: arm64: dts: qcom: sm6125: fix SDHCI CQE reg names + +From: Krzysztof Kozlowski + +[ Upstream commit 3de1172624b3c4ca65730bc34333ab493510b3e1 ] + +SM6125 comes with SDCC (SDHCI controller) v5, so the second range of +registers is cqhci, not core. + +Fixes: cff4bbaf2a2d ("arm64: dts: qcom: Add support for SM6125") +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Marijn Suijten +Tested-by: Marijn Suijten # Sony Xperia 10 II +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221026163646.37433-1-krzysztof.kozlowski@linaro.org +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 8c582a9e4ada..012722408682 100644 +--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi +@@ -458,7 +458,7 @@ rpm_msg_ram: sram@45f0000 { + sdhc_1: mmc@4744000 { + compatible = "qcom,sm6125-sdhci", "qcom,sdhci-msm-v5"; + reg = <0x04744000 0x1000>, <0x04745000 0x1000>; +- reg-names = "hc", "core"; ++ reg-names = "hc", "cqhci"; + + interrupts = , + ; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-sm6350-add-apps_smmu-with-streamid-to.patch b/queue-6.0/arm64-dts-qcom-sm6350-add-apps_smmu-with-streamid-to.patch new file mode 100644 index 00000000000..cf3bb5286c6 --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-sm6350-add-apps_smmu-with-streamid-to.patch @@ -0,0 +1,54 @@ +From c028175bda799fcd0212c5ce26b3bd414dabfcdd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 30 Oct 2022 08:32:32 +0100 +Subject: arm64: dts: qcom: sm6350: Add apps_smmu with streamID to SDHCI 1/2 + nodes + +From: Marijn Suijten + +[ Upstream commit 7372b944a6ba5ac86628eaacc89ed4f103435cb9 ] + +When enabling the APPS SMMU the mainline driver reconfigures the SMMU +from its bootloader configuration, losing the stream mapping for (among +which) the SDHCI hardware and breaking its ADMA feature. This feature +can be disabled with: + + sdhci.debug_quirks=0x40 + +But it is of course desired to have this feature enabled and working +through the SMMU. + +Signed-off-by: Marijn Suijten +Reviewed-by: Konrad Dybcio +Reviewed-by: Luca Weiss +Tested-by: Luca Weiss # sm7225-fairphone-fp4 +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221030073232.22726-11-marijn.suijten@somainline.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm6350.dtsi | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi +index ec64b6a12e20..4ec19f8ba928 100644 +--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi +@@ -482,6 +482,7 @@ sdhc_1: mmc@7c4000 { + interrupts = , + ; + interrupt-names = "hc_irq", "pwr_irq"; ++ iommus = <&apps_smmu 0x60 0x0>; + + clocks = <&gcc GCC_SDCC1_AHB_CLK>, + <&gcc GCC_SDCC1_APPS_CLK>, +@@ -928,6 +929,7 @@ sdhc_2: mmc@8804000 { + interrupts = , + ; + interrupt-names = "hc_irq", "pwr_irq"; ++ iommus = <&apps_smmu 0x560 0x0>; + + clocks = <&gcc GCC_SDCC2_AHB_CLK>, + <&gcc GCC_SDCC2_APPS_CLK>, +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-sm6350-drop-bogus-dp-phy-clock.patch b/queue-6.0/arm64-dts-qcom-sm6350-drop-bogus-dp-phy-clock.patch new file mode 100644 index 00000000000..79747a6b7cb --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-sm6350-drop-bogus-dp-phy-clock.patch @@ -0,0 +1,38 @@ +From 7863a1ad0e83726879b3c9296aa1a90db64d8405 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 17:25:11 +0200 +Subject: arm64: dts: qcom: sm6350: drop bogus DP PHY clock + +From: Johan Hovold + +[ Upstream commit 95fade4016cbd57ee050ab226c8f0483af1753c4 ] + +The QMP pipe clock is used by the USB part of the PHY so drop the +corresponding properties from the DP child node. + +Fixes: 23737b9557fe ("arm64: dts: qcom: sm6350: Add USB1 nodes") +Signed-off-by: Johan Hovold +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221026152511.9661-3-johan+linaro@kernel.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm6350.dtsi | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi +index d06aefdf3d9e..ec64b6a12e20 100644 +--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi +@@ -1011,9 +1011,6 @@ dp_phy: dp-phy@88ea200 { + <0 0x088eaa00 0 0x100>; + #phy-cells = <0>; + #clock-cells = <1>; +- clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; +- clock-names = "pipe0"; +- clock-output-names = "usb3_phy_pipe_clk_src"; + }; + }; + +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-sm8150-fix-ufs-phy-registers.patch b/queue-6.0/arm64-dts-qcom-sm8150-fix-ufs-phy-registers.patch new file mode 100644 index 00000000000..375419f5b47 --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-sm8150-fix-ufs-phy-registers.patch @@ -0,0 +1,48 @@ +From 9e77cf2afa93b9fe030c3f9687ad51277eb6834e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Oct 2022 11:15:04 +0200 +Subject: arm64: dts: qcom: sm8150: fix UFS PHY registers + +From: Johan Hovold + +[ Upstream commit 36a31b3a8d9ba1707a23de8d8dc1ceaef4eda695 ] + +The sizes of the UFS PHY register regions are too small and does +specifically not cover all registers used by the Linux driver. + +As Linux maps these regions as full pages this is currently not an issue +on Linux, but let's update the sizes to match the vendor driver. + +Fixes: 3834a2e92229 ("arm64: dts: qcom: sm8150: Add ufs nodes") +Signed-off-by: Johan Hovold +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221024091507.20342-2-johan+linaro@kernel.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm8150.dtsi | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi +index 916f12b799b7..3df80dde9249 100644 +--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi +@@ -2038,11 +2038,11 @@ ufs_mem_phy: phy@1d87000 { + status = "disabled"; + + ufs_mem_phy_lanes: phy@1d87400 { +- reg = <0 0x01d87400 0 0x108>, +- <0 0x01d87600 0 0x1e0>, +- <0 0x01d87c00 0 0x1dc>, +- <0 0x01d87800 0 0x108>, +- <0 0x01d87a00 0 0x1e0>; ++ reg = <0 0x01d87400 0 0x16c>, ++ <0 0x01d87600 0 0x200>, ++ <0 0x01d87c00 0 0x200>, ++ <0 0x01d87800 0 0x16c>, ++ <0 0x01d87a00 0 0x200>; + #phy-cells = <0>; + }; + }; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-sm8250-correct-lpass-pin-pull-down.patch b/queue-6.0/arm64-dts-qcom-sm8250-correct-lpass-pin-pull-down.patch new file mode 100644 index 00000000000..420da1d83e5 --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-sm8250-correct-lpass-pin-pull-down.patch @@ -0,0 +1,37 @@ +From aace118558c687430818ca3dec307d48bb51eebd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Sep 2022 17:34:20 +0200 +Subject: arm64: dts: qcom: sm8250: correct LPASS pin pull down + +From: Krzysztof Kozlowski + +[ Upstream commit 195a0a11d66d6c696cbcf398d6bc3f3a3a462f7c ] + +The pull-down property is actually bias-pull-down. + +Fixes: 3160c1b894d9 ("arm64: dts: qcom: sm8250: add lpass lpi pin controller node") +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Neil Armstrong +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220927153429.55365-4-krzysztof.kozlowski@linaro.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm8250.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi +index 052b4dbc1ee4..f4abca3a0843 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi +@@ -2447,7 +2447,7 @@ data { + pins = "gpio7"; + function = "dmic1_data"; + drive-strength = <2>; +- pull-down; ++ bias-pull-down; + input-enable; + }; + }; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-sm8250-drop-bogus-dp-phy-clock.patch b/queue-6.0/arm64-dts-qcom-sm8250-drop-bogus-dp-phy-clock.patch new file mode 100644 index 00000000000..9003dda1b62 --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-sm8250-drop-bogus-dp-phy-clock.patch @@ -0,0 +1,38 @@ +From 4a4e9c2ebab2eb1f99ba062b3a59d0f258fb055f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 17:25:10 +0200 +Subject: arm64: dts: qcom: sm8250: drop bogus DP PHY clock + +From: Johan Hovold + +[ Upstream commit bb9f23e46ddcebe1bc68a43a0f7acfc1865a6472 ] + +The QMP pipe clock is used by the USB part of the PHY so drop the +corresponding properties from the DP child node. + +Fixes: 5aa0d1becd5b ("arm64: dts: qcom: sm8250: switch usb1 qmp phy to USB3+DP mode") +Signed-off-by: Johan Hovold +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221026152511.9661-2-johan+linaro@kernel.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm8250.dtsi | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi +index 7df2abd40525..ab6c4c354338 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi +@@ -2890,9 +2890,6 @@ dp_phy: dp-phy@88ea200 { + <0 0x088eaa00 0 0x100>; + #phy-cells = <0>; + #clock-cells = <1>; +- clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; +- clock-names = "pipe0"; +- clock-output-names = "usb3_phy_pipe_clk_src"; + }; + }; + +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-sm8250-fix-ufs-phy-registers.patch b/queue-6.0/arm64-dts-qcom-sm8250-fix-ufs-phy-registers.patch new file mode 100644 index 00000000000..8fb0fdcbf31 --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-sm8250-fix-ufs-phy-registers.patch @@ -0,0 +1,48 @@ +From cce089d70978ce6c51f9238ab48966840b8b3696 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Oct 2022 11:15:05 +0200 +Subject: arm64: dts: qcom: sm8250: fix UFS PHY registers + +From: Johan Hovold + +[ Upstream commit 7f8b37dd4e7bf50160529530d9789b846153df71 ] + +The sizes of the UFS PHY register regions are too small and does +specifically not cover all registers used by the Linux driver. + +As Linux maps these regions as full pages this is currently not an issue +on Linux, but let's update the sizes to match the vendor driver. + +Fixes: b7e2fba06622 ("arm64: dts: qcom: sm8250: Add UFS controller and PHY") +Signed-off-by: Johan Hovold +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221024091507.20342-3-johan+linaro@kernel.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm8250.dtsi | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi +index f4abca3a0843..7df2abd40525 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi +@@ -2172,11 +2172,11 @@ ufs_mem_phy: phy@1d87000 { + status = "disabled"; + + ufs_mem_phy_lanes: phy@1d87400 { +- reg = <0 0x01d87400 0 0x108>, +- <0 0x01d87600 0 0x1e0>, +- <0 0x01d87c00 0 0x1dc>, +- <0 0x01d87800 0 0x108>, +- <0 0x01d87a00 0 0x1e0>; ++ reg = <0 0x01d87400 0 0x16c>, ++ <0 0x01d87600 0 0x200>, ++ <0 0x01d87c00 0 0x200>, ++ <0 0x01d87800 0 0x16c>, ++ <0 0x01d87a00 0 0x200>; + #phy-cells = <0>; + }; + }; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-sm8250-mtp-fix-reset-line-polarity.patch b/queue-6.0/arm64-dts-qcom-sm8250-mtp-fix-reset-line-polarity.patch new file mode 100644 index 00000000000..d26805e5280 --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-sm8250-mtp-fix-reset-line-polarity.patch @@ -0,0 +1,39 @@ +From 61ba54c9a15e51ba0020e8d9c3abfb2cdb29431a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Oct 2022 00:46:49 -0700 +Subject: arm64: dts: qcom: sm8250-mtp: fix reset line polarity + +From: Dmitry Torokhov + +[ Upstream commit 15d9fcbb3e6e8420c7d1ae331405780c5d9c1c25 ] + +The driver for the codec, when resetting the chip, first drives the line +low, and then high. This means that the line is active low. Change the +annotation in the DTS accordingly. + +Fixes: 36c9d012f193 ("arm64: dts: qcom: use GPIO flags for tlmm") +Fixes: 5a263cf629a8 ("arm64: dts: qcom: sm8250-mtp: Add wcd9380 audio codec node") +Signed-off-by: Dmitry Torokhov +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221027074652.1044235-3-dmitry.torokhov@gmail.com +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm8250-mtp.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts +index a102aa5efa32..a05fe468e0b4 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts ++++ b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts +@@ -635,7 +635,7 @@ &soc { + wcd938x: codec { + compatible = "qcom,wcd9380-codec"; + #sound-dai-cells = <1>; +- reset-gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>; ++ reset-gpios = <&tlmm 32 GPIO_ACTIVE_LOW>; + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-rxtx-supply = <&vreg_s4a_1p8>; + vdd-io-supply = <&vreg_s4a_1p8>; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-sm8250-sony-xperia-edo-fix-touchscree.patch b/queue-6.0/arm64-dts-qcom-sm8250-sony-xperia-edo-fix-touchscree.patch new file mode 100644 index 00000000000..86294b8d048 --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-sm8250-sony-xperia-edo-fix-touchscree.patch @@ -0,0 +1,38 @@ +From a8e71ab4f085a33b19accabf5abaf5b2edcfea06 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Sep 2022 21:29:40 +0200 +Subject: arm64: dts: qcom: sm8250-sony-xperia-edo: fix touchscreen + bias-disable + +From: Krzysztof Kozlowski + +[ Upstream commit 7ff4a646fae3697b039c6b684786a1e309e8445c ] + +The property to disable bias is "bias-disable". + +Fixes: e76c7e1f15fe ("arm64: dts: qcom: sm8250-edo: Add Samsung touchscreen") +Reviewed-by: Konrad Dybcio +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220930192954.242546-3-krzysztof.kozlowski@linaro.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi +index 5428aab3058d..e4769dcfaad7 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi +@@ -619,7 +619,7 @@ ts_int_default: ts-int-default { + pins = "gpio39"; + function = "gpio"; + drive-strength = <2>; +- bias-disabled; ++ bias-disable; + input-enable; + }; + +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-sm8350-fix-ufs-phy-registers.patch b/queue-6.0/arm64-dts-qcom-sm8350-fix-ufs-phy-registers.patch new file mode 100644 index 00000000000..9c2bd314e3a --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-sm8350-fix-ufs-phy-registers.patch @@ -0,0 +1,48 @@ +From 4d1e70b2a4b7045b35ab8071ed0a49ff576679ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Oct 2022 11:15:06 +0200 +Subject: arm64: dts: qcom: sm8350: fix UFS PHY registers + +From: Johan Hovold + +[ Upstream commit b3c7839b698cc617e97dd2e4f1eeb4adc280fe58 ] + +The sizes of the UFS PHY register regions are too small and does +specifically not cover all registers used by the Linux driver. + +As Linux maps these regions as full pages this is currently not an issue +on Linux, but let's update the sizes to match the vendor driver. + +Fixes: 59c7cf814783 ("arm64: dts: qcom: sm8350: Add UFS nodes") +Signed-off-by: Johan Hovold +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221024091507.20342-4-johan+linaro@kernel.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm8350.dtsi | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi +index d9b08dfc2980..eace5b2ee381 100644 +--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi +@@ -2142,11 +2142,11 @@ ufs_mem_phy: phy@1d87000 { + status = "disabled"; + + ufs_mem_phy_lanes: phy@1d87400 { +- reg = <0 0x01d87400 0 0x108>, +- <0 0x01d87600 0 0x1e0>, +- <0 0x01d87c00 0 0x1dc>, +- <0 0x01d87800 0 0x108>, +- <0 0x01d87a00 0 0x1e0>; ++ reg = <0 0x01d87400 0 0x188>, ++ <0 0x01d87600 0 0x200>, ++ <0 0x01d87c00 0 0x200>, ++ <0 0x01d87800 0 0x188>, ++ <0 0x01d87a00 0 0x200>; + #phy-cells = <0>; + }; + }; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-sm8450-fix-ufs-phy-registers.patch b/queue-6.0/arm64-dts-qcom-sm8450-fix-ufs-phy-registers.patch new file mode 100644 index 00000000000..9ec4c54a1fe --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-sm8450-fix-ufs-phy-registers.patch @@ -0,0 +1,48 @@ +From ac66bd556e06a8a165e763be52b5d57da63bf35b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Oct 2022 11:15:07 +0200 +Subject: arm64: dts: qcom: sm8450: fix UFS PHY registers + +From: Johan Hovold + +[ Upstream commit 7af949211a0554bbc06163b081fc2cb516674880 ] + +The sizes of the UFS PHY register regions are too small and does +specifically not cover all registers used by the Linux driver. + +As Linux maps these regions as full pages this is currently not an issue +on Linux, but let's update the sizes to match the vendor driver. + +Fixes: 07fa917a335e ("arm64: dts: qcom: sm8450: add ufs nodes") +Signed-off-by: Johan Hovold +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221024091507.20342-5-johan+linaro@kernel.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm8450.dtsi | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi +index 8a6c0f3e7bb7..ed3e1eff4f58 100644 +--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi +@@ -3131,11 +3131,11 @@ ufs_mem_phy: phy@1d87000 { + status = "disabled"; + + ufs_mem_phy_lanes: phy@1d87400 { +- reg = <0 0x01d87400 0 0x108>, +- <0 0x01d87600 0 0x1e0>, +- <0 0x01d87c00 0 0x1dc>, +- <0 0x01d87800 0 0x108>, +- <0 0x01d87a00 0 0x1e0>; ++ reg = <0 0x01d87400 0 0x188>, ++ <0 0x01d87600 0 0x200>, ++ <0 0x01d87c00 0 0x200>, ++ <0 0x01d87800 0 0x188>, ++ <0 0x01d87a00 0 0x200>; + #phy-cells = <0>; + }; + }; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-qcom-use-gpio-flags-for-tlmm.patch b/queue-6.0/arm64-dts-qcom-use-gpio-flags-for-tlmm.patch new file mode 100644 index 00000000000..4f39e29d7d8 --- /dev/null +++ b/queue-6.0/arm64-dts-qcom-use-gpio-flags-for-tlmm.patch @@ -0,0 +1,198 @@ +From 36940521213cda252bd7b5a8e19a05a864054d85 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Aug 2022 17:39:45 +0200 +Subject: arm64: dts: qcom: use GPIO flags for tlmm + +From: Krzysztof Kozlowski + +[ Upstream commit 36c9d012f193747d42af80b634217addd974c522 ] + +Use respective GPIO_ACTIVE_LOW/HIGH flags for tlmm GPIOs. Include +gpio.h header if this is first usage of that flag. + +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Konrad Dybcio +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220802153947.44457-4-krzysztof.kozlowski@linaro.org +Stable-dep-of: 76d21ffc5d42 ("arm64: dts: qcom: msm8996: fix sound card reset line polarity") +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts | 2 +- + arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi | 2 +- + arch/arm64/boot/dts/qcom/msm8994.dtsi | 3 ++- + arch/arm64/boot/dts/qcom/msm8996.dtsi | 3 ++- + arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 4 ++-- + arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts | 2 +- + arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts | 4 ++-- + arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts | 2 +- + arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts | 2 +- + arch/arm64/boot/dts/qcom/sm8250-mtp.dts | 2 +- + 10 files changed, 14 insertions(+), 12 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts b/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts +index 567b33106556..92f264891d84 100644 +--- a/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts ++++ b/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts +@@ -368,7 +368,7 @@ &sdhc2 { + + bus-width = <4>; + +- cd-gpios = <&tlmm 38 0x1>; ++ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>; + + vmmc-supply = <&vreg_l21a_2p95>; + vqmmc-supply = <&vreg_l13a_2p95>; +diff --git a/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi b/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi +index f430d797196f..ff60b7004d26 100644 +--- a/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi +@@ -471,7 +471,7 @@ &sdhc1 { + &sdhc2 { + status = "okay"; + +- cd-gpios = <&tlmm 100 0>; ++ cd-gpios = <&tlmm 100 GPIO_ACTIVE_HIGH>; + vmmc-supply = <&pm8994_l21>; + vqmmc-supply = <&pm8994_l13>; + }; +diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi +index 8bc6c070e306..86ef0091caff 100644 +--- a/arch/arm64/boot/dts/qcom/msm8994.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + #include + + / { +@@ -502,7 +503,7 @@ sdhc2: mmc@f98a4900 { + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>; + +- cd-gpios = <&tlmm 100 0>; ++ cd-gpios = <&tlmm 100 GPIO_ACTIVE_HIGH>; + bus-width = <4>; + status = "disabled"; + }; +diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi +index c8b9d7d60774..d3cf0677ea28 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -3357,7 +3358,7 @@ wcd9335: codec@1{ + interrupt-names = "intr1", "intr2"; + interrupt-controller; + #interrupt-cells = <1>; +- reset-gpios = <&tlmm 64 0>; ++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>; + + slim-ifc-dev = <&tasha_ifd>; + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +index c6e2c571b452..b2eddcd87506 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +@@ -1081,7 +1081,7 @@ &wcd9340{ + pinctrl-names = "default"; + clock-names = "extclk"; + clocks = <&rpmhcc RPMH_LN_BB_CLK2>; +- reset-gpios = <&tlmm 64 0>; ++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>; + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-buck-sido-supply = <&vreg_s4a_1p8>; + vdd-tx-supply = <&vreg_s4a_1p8>; +@@ -1255,7 +1255,7 @@ camera@60 { + reg = <0x60>; + + // CAM3_RST_N +- enable-gpios = <&tlmm 21 0>; ++ enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&cam3_default>; + gpios = <&tlmm 16 0>, +diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts +index 82c27f90d300..0f470cf1ed1c 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts +@@ -546,7 +546,7 @@ &wcd9340{ + pinctrl-names = "default"; + clock-names = "extclk"; + clocks = <&rpmhcc RPMH_LN_BB_CLK2>; +- reset-gpios = <&tlmm 64 0>; ++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>; + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-buck-sido-supply = <&vreg_s4a_1p8>; + vdd-tx-supply = <&vreg_s4a_1p8>; +diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts +index 2611a5c40ba3..1cc477c30945 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts +@@ -126,7 +126,7 @@ vreg_tp_vddio: vreg-tp-vddio { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + +- gpio = <&tlmm 23 0>; ++ gpio = <&tlmm 23 GPIO_ACTIVE_HIGH>; + regulator-always-on; + regulator-boot-on; + enable-active-high; +@@ -712,7 +712,7 @@ &wcd9340 { + pinctrl-names = "default"; + clock-names = "extclk"; + clocks = <&rpmhcc RPMH_LN_BB_CLK2>; +- reset-gpios = <&tlmm 64 0>; ++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>; + vdd-buck-sido-supply = <&vreg_s4a_1p8>; + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-tx-supply = <&vreg_s4a_1p8>; +diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts +index a7af1bed4312..be59a8ba9c1f 100644 +--- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts ++++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts +@@ -772,7 +772,7 @@ &wcd9340{ + pinctrl-names = "default"; + clock-names = "extclk"; + clocks = <&rpmhcc RPMH_LN_BB_CLK2>; +- reset-gpios = <&tlmm 64 0>; ++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>; + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-buck-sido-supply = <&vreg_s4a_1p8>; + vdd-tx-supply = <&vreg_s4a_1p8>; +diff --git a/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts b/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts +index b0315eeb1320..f954fe5cb61a 100644 +--- a/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts ++++ b/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts +@@ -704,7 +704,7 @@ &wcd9340{ + pinctrl-names = "default"; + clock-names = "extclk"; + clocks = <&rpmhcc RPMH_LN_BB_CLK2>; +- reset-gpios = <&tlmm 64 0>; ++ reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>; + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-buck-sido-supply = <&vreg_s4a_1p8>; + vdd-tx-supply = <&vreg_s4a_1p8>; +diff --git a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts +index 7ab3627cc347..a102aa5efa32 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts ++++ b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts +@@ -635,7 +635,7 @@ &soc { + wcd938x: codec { + compatible = "qcom,wcd9380-codec"; + #sound-dai-cells = <1>; +- reset-gpios = <&tlmm 32 0>; ++ reset-gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>; + vdd-buck-supply = <&vreg_s4a_1p8>; + vdd-rxtx-supply = <&vreg_s4a_1p8>; + vdd-io-supply = <&vreg_s4a_1p8>; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-renesas-r8a779f0-fix-hscif-brg_int-clock.patch b/queue-6.0/arm64-dts-renesas-r8a779f0-fix-hscif-brg_int-clock.patch new file mode 100644 index 00000000000..1da8e447877 --- /dev/null +++ b/queue-6.0/arm64-dts-renesas-r8a779f0-fix-hscif-brg_int-clock.patch @@ -0,0 +1,70 @@ +From ee83246cfb8fce8018c7dff233c16a3316d2acf4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Nov 2022 15:34:39 +0100 +Subject: arm64: dts: renesas: r8a779f0: Fix HSCIF "brg_int" clock + +From: Wolfram Sang + +[ Upstream commit a5101ef18b4d0751588f61d939694bad183cc240 ] + +As serial communication requires a clean clock signal, the High Speed +Serial Communication Interfaces with FIFO (HSCIF) are clocked by a clock +that is not affected by Spread Spectrum or Fractional Multiplication. + +Hence change the clock input for the HSCIF Baud Rate Generator internal +clock from the S0D3_PER clock to the SASYNCPERD1 clock (which has the +same clock rate), cfr. R-Car S4-8 Hardware User's Manual rev. 0.81. + +Fixes: 01a787f78bfd ("arm64: dts: renesas: r8a779f0: Add HSCIF nodes") +Reported-by: Geert Uytterhoeven +Signed-off-by: Wolfram Sang +Link: https://lore.kernel.org/r/20221103143440.46449-4-wsa+renesas@sang-engineering.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/renesas/r8a779f0.dtsi | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi +index 384817ffa4de..6ee5f0a54b13 100644 +--- a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi +@@ -442,7 +442,7 @@ hscif0: serial@e6540000 { + reg = <0 0xe6540000 0 0x60>; + interrupts = ; + clocks = <&cpg CPG_MOD 514>, +- <&cpg CPG_CORE R8A779F0_CLK_S0D3>, ++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac0 0x31>, <&dmac0 0x30>, +@@ -459,7 +459,7 @@ hscif1: serial@e6550000 { + reg = <0 0xe6550000 0 0x60>; + interrupts = ; + clocks = <&cpg CPG_MOD 515>, +- <&cpg CPG_CORE R8A779F0_CLK_S0D3>, ++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac0 0x33>, <&dmac0 0x32>, +@@ -476,7 +476,7 @@ hscif2: serial@e6560000 { + reg = <0 0xe6560000 0 0x60>; + interrupts = ; + clocks = <&cpg CPG_MOD 516>, +- <&cpg CPG_CORE R8A779F0_CLK_S0D3>, ++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac0 0x35>, <&dmac0 0x34>, +@@ -493,7 +493,7 @@ hscif3: serial@e66a0000 { + reg = <0 0xe66a0000 0 0x60>; + interrupts = ; + clocks = <&cpg CPG_MOD 517>, +- <&cpg CPG_CORE R8A779F0_CLK_S0D3>, ++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac0 0x37>, <&dmac0 0x36>, +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-renesas-r8a779f0-fix-scif-brg_int-clock.patch b/queue-6.0/arm64-dts-renesas-r8a779f0-fix-scif-brg_int-clock.patch new file mode 100644 index 00000000000..4279c280966 --- /dev/null +++ b/queue-6.0/arm64-dts-renesas-r8a779f0-fix-scif-brg_int-clock.patch @@ -0,0 +1,71 @@ +From e786eca96a1da079ef27d4db4e6ec43cdcf80778 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Nov 2022 15:34:40 +0100 +Subject: arm64: dts: renesas: r8a779f0: Fix SCIF "brg_int" clock + +From: Wolfram Sang + +[ Upstream commit 64416ef0b0c4d73349035d1b3206eed3d2047ee0 ] + +As serial communication requires a clean clock signal, the Serial +Communication Interfaces with FIFO (SCIF) are clocked by a clock that is +not affected by Spread Spectrum or Fractional Multiplication. + +Hence change the clock input for the SCIF Baud Rate Generator internal +clock from the S0D3_PER clock to the SASYNCPERD1 clock (which has the +same clock rate), cfr. R-Car S4-8 Hardware User's Manual rev. 0.81. + +Fixes: c62331e8222f ("arm64: dts: renesas: Add Renesas R8A779F0 SoC support") +Fixes: 40753144256b ("arm64: dts: renesas: r8a779f0: Add SCIF nodes") +Reported-by: Geert Uytterhoeven +Signed-off-by: Wolfram Sang +Link: https://lore.kernel.org/r/20221103143440.46449-5-wsa+renesas@sang-engineering.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/renesas/r8a779f0.dtsi | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi +index 6ee5f0a54b13..d4f3ebfe841a 100644 +--- a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi +@@ -522,7 +522,7 @@ scif0: serial@e6e60000 { + reg = <0 0xe6e60000 0 64>; + interrupts = ; + clocks = <&cpg CPG_MOD 702>, +- <&cpg CPG_CORE R8A779F0_CLK_S0D3_PER>, ++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac0 0x51>, <&dmac0 0x50>, +@@ -539,7 +539,7 @@ scif1: serial@e6e68000 { + reg = <0 0xe6e68000 0 64>; + interrupts = ; + clocks = <&cpg CPG_MOD 703>, +- <&cpg CPG_CORE R8A779F0_CLK_S0D3_PER>, ++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac0 0x53>, <&dmac0 0x52>, +@@ -556,7 +556,7 @@ scif3: serial@e6c50000 { + reg = <0 0xe6c50000 0 64>; + interrupts = ; + clocks = <&cpg CPG_MOD 704>, +- <&cpg CPG_CORE R8A779F0_CLK_S0D3_PER>, ++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac0 0x57>, <&dmac0 0x56>, +@@ -573,7 +573,7 @@ scif4: serial@e6c40000 { + reg = <0 0xe6c40000 0 64>; + interrupts = ; + clocks = <&cpg CPG_MOD 705>, +- <&cpg CPG_CORE R8A779F0_CLK_S0D3_PER>, ++ <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + dmas = <&dmac0 0x59>, <&dmac0 0x58>, +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-renesas-r8a779g0-fix-hscif0-brg_int-clock.patch b/queue-6.0/arm64-dts-renesas-r8a779g0-fix-hscif0-brg_int-clock.patch new file mode 100644 index 00000000000..d50fec52e38 --- /dev/null +++ b/queue-6.0/arm64-dts-renesas-r8a779g0-fix-hscif0-brg_int-clock.patch @@ -0,0 +1,42 @@ +From 98dacbe37aaa4f3083cae1ad0d94bc72ab0496e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Oct 2022 17:20:03 +0200 +Subject: arm64: dts: renesas: r8a779g0: Fix HSCIF0 "brg_int" clock + +From: Geert Uytterhoeven + +[ Upstream commit a4290d407aa9fd174d8053878783d466d3124e38 ] + +As serial communication requires a clock signal, the High Speed Serial +Communication Interfaces with FIFO (HSCIF) are clocked by a clock that +is not affected by Spread Spectrum or Fractional Multiplication. + +Hence change the clock input for the HSCIF0 Baud Rate Generator internal +clock from the S0D3_PER clock to the SASYNCPERD1 clock (which has the +same clock rate), cfr. R-Car V4H Hardware User's Manual rev. 0.54. + +Fixes: 987da486d84a5643 ("arm64: dts: renesas: Add Renesas R8A779G0 SoC support") +Signed-off-by: Geert Uytterhoeven +Reviewed-by: Wolfram Sang +Link: https://lore.kernel.org/r/a5bd4148f92806f7c8e577d383370f810315f586.1665155947.git.geert+renesas@glider.be +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/renesas/r8a779g0.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi +index 1c15726cff8b..4bd3cb107b38 100644 +--- a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi ++++ b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi +@@ -87,7 +87,7 @@ hscif0: serial@e6540000 { + reg = <0 0xe6540000 0 96>; + interrupts = ; + clocks = <&cpg CPG_MOD 514>, +- <&cpg CPG_CORE R8A779G0_CLK_S0D3_PER>, ++ <&cpg CPG_CORE R8A779G0_CLK_SASYNCPERD1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-renesas-r9a09g011-fix-unit-address-format-.patch b/queue-6.0/arm64-dts-renesas-r9a09g011-fix-unit-address-format-.patch new file mode 100644 index 00000000000..b71294805a8 --- /dev/null +++ b/queue-6.0/arm64-dts-renesas-r9a09g011-fix-unit-address-format-.patch @@ -0,0 +1,47 @@ +From 36d53e30adda83786a6eaae80e6ad41914c7c12c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Nov 2022 23:06:46 +0000 +Subject: arm64: dts: renesas: r9a09g011: Fix unit address format error + +From: Fabrizio Castro + +[ Upstream commit 278f5015a3deaa2ea0db6070bbc2a8edf2455643 ] + +Although the HW User Manual for RZ/V2M states in the "Address Map" +section that the interrupt controller is assigned addresses starting +from 0x82000000, the memory locations from 0x82000000 0x0x8200FFFF +are marked as reserved in the "Interrupt Controller (GIC)" section +and are currently not used by the device tree, leading to the below +warning: + +arch/arm64/boot/dts/renesas/r9a09g011.dtsi:51.38-63.5: Warning +(simple_bus_reg): /soc/interrupt-controller@82000000: simple-bus unit +address format error, expected "82010000" + +Fix the unit address accordingly. + +Fixes: fb1929b98f2e ("arm64: dts: renesas: Add initial DTSI for RZ/V2M SoC") +Signed-off-by: Fabrizio Castro +Link: https://lore.kernel.org/r/20221103230648.53748-2-fabrizio.castro.jz@renesas.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/renesas/r9a09g011.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi +index d4cc5459fbb7..4ce0f3944649 100644 +--- a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi ++++ b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi +@@ -48,7 +48,7 @@ soc: soc { + #size-cells = <2>; + ranges; + +- gic: interrupt-controller@82000000 { ++ gic: interrupt-controller@82010000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + #address-cells = <0>; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-ti-k3-am65-main-drop-dma-coherent-in-crypt.patch b/queue-6.0/arm64-dts-ti-k3-am65-main-drop-dma-coherent-in-crypt.patch new file mode 100644 index 00000000000..c4ee40197a4 --- /dev/null +++ b/queue-6.0/arm64-dts-ti-k3-am65-main-drop-dma-coherent-in-crypt.patch @@ -0,0 +1,36 @@ +From 4eeb39bb4687d0222299221ae91027855b8cf965 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 31 Oct 2022 20:55:18 +0530 +Subject: arm64: dts: ti: k3-am65-main: Drop dma-coherent in crypto node + +From: Jayesh Choudhary + +[ Upstream commit b86833ab3653dbb0dc453eec4eef8615e63de4e2 ] + +crypto driver itself is not dma-coherent. So drop it. + +Fixes: b366b2409c97 ("arm64: dts: ti: k3-am6: Add crypto accelarator node") +Signed-off-by: Jayesh Choudhary +Signed-off-by: Nishanth Menon +Reviewed-by: Manorit Chawdhry +Link: https://lore.kernel.org/r/20221031152520.355653-2-j-choudhary@ti.com +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +index 8919fede3cd7..ef960386c62c 100644 +--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +@@ -120,7 +120,6 @@ crypto: crypto@4e00000 { + dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>, + <&main_udmap 0x4001>; + dma-names = "tx", "rx1", "rx2"; +- dma-coherent; + + rng: rng@4e10000 { + compatible = "inside-secure,safexcel-eip76"; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-ti-k3-j721e-main-drop-dma-coherent-in-cryp.patch b/queue-6.0/arm64-dts-ti-k3-j721e-main-drop-dma-coherent-in-cryp.patch new file mode 100644 index 00000000000..28a34146d00 --- /dev/null +++ b/queue-6.0/arm64-dts-ti-k3-j721e-main-drop-dma-coherent-in-cryp.patch @@ -0,0 +1,36 @@ +From cd39f52759b171874f33afd34d42df53819bab4a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 31 Oct 2022 20:55:19 +0530 +Subject: arm64: dts: ti: k3-j721e-main: Drop dma-coherent in crypto node + +From: Jayesh Choudhary + +[ Upstream commit 26c5012403f3f1fd3bf8f7d3389ee539ae5cc162 ] + +crypto driver itself is not dma-coherent. So drop it. + +Fixes: 8ebcaaae8017 ("arm64: dts: ti: k3-j721e-main: Add crypto accelerator node") +Signed-off-by: Jayesh Choudhary +Signed-off-by: Nishanth Menon +Reviewed-by: Manorit Chawdhry +Link: https://lore.kernel.org/r/20221031152520.355653-3-j-choudhary@ti.com +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi +index 43b6cf5791ee..75789c0f82bd 100644 +--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi +@@ -337,7 +337,6 @@ main_crypto: crypto@4e00000 { + dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>, + <&main_udmap 0x4001>; + dma-names = "tx", "rx1", "rx2"; +- dma-coherent; + + rng: rng@4e10000 { + compatible = "inside-secure,safexcel-eip76"; +-- +2.35.1 + diff --git a/queue-6.0/arm64-dts-ti-k3-j721s2-fix-the-interrupt-ranges-prop.patch b/queue-6.0/arm64-dts-ti-k3-j721s2-fix-the-interrupt-ranges-prop.patch new file mode 100644 index 00000000000..128392b64d9 --- /dev/null +++ b/queue-6.0/arm64-dts-ti-k3-j721s2-fix-the-interrupt-ranges-prop.patch @@ -0,0 +1,61 @@ +From b4b3d84214c54cc458dba3b2f9bf42b4f40526fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Sep 2022 12:59:50 +0530 +Subject: arm64: dts: ti: k3-j721s2: Fix the interrupt ranges property for main + & wkup gpio intr + +From: Keerthy + +[ Upstream commit b8aa36c22da7d64c5a5d89ccb4a2abb9aeaab2e3 ] + +The parent's input irq number is wrongly subtracted with 32 instead of +using the exact numbers in: + +https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j721s2/interrupt_cfg.html + +The GPIO interrupts are not working because of that. The toggling works +fine but interrupts are not firing. Fix the parent's input irq that +specifies the base for parent irq. + +Tested for MAIN_GPIO0_6 interrupt on the j721s2 EVM. + +Fixes: b8545f9d3a54 ("arm64: dts: ti: Add initial support for J721S2 SoC") +Signed-off-by: Keerthy +Signed-off-by: Nishanth Menon +Reviewed-by: Vaishnav Achath +Link: https://lore.kernel.org/r/20220922072950.9157-1-j-keerthy@ti.com +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi | 2 +- + arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi +index 34e7d577ae13..c89f28235812 100644 +--- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi +@@ -60,7 +60,7 @@ main_gpio_intr: interrupt-controller@a00000 { + #interrupt-cells = <1>; + ti,sci = <&sms>; + ti,sci-dev-id = <148>; +- ti,interrupt-ranges = <8 360 56>; ++ ti,interrupt-ranges = <8 392 56>; + }; + + main_pmx0: pinctrl@11c000 { +diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi +index 4d1bfabd1313..f0644851602c 100644 +--- a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi +@@ -65,7 +65,7 @@ wkup_gpio_intr: interrupt-controller@42200000 { + #interrupt-cells = <1>; + ti,sci = <&sms>; + ti,sci-dev-id = <125>; +- ti,interrupt-ranges = <16 928 16>; ++ ti,interrupt-ranges = <16 960 16>; + }; + + mcu_conf: syscon@40f00000 { +-- +2.35.1 + diff --git a/queue-6.0/arm64-make-is_ttbrx_addr-noinstr-safe.patch b/queue-6.0/arm64-make-is_ttbrx_addr-noinstr-safe.patch new file mode 100644 index 00000000000..8a870c5588f --- /dev/null +++ b/queue-6.0/arm64-make-is_ttbrx_addr-noinstr-safe.patch @@ -0,0 +1,52 @@ +From 9ccfffaff481a1f79705c1b9d6613c5478f623d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Nov 2022 14:40:42 +0000 +Subject: arm64: make is_ttbrX_addr() noinstr-safe + +From: Mark Rutland + +[ Upstream commit d8c1d798a2e5091128c391c6dadcc9be334af3f5 ] + +We use is_ttbr0_addr() in noinstr code, but as it's only marked as +inline, it's theoretically possible for the compiler to place it +out-of-line and instrument it, which would be problematic. + +Mark is_ttbr0_addr() as __always_inline such that that can safely be +used from noinstr code. For consistency, do the same to is_ttbr1_addr(). +Note that while is_ttbr1_addr() calls arch_kasan_reset_tag(), this is a +macro (and its callees are either macros or __always_inline), so there +is not a risk of transient instrumentation. + +Signed-off-by: Mark Rutland +Cc: Catalin Marinas +Cc: Will Deacon +Link: https://lore.kernel.org/r/20221114144042.3001140-1-mark.rutland@arm.com +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + arch/arm64/include/asm/processor.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h +index 86eb0bfe3b38..d9144b6e078c 100644 +--- a/arch/arm64/include/asm/processor.h ++++ b/arch/arm64/include/asm/processor.h +@@ -308,13 +308,13 @@ static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc, + } + #endif + +-static inline bool is_ttbr0_addr(unsigned long addr) ++static __always_inline bool is_ttbr0_addr(unsigned long addr) + { + /* entry assembly clears tags for TTBR0 addrs */ + return addr < TASK_SIZE; + } + +-static inline bool is_ttbr1_addr(unsigned long addr) ++static __always_inline bool is_ttbr1_addr(unsigned long addr) + { + /* TTBR1 addresses may have a tag if KASAN_SW_TAGS is in use */ + return arch_kasan_reset_tag(addr) >= PAGE_OFFSET; +-- +2.35.1 + diff --git a/queue-6.0/arm64-mm-kfence-only-handle-translation-faults.patch b/queue-6.0/arm64-mm-kfence-only-handle-translation-faults.patch new file mode 100644 index 00000000000..0a05e22d492 --- /dev/null +++ b/queue-6.0/arm64-mm-kfence-only-handle-translation-faults.patch @@ -0,0 +1,66 @@ +From b0bdc9418531ecccb25c592456e8ba7b48875b56 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Nov 2022 10:44:11 +0000 +Subject: arm64: mm: kfence: only handle translation faults + +From: Mark Rutland + +[ Upstream commit 0bb1fbffc631064db567ccaeb9ed6b6df6342b66 ] + +Alexander noted that KFENCE only expects to handle faults from invalid page +table entries (i.e. translation faults), but arm64's fault handling logic will +call kfence_handle_page_fault() for other types of faults, including alignment +faults caused by unaligned atomics. This has the unfortunate property of +causing those other faults to be reported as "KFENCE: use-after-free", +which is misleading and hinders debugging. + +Fix this by only forwarding unhandled translation faults to the KFENCE +code, similar to what x86 does already. + +Alexander has verified that this passes all the tests in the KFENCE test +suite and avoids bogus reports on misaligned atomics. + +Link: https://lore.kernel.org/all/20221102081620.1465154-1-zhongbaisong@huawei.com/ +Fixes: 840b23986344 ("arm64, kfence: enable KFENCE for ARM64") +Signed-off-by: Mark Rutland +Reviewed-by: Alexander Potapenko +Tested-by: Alexander Potapenko +Cc: Catalin Marinas +Cc: Marco Elver +Cc: Will Deacon +Link: https://lore.kernel.org/r/20221114104411.2853040-1-mark.rutland@arm.com +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + arch/arm64/mm/fault.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c +index c33f1fad2745..89628bd370d9 100644 +--- a/arch/arm64/mm/fault.c ++++ b/arch/arm64/mm/fault.c +@@ -353,6 +353,11 @@ static bool is_el1_mte_sync_tag_check_fault(unsigned long esr) + return false; + } + ++static bool is_translation_fault(unsigned long esr) ++{ ++ return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_FAULT; ++} ++ + static void __do_kernel_fault(unsigned long addr, unsigned long esr, + struct pt_regs *regs) + { +@@ -385,7 +390,8 @@ static void __do_kernel_fault(unsigned long addr, unsigned long esr, + } else if (addr < PAGE_SIZE) { + msg = "NULL pointer dereference"; + } else { +- if (kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs)) ++ if (is_translation_fault(esr) && ++ kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs)) + return; + + msg = "paging request"; +-- +2.35.1 + diff --git a/queue-6.0/asoc-amd-yc-add-xiaomi-redmi-book-pro-14-2022-into-d.patch b/queue-6.0/asoc-amd-yc-add-xiaomi-redmi-book-pro-14-2022-into-d.patch new file mode 100644 index 00000000000..e3492069724 --- /dev/null +++ b/queue-6.0/asoc-amd-yc-add-xiaomi-redmi-book-pro-14-2022-into-d.patch @@ -0,0 +1,42 @@ +From 644a53aa5b53e6db07ee94604c58251e4af6d862 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Nov 2022 11:52:47 +0300 +Subject: ASoC: amd: yc: Add Xiaomi Redmi Book Pro 14 2022 into DMI table + +From: Artem Lukyanov + +[ Upstream commit c1dd6bf6199752890d8c59d895dd45094da51d1f ] + +This model requires an additional detection quirk to enable the +internal microphone - BIOS doesn't seem to support AcpDmicConnected +(nothing in acpidump output). + +Signed-off-by: Artem Lukyanov +Link: https://lore.kernel.org/r/20221130085247.85126-1-dukzcry@ya.ru +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c +index d9715bea965e..1f0b5527c594 100644 +--- a/sound/soc/amd/yc/acp6x-mach.c ++++ b/sound/soc/amd/yc/acp6x-mach.c +@@ -213,6 +213,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"), + } + }, ++ { ++ .driver_data = &acp6x_card, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "TIMI"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 14 2022"), ++ } ++ }, + {} + }; + +-- +2.35.1 + diff --git a/queue-6.0/asoc-codecs-rt298-add-quirk-for-kbl-r-rvp-platform.patch b/queue-6.0/asoc-codecs-rt298-add-quirk-for-kbl-r-rvp-platform.patch new file mode 100644 index 00000000000..5c77349849a --- /dev/null +++ b/queue-6.0/asoc-codecs-rt298-add-quirk-for-kbl-r-rvp-platform.patch @@ -0,0 +1,45 @@ +From 86b65cae3b93800b4173e76e2d32249b202438aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 14:19:43 +0200 +Subject: ASoC: codecs: rt298: Add quirk for KBL-R RVP platform +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Amadeusz Sławiński + +[ Upstream commit 953dbd1cef18ce9ac0d69c1bd735b929fe52a17e ] + +KBL-R RVP platforms also use combojack, so we need to enable that +configuration for them. + +Signed-off-by: Amadeusz Sławiński +Signed-off-by: Cezary Rojewski +Link: https://lore.kernel.org/r/20221010121955.718168-4-cezary.rojewski@intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/rt298.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c +index b0b53d4f07df..5f36064ed6e6 100644 +--- a/sound/soc/codecs/rt298.c ++++ b/sound/soc/codecs/rt298.c +@@ -1166,6 +1166,13 @@ static const struct dmi_system_id force_combo_jack_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Geminilake") + } + }, ++ { ++ .ident = "Intel Kabylake R RVP", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Kabylake Client platform") ++ } ++ }, + { } + }; + +-- +2.35.1 + diff --git a/queue-6.0/asoc-codecs-wsa883x-use-correct-header-file.patch b/queue-6.0/asoc-codecs-wsa883x-use-correct-header-file.patch new file mode 100644 index 00000000000..91de9aecbe2 --- /dev/null +++ b/queue-6.0/asoc-codecs-wsa883x-use-correct-header-file.patch @@ -0,0 +1,53 @@ +From 1033e939a080de912652b3798052e8608676417a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Nov 2022 16:18:29 -0800 +Subject: ASoC: codecs: wsa883x: use correct header file + +From: Randy Dunlap + +[ Upstream commit 5f52ceddc40cd61b1dd2ecf735624deaf05f779f ] + +Fix build errors when GPIOLIB is not set/enabled: + +../sound/soc/codecs/wsa883x.c: In function 'wsa883x_probe': +../sound/soc/codecs/wsa883x.c:1394:25: error: implicit declaration of function 'devm_gpiod_get_optional'; did you mean 'devm_regulator_get_optional'? [-Werror=implicit-function-declaration] + wsa883x->sd_n = devm_gpiod_get_optional(&pdev->dev, "powerdown", +../sound/soc/codecs/wsa883x.c:1395:49: error: 'GPIOD_FLAGS_BIT_NONEXCLUSIVE' undeclared (first use in this function) + GPIOD_FLAGS_BIT_NONEXCLUSIVE); +../sound/soc/codecs/wsa883x.c:1414:9: error: implicit declaration of function 'gpiod_direction_output'; did you mean 'gpio_direction_output'? [-Werror=implicit-function-declaration] + gpiod_direction_output(wsa883x->sd_n, 1); + +Fixes: 43b8c7dc85a1 ("ASoC: codecs: add wsa883x amplifier support") +Signed-off-by: Randy Dunlap +Reported-by: kernel test robot +Cc: Srinivas Kandagatla +Cc: Banajit Goswami +Cc: Mark Brown +Cc: Liam Girdwood +Cc: alsa-devel@alsa-project.org +Cc: Jaroslav Kysela +Cc: Takashi Iwai +Reviewed-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20221108001829.5100-1-rdunlap@infradead.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/wsa883x.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c +index cb1d0a3e90e6..9dfa0ac08e6f 100644 +--- a/sound/soc/codecs/wsa883x.c ++++ b/sound/soc/codecs/wsa883x.c +@@ -7,7 +7,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +-- +2.35.1 + diff --git a/queue-6.0/asoc-codecs-wsa883x-use-proper-shutdown-gpio-polarit.patch b/queue-6.0/asoc-codecs-wsa883x-use-proper-shutdown-gpio-polarit.patch new file mode 100644 index 00000000000..a12b663f31d --- /dev/null +++ b/queue-6.0/asoc-codecs-wsa883x-use-proper-shutdown-gpio-polarit.patch @@ -0,0 +1,50 @@ +From 8209a0bf968e21e4c7c8fa9e4f2f2bcd66527393 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 10 Nov 2022 14:35:12 +0100 +Subject: ASoC: codecs: wsa883x: Use proper shutdown GPIO polarity + +From: Krzysztof Kozlowski + +[ Upstream commit ec5dba73f7ba10797904cf18092d2e6975a22147 ] + +The shutdown GPIO is active low (SD_N), but this depends on actual board +layout. Linux drivers should only care about logical state, where high +(1) means shutdown and low (0) means do not shutdown. + +Invert the GPIO to match logical value. + +Fixes: 43b8c7dc85a1 ("ASoC: codecs: add wsa883x amplifier support") +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20221110133512.478831-2-krzysztof.kozlowski@linaro.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/wsa883x.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c +index 63e1d7aa6137..cb1d0a3e90e6 100644 +--- a/sound/soc/codecs/wsa883x.c ++++ b/sound/soc/codecs/wsa883x.c +@@ -1393,7 +1393,7 @@ static int wsa883x_probe(struct sdw_slave *pdev, + } + + wsa883x->sd_n = devm_gpiod_get_optional(&pdev->dev, "powerdown", +- GPIOD_FLAGS_BIT_NONEXCLUSIVE); ++ GPIOD_FLAGS_BIT_NONEXCLUSIVE | GPIOD_OUT_HIGH); + if (IS_ERR(wsa883x->sd_n)) { + dev_err(&pdev->dev, "Shutdown Control GPIO not found\n"); + ret = PTR_ERR(wsa883x->sd_n); +@@ -1411,7 +1411,7 @@ static int wsa883x_probe(struct sdw_slave *pdev, + pdev->prop.sink_ports = GENMASK(WSA883X_MAX_SWR_PORTS, 0); + pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop; + pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; +- gpiod_direction_output(wsa883x->sd_n, 1); ++ gpiod_direction_output(wsa883x->sd_n, 0); + + wsa883x->regmap = devm_regmap_init_sdw(pdev, &wsa883x_regmap_config); + if (IS_ERR(wsa883x->regmap)) { +-- +2.35.1 + diff --git a/queue-6.0/asoc-dt-bindings-rt5682-set-sound-dai-cells-to-1.patch b/queue-6.0/asoc-dt-bindings-rt5682-set-sound-dai-cells-to-1.patch new file mode 100644 index 00000000000..efd5696da2c --- /dev/null +++ b/queue-6.0/asoc-dt-bindings-rt5682-set-sound-dai-cells-to-1.patch @@ -0,0 +1,45 @@ +From 5331eab3c206a29e75f222432c6ad897d1e82397 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Oct 2022 18:00:14 -0400 +Subject: ASoC: dt-bindings: rt5682: Set sound-dai-cells to 1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Nícolas F. R. A. Prado + +[ Upstream commit 07b16192f3f01d002d8ff37dcd4372980330ea93 ] + +Commit 0adccaf1eac9 ("ASoC: dt-bindings: rt5682: Add #sound-dai-cells") +defined the sound-dai-cells property as 0. However, rt5682 has two DAIs, +AIF1 and AIF2, and therefore should have sound-dai-cells set to 1. Fix +it. + +Fixes: 0adccaf1eac9 ("ASoC: dt-bindings: rt5682: Add #sound-dai-cells") +Signed-off-by: Nícolas F. R. A. Prado +Reviewed-by: Chen-Yu Tsai +Acked-by: Krzysztof Kozlowski +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221024220015.1759428-4-nfraprado@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + Documentation/devicetree/bindings/sound/rt5682.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/sound/rt5682.txt b/Documentation/devicetree/bindings/sound/rt5682.txt +index c5f2b8febcee..6b87db68337c 100644 +--- a/Documentation/devicetree/bindings/sound/rt5682.txt ++++ b/Documentation/devicetree/bindings/sound/rt5682.txt +@@ -46,7 +46,7 @@ Optional properties: + + - realtek,dmic-clk-driving-high : Set the high driving of the DMIC clock out. + +-- #sound-dai-cells: Should be set to '<0>'. ++- #sound-dai-cells: Should be set to '<1>'. + + Pins on the device (for linking into audio routes) for RT5682: + +-- +2.35.1 + diff --git a/queue-6.0/asoc-dt-bindings-wcd9335-fix-reset-line-polarity-in-.patch b/queue-6.0/asoc-dt-bindings-wcd9335-fix-reset-line-polarity-in-.patch new file mode 100644 index 00000000000..4aff85cea0d --- /dev/null +++ b/queue-6.0/asoc-dt-bindings-wcd9335-fix-reset-line-polarity-in-.patch @@ -0,0 +1,39 @@ +From b20e33df5faf3606de6ffc435401eafc82d55011 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Oct 2022 00:46:48 -0700 +Subject: ASoC: dt-bindings: wcd9335: fix reset line polarity in example + +From: Dmitry Torokhov + +[ Upstream commit 34cb111f8a7b98b5fec809dd194003bca20ef1b2 ] + +When resetting the block, the reset line is being driven low and then +high, which means that the line in DTS should be annotated as "active +low". + +Fixes: 1877c9fda1b7 ("ASoC: dt-bindings: add dt bindings for wcd9335 audio codec") +Signed-off-by: Dmitry Torokhov +Acked-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20221027074652.1044235-2-dmitry.torokhov@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + Documentation/devicetree/bindings/sound/qcom,wcd9335.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt b/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt +index 5d6ea66a863f..1f75feec3dec 100644 +--- a/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt ++++ b/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt +@@ -109,7 +109,7 @@ audio-codec@1{ + reg = <1 0>; + interrupts = <&msmgpio 54 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "intr2" +- reset-gpios = <&msmgpio 64 0>; ++ reset-gpios = <&msmgpio 64 GPIO_ACTIVE_LOW>; + slim-ifc-dev = <&wc9335_ifd>; + clock-names = "mclk", "native"; + clocks = <&rpmcc RPM_SMD_DIV_CLK1>, +-- +2.35.1 + diff --git a/queue-6.0/asoc-intel-avs-add-quirk-for-kbl-r-rvp-platform.patch b/queue-6.0/asoc-intel-avs-add-quirk-for-kbl-r-rvp-platform.patch new file mode 100644 index 00000000000..f32d15feec2 --- /dev/null +++ b/queue-6.0/asoc-intel-avs-add-quirk-for-kbl-r-rvp-platform.patch @@ -0,0 +1,85 @@ +From b4469f5a2a8370a378c30030979d1ccd18f6c69a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 14:19:44 +0200 +Subject: ASoC: Intel: avs: Add quirk for KBL-R RVP platform +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Amadeusz Sławiński + +[ Upstream commit 9d0737fa0e7530313634c0ecd75f09a95ba8d44a ] + +KBL-R RVPs contain built-in rt298 codec which requires different PLL +clock and .dai_fmt configuration than seen on other boards. + +Signed-off-by: Amadeusz Sławiński +Signed-off-by: Cezary Rojewski +Link: https://lore.kernel.org/r/20221010121955.718168-5-cezary.rojewski@intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/avs/boards/rt298.c | 24 ++++++++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/intel/avs/boards/rt298.c b/sound/soc/intel/avs/boards/rt298.c +index b28d36872dcb..58c9d9edecf0 100644 +--- a/sound/soc/intel/avs/boards/rt298.c ++++ b/sound/soc/intel/avs/boards/rt298.c +@@ -6,6 +6,7 @@ + // Amadeusz Slawinski + // + ++#include + #include + #include + #include +@@ -14,6 +15,16 @@ + #include + #include "../../../codecs/rt298.h" + ++static const struct dmi_system_id kblr_dmi_table[] = { ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), ++ DMI_MATCH(DMI_BOARD_NAME, "Kabylake R DDR4 RVP"), ++ }, ++ }, ++ {} ++}; ++ + static const struct snd_kcontrol_new card_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone Jack"), + SOC_DAPM_PIN_SWITCH("Mic Jack"), +@@ -96,9 +107,15 @@ avs_rt298_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_param + { + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); ++ unsigned int clk_freq; + int ret; + +- ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, 19200000, SND_SOC_CLOCK_IN); ++ if (dmi_first_match(kblr_dmi_table)) ++ clk_freq = 24000000; ++ else ++ clk_freq = 19200000; ++ ++ ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, clk_freq, SND_SOC_CLOCK_IN); + if (ret < 0) + dev_err(rtd->dev, "Set codec sysclk failed: %d\n", ret); + +@@ -139,7 +156,10 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in + dl->platforms = platform; + dl->num_platforms = 1; + dl->id = 0; +- dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; ++ if (dmi_first_match(kblr_dmi_table)) ++ dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; ++ else ++ dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->init = avs_rt298_codec_init; + dl->be_hw_params_fixup = avs_rt298_be_fixup; + dl->ops = &avs_rt298_ops; +-- +2.35.1 + diff --git a/queue-6.0/asoc-intel-avs-fix-dma-mask-assignment.patch b/queue-6.0/asoc-intel-avs-fix-dma-mask-assignment.patch new file mode 100644 index 00000000000..41f9f30bad4 --- /dev/null +++ b/queue-6.0/asoc-intel-avs-fix-dma-mask-assignment.patch @@ -0,0 +1,36 @@ +From cd31722abe437f029a446aca26e9dc4dd6462464 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 14:19:41 +0200 +Subject: ASoC: Intel: avs: Fix DMA mask assignment + +From: Cezary Rojewski + +[ Upstream commit 83375566a7a7042cb34b24986d100f46bfa0c1e5 ] + +Spelling error leads to incorrect behavior when setting up DMA mask. + +Fixes: a5bbbde2b81e ("ASoC: Intel: avs: Use helper function to set up DMA") +Signed-off-by: Cezary Rojewski +Link: https://lore.kernel.org/r/20221010121955.718168-2-cezary.rojewski@intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/avs/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c +index c50c20fd681a..58db13374166 100644 +--- a/sound/soc/intel/avs/core.c ++++ b/sound/soc/intel/avs/core.c +@@ -440,7 +440,7 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) + if (bus->mlcap) + snd_hdac_ext_bus_get_ml_capabilities(bus); + +- if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) ++ if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) + dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + dma_set_max_seg_size(dev, UINT_MAX); + +-- +2.35.1 + diff --git a/queue-6.0/asoc-intel-avs-fix-potential-rx-buffer-overflow.patch b/queue-6.0/asoc-intel-avs-fix-potential-rx-buffer-overflow.patch new file mode 100644 index 00000000000..df5760c23fe --- /dev/null +++ b/queue-6.0/asoc-intel-avs-fix-potential-rx-buffer-overflow.patch @@ -0,0 +1,40 @@ +From 62639ddf544a8da6d14283bc5a6a7b8a352687ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 14:19:42 +0200 +Subject: ASoC: Intel: avs: Fix potential RX buffer overflow + +From: Cezary Rojewski + +[ Upstream commit 23ae34e033b2c0e5e88237af82b163b296fd6aa9 ] + +If an event caused firmware to return invalid RX size for +LARGE_CONFIG_GET, memcpy_fromio() could end up copying too many bytes. +Fix by utilizing min_t(). + +Reported-by: CoolStar +Fixes: f14a1c5a9f83 ("ASoC: Intel: avs: Add module management requests") +Signed-off-by: Cezary Rojewski +Link: https://lore.kernel.org/r/20221010121955.718168-3-cezary.rojewski@intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/avs/ipc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c +index 020d85c7520d..77da206f7dbb 100644 +--- a/sound/soc/intel/avs/ipc.c ++++ b/sound/soc/intel/avs/ipc.c +@@ -192,7 +192,8 @@ static void avs_dsp_receive_rx(struct avs_dev *adev, u64 header) + /* update size in case of LARGE_CONFIG_GET */ + if (msg.msg_target == AVS_MOD_MSG && + msg.global_msg_type == AVS_MOD_LARGE_CONFIG_GET) +- ipc->rx.size = msg.ext.large_config.data_off_size; ++ ipc->rx.size = min_t(u32, AVS_MAILBOX_SIZE, ++ msg.ext.large_config.data_off_size); + + memcpy_fromio(ipc->rx.data, avs_uplink_addr(adev), ipc->rx.size); + trace_avs_msg_payload(ipc->rx.data, ipc->rx.size); +-- +2.35.1 + diff --git a/queue-6.0/asoc-intel-avs-lock-substream-before-snd_pcm_stop.patch b/queue-6.0/asoc-intel-avs-lock-substream-before-snd_pcm_stop.patch new file mode 100644 index 00000000000..7f8f82b4bfd --- /dev/null +++ b/queue-6.0/asoc-intel-avs-lock-substream-before-snd_pcm_stop.patch @@ -0,0 +1,39 @@ +From 692e422f8f231cdf4debed8f2e83e6301a2299bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Nov 2022 12:55:49 +0100 +Subject: ASoC: Intel: avs: Lock substream before snd_pcm_stop() + +From: Cezary Rojewski + +[ Upstream commit c30c8f9d51ec24b36e2c65a6307a5c8cbc5a0ebc ] + +snd_pcm_stop() shall be called with stream lock held to prevent any +races between nonatomic streaming operations. + +Fixes: 2f1f570cd730 ("ASoC: Intel: avs: Coredump and recovery flow") +Signed-off-by: Cezary Rojewski +Link: https://lore.kernel.org/r/20221116115550.1100398-2-cezary.rojewski@intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/avs/ipc.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c +index 77da206f7dbb..306f0dc4eaf5 100644 +--- a/sound/soc/intel/avs/ipc.c ++++ b/sound/soc/intel/avs/ipc.c +@@ -123,7 +123,10 @@ static void avs_dsp_recovery(struct avs_dev *adev) + if (!substream || !substream->runtime) + continue; + ++ /* No need for _irq() as we are in nonatomic context. */ ++ snd_pcm_stream_lock(substream); + snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); ++ snd_pcm_stream_unlock(substream); + } + } + } +-- +2.35.1 + diff --git a/queue-6.0/asoc-mediatek-mt8173-enable-irq-when-pdata-is-ready.patch b/queue-6.0/asoc-mediatek-mt8173-enable-irq-when-pdata-is-ready.patch new file mode 100644 index 00000000000..c24306b8374 --- /dev/null +++ b/queue-6.0/asoc-mediatek-mt8173-enable-irq-when-pdata-is-ready.patch @@ -0,0 +1,71 @@ +From d77ed2feac97d4d2e49c79ae689c811fec0cb939 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Nov 2022 11:49:16 +0100 +Subject: ASoC: mediatek: mt8173: Enable IRQ when pdata is ready + +From: Ricardo Ribalda + +[ Upstream commit 4cbb264d4e9136acab2c8fd39e39ab1b1402b84b ] + +If the device does not come straight from reset, we might receive an IRQ +before we are ready to handle it. + +Fixes: + +[ 2.334737] Unable to handle kernel read from unreadable memory at virtual address 00000000000001e4 +[ 2.522601] Call trace: +[ 2.525040] regmap_read+0x1c/0x80 +[ 2.528434] mt8173_afe_irq_handler+0x40/0xf0 +... +[ 2.598921] start_kernel+0x338/0x42c + +Signed-off-by: Ricardo Ribalda +Fixes: ee0bcaff109f ("ASoC: mediatek: Add AFE platform driver") +Link: https://lore.kernel.org/r/20221128-mt8173-afe-v1-0-70728221628f@chromium.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/mediatek/mt8173/mt8173-afe-pcm.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c +index dcaeeeb8aac7..bc155dd937e0 100644 +--- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c ++++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c +@@ -1070,16 +1070,6 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev) + + afe->dev = &pdev->dev; + +- irq_id = platform_get_irq(pdev, 0); +- if (irq_id <= 0) +- return irq_id < 0 ? irq_id : -ENXIO; +- ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler, +- 0, "Afe_ISR_Handle", (void *)afe); +- if (ret) { +- dev_err(afe->dev, "could not request_irq\n"); +- return ret; +- } +- + afe->base_addr = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(afe->base_addr)) + return PTR_ERR(afe->base_addr); +@@ -1185,6 +1175,16 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev) + if (ret) + goto err_cleanup_components; + ++ irq_id = platform_get_irq(pdev, 0); ++ if (irq_id <= 0) ++ return irq_id < 0 ? irq_id : -ENXIO; ++ ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler, ++ 0, "Afe_ISR_Handle", (void *)afe); ++ if (ret) { ++ dev_err(afe->dev, "could not request_irq\n"); ++ goto err_pm_disable; ++ } ++ + dev_info(&pdev->dev, "MT8173 AFE driver initialized.\n"); + return 0; + +-- +2.35.1 + diff --git a/queue-6.0/asoc-mediatek-mtk-btcvsd-add-checks-for-write-and-re.patch b/queue-6.0/asoc-mediatek-mtk-btcvsd-add-checks-for-write-and-re.patch new file mode 100644 index 00000000000..5ac2f202015 --- /dev/null +++ b/queue-6.0/asoc-mediatek-mtk-btcvsd-add-checks-for-write-and-re.patch @@ -0,0 +1,43 @@ +From b0cf6af0c1c97aad720c51386dd15e2852a3444c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Nov 2022 11:07:50 +0800 +Subject: ASoC: mediatek: mtk-btcvsd: Add checks for write and read of + mtk_btcvsd_snd + +From: Jiasheng Jiang + +[ Upstream commit d067b3378a78c9c3048ac535e31c171b6f5b5846 ] + +As the mtk_btcvsd_snd_write and mtk_btcvsd_snd_read may return error, +it should be better to catch the exception. + +Fixes: 4bd8597dc36c ("ASoC: mediatek: add btcvsd driver") +Signed-off-by: Jiasheng Jiang +Link: https://lore.kernel.org/r/20221116030750.40500-1-jiasheng@iscas.ac.cn +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/mediatek/common/mtk-btcvsd.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/sound/soc/mediatek/common/mtk-btcvsd.c b/sound/soc/mediatek/common/mtk-btcvsd.c +index d884bb7c0fc7..1c28b41e4311 100644 +--- a/sound/soc/mediatek/common/mtk-btcvsd.c ++++ b/sound/soc/mediatek/common/mtk-btcvsd.c +@@ -1038,11 +1038,9 @@ static int mtk_pcm_btcvsd_copy(struct snd_soc_component *component, + struct mtk_btcvsd_snd *bt = snd_soc_component_get_drvdata(component); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) +- mtk_btcvsd_snd_write(bt, buf, count); ++ return mtk_btcvsd_snd_write(bt, buf, count); + else +- mtk_btcvsd_snd_read(bt, buf, count); +- +- return 0; ++ return mtk_btcvsd_snd_read(bt, buf, count); + } + + /* kcontrol */ +-- +2.35.1 + diff --git a/queue-6.0/asoc-pcm512x-fix-pm-disable-depth-imbalance-in-pcm51.patch b/queue-6.0/asoc-pcm512x-fix-pm-disable-depth-imbalance-in-pcm51.patch new file mode 100644 index 00000000000..66a15e705fd --- /dev/null +++ b/queue-6.0/asoc-pcm512x-fix-pm-disable-depth-imbalance-in-pcm51.patch @@ -0,0 +1,64 @@ +From 0725cf9007787a9da0ee9c0153f7201b23ebc38a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Sep 2022 00:04:02 +0800 +Subject: ASoC: pcm512x: Fix PM disable depth imbalance in pcm512x_probe + +From: Zhang Qilong + +[ Upstream commit 97b801be6f8e53676b9f2b105f54e35c745c1b22 ] + +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 going to +err_pm instead of err_clk. + +Fixes:f086ba9d5389c ("ASoC: pcm512x: Support mastering BCLK/LRCLK using the PLL") + +Signed-off-by: Zhang Qilong +Link: https://lore.kernel.org/r/20220928160402.126140-1-zhangqilong3@huawei.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/pcm512x.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c +index 767463e82665..89059a673cf0 100644 +--- a/sound/soc/codecs/pcm512x.c ++++ b/sound/soc/codecs/pcm512x.c +@@ -1634,7 +1634,7 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap) + if (val > 6) { + dev_err(dev, "Invalid pll-in\n"); + ret = -EINVAL; +- goto err_clk; ++ goto err_pm; + } + pcm512x->pll_in = val; + } +@@ -1643,7 +1643,7 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap) + if (val > 6) { + dev_err(dev, "Invalid pll-out\n"); + ret = -EINVAL; +- goto err_clk; ++ goto err_pm; + } + pcm512x->pll_out = val; + } +@@ -1652,12 +1652,12 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap) + dev_err(dev, + "Error: both pll-in and pll-out, or none\n"); + ret = -EINVAL; +- goto err_clk; ++ goto err_pm; + } + if (pcm512x->pll_in && pcm512x->pll_in == pcm512x->pll_out) { + dev_err(dev, "Error: pll-in == pll-out\n"); + ret = -EINVAL; +- goto err_clk; ++ goto err_pm; + } + } + #endif +-- +2.35.1 + diff --git a/queue-6.0/asoc-pxa-fix-null-pointer-dereference-in-filter.patch b/queue-6.0/asoc-pxa-fix-null-pointer-dereference-in-filter.patch new file mode 100644 index 00000000000..e37c1372026 --- /dev/null +++ b/queue-6.0/asoc-pxa-fix-null-pointer-dereference-in-filter.patch @@ -0,0 +1,37 @@ +From 48d557f3fd866ea6e19b5d033796be12601dd61a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Nov 2022 16:56:29 +0800 +Subject: ASoC: pxa: fix null-pointer dereference in filter() + +From: Zeng Heng + +[ Upstream commit ec7bf231aaa1bdbcb69d23bc50c753c80fb22429 ] + +kasprintf() would return NULL pointer when kmalloc() fail to allocate. +Need to check the return pointer before calling strcmp(). + +Fixes: 7a824e214e25 ("ASoC: mmp: add audio dma support") +Signed-off-by: Zeng Heng +Link: https://lore.kernel.org/r/20221114085629.1910435-1-zengheng4@huawei.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/pxa/mmp-pcm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c +index 5d520e18e512..99b245e3079a 100644 +--- a/sound/soc/pxa/mmp-pcm.c ++++ b/sound/soc/pxa/mmp-pcm.c +@@ -98,7 +98,7 @@ static bool filter(struct dma_chan *chan, void *param) + + devname = kasprintf(GFP_KERNEL, "%s.%d", dma_data->dma_res->name, + dma_data->ssp_id); +- if ((strcmp(dev_name(chan->device->dev), devname) == 0) && ++ if (devname && (strcmp(dev_name(chan->device->dev), devname) == 0) && + (chan->chan_id == dma_data->dma_res->start)) { + found = true; + } +-- +2.35.1 + diff --git a/queue-6.0/asoc-qcom-add-checks-for-devm_kcalloc.patch b/queue-6.0/asoc-qcom-add-checks-for-devm_kcalloc.patch new file mode 100644 index 00000000000..87c421b9907 --- /dev/null +++ b/queue-6.0/asoc-qcom-add-checks-for-devm_kcalloc.patch @@ -0,0 +1,38 @@ +From 19ca3ae12acde279dd43b7075c8390318b5a1ee8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Nov 2022 14:05:10 +0000 +Subject: ASoC: qcom: Add checks for devm_kcalloc + +From: Yuan Can + +[ Upstream commit 1bf5ee979076ceb121ee51c95197d890b1cee7f4 ] + +As the devm_kcalloc may return NULL, the return value needs to be checked +to avoid NULL poineter dereference. + +Fixes: 24caf8d9eb10 ("ASoC: qcom: lpass-sc7180: Add platform driver for lpass audio") +Signed-off-by: Yuan Can +Link: https://lore.kernel.org/r/20221124140510.63468-1-yuancan@huawei.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/qcom/lpass-sc7180.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/qcom/lpass-sc7180.c b/sound/soc/qcom/lpass-sc7180.c +index 77a556b27cf0..24a1c121cb2e 100644 +--- a/sound/soc/qcom/lpass-sc7180.c ++++ b/sound/soc/qcom/lpass-sc7180.c +@@ -131,6 +131,9 @@ static int sc7180_lpass_init(struct platform_device *pdev) + + drvdata->clks = devm_kcalloc(dev, variant->num_clks, + sizeof(*drvdata->clks), GFP_KERNEL); ++ if (!drvdata->clks) ++ return -ENOMEM; ++ + drvdata->num_clks = variant->num_clks; + + for (i = 0; i < drvdata->num_clks; i++) +-- +2.35.1 + diff --git a/queue-6.0/ata-libata-fix-ncq-autosense-logic.patch b/queue-6.0/ata-libata-fix-ncq-autosense-logic.patch new file mode 100644 index 00000000000..6e5dfcf1e44 --- /dev/null +++ b/queue-6.0/ata-libata-fix-ncq-autosense-logic.patch @@ -0,0 +1,76 @@ +From 4d4c01c86697b73baa9e77275355385ef0bb3aa0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Sep 2022 20:53:06 +0000 +Subject: ata: libata: fix NCQ autosense logic + +From: Niklas Cassel + +[ Upstream commit 7390896b3484d44cbdb8bc4859964314ac66d3c9 ] + +Currently, the logic if we should call ata_scsi_set_sense() +(and set flag ATA_QCFLAG_SENSE_VALID to indicate that we have +successfully added sense data to the struct ata_queued_cmd) +looks like this: + +if (dev->class == ATA_DEV_ZAC && + ((qc->result_tf.status & ATA_SENSE) || qc->result_tf.auxiliary)) + +The problem with this is that a drive can support the NCQ command +error log without supporting NCQ autosense. + +On such a drive, if the failing command has sense data, the status +field in the NCQ command error log will have the ATA_SENSE bit set. + +It is just that this sense data is not included in the NCQ command +error log when NCQ autosense is not supported. Instead the sense +data has to be fetched using the REQUEST SENSE DATA EXT command. + +Therefore, we should only add the sense data if the drive supports +NCQ autosense AND the ATA_SENSE bit is set in the status field. + +Fix this, and at the same time, remove the duplicated ATA_DEV_ZAC +check. The struct ata_taskfile supplied to ata_eh_read_log_10h() +is memset:ed before calling the function, so simply checking if +qc->result_tf.auxiliary is set is sufficient to tell us that the +log actually contained sense data. + +Fixes: d238ffd59d3c ("libata: do not attempt to retrieve sense code twice") +Signed-off-by: Niklas Cassel +Signed-off-by: Damien Le Moal +Signed-off-by: Sasha Levin +--- + drivers/ata/libata-sata.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c +index 13b9d0fdd42c..8e292e2abb04 100644 +--- a/drivers/ata/libata-sata.c ++++ b/drivers/ata/libata-sata.c +@@ -1392,7 +1392,8 @@ static int ata_eh_read_log_10h(struct ata_device *dev, + tf->hob_lbah = buf[10]; + tf->nsect = buf[12]; + tf->hob_nsect = buf[13]; +- if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id)) ++ if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id) && ++ (tf->status & ATA_SENSE)) + tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16]; + + return 0; +@@ -1456,8 +1457,12 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) + memcpy(&qc->result_tf, &tf, sizeof(tf)); + qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48; + qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ; +- if (dev->class == ATA_DEV_ZAC && +- ((qc->result_tf.status & ATA_SENSE) || qc->result_tf.auxiliary)) { ++ ++ /* ++ * If the device supports NCQ autosense, ata_eh_read_log_10h() will have ++ * stored the sense data in qc->result_tf.auxiliary. ++ */ ++ if (qc->result_tf.auxiliary) { + char sense_key, asc, ascq; + + sense_key = (qc->result_tf.auxiliary >> 16) & 0xff; +-- +2.35.1 + diff --git a/queue-6.0/bfq-fix-waker_bfqq-inconsistency-crash.patch b/queue-6.0/bfq-fix-waker_bfqq-inconsistency-crash.patch new file mode 100644 index 00000000000..3b42a1b8079 --- /dev/null +++ b/queue-6.0/bfq-fix-waker_bfqq-inconsistency-crash.patch @@ -0,0 +1,77 @@ +From 2b5f8bf239185327866673a881112d89d2df68c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Nov 2022 10:10:29 -0800 +Subject: bfq: fix waker_bfqq inconsistency crash + +From: Khazhismel Kumykov + +[ Upstream commit a1795c2ccb1e4c49220d2a0d381540024d71647c ] + +This fixes crashes in bfq_add_bfqq_busy due to waker_bfqq being NULL, +but woken_list_node still being hashed. This would happen when +bfq_init_rq() expects a brand new allocated queue to be returned from +bfq_get_bfqq_handle_split() and unconditionally updates waker_bfqq +without resetting woken_list_node. Since we can always return oom_bfqq +when attempting to allocate, we cannot assume waker_bfqq starts as NULL. + +Avoid setting woken_bfqq for oom_bfqq entirely, as it's not useful. + +Crashes would have a stacktrace like: +[160595.656560] bfq_add_bfqq_busy+0x110/0x1ec +[160595.661142] bfq_add_request+0x6bc/0x980 +[160595.666602] bfq_insert_request+0x8ec/0x1240 +[160595.671762] bfq_insert_requests+0x58/0x9c +[160595.676420] blk_mq_sched_insert_request+0x11c/0x198 +[160595.682107] blk_mq_submit_bio+0x270/0x62c +[160595.686759] __submit_bio_noacct_mq+0xec/0x178 +[160595.691926] submit_bio+0x120/0x184 +[160595.695990] ext4_mpage_readpages+0x77c/0x7c8 +[160595.701026] ext4_readpage+0x60/0xb0 +[160595.705158] filemap_read_page+0x54/0x114 +[160595.711961] filemap_fault+0x228/0x5f4 +[160595.716272] do_read_fault+0xe0/0x1f0 +[160595.720487] do_fault+0x40/0x1c8 + +Tested by injecting random failures into bfq_get_queue, crashes go away +completely. + +Fixes: 8ef3fc3a043c ("block, bfq: make shared queues inherit wakers") +Signed-off-by: Khazhismel Kumykov +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20221108181030.1611703-1-khazhy@google.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/bfq-iosched.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c +index c740b41fe0a4..68872a61706a 100644 +--- a/block/bfq-iosched.c ++++ b/block/bfq-iosched.c +@@ -6786,6 +6786,12 @@ static struct bfq_queue *bfq_init_rq(struct request *rq) + bfqq = bfq_get_bfqq_handle_split(bfqd, bic, bio, + true, is_sync, + NULL); ++ if (unlikely(bfqq == &bfqd->oom_bfqq)) ++ bfqq_already_existing = true; ++ } else ++ bfqq_already_existing = true; ++ ++ if (!bfqq_already_existing) { + bfqq->waker_bfqq = old_bfqq->waker_bfqq; + bfqq->tentative_waker_bfqq = NULL; + +@@ -6799,8 +6805,7 @@ static struct bfq_queue *bfq_init_rq(struct request *rq) + if (bfqq->waker_bfqq) + hlist_add_head(&bfqq->woken_list_node, + &bfqq->waker_bfqq->woken_list); +- } else +- bfqq_already_existing = true; ++ } + } + } + +-- +2.35.1 + diff --git a/queue-6.0/binfmt_misc-fix-shift-out-of-bounds-in-check_special.patch b/queue-6.0/binfmt_misc-fix-shift-out-of-bounds-in-check_special.patch new file mode 100644 index 00000000000..005bf8692c3 --- /dev/null +++ b/queue-6.0/binfmt_misc-fix-shift-out-of-bounds-in-check_special.patch @@ -0,0 +1,61 @@ +From 0c8c24eb7d113ef7d3b19abe13cff4789aca8241 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Nov 2022 10:51:23 +0800 +Subject: binfmt_misc: fix shift-out-of-bounds in check_special_flags + +From: Liu Shixin + +[ Upstream commit 6a46bf558803dd2b959ca7435a5c143efe837217 ] + +UBSAN reported a shift-out-of-bounds warning: + + left shift of 1 by 31 places cannot be represented in type 'int' + Call Trace: + + __dump_stack lib/dump_stack.c:88 [inline] + dump_stack_lvl+0x8d/0xcf lib/dump_stack.c:106 + ubsan_epilogue+0xa/0x44 lib/ubsan.c:151 + __ubsan_handle_shift_out_of_bounds+0x1e7/0x208 lib/ubsan.c:322 + check_special_flags fs/binfmt_misc.c:241 [inline] + create_entry fs/binfmt_misc.c:456 [inline] + bm_register_write+0x9d3/0xa20 fs/binfmt_misc.c:654 + vfs_write+0x11e/0x580 fs/read_write.c:582 + ksys_write+0xcf/0x120 fs/read_write.c:637 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x34/0x80 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + RIP: 0033:0x4194e1 + +Since the type of Node's flags is unsigned long, we should define these +macros with same type too. + +Signed-off-by: Liu Shixin +Signed-off-by: Kees Cook +Link: https://lore.kernel.org/r/20221102025123.1117184-1-liushixin2@huawei.com +Signed-off-by: Sasha Levin +--- + fs/binfmt_misc.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c +index e1eae7ea823a..bb202ad369d5 100644 +--- a/fs/binfmt_misc.c ++++ b/fs/binfmt_misc.c +@@ -44,10 +44,10 @@ static LIST_HEAD(entries); + static int enabled = 1; + + enum {Enabled, Magic}; +-#define MISC_FMT_PRESERVE_ARGV0 (1 << 31) +-#define MISC_FMT_OPEN_BINARY (1 << 30) +-#define MISC_FMT_CREDENTIALS (1 << 29) +-#define MISC_FMT_OPEN_FILE (1 << 28) ++#define MISC_FMT_PRESERVE_ARGV0 (1UL << 31) ++#define MISC_FMT_OPEN_BINARY (1UL << 30) ++#define MISC_FMT_CREDENTIALS (1UL << 29) ++#define MISC_FMT_OPEN_FILE (1UL << 28) + + typedef struct { + struct list_head list; +-- +2.35.1 + diff --git a/queue-6.0/blk-crypto-pass-a-gendisk-to-blk_crypto_sysfs_-un-re.patch b/queue-6.0/blk-crypto-pass-a-gendisk-to-blk_crypto_sysfs_-un-re.patch new file mode 100644 index 00000000000..7fc6fa21912 --- /dev/null +++ b/queue-6.0/blk-crypto-pass-a-gendisk-to-blk_crypto_sysfs_-un-re.patch @@ -0,0 +1,109 @@ +From 4b2c661b8e504a4e7f15f4c76d71787aed506cf8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Nov 2022 05:26:33 +0100 +Subject: blk-crypto: pass a gendisk to blk_crypto_sysfs_{,un}register + +From: Christoph Hellwig + +[ Upstream commit 450deb93df7d457cdd93594a1987f9650c749b96 ] + +Prepare for changes to the block layer sysfs handling by passing the +readily available gendisk to blk_crypto_sysfs_{,un}register. + +Signed-off-by: Christoph Hellwig +Reviewed-by: Eric Biggers +Link: https://lore.kernel.org/r/20221114042637.1009333-2-hch@lst.de +Signed-off-by: Jens Axboe +Stable-dep-of: d36a9ea5e776 ("block: fix use-after-free of q->q_usage_counter") +Signed-off-by: Sasha Levin +--- + block/blk-crypto-internal.h | 10 ++++++---- + block/blk-crypto-sysfs.c | 7 ++++--- + block/blk-sysfs.c | 4 ++-- + 3 files changed, 12 insertions(+), 9 deletions(-) + +diff --git a/block/blk-crypto-internal.h b/block/blk-crypto-internal.h +index e6818ffaddbf..b8a00847171f 100644 +--- a/block/blk-crypto-internal.h ++++ b/block/blk-crypto-internal.h +@@ -21,9 +21,9 @@ extern const struct blk_crypto_mode blk_crypto_modes[]; + + #ifdef CONFIG_BLK_INLINE_ENCRYPTION + +-int blk_crypto_sysfs_register(struct request_queue *q); ++int blk_crypto_sysfs_register(struct gendisk *disk); + +-void blk_crypto_sysfs_unregister(struct request_queue *q); ++void blk_crypto_sysfs_unregister(struct gendisk *disk); + + void bio_crypt_dun_increment(u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE], + unsigned int inc); +@@ -67,12 +67,14 @@ static inline bool blk_crypto_rq_is_encrypted(struct request *rq) + + #else /* CONFIG_BLK_INLINE_ENCRYPTION */ + +-static inline int blk_crypto_sysfs_register(struct request_queue *q) ++static inline int blk_crypto_sysfs_register(struct gendisk *disk) + { + return 0; + } + +-static inline void blk_crypto_sysfs_unregister(struct request_queue *q) { } ++static inline void blk_crypto_sysfs_unregister(struct gendisk *disk) ++{ ++} + + static inline bool bio_crypt_rq_ctx_compatible(struct request *rq, + struct bio *bio) +diff --git a/block/blk-crypto-sysfs.c b/block/blk-crypto-sysfs.c +index fd93bd2f33b7..e05f145cd797 100644 +--- a/block/blk-crypto-sysfs.c ++++ b/block/blk-crypto-sysfs.c +@@ -126,8 +126,9 @@ static struct kobj_type blk_crypto_ktype = { + * If the request_queue has a blk_crypto_profile, create the "crypto" + * subdirectory in sysfs (/sys/block/$disk/queue/crypto/). + */ +-int blk_crypto_sysfs_register(struct request_queue *q) ++int blk_crypto_sysfs_register(struct gendisk *disk) + { ++ struct request_queue *q = disk->queue; + struct blk_crypto_kobj *obj; + int err; + +@@ -149,9 +150,9 @@ int blk_crypto_sysfs_register(struct request_queue *q) + return 0; + } + +-void blk_crypto_sysfs_unregister(struct request_queue *q) ++void blk_crypto_sysfs_unregister(struct gendisk *disk) + { +- kobject_put(q->crypto_kobject); ++ kobject_put(disk->queue->crypto_kobject); + } + + static int __init blk_crypto_sysfs_init(void) +diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c +index 8822b4b6bed2..c8a1119c3950 100644 +--- a/block/blk-sysfs.c ++++ b/block/blk-sysfs.c +@@ -833,7 +833,7 @@ int blk_register_queue(struct gendisk *disk) + goto put_dev; + } + +- ret = blk_crypto_sysfs_register(q); ++ ret = blk_crypto_sysfs_register(disk); + if (ret) + goto put_dev; + +@@ -910,7 +910,7 @@ void blk_unregister_queue(struct gendisk *disk) + */ + if (queue_is_mq(q)) + blk_mq_sysfs_unregister(disk); +- blk_crypto_sysfs_unregister(q); ++ blk_crypto_sysfs_unregister(disk); + + mutex_lock(&q->sysfs_lock); + elv_unregister_queue(q); +-- +2.35.1 + diff --git a/queue-6.0/blk-iocost-simplify-ioc_name.patch b/queue-6.0/blk-iocost-simplify-ioc_name.patch new file mode 100644 index 00000000000..cc90358ba20 --- /dev/null +++ b/queue-6.0/blk-iocost-simplify-ioc_name.patch @@ -0,0 +1,53 @@ +From 424aa521e25e77c9e3d3660dce0be8707352a5c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Sep 2022 20:04:53 +0200 +Subject: blk-iocost: simplify ioc_name + +From: Christoph Hellwig + +[ Upstream commit 9df3e65139b923dfe98f76b7057882c7afb2d3e4 ] + +Just directly dereference the disk name instead of going through multiple +hoops to find the same value. + +Signed-off-by: Christoph Hellwig +Reviewed-by: Andreas Herrmann +Acked-by: Tejun Heo +Link: https://lore.kernel.org/r/20220921180501.1539876-10-hch@lst.de +Signed-off-by: Jens Axboe +Stable-dep-of: d36a9ea5e776 ("block: fix use-after-free of q->q_usage_counter") +Signed-off-by: Sasha Levin +--- + block/blk-iocost.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/block/blk-iocost.c b/block/blk-iocost.c +index 7936e5f5821c..cba9d3ad58e1 100644 +--- a/block/blk-iocost.c ++++ b/block/blk-iocost.c +@@ -664,17 +664,13 @@ static struct ioc *q_to_ioc(struct request_queue *q) + return rqos_to_ioc(rq_qos_id(q, RQ_QOS_COST)); + } + +-static const char *q_name(struct request_queue *q) +-{ +- if (blk_queue_registered(q)) +- return kobject_name(q->kobj.parent); +- else +- return ""; +-} +- + static const char __maybe_unused *ioc_name(struct ioc *ioc) + { +- return q_name(ioc->rqos.q); ++ struct gendisk *disk = ioc->rqos.q->disk; ++ ++ if (!disk) ++ return ""; ++ return disk->disk_name; + } + + static struct ioc_gq *pd_to_iocg(struct blkg_policy_data *pd) +-- +2.35.1 + diff --git a/queue-6.0/blk-mq-avoid-double-queue_rq-because-of-early-timeou.patch b/queue-6.0/blk-mq-avoid-double-queue_rq-because-of-early-timeou.patch new file mode 100644 index 00000000000..7aa1a4d5106 --- /dev/null +++ b/queue-6.0/blk-mq-avoid-double-queue_rq-because-of-early-timeou.patch @@ -0,0 +1,148 @@ +From dbe0e68e1a1a2d634dd3b7a4564f2a7098079960 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 13:19:57 +0800 +Subject: blk-mq: avoid double ->queue_rq() because of early timeout + +From: David Jeffery + +[ Upstream commit 82c229476b8f6afd7e09bc4dc77d89dc19ff7688 ] + +David Jeffery found one double ->queue_rq() issue, so far it can +be triggered in VM use case because of long vmexit latency or preempt +latency of vCPU pthread or long page fault in vCPU pthread, then block +IO req could be timed out before queuing the request to hardware but after +calling blk_mq_start_request() during ->queue_rq(), then timeout handler +may handle it by requeue, then double ->queue_rq() is caused, and kernel +panic. + +So far, it is driver's responsibility to cover the race between timeout +and completion, so it seems supposed to be solved in driver in theory, +given driver has enough knowledge. + +But it is really one common problem, lots of driver could have similar +issue, and could be hard to fix all affected drivers, even it isn't easy +for driver to handle the race. So David suggests this patch by draining +in-progress ->queue_rq() for solving this issue. + +Cc: Stefan Hajnoczi +Cc: Keith Busch +Cc: virtualization@lists.linux-foundation.org +Cc: Bart Van Assche +Signed-off-by: David Jeffery +Signed-off-by: Ming Lei +Reviewed-by: Bart Van Assche +Link: https://lore.kernel.org/r/20221026051957.358818-1-ming.lei@redhat.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-mq.c | 56 +++++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 44 insertions(+), 12 deletions(-) + +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 88975170cc32..05e33c51702d 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -1442,7 +1442,13 @@ static void blk_mq_rq_timed_out(struct request *req) + blk_add_timer(req); + } + +-static bool blk_mq_req_expired(struct request *rq, unsigned long *next) ++struct blk_expired_data { ++ bool has_timedout_rq; ++ unsigned long next; ++ unsigned long timeout_start; ++}; ++ ++static bool blk_mq_req_expired(struct request *rq, struct blk_expired_data *expired) + { + unsigned long deadline; + +@@ -1452,13 +1458,13 @@ static bool blk_mq_req_expired(struct request *rq, unsigned long *next) + return false; + + deadline = READ_ONCE(rq->deadline); +- if (time_after_eq(jiffies, deadline)) ++ if (time_after_eq(expired->timeout_start, deadline)) + return true; + +- if (*next == 0) +- *next = deadline; +- else if (time_after(*next, deadline)) +- *next = deadline; ++ if (expired->next == 0) ++ expired->next = deadline; ++ else if (time_after(expired->next, deadline)) ++ expired->next = deadline; + return false; + } + +@@ -1472,7 +1478,7 @@ void blk_mq_put_rq_ref(struct request *rq) + + static bool blk_mq_check_expired(struct request *rq, void *priv) + { +- unsigned long *next = priv; ++ struct blk_expired_data *expired = priv; + + /* + * blk_mq_queue_tag_busy_iter() has locked the request, so it cannot +@@ -1481,7 +1487,18 @@ static bool blk_mq_check_expired(struct request *rq, void *priv) + * it was completed and reallocated as a new request after returning + * from blk_mq_check_expired(). + */ +- if (blk_mq_req_expired(rq, next)) ++ if (blk_mq_req_expired(rq, expired)) { ++ expired->has_timedout_rq = true; ++ return false; ++ } ++ return true; ++} ++ ++static bool blk_mq_handle_expired(struct request *rq, void *priv) ++{ ++ struct blk_expired_data *expired = priv; ++ ++ if (blk_mq_req_expired(rq, expired)) + blk_mq_rq_timed_out(rq); + return true; + } +@@ -1490,7 +1507,9 @@ static void blk_mq_timeout_work(struct work_struct *work) + { + struct request_queue *q = + container_of(work, struct request_queue, timeout_work); +- unsigned long next = 0; ++ struct blk_expired_data expired = { ++ .timeout_start = jiffies, ++ }; + struct blk_mq_hw_ctx *hctx; + unsigned long i; + +@@ -1510,10 +1529,23 @@ static void blk_mq_timeout_work(struct work_struct *work) + if (!percpu_ref_tryget(&q->q_usage_counter)) + return; + +- blk_mq_queue_tag_busy_iter(q, blk_mq_check_expired, &next); ++ /* check if there is any timed-out request */ ++ blk_mq_queue_tag_busy_iter(q, blk_mq_check_expired, &expired); ++ if (expired.has_timedout_rq) { ++ /* ++ * Before walking tags, we must ensure any submit started ++ * before the current time has finished. Since the submit ++ * uses srcu or rcu, wait for a synchronization point to ++ * ensure all running submits have finished ++ */ ++ blk_mq_wait_quiesce_done(q); ++ ++ expired.next = 0; ++ blk_mq_queue_tag_busy_iter(q, blk_mq_handle_expired, &expired); ++ } + +- if (next != 0) { +- mod_timer(&q->timeout, next); ++ if (expired.next != 0) { ++ mod_timer(&q->timeout, expired.next); + } else { + /* + * Request timeouts are handled as a forward rolling timer. If +-- +2.35.1 + diff --git a/queue-6.0/blk-mq-fix-possible-memleak-when-register-hctx-faile.patch b/queue-6.0/blk-mq-fix-possible-memleak-when-register-hctx-faile.patch new file mode 100644 index 00000000000..8a7ad694f08 --- /dev/null +++ b/queue-6.0/blk-mq-fix-possible-memleak-when-register-hctx-faile.patch @@ -0,0 +1,86 @@ +From e06fd7d2df30982c63a4e9044ca71aa0b9b1d829 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 10:29:40 +0800 +Subject: blk-mq: fix possible memleak when register 'hctx' failed + +From: Ye Bin + +[ Upstream commit 4b7a21c57b14fbcd0e1729150189e5933f5088e9 ] + +There's issue as follows when do fault injection test: +unreferenced object 0xffff888132a9f400 (size 512): + comm "insmod", pid 308021, jiffies 4324277909 (age 509.733s) + hex dump (first 32 bytes): + 00 00 00 00 00 00 00 00 08 f4 a9 32 81 88 ff ff ...........2.... + 08 f4 a9 32 81 88 ff ff 00 00 00 00 00 00 00 00 ...2............ + backtrace: + [<00000000e8952bb4>] kmalloc_node_trace+0x22/0xa0 + [<00000000f9980e0f>] blk_mq_alloc_and_init_hctx+0x3f1/0x7e0 + [<000000002e719efa>] blk_mq_realloc_hw_ctxs+0x1e6/0x230 + [<000000004f1fda40>] blk_mq_init_allocated_queue+0x27e/0x910 + [<00000000287123ec>] __blk_mq_alloc_disk+0x67/0xf0 + [<00000000a2a34657>] 0xffffffffa2ad310f + [<00000000b173f718>] 0xffffffffa2af824a + [<0000000095a1dabb>] do_one_initcall+0x87/0x2a0 + [<00000000f32fdf93>] do_init_module+0xdf/0x320 + [<00000000cbe8541e>] load_module+0x3006/0x3390 + [<0000000069ed1bdb>] __do_sys_finit_module+0x113/0x1b0 + [<00000000a1a29ae8>] do_syscall_64+0x35/0x80 + [<000000009cd878b0>] entry_SYSCALL_64_after_hwframe+0x46/0xb0 + +Fault injection context as follows: + kobject_add + blk_mq_register_hctx + blk_mq_sysfs_register + blk_register_queue + device_add_disk + null_add_dev.part.0 [null_blk] + +As 'blk_mq_register_hctx' may already add some objects when failed halfway, +but there isn't do fallback, caller don't know which objects add failed. +To solve above issue just do fallback when add objects failed halfway in +'blk_mq_register_hctx'. + +Signed-off-by: Ye Bin +Reviewed-by: Ming Lei +Link: https://lore.kernel.org/r/20221117022940.873959-1-yebin@huaweicloud.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-mq-sysfs.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c +index 93997d297d42..4515288fbe35 100644 +--- a/block/blk-mq-sysfs.c ++++ b/block/blk-mq-sysfs.c +@@ -185,7 +185,7 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx) + { + struct request_queue *q = hctx->queue; + struct blk_mq_ctx *ctx; +- int i, ret; ++ int i, j, ret; + + if (!hctx->nr_ctx) + return 0; +@@ -197,9 +197,16 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx) + hctx_for_each_ctx(hctx, ctx, i) { + ret = kobject_add(&ctx->kobj, &hctx->kobj, "cpu%u", ctx->cpu); + if (ret) +- break; ++ goto out; + } + ++ return 0; ++out: ++ hctx_for_each_ctx(hctx, ctx, j) { ++ if (j < i) ++ kobject_del(&ctx->kobj); ++ } ++ kobject_del(&hctx->kobj); + return ret; + } + +-- +2.35.1 + diff --git a/queue-6.0/blk-mq-move-the-srcu_struct-used-for-quiescing-to-th.patch b/queue-6.0/blk-mq-move-the-srcu_struct-used-for-quiescing-to-th.patch new file mode 100644 index 00000000000..19ae0017b2e --- /dev/null +++ b/queue-6.0/blk-mq-move-the-srcu_struct-used-for-quiescing-to-th.patch @@ -0,0 +1,358 @@ +From b026ab41394c0bc83c5614f5aed463e0a27b1ea5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Nov 2022 16:00:47 +0100 +Subject: blk-mq: move the srcu_struct used for quiescing to the tagset + +From: Christoph Hellwig + +[ Upstream commit 80bd4a7aab4c9ce59bf5e35fdf52aa23d8a3c9f5 ] + +All I/O submissions have fairly similar latencies, and a tagset-wide +quiesce is a fairly common operation. + +Signed-off-by: Christoph Hellwig +Reviewed-by: Keith Busch +Reviewed-by: Ming Lei +Reviewed-by: Chao Leng +Reviewed-by: Sagi Grimberg +Reviewed-by: Hannes Reinecke +Reviewed-by: Chaitanya Kulkarni +Link: https://lore.kernel.org/r/20221101150050.3510-12-hch@lst.de +[axboe: fix whitespace] +Signed-off-by: Jens Axboe +Stable-dep-of: d36a9ea5e776 ("block: fix use-after-free of q->q_usage_counter") +Signed-off-by: Sasha Levin +--- + block/blk-core.c | 27 +++++---------------------- + block/blk-mq.c | 33 +++++++++++++++++++++++++-------- + block/blk-mq.h | 14 +++++++------- + block/blk-sysfs.c | 9 ++------- + block/blk.h | 9 +-------- + block/genhd.c | 2 +- + include/linux/blk-mq.h | 4 ++++ + include/linux/blkdev.h | 9 --------- + 8 files changed, 45 insertions(+), 62 deletions(-) + +diff --git a/block/blk-core.c b/block/blk-core.c +index 2fbdf17f2206..adc5fc562348 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -66,7 +66,6 @@ DEFINE_IDA(blk_queue_ida); + * For queue allocation + */ + struct kmem_cache *blk_requestq_cachep; +-struct kmem_cache *blk_requestq_srcu_cachep; + + /* + * Controlling structure to kblockd +@@ -374,26 +373,20 @@ static void blk_timeout_work(struct work_struct *work) + { + } + +-struct request_queue *blk_alloc_queue(int node_id, bool alloc_srcu) ++struct request_queue *blk_alloc_queue(int node_id) + { + struct request_queue *q; + +- q = kmem_cache_alloc_node(blk_get_queue_kmem_cache(alloc_srcu), +- GFP_KERNEL | __GFP_ZERO, node_id); ++ q = kmem_cache_alloc_node(blk_requestq_cachep, GFP_KERNEL | __GFP_ZERO, ++ node_id); + if (!q) + return NULL; + +- if (alloc_srcu) { +- blk_queue_flag_set(QUEUE_FLAG_HAS_SRCU, q); +- if (init_srcu_struct(q->srcu) != 0) +- goto fail_q; +- } +- + q->last_merge = NULL; + + q->id = ida_alloc(&blk_queue_ida, GFP_KERNEL); + if (q->id < 0) +- goto fail_srcu; ++ goto fail_q; + + q->stats = blk_alloc_queue_stats(); + if (!q->stats) +@@ -435,11 +428,8 @@ struct request_queue *blk_alloc_queue(int node_id, bool alloc_srcu) + blk_free_queue_stats(q->stats); + fail_id: + ida_free(&blk_queue_ida, q->id); +-fail_srcu: +- if (alloc_srcu) +- cleanup_srcu_struct(q->srcu); + fail_q: +- kmem_cache_free(blk_get_queue_kmem_cache(alloc_srcu), q); ++ kmem_cache_free(blk_requestq_cachep, q); + return NULL; + } + +@@ -1198,9 +1188,6 @@ int __init blk_dev_init(void) + sizeof_field(struct request, cmd_flags)); + BUILD_BUG_ON(REQ_OP_BITS + REQ_FLAG_BITS > 8 * + sizeof_field(struct bio, bi_opf)); +- BUILD_BUG_ON(ALIGN(offsetof(struct request_queue, srcu), +- __alignof__(struct request_queue)) != +- sizeof(struct request_queue)); + + /* used for unplugging and affects IO latency/throughput - HIGHPRI */ + kblockd_workqueue = alloc_workqueue("kblockd", +@@ -1211,10 +1198,6 @@ int __init blk_dev_init(void) + blk_requestq_cachep = kmem_cache_create("request_queue", + sizeof(struct request_queue), 0, SLAB_PANIC, NULL); + +- blk_requestq_srcu_cachep = kmem_cache_create("request_queue_srcu", +- sizeof(struct request_queue) + +- sizeof(struct srcu_struct), 0, SLAB_PANIC, NULL); +- + blk_debugfs_root = debugfs_create_dir("block", NULL); + + return 0; +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 3f1f5e3e0951..88975170cc32 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -261,8 +261,8 @@ EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue_nowait); + */ + void blk_mq_wait_quiesce_done(struct request_queue *q) + { +- if (blk_queue_has_srcu(q)) +- synchronize_srcu(q->srcu); ++ if (q->tag_set->flags & BLK_MQ_F_BLOCKING) ++ synchronize_srcu(q->tag_set->srcu); + else + synchronize_rcu(); + } +@@ -3886,7 +3886,7 @@ static struct request_queue *blk_mq_init_queue_data(struct blk_mq_tag_set *set, + struct request_queue *q; + int ret; + +- q = blk_alloc_queue(set->numa_node, set->flags & BLK_MQ_F_BLOCKING); ++ q = blk_alloc_queue(set->numa_node); + if (!q) + return ERR_PTR(-ENOMEM); + q->queuedata = queuedata; +@@ -4058,9 +4058,6 @@ static void blk_mq_update_poll_flag(struct request_queue *q) + int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, + struct request_queue *q) + { +- WARN_ON_ONCE(blk_queue_has_srcu(q) != +- !!(set->flags & BLK_MQ_F_BLOCKING)); +- + /* mark the queue as mq asap */ + q->mq_ops = set->ops; + +@@ -4317,8 +4314,18 @@ int blk_mq_alloc_tag_set(struct blk_mq_tag_set *set) + if (set->nr_maps == 1 && set->nr_hw_queues > nr_cpu_ids) + set->nr_hw_queues = nr_cpu_ids; + +- if (blk_mq_alloc_tag_set_tags(set, set->nr_hw_queues) < 0) +- return -ENOMEM; ++ if (set->flags & BLK_MQ_F_BLOCKING) { ++ set->srcu = kmalloc(sizeof(*set->srcu), GFP_KERNEL); ++ if (!set->srcu) ++ return -ENOMEM; ++ ret = init_srcu_struct(set->srcu); ++ if (ret) ++ goto out_free_srcu; ++ } ++ ++ ret = blk_mq_alloc_tag_set_tags(set, set->nr_hw_queues); ++ if (ret) ++ goto out_cleanup_srcu; + + ret = -ENOMEM; + for (i = 0; i < set->nr_maps; i++) { +@@ -4350,6 +4357,12 @@ int blk_mq_alloc_tag_set(struct blk_mq_tag_set *set) + } + kfree(set->tags); + set->tags = NULL; ++out_cleanup_srcu: ++ if (set->flags & BLK_MQ_F_BLOCKING) ++ cleanup_srcu_struct(set->srcu); ++out_free_srcu: ++ if (set->flags & BLK_MQ_F_BLOCKING) ++ kfree(set->srcu); + return ret; + } + EXPORT_SYMBOL(blk_mq_alloc_tag_set); +@@ -4389,6 +4402,10 @@ void blk_mq_free_tag_set(struct blk_mq_tag_set *set) + + kfree(set->tags); + set->tags = NULL; ++ if (set->flags & BLK_MQ_F_BLOCKING) { ++ cleanup_srcu_struct(set->srcu); ++ kfree(set->srcu); ++ } + } + EXPORT_SYMBOL(blk_mq_free_tag_set); + +diff --git a/block/blk-mq.h b/block/blk-mq.h +index 8ca453ac243d..1a88ad9428b7 100644 +--- a/block/blk-mq.h ++++ b/block/blk-mq.h +@@ -376,17 +376,17 @@ static inline bool hctx_may_queue(struct blk_mq_hw_ctx *hctx, + /* run the code block in @dispatch_ops with rcu/srcu read lock held */ + #define __blk_mq_run_dispatch_ops(q, check_sleep, dispatch_ops) \ + do { \ +- if (!blk_queue_has_srcu(q)) { \ +- rcu_read_lock(); \ +- (dispatch_ops); \ +- rcu_read_unlock(); \ +- } else { \ ++ if ((q)->tag_set->flags & BLK_MQ_F_BLOCKING) { \ + int srcu_idx; \ + \ + might_sleep_if(check_sleep); \ +- srcu_idx = srcu_read_lock((q)->srcu); \ ++ srcu_idx = srcu_read_lock((q)->tag_set->srcu); \ + (dispatch_ops); \ +- srcu_read_unlock((q)->srcu, srcu_idx); \ ++ srcu_read_unlock((q)->tag_set->srcu, srcu_idx); \ ++ } else { \ ++ rcu_read_lock(); \ ++ (dispatch_ops); \ ++ rcu_read_unlock(); \ + } \ + } while (0) + +diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c +index e1f009aba6fd..8822b4b6bed2 100644 +--- a/block/blk-sysfs.c ++++ b/block/blk-sysfs.c +@@ -739,10 +739,8 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr, + + static void blk_free_queue_rcu(struct rcu_head *rcu_head) + { +- struct request_queue *q = container_of(rcu_head, struct request_queue, +- rcu_head); +- +- kmem_cache_free(blk_get_queue_kmem_cache(blk_queue_has_srcu(q)), q); ++ kmem_cache_free(blk_requestq_cachep, ++ container_of(rcu_head, struct request_queue, rcu_head)); + } + + /** +@@ -779,9 +777,6 @@ static void blk_release_queue(struct kobject *kobj) + if (queue_is_mq(q)) + blk_mq_release(q); + +- if (blk_queue_has_srcu(q)) +- cleanup_srcu_struct(q->srcu); +- + ida_free(&blk_queue_ida, q->id); + call_rcu(&q->rcu_head, blk_free_queue_rcu); + } +diff --git a/block/blk.h b/block/blk.h +index ff0bec16f0fa..5040c5b4ee70 100644 +--- a/block/blk.h ++++ b/block/blk.h +@@ -27,7 +27,6 @@ struct blk_flush_queue { + }; + + extern struct kmem_cache *blk_requestq_cachep; +-extern struct kmem_cache *blk_requestq_srcu_cachep; + extern struct kobj_type blk_queue_ktype; + extern struct ida blk_queue_ida; + +@@ -421,13 +420,7 @@ int bio_add_hw_page(struct request_queue *q, struct bio *bio, + struct page *page, unsigned int len, unsigned int offset, + unsigned int max_sectors, bool *same_page); + +-static inline struct kmem_cache *blk_get_queue_kmem_cache(bool srcu) +-{ +- if (srcu) +- return blk_requestq_srcu_cachep; +- return blk_requestq_cachep; +-} +-struct request_queue *blk_alloc_queue(int node_id, bool alloc_srcu); ++struct request_queue *blk_alloc_queue(int node_id); + + int disk_scan_partitions(struct gendisk *disk, fmode_t mode); + +diff --git a/block/genhd.c b/block/genhd.c +index 28654723bc2b..d4715ea7dc39 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -1402,7 +1402,7 @@ struct gendisk *__blk_alloc_disk(int node, struct lock_class_key *lkclass) + struct request_queue *q; + struct gendisk *disk; + +- q = blk_alloc_queue(node, false); ++ q = blk_alloc_queue(node); + if (!q) + return NULL; + +diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h +index 1532cd07a597..21f7b889f54e 100644 +--- a/include/linux/blk-mq.h ++++ b/include/linux/blk-mq.h +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + + struct blk_mq_tags; + struct blk_flush_queue; +@@ -496,6 +497,8 @@ enum hctx_type { + * @tag_list_lock: Serializes tag_list accesses. + * @tag_list: List of the request queues that use this tag set. See also + * request_queue.tag_set_list. ++ * @srcu: Use as lock when type of the request queue is blocking ++ * (BLK_MQ_F_BLOCKING). + */ + struct blk_mq_tag_set { + struct blk_mq_queue_map map[HCTX_MAX_TYPES]; +@@ -516,6 +519,7 @@ struct blk_mq_tag_set { + + struct mutex tag_list_lock; + struct list_head tag_list; ++ struct srcu_struct *srcu; + }; + + /** +diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h +index e6bf06dc0770..0526f1c49fc6 100644 +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -22,7 +22,6 @@ + #include + #include + #include +-#include + #include + #include + +@@ -544,18 +543,11 @@ struct request_queue { + struct mutex debugfs_mutex; + + bool mq_sysfs_init_done; +- +- /** +- * @srcu: Sleepable RCU. Use as lock when type of the request queue +- * is blocking (BLK_MQ_F_BLOCKING). Must be the last member +- */ +- struct srcu_struct srcu[]; + }; + + /* Keep blk_queue_flag_name[] in sync with the definitions below */ + #define QUEUE_FLAG_STOPPED 0 /* queue is stopped */ + #define QUEUE_FLAG_DYING 1 /* queue being torn down */ +-#define QUEUE_FLAG_HAS_SRCU 2 /* SRCU is allocated */ + #define QUEUE_FLAG_NOMERGES 3 /* disable merge attempts */ + #define QUEUE_FLAG_SAME_COMP 4 /* complete on same CPU-group */ + #define QUEUE_FLAG_FAIL_IO 5 /* fake timeout */ +@@ -591,7 +583,6 @@ bool blk_queue_flag_test_and_set(unsigned int flag, struct request_queue *q); + + #define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags) + #define blk_queue_dying(q) test_bit(QUEUE_FLAG_DYING, &(q)->queue_flags) +-#define blk_queue_has_srcu(q) test_bit(QUEUE_FLAG_HAS_SRCU, &(q)->queue_flags) + #define blk_queue_init_done(q) test_bit(QUEUE_FLAG_INIT_DONE, &(q)->queue_flags) + #define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags) + #define blk_queue_noxmerges(q) \ +-- +2.35.1 + diff --git a/queue-6.0/blktrace-fix-output-non-blktrace-event-when-blk_clas.patch b/queue-6.0/blktrace-fix-output-non-blktrace-event-when-blk_clas.patch new file mode 100644 index 00000000000..0dc5eb186e9 --- /dev/null +++ b/queue-6.0/blktrace-fix-output-non-blktrace-event-when-blk_clas.patch @@ -0,0 +1,47 @@ +From 8103c0b56366884f01997ee98474326b813ad0cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Nov 2022 12:04:10 +0800 +Subject: blktrace: Fix output non-blktrace event when blk_classic option + enabled + +From: Yang Jihong + +[ Upstream commit f596da3efaf4130ff61cd029558845808df9bf99 ] + +When the blk_classic option is enabled, non-blktrace events must be +filtered out. Otherwise, events of other types are output in the blktrace +classic format, which is unexpected. + +The problem can be triggered in the following ways: + + # echo 1 > /sys/kernel/debug/tracing/options/blk_classic + # echo 1 > /sys/kernel/debug/tracing/events/enable + # echo blk > /sys/kernel/debug/tracing/current_tracer + # cat /sys/kernel/debug/tracing/trace_pipe + +Fixes: c71a89615411 ("blktrace: add ftrace plugin") +Signed-off-by: Yang Jihong +Link: https://lore.kernel.org/r/20221122040410.85113-1-yangjihong1@huawei.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + kernel/trace/blktrace.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c +index 7f5eb295fe19..ee22a3b1c181 100644 +--- a/kernel/trace/blktrace.c ++++ b/kernel/trace/blktrace.c +@@ -1546,7 +1546,8 @@ blk_trace_event_print_binary(struct trace_iterator *iter, int flags, + + static enum print_line_t blk_tracer_print_line(struct trace_iterator *iter) + { +- if (!(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC)) ++ if ((iter->ent->type != TRACE_BLK) || ++ !(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC)) + return TRACE_TYPE_UNHANDLED; + + return print_one_line(iter, true); +-- +2.35.1 + diff --git a/queue-6.0/block-bfq-fix-possible-uaf-for-bfqq-bic.patch b/queue-6.0/block-bfq-fix-possible-uaf-for-bfqq-bic.patch new file mode 100644 index 00000000000..b1e2d323ced --- /dev/null +++ b/queue-6.0/block-bfq-fix-possible-uaf-for-bfqq-bic.patch @@ -0,0 +1,125 @@ +From af01406cd0a3ee49b96c8ee520c2f814b6606675 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Dec 2022 11:04:30 +0800 +Subject: block, bfq: fix possible uaf for 'bfqq->bic' +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Yu Kuai + +[ Upstream commit 64dc8c732f5c2b406cc752e6aaa1bd5471159cab ] + +Our test report a uaf for 'bfqq->bic' in 5.10: + +================================================================== +BUG: KASAN: use-after-free in bfq_select_queue+0x378/0xa30 + +CPU: 6 PID: 2318352 Comm: fsstress Kdump: loaded Not tainted 5.10.0-60.18.0.50.h602.kasan.eulerosv2r11.x86_64 #1 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58-20220320_160524-szxrtosci10000 04/01/2014 +Call Trace: + bfq_select_queue+0x378/0xa30 + bfq_dispatch_request+0xe8/0x130 + blk_mq_do_dispatch_sched+0x62/0xb0 + __blk_mq_sched_dispatch_requests+0x215/0x2a0 + blk_mq_sched_dispatch_requests+0x8f/0xd0 + __blk_mq_run_hw_queue+0x98/0x180 + __blk_mq_delay_run_hw_queue+0x22b/0x240 + blk_mq_run_hw_queue+0xe3/0x190 + blk_mq_sched_insert_requests+0x107/0x200 + blk_mq_flush_plug_list+0x26e/0x3c0 + blk_finish_plug+0x63/0x90 + __iomap_dio_rw+0x7b5/0x910 + iomap_dio_rw+0x36/0x80 + ext4_dio_read_iter+0x146/0x190 [ext4] + ext4_file_read_iter+0x1e2/0x230 [ext4] + new_sync_read+0x29f/0x400 + vfs_read+0x24e/0x2d0 + ksys_read+0xd5/0x1b0 + do_syscall_64+0x33/0x40 + entry_SYSCALL_64_after_hwframe+0x61/0xc6 + +Commit 3bc5e683c67d ("bfq: Split shared queues on move between cgroups") +changes that move process to a new cgroup will allocate a new bfqq to +use, however, the old bfqq and new bfqq can point to the same bic: + +1) Initial state, two process with io in the same cgroup. + +Process 1 Process 2 + (BIC1) (BIC2) + | Λ | Λ + | | | | + V | V | + bfqq1 bfqq2 + +2) bfqq1 is merged to bfqq2. + +Process 1 Process 2 + (BIC1) (BIC2) + | | + \-------------\| + V + bfqq1 bfqq2(coop) + +3) Process 1 exit, then issue new io(denoce IOA) from Process 2. + + (BIC2) + | Λ + | | + V | + bfqq2(coop) + +4) Before IOA is completed, move Process 2 to another cgroup and issue io. + +Process 2 + (BIC2) + Λ + |\--------------\ + | V + bfqq2 bfqq3 + +Now that BIC2 points to bfqq3, while bfqq2 and bfqq3 both point to BIC2. +If all the requests are completed, and Process 2 exit, BIC2 will be +freed while there is no guarantee that bfqq2 will be freed before BIC2. + +Fix the problem by clearing bfqq->bic while bfqq is detached from bic. + +Fixes: 3bc5e683c67d ("bfq: Split shared queues on move between cgroups") +Suggested-by: Jan Kara +Signed-off-by: Yu Kuai +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20221214030430.3304151-1-yukuai1@huaweicloud.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/bfq-iosched.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c +index 68872a61706a..528ca21044a5 100644 +--- a/block/bfq-iosched.c ++++ b/block/bfq-iosched.c +@@ -386,6 +386,12 @@ static void bfq_put_stable_ref(struct bfq_queue *bfqq); + + void bic_set_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq, bool is_sync) + { ++ struct bfq_queue *old_bfqq = bic->bfqq[is_sync]; ++ ++ /* Clear bic pointer if bfqq is detached from this bic */ ++ if (old_bfqq && old_bfqq->bic == bic) ++ old_bfqq->bic = NULL; ++ + /* + * If bfqq != NULL, then a non-stable queue merge between + * bic->bfqq and bfqq is happening here. This causes troubles +@@ -5379,7 +5385,6 @@ static void bfq_exit_icq_bfqq(struct bfq_io_cq *bic, bool is_sync) + unsigned long flags; + + spin_lock_irqsave(&bfqd->lock, flags); +- bfqq->bic = NULL; + bfq_exit_bfqq(bfqd, bfqq); + bic_set_bfqq(bic, NULL, is_sync); + spin_unlock_irqrestore(&bfqd->lock, flags); +-- +2.35.1 + diff --git a/queue-6.0/block-clear-slave_dir-when-dropping-the-main-slave_d.patch b/queue-6.0/block-clear-slave_dir-when-dropping-the-main-slave_d.patch new file mode 100644 index 00000000000..77970e37913 --- /dev/null +++ b/queue-6.0/block-clear-slave_dir-when-dropping-the-main-slave_d.patch @@ -0,0 +1,48 @@ +From a8a4382473b6b730a459a920348cb5ad68ba1e59 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Nov 2022 22:10:45 +0800 +Subject: block: clear ->slave_dir when dropping the main slave_dir reference + +From: Christoph Hellwig + +[ Upstream commit d90db3b1c8676bc88b4309c5a571333de2263b8e ] + +Zero out the pointer to ->slave_dir so that the holder code doesn't +incorrectly treat the object as alive when add_disk failed or after +del_gendisk was called. + +Fixes: 89f871af1b26 ("dm: delay registering the gendisk") +Reported-by: Yu Kuai +Signed-off-by: Christoph Hellwig +Signed-off-by: Yu Kuai +Reviewed-by: Mike Snitzer +Link: https://lore.kernel.org/r/20221115141054.1051801-2-yukuai1@huaweicloud.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/genhd.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/block/genhd.c b/block/genhd.c +index 044ff97381e3..28654723bc2b 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -522,6 +522,7 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk, + rq_qos_exit(disk->queue); + out_put_slave_dir: + kobject_put(disk->slave_dir); ++ disk->slave_dir = NULL; + out_put_holder_dir: + kobject_put(disk->part0->bd_holder_dir); + out_del_integrity: +@@ -618,6 +619,7 @@ void del_gendisk(struct gendisk *disk) + + kobject_put(disk->part0->bd_holder_dir); + kobject_put(disk->slave_dir); ++ disk->slave_dir = NULL; + + part_stat_set_all(disk->part0, 0); + disk->part0->bd_stamp = 0; +-- +2.35.1 + diff --git a/queue-6.0/block-factor-out-a-blk_debugfs_remove-helper.patch b/queue-6.0/block-factor-out-a-blk_debugfs_remove-helper.patch new file mode 100644 index 00000000000..51b80e32977 --- /dev/null +++ b/queue-6.0/block-factor-out-a-blk_debugfs_remove-helper.patch @@ -0,0 +1,61 @@ +From 03483a014ed2cecaba0e02ac736db0e5da640551 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Nov 2022 05:26:34 +0100 +Subject: block: factor out a blk_debugfs_remove helper + +From: Christoph Hellwig + +[ Upstream commit 6fc75f309d291d328b4ea2f91bef0ff56e4bc7c2 ] + +Split the debugfs removal from blk_unregister_queue into a helper so that +the it can be reused for blk_register_queue error handling. + +Signed-off-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20221114042637.1009333-3-hch@lst.de +Signed-off-by: Jens Axboe +Stable-dep-of: d36a9ea5e776 ("block: fix use-after-free of q->q_usage_counter") +Signed-off-by: Sasha Levin +--- + block/blk-sysfs.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c +index c8a1119c3950..4825eaa4363a 100644 +--- a/block/blk-sysfs.c ++++ b/block/blk-sysfs.c +@@ -797,6 +797,19 @@ struct kobj_type blk_queue_ktype = { + .release = blk_release_queue, + }; + ++static void blk_debugfs_remove(struct gendisk *disk) ++{ ++ struct request_queue *q = disk->queue; ++ ++ mutex_lock(&q->debugfs_mutex); ++ blk_trace_shutdown(q); ++ debugfs_remove_recursive(q->debugfs_dir); ++ q->debugfs_dir = NULL; ++ q->sched_debugfs_dir = NULL; ++ q->rqos_debugfs_dir = NULL; ++ mutex_unlock(&q->debugfs_mutex); ++} ++ + /** + * blk_register_queue - register a block layer queue with sysfs + * @disk: Disk of which the request queue should be registered with sysfs. +@@ -922,11 +935,5 @@ void blk_unregister_queue(struct gendisk *disk) + kobject_del(&q->kobj); + mutex_unlock(&q->sysfs_dir_lock); + +- mutex_lock(&q->debugfs_mutex); +- blk_trace_shutdown(q); +- debugfs_remove_recursive(q->debugfs_dir); +- q->debugfs_dir = NULL; +- q->sched_debugfs_dir = NULL; +- q->rqos_debugfs_dir = NULL; +- mutex_unlock(&q->debugfs_mutex); ++ blk_debugfs_remove(disk); + } +-- +2.35.1 + diff --git a/queue-6.0/block-fix-error-unwinding-in-blk_register_queue.patch b/queue-6.0/block-fix-error-unwinding-in-blk_register_queue.patch new file mode 100644 index 00000000000..99fa92968ed --- /dev/null +++ b/queue-6.0/block-fix-error-unwinding-in-blk_register_queue.patch @@ -0,0 +1,101 @@ +From 2aa320938830cd91d5f595f84c736a8f56d2c0e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Nov 2022 05:26:35 +0100 +Subject: block: fix error unwinding in blk_register_queue + +From: Christoph Hellwig + +[ Upstream commit 40602997be26887bdfa3d58659c3acb4579099e9 ] + +blk_register_queue fails to handle errors from blk_mq_sysfs_register, +leaks various resources on errors and accidentally sets queue refs percpu +refcount to percpu mode on kobject_add failure. Fix all that by +properly unwinding on errors. + +Signed-off-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20221114042637.1009333-4-hch@lst.de +Signed-off-by: Jens Axboe +Stable-dep-of: d36a9ea5e776 ("block: fix use-after-free of q->q_usage_counter") +Signed-off-by: Sasha Levin +--- + block/blk-sysfs.c | 28 ++++++++++++++++------------ + 1 file changed, 16 insertions(+), 12 deletions(-) + +diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c +index 4825eaa4363a..02931b6f25c5 100644 +--- a/block/blk-sysfs.c ++++ b/block/blk-sysfs.c +@@ -820,13 +820,15 @@ int blk_register_queue(struct gendisk *disk) + int ret; + + mutex_lock(&q->sysfs_dir_lock); +- + ret = kobject_add(&q->kobj, &disk_to_dev(disk)->kobj, "queue"); + if (ret < 0) +- goto unlock; ++ goto out_unlock_dir; + +- if (queue_is_mq(q)) +- blk_mq_sysfs_register(disk); ++ if (queue_is_mq(q)) { ++ ret = blk_mq_sysfs_register(disk); ++ if (ret) ++ goto out_del_queue_kobj; ++ } + mutex_lock(&q->sysfs_lock); + + mutex_lock(&q->debugfs_mutex); +@@ -838,17 +840,17 @@ int blk_register_queue(struct gendisk *disk) + + ret = disk_register_independent_access_ranges(disk); + if (ret) +- goto put_dev; ++ goto out_debugfs_remove; + + if (q->elevator) { + ret = elv_register_queue(q, false); + if (ret) +- goto put_dev; ++ goto out_unregister_ia_ranges; + } + + ret = blk_crypto_sysfs_register(disk); + if (ret) +- goto put_dev; ++ goto out_elv_unregister; + + blk_queue_flag_set(QUEUE_FLAG_REGISTERED, q); + wbt_enable_default(q); +@@ -859,8 +861,6 @@ int blk_register_queue(struct gendisk *disk) + if (q->elevator) + kobject_uevent(&q->elevator->kobj, KOBJ_ADD); + mutex_unlock(&q->sysfs_lock); +- +-unlock: + mutex_unlock(&q->sysfs_dir_lock); + + /* +@@ -879,13 +879,17 @@ int blk_register_queue(struct gendisk *disk) + + return ret; + +-put_dev: ++out_elv_unregister: + elv_unregister_queue(q); ++out_unregister_ia_ranges: + disk_unregister_independent_access_ranges(disk); ++out_debugfs_remove: ++ blk_debugfs_remove(disk); + mutex_unlock(&q->sysfs_lock); +- mutex_unlock(&q->sysfs_dir_lock); ++out_del_queue_kobj: + kobject_del(&q->kobj); +- ++out_unlock_dir: ++ mutex_unlock(&q->sysfs_dir_lock); + return ret; + } + +-- +2.35.1 + diff --git a/queue-6.0/block-fix-use-after-free-of-q-q_usage_counter.patch b/queue-6.0/block-fix-use-after-free-of-q-q_usage_counter.patch new file mode 100644 index 00000000000..a92c752c120 --- /dev/null +++ b/queue-6.0/block-fix-use-after-free-of-q-q_usage_counter.patch @@ -0,0 +1,61 @@ +From 73552cce158716c61be4dfc1d006ceac44b9c775 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Dec 2022 10:16:29 +0800 +Subject: block: fix use-after-free of q->q_usage_counter + +From: Ming Lei + +[ Upstream commit d36a9ea5e7766961e753ee38d4c331bbe6ef659b ] + +For blk-mq, queue release handler is usually called after +blk_mq_freeze_queue_wait() returns. However, the +q_usage_counter->release() handler may not be run yet at that time, so +this can cause a use-after-free. + +Fix the issue by moving percpu_ref_exit() into blk_free_queue_rcu(). +Since ->release() is called with rcu read lock held, it is agreed that +the race should be covered in caller per discussion from the two links. + +Reported-by: Zhang Wensheng +Reported-by: Zhong Jinghua +Link: https://lore.kernel.org/linux-block/Y5prfOjyyjQKUrtH@T590/T/#u +Link: https://lore.kernel.org/lkml/Y4%2FmzMd4evRg9yDi@fedora/ +Cc: Hillf Danton +Cc: Yu Kuai +Cc: Dennis Zhou +Fixes: 2b0d3d3e4fcf ("percpu_ref: reduce memory footprint of percpu_ref in fast path") +Signed-off-by: Ming Lei +Link: https://lore.kernel.org/r/20221215021629.74870-1-ming.lei@redhat.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-core.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/block/blk-core.c b/block/blk-core.c +index 818002b8be7c..3459fe316a34 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -255,14 +255,15 @@ EXPORT_SYMBOL_GPL(blk_clear_pm_only); + + static void blk_free_queue_rcu(struct rcu_head *rcu_head) + { +- kmem_cache_free(blk_requestq_cachep, +- container_of(rcu_head, struct request_queue, rcu_head)); ++ struct request_queue *q = container_of(rcu_head, ++ struct request_queue, rcu_head); ++ ++ percpu_ref_exit(&q->q_usage_counter); ++ kmem_cache_free(blk_requestq_cachep, q); + } + + static void blk_free_queue(struct request_queue *q) + { +- percpu_ref_exit(&q->q_usage_counter); +- + if (q->poll_stat) + blk_stat_remove_callback(q, q->poll_cb); + blk_stat_free_callback(q->poll_cb); +-- +2.35.1 + diff --git a/queue-6.0/block-mark-blk_put_queue-as-potentially-blocking.patch b/queue-6.0/block-mark-blk_put_queue-as-potentially-blocking.patch new file mode 100644 index 00000000000..6919b9ee74d --- /dev/null +++ b/queue-6.0/block-mark-blk_put_queue-as-potentially-blocking.patch @@ -0,0 +1,52 @@ +From 3c93e8c2961b28620ee655ac56add38e18869042 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Nov 2022 05:26:37 +0100 +Subject: block: mark blk_put_queue as potentially blocking + +From: Christoph Hellwig + +[ Upstream commit 63f93fd6fa5717769a78d6d7bea6f7f9a1ccca8e ] + +We can't just say that the last reference release may block, as any +reference dropped could be the last one. So move the might_sleep() from +blk_free_queue to blk_put_queue and update the documentation. + +Signed-off-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20221114042637.1009333-6-hch@lst.de +Signed-off-by: Jens Axboe +Stable-dep-of: d36a9ea5e776 ("block: fix use-after-free of q->q_usage_counter") +Signed-off-by: Sasha Levin +--- + block/blk-core.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/block/blk-core.c b/block/blk-core.c +index 3920e101654f..818002b8be7c 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -261,8 +261,6 @@ static void blk_free_queue_rcu(struct rcu_head *rcu_head) + + static void blk_free_queue(struct request_queue *q) + { +- might_sleep(); +- + percpu_ref_exit(&q->q_usage_counter); + + if (q->poll_stat) +@@ -286,11 +284,11 @@ static void blk_free_queue(struct request_queue *q) + * Decrements the refcount of the request_queue and free it when the refcount + * reaches 0. + * +- * Context: Any context, but the last reference must not be dropped from +- * atomic context. ++ * Context: Can sleep. + */ + void blk_put_queue(struct request_queue *q) + { ++ might_sleep(); + if (refcount_dec_and_test(&q->refs)) + blk_free_queue(q); + } +-- +2.35.1 + diff --git a/queue-6.0/block-untangle-request_queue-refcounting-from-sysfs.patch b/queue-6.0/block-untangle-request_queue-refcounting-from-sysfs.patch new file mode 100644 index 00000000000..3bd33502c5f --- /dev/null +++ b/queue-6.0/block-untangle-request_queue-refcounting-from-sysfs.patch @@ -0,0 +1,400 @@ +From ea647559f200f259accf0abdf468ab691de8bc97 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Nov 2022 05:26:36 +0100 +Subject: block: untangle request_queue refcounting from sysfs + +From: Christoph Hellwig + +[ Upstream commit 2bd85221a625b316114bafaab527770b607095d3 ] + +The kobject embedded into the request_queue is used for the queue +directory in sysfs, but that is a child of the gendisks directory and is +intimately tied to it. Move this kobject to the gendisk and use a +refcount_t in the request_queue for the actual request_queue refcounting +that is completely unrelated to the device model. + +Signed-off-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20221114042637.1009333-5-hch@lst.de +Signed-off-by: Jens Axboe +Stable-dep-of: d36a9ea5e776 ("block: fix use-after-free of q->q_usage_counter") +Signed-off-by: Sasha Levin +--- + block/blk-core.c | 42 ++++++++++++++++---- + block/blk-crypto-sysfs.c | 4 +- + block/blk-ia-ranges.c | 3 +- + block/blk-sysfs.c | 86 +++++++++++----------------------------- + block/blk.h | 4 -- + block/bsg.c | 11 +++-- + block/elevator.c | 2 +- + include/linux/blkdev.h | 6 +-- + 8 files changed, 71 insertions(+), 87 deletions(-) + +diff --git a/block/blk-core.c b/block/blk-core.c +index adc5fc562348..3920e101654f 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -60,12 +60,12 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(block_split); + EXPORT_TRACEPOINT_SYMBOL_GPL(block_unplug); + EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_insert); + +-DEFINE_IDA(blk_queue_ida); ++static DEFINE_IDA(blk_queue_ida); + + /* + * For queue allocation + */ +-struct kmem_cache *blk_requestq_cachep; ++static struct kmem_cache *blk_requestq_cachep; + + /* + * Controlling structure to kblockd +@@ -253,19 +253,46 @@ void blk_clear_pm_only(struct request_queue *q) + } + EXPORT_SYMBOL_GPL(blk_clear_pm_only); + ++static void blk_free_queue_rcu(struct rcu_head *rcu_head) ++{ ++ kmem_cache_free(blk_requestq_cachep, ++ container_of(rcu_head, struct request_queue, rcu_head)); ++} ++ ++static void blk_free_queue(struct request_queue *q) ++{ ++ might_sleep(); ++ ++ percpu_ref_exit(&q->q_usage_counter); ++ ++ if (q->poll_stat) ++ blk_stat_remove_callback(q, q->poll_cb); ++ blk_stat_free_callback(q->poll_cb); ++ ++ blk_free_queue_stats(q->stats); ++ kfree(q->poll_stat); ++ ++ if (queue_is_mq(q)) ++ blk_mq_release(q); ++ ++ ida_free(&blk_queue_ida, q->id); ++ call_rcu(&q->rcu_head, blk_free_queue_rcu); ++} ++ + /** + * blk_put_queue - decrement the request_queue refcount + * @q: the request_queue structure to decrement the refcount for + * +- * Decrements the refcount of the request_queue kobject. When this reaches 0 +- * we'll have blk_release_queue() called. ++ * Decrements the refcount of the request_queue and free it when the refcount ++ * reaches 0. + * + * Context: Any context, but the last reference must not be dropped from + * atomic context. + */ + void blk_put_queue(struct request_queue *q) + { +- kobject_put(&q->kobj); ++ if (refcount_dec_and_test(&q->refs)) ++ blk_free_queue(q); + } + EXPORT_SYMBOL(blk_put_queue); + +@@ -400,8 +427,7 @@ struct request_queue *blk_alloc_queue(int node_id) + INIT_WORK(&q->timeout_work, blk_timeout_work); + INIT_LIST_HEAD(&q->icq_list); + +- kobject_init(&q->kobj, &blk_queue_ktype); +- ++ refcount_set(&q->refs, 1); + mutex_init(&q->debugfs_mutex); + mutex_init(&q->sysfs_lock); + mutex_init(&q->sysfs_dir_lock); +@@ -445,7 +471,7 @@ bool blk_get_queue(struct request_queue *q) + { + if (unlikely(blk_queue_dying(q))) + return false; +- kobject_get(&q->kobj); ++ refcount_inc(&q->refs); + return true; + } + EXPORT_SYMBOL(blk_get_queue); +diff --git a/block/blk-crypto-sysfs.c b/block/blk-crypto-sysfs.c +index e05f145cd797..55268edc0625 100644 +--- a/block/blk-crypto-sysfs.c ++++ b/block/blk-crypto-sysfs.c +@@ -140,8 +140,8 @@ int blk_crypto_sysfs_register(struct gendisk *disk) + return -ENOMEM; + obj->profile = q->crypto_profile; + +- err = kobject_init_and_add(&obj->kobj, &blk_crypto_ktype, &q->kobj, +- "crypto"); ++ err = kobject_init_and_add(&obj->kobj, &blk_crypto_ktype, ++ &disk->queue_kobj, "crypto"); + if (err) { + kobject_put(&obj->kobj); + return err; +diff --git a/block/blk-ia-ranges.c b/block/blk-ia-ranges.c +index 2bd1d311033b..2141931ddd37 100644 +--- a/block/blk-ia-ranges.c ++++ b/block/blk-ia-ranges.c +@@ -123,7 +123,8 @@ int disk_register_independent_access_ranges(struct gendisk *disk) + */ + WARN_ON(iars->sysfs_registered); + ret = kobject_init_and_add(&iars->kobj, &blk_ia_ranges_ktype, +- &q->kobj, "%s", "independent_access_ranges"); ++ &disk->queue_kobj, "%s", ++ "independent_access_ranges"); + if (ret) { + disk->ia_ranges = NULL; + kobject_put(&iars->kobj); +diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c +index 02931b6f25c5..f32c195c9767 100644 +--- a/block/blk-sysfs.c ++++ b/block/blk-sysfs.c +@@ -680,8 +680,8 @@ static struct attribute *queue_attrs[] = { + static umode_t queue_attr_visible(struct kobject *kobj, struct attribute *attr, + int n) + { +- struct request_queue *q = +- container_of(kobj, struct request_queue, kobj); ++ struct gendisk *disk = container_of(kobj, struct gendisk, queue_kobj); ++ struct request_queue *q = disk->queue; + + if (attr == &queue_io_timeout_entry.attr && + (!q->mq_ops || !q->mq_ops->timeout)) +@@ -707,8 +707,8 @@ static ssize_t + queue_attr_show(struct kobject *kobj, struct attribute *attr, char *page) + { + struct queue_sysfs_entry *entry = to_queue(attr); +- struct request_queue *q = +- container_of(kobj, struct request_queue, kobj); ++ struct gendisk *disk = container_of(kobj, struct gendisk, queue_kobj); ++ struct request_queue *q = disk->queue; + ssize_t res; + + if (!entry->show) +@@ -724,63 +724,19 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr, + const char *page, size_t length) + { + struct queue_sysfs_entry *entry = to_queue(attr); +- struct request_queue *q; ++ struct gendisk *disk = container_of(kobj, struct gendisk, queue_kobj); ++ struct request_queue *q = disk->queue; + ssize_t res; + + if (!entry->store) + return -EIO; + +- q = container_of(kobj, struct request_queue, kobj); + mutex_lock(&q->sysfs_lock); + res = entry->store(q, page, length); + mutex_unlock(&q->sysfs_lock); + return res; + } + +-static void blk_free_queue_rcu(struct rcu_head *rcu_head) +-{ +- kmem_cache_free(blk_requestq_cachep, +- container_of(rcu_head, struct request_queue, rcu_head)); +-} +- +-/** +- * blk_release_queue - releases all allocated resources of the request_queue +- * @kobj: pointer to a kobject, whose container is a request_queue +- * +- * This function releases all allocated resources of the request queue. +- * +- * The struct request_queue refcount is incremented with blk_get_queue() and +- * decremented with blk_put_queue(). Once the refcount reaches 0 this function +- * is called. +- * +- * Drivers exist which depend on the release of the request_queue to be +- * synchronous, it should not be deferred. +- * +- * Context: can sleep +- */ +-static void blk_release_queue(struct kobject *kobj) +-{ +- struct request_queue *q = +- container_of(kobj, struct request_queue, kobj); +- +- might_sleep(); +- +- percpu_ref_exit(&q->q_usage_counter); +- +- if (q->poll_stat) +- blk_stat_remove_callback(q, q->poll_cb); +- blk_stat_free_callback(q->poll_cb); +- +- blk_free_queue_stats(q->stats); +- kfree(q->poll_stat); +- +- if (queue_is_mq(q)) +- blk_mq_release(q); +- +- ida_free(&blk_queue_ida, q->id); +- call_rcu(&q->rcu_head, blk_free_queue_rcu); +-} +- + static const struct sysfs_ops queue_sysfs_ops = { + .show = queue_attr_show, + .store = queue_attr_store, +@@ -791,10 +747,15 @@ static const struct attribute_group *blk_queue_attr_groups[] = { + NULL + }; + +-struct kobj_type blk_queue_ktype = { ++static void blk_queue_release(struct kobject *kobj) ++{ ++ /* nothing to do here, all data is associated with the parent gendisk */ ++} ++ ++static struct kobj_type blk_queue_ktype = { + .default_groups = blk_queue_attr_groups, + .sysfs_ops = &queue_sysfs_ops, +- .release = blk_release_queue, ++ .release = blk_queue_release, + }; + + static void blk_debugfs_remove(struct gendisk *disk) +@@ -820,20 +781,20 @@ int blk_register_queue(struct gendisk *disk) + int ret; + + mutex_lock(&q->sysfs_dir_lock); +- ret = kobject_add(&q->kobj, &disk_to_dev(disk)->kobj, "queue"); ++ kobject_init(&disk->queue_kobj, &blk_queue_ktype); ++ ret = kobject_add(&disk->queue_kobj, &disk_to_dev(disk)->kobj, "queue"); + if (ret < 0) +- goto out_unlock_dir; ++ goto out_put_queue_kobj; + + if (queue_is_mq(q)) { + ret = blk_mq_sysfs_register(disk); + if (ret) +- goto out_del_queue_kobj; ++ goto out_put_queue_kobj; + } + mutex_lock(&q->sysfs_lock); + + mutex_lock(&q->debugfs_mutex); +- q->debugfs_dir = debugfs_create_dir(kobject_name(q->kobj.parent), +- blk_debugfs_root); ++ q->debugfs_dir = debugfs_create_dir(disk->disk_name, blk_debugfs_root); + if (queue_is_mq(q)) + blk_mq_debugfs_register(q); + mutex_unlock(&q->debugfs_mutex); +@@ -857,7 +818,7 @@ int blk_register_queue(struct gendisk *disk) + blk_throtl_register_queue(q); + + /* Now everything is ready and send out KOBJ_ADD uevent */ +- kobject_uevent(&q->kobj, KOBJ_ADD); ++ kobject_uevent(&disk->queue_kobj, KOBJ_ADD); + if (q->elevator) + kobject_uevent(&q->elevator->kobj, KOBJ_ADD); + mutex_unlock(&q->sysfs_lock); +@@ -886,9 +847,8 @@ int blk_register_queue(struct gendisk *disk) + out_debugfs_remove: + blk_debugfs_remove(disk); + mutex_unlock(&q->sysfs_lock); +-out_del_queue_kobj: +- kobject_del(&q->kobj); +-out_unlock_dir: ++out_put_queue_kobj: ++ kobject_put(&disk->queue_kobj); + mutex_unlock(&q->sysfs_dir_lock); + return ret; + } +@@ -935,8 +895,8 @@ void blk_unregister_queue(struct gendisk *disk) + mutex_unlock(&q->sysfs_lock); + + /* Now that we've deleted all child objects, we can delete the queue. */ +- kobject_uevent(&q->kobj, KOBJ_REMOVE); +- kobject_del(&q->kobj); ++ kobject_uevent(&disk->queue_kobj, KOBJ_REMOVE); ++ kobject_del(&disk->queue_kobj); + mutex_unlock(&q->sysfs_dir_lock); + + blk_debugfs_remove(disk); +diff --git a/block/blk.h b/block/blk.h +index 5040c5b4ee70..bf20ed1c3054 100644 +--- a/block/blk.h ++++ b/block/blk.h +@@ -26,10 +26,6 @@ struct blk_flush_queue { + spinlock_t mq_flush_lock; + }; + +-extern struct kmem_cache *blk_requestq_cachep; +-extern struct kobj_type blk_queue_ktype; +-extern struct ida blk_queue_ida; +- + bool is_flush_rq(struct request *req); + + struct blk_flush_queue *blk_alloc_flush_queue(int node, int cmd_size, +diff --git a/block/bsg.c b/block/bsg.c +index 2ab1351eb082..8eba57b9bb46 100644 +--- a/block/bsg.c ++++ b/block/bsg.c +@@ -175,8 +175,10 @@ static void bsg_device_release(struct device *dev) + + void bsg_unregister_queue(struct bsg_device *bd) + { +- if (bd->queue->kobj.sd) +- sysfs_remove_link(&bd->queue->kobj, "bsg"); ++ struct gendisk *disk = bd->queue->disk; ++ ++ if (disk && disk->queue_kobj.sd) ++ sysfs_remove_link(&disk->queue_kobj, "bsg"); + cdev_device_del(&bd->cdev, &bd->device); + put_device(&bd->device); + } +@@ -216,8 +218,9 @@ struct bsg_device *bsg_register_queue(struct request_queue *q, + if (ret) + goto out_put_device; + +- if (q->kobj.sd) { +- ret = sysfs_create_link(&q->kobj, &bd->device.kobj, "bsg"); ++ if (q->disk && q->disk->queue_kobj.sd) { ++ ret = sysfs_create_link(&q->disk->queue_kobj, &bd->device.kobj, ++ "bsg"); + if (ret) + goto out_device_del; + } +diff --git a/block/elevator.c b/block/elevator.c +index bd71f0fc4e4b..ac096f494911 100644 +--- a/block/elevator.c ++++ b/block/elevator.c +@@ -499,7 +499,7 @@ int elv_register_queue(struct request_queue *q, bool uevent) + + lockdep_assert_held(&q->sysfs_lock); + +- error = kobject_add(&e->kobj, &q->kobj, "%s", "iosched"); ++ error = kobject_add(&e->kobj, &q->disk->queue_kobj, "iosched"); + if (!error) { + struct elv_fs_entry *attr = e->type->elevator_attrs; + if (attr) { +diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h +index 0526f1c49fc6..c712841ef64b 100644 +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -155,6 +155,7 @@ struct gendisk { + unsigned open_partitions; /* number of open partitions */ + + struct backing_dev_info *bdi; ++ struct kobject queue_kobj; /* the queue/ directory */ + struct kobject *slave_dir; + #ifdef CONFIG_BLOCK_HOLDER_DEPRECATED + struct list_head slave_bdevs; +@@ -437,10 +438,7 @@ struct request_queue { + + struct gendisk *disk; + +- /* +- * queue kobject +- */ +- struct kobject kobj; ++ refcount_t refs; + + /* + * mq queue kobject +-- +2.35.1 + diff --git a/queue-6.0/bluetooth-add-quirk-to-disable-extended-scanning.patch b/queue-6.0/bluetooth-add-quirk-to-disable-extended-scanning.patch new file mode 100644 index 00000000000..e1b7ccd344a --- /dev/null +++ b/queue-6.0/bluetooth-add-quirk-to-disable-extended-scanning.patch @@ -0,0 +1,83 @@ +From 9659543befaf55b242ba861eb4350e65f242ff21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Nov 2022 22:13:01 +0100 +Subject: Bluetooth: Add quirk to disable extended scanning + +From: Sven Peter + +[ Upstream commit 392fca352c7a95e2828d49e7500e26d0c87ca265 ] + +Broadcom 4377 controllers found in Apple x86 Macs with the T2 chip +claim to support extended scanning when querying supported states, + +< HCI Command: LE Read Supported St.. (0x08|0x001c) plen 0 +> HCI Event: Command Complete (0x0e) plen 12 + LE Read Supported States (0x08|0x001c) ncmd 1 + Status: Success (0x00) + States: 0x000003ffffffffff +[...] + LE Set Extended Scan Parameters (Octet 37 - Bit 5) + LE Set Extended Scan Enable (Octet 37 - Bit 6) +[...] + +, but then fail to actually implement the extended scanning: + +< HCI Command: LE Set Extended Sca.. (0x08|0x0041) plen 8 + Own address type: Random (0x01) + Filter policy: Accept all advertisement (0x00) + PHYs: 0x01 + Entry 0: LE 1M + Type: Active (0x01) + Interval: 11.250 msec (0x0012) + Window: 11.250 msec (0x0012) +> HCI Event: Command Complete (0x0e) plen 4 + LE Set Extended Scan Parameters (0x08|0x0041) ncmd 1 + Status: Unknown HCI Command (0x01) + +Signed-off-by: Sven Peter +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + include/net/bluetooth/hci.h | 10 ++++++++++ + include/net/bluetooth/hci_core.h | 4 +++- + 2 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h +index 4518c63e9d17..78c55b69919d 100644 +--- a/include/net/bluetooth/hci.h ++++ b/include/net/bluetooth/hci.h +@@ -274,6 +274,16 @@ enum { + * during the hdev->setup vendor callback. + */ + HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN, ++ ++ /* ++ * When this quirk is set, the HCI_OP_LE_SET_EXT_SCAN_ENABLE command is ++ * disabled. This is required for some Broadcom controllers which ++ * erroneously claim to support extended scanning. ++ * ++ * This quirk can be set before hci_register_dev is called or ++ * during the hdev->setup vendor callback. ++ */ ++ HCI_QUIRK_BROKEN_EXT_SCAN, + }; + + /* HCI device flags */ +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index e7862903187d..29d1254f9856 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -1681,7 +1681,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn); + + /* Use ext scanning if set ext scan param and ext scan enable is supported */ + #define use_ext_scan(dev) (((dev)->commands[37] & 0x20) && \ +- ((dev)->commands[37] & 0x40)) ++ ((dev)->commands[37] & 0x40) && \ ++ !test_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &(dev)->quirks)) ++ + /* Use ext create connection if command is supported */ + #define use_ext_conn(dev) ((dev)->commands[37] & 0x80) + +-- +2.35.1 + diff --git a/queue-6.0/bluetooth-add-quirk-to-disable-mws-transport-configu.patch b/queue-6.0/bluetooth-add-quirk-to-disable-mws-transport-configu.patch new file mode 100644 index 00000000000..68125333993 --- /dev/null +++ b/queue-6.0/bluetooth-add-quirk-to-disable-mws-transport-configu.patch @@ -0,0 +1,89 @@ +From 865776449ed62ca0138ebf5a82e0ebd72f408e2e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Nov 2022 22:13:02 +0100 +Subject: Bluetooth: Add quirk to disable MWS Transport Configuration + +From: Sven Peter + +[ Upstream commit ffcb0a445ec2d5753751437706aa0a7ea8351099 ] + +Broadcom 4378/4387 controllers found in Apple Silicon Macs claim to +support getting MWS Transport Layer Configuration, + +< HCI Command: Read Local Supported... (0x04|0x0002) plen 0 +> HCI Event: Command Complete (0x0e) plen 68 + Read Local Supported Commands (0x04|0x0002) ncmd 1 + Status: Success (0x00) +[...] + Get MWS Transport Layer Configuration (Octet 30 - Bit 3)] +[...] + +, but then don't actually allow the required command: + +> HCI Event: Command Complete (0x0e) plen 15 + Get MWS Transport Layer Configuration (0x05|0x000c) ncmd 1 + Status: Command Disallowed (0x0c) + Number of transports: 0 + Baud rate list: 0 entries + 00 00 00 00 00 00 00 00 00 00 + +Signed-off-by: Sven Peter +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + include/net/bluetooth/hci.h | 10 ++++++++++ + include/net/bluetooth/hci_core.h | 3 +++ + net/bluetooth/hci_sync.c | 2 +- + 3 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h +index 78c55b69919d..dd455ce06770 100644 +--- a/include/net/bluetooth/hci.h ++++ b/include/net/bluetooth/hci.h +@@ -284,6 +284,16 @@ enum { + * during the hdev->setup vendor callback. + */ + HCI_QUIRK_BROKEN_EXT_SCAN, ++ ++ /* ++ * When this quirk is set, the HCI_OP_GET_MWS_TRANSPORT_CONFIG command is ++ * disabled. This is required for some Broadcom controllers which ++ * erroneously claim to support MWS Transport Layer Configuration. ++ * ++ * This quirk can be set before hci_register_dev is called or ++ * during the hdev->setup vendor callback. ++ */ ++ HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG, + }; + + /* HCI device flags */ +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index 29d1254f9856..6afb4771ce35 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -1711,6 +1711,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn); + ((dev)->le_features[3] & HCI_LE_CIS_PERIPHERAL) + #define bis_capable(dev) ((dev)->le_features[3] & HCI_LE_ISO_BROADCASTER) + ++#define mws_transport_config_capable(dev) (((dev)->commands[30] & 0x08) && \ ++ (!test_bit(HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG, &(dev)->quirks))) ++ + /* ----- HCI protocols ----- */ + #define HCI_PROTO_DEFER 0x01 + +diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c +index a5e89e1b5452..117537f3e7ad 100644 +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -3940,7 +3940,7 @@ static int hci_read_local_pairing_opts_sync(struct hci_dev *hdev) + /* Get MWS transport configuration if the HCI command is supported */ + static int hci_get_mws_transport_config_sync(struct hci_dev *hdev) + { +- if (!(hdev->commands[30] & 0x08)) ++ if (!mws_transport_config_capable(hdev)) + return 0; + + return __hci_cmd_sync_status(hdev, HCI_OP_GET_MWS_TRANSPORT_CONFIG, +-- +2.35.1 + diff --git a/queue-6.0/bluetooth-btintel-fix-missing-free-skb-in-btintel_se.patch b/queue-6.0/bluetooth-btintel-fix-missing-free-skb-in-btintel_se.patch new file mode 100644 index 00000000000..8b19734b4c4 --- /dev/null +++ b/queue-6.0/bluetooth-btintel-fix-missing-free-skb-in-btintel_se.patch @@ -0,0 +1,50 @@ +From ad3e8986570cf4a573aec1f9c6367d42cab2f0c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Dec 2022 21:53:57 +0800 +Subject: Bluetooth: btintel: Fix missing free skb in btintel_setup_combined() + +From: Wang ShaoBo + +[ Upstream commit cee50ce899de415baf4da3ed38b7d4f13c3170d1 ] + +skb allocated by __hci_cmd_sync would not be used whether in checking +for supported iBT hardware variants or after, we should free it in all +error branches, this patch makes the case read version failed or default +error case free skb before return. + +Fixes: c86c7285bb08 ("Bluetooth: btintel: Fix the legacy bootloader returns tlv based version") +Fixes: 019a1caa7fd2 ("Bluetooth: btintel: Refactoring setup routine for bootloader devices") +Signed-off-by: Wang ShaoBo +Reviewed-by: Tedd Ho-Jeong An +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btintel.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c +index d44a96667517..0c2542cee294 100644 +--- a/drivers/bluetooth/btintel.c ++++ b/drivers/bluetooth/btintel.c +@@ -2522,7 +2522,7 @@ static int btintel_setup_combined(struct hci_dev *hdev) + */ + err = btintel_read_version(hdev, &ver); + if (err) +- return err; ++ break; + + /* Apply the device specific HCI quirks + * +@@ -2563,7 +2563,8 @@ static int btintel_setup_combined(struct hci_dev *hdev) + default: + bt_dev_err(hdev, "Unsupported Intel hw variant (%u)", + INTEL_HW_VARIANT(ver_tlv.cnvi_bt)); +- return -EINVAL; ++ err = -EINVAL; ++ break; + } + + exit_error: +-- +2.35.1 + diff --git a/queue-6.0/bluetooth-btusb-don-t-call-kfree_skb-under-spin_lock.patch b/queue-6.0/bluetooth-btusb-don-t-call-kfree_skb-under-spin_lock.patch new file mode 100644 index 00000000000..157439f15f1 --- /dev/null +++ b/queue-6.0/bluetooth-btusb-don-t-call-kfree_skb-under-spin_lock.patch @@ -0,0 +1,45 @@ +From dea7f5b1ab0151a521c11cdafffc504b4dc97009 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Dec 2022 20:59:10 +0800 +Subject: Bluetooth: btusb: don't call kfree_skb() under spin_lock_irqsave() + +From: Yang Yingliang + +[ Upstream commit b15a6bd3c80c77faec8317319b97f976b1a08332 ] + +It is not allowed to call kfree_skb() from hardware interrupt +context or with interrupts being disabled. So replace kfree_skb() +with dev_kfree_skb_irq() under spin_lock_irqsave(). + +Fixes: 803b58367ffb ("Bluetooth: btusb: Implement driver internal packet reassembly") +Signed-off-by: Yang Yingliang +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 882b5893f910..a132e7aba605 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -788,13 +788,13 @@ static inline void btusb_free_frags(struct btusb_data *data) + + spin_lock_irqsave(&data->rxlock, flags); + +- kfree_skb(data->evt_skb); ++ dev_kfree_skb_irq(data->evt_skb); + data->evt_skb = NULL; + +- kfree_skb(data->acl_skb); ++ dev_kfree_skb_irq(data->acl_skb); + data->acl_skb = NULL; + +- kfree_skb(data->sco_skb); ++ dev_kfree_skb_irq(data->sco_skb); + data->sco_skb = NULL; + + spin_unlock_irqrestore(&data->rxlock, flags); +-- +2.35.1 + diff --git a/queue-6.0/bluetooth-fix-ealready-and-eloop-cases-in-bt_status.patch b/queue-6.0/bluetooth-fix-ealready-and-eloop-cases-in-bt_status.patch new file mode 100644 index 00000000000..0ed4afac027 --- /dev/null +++ b/queue-6.0/bluetooth-fix-ealready-and-eloop-cases-in-bt_status.patch @@ -0,0 +1,47 @@ +From 2f18fd9cda2db03b0a69d5675199611be1a78a23 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 30 Oct 2022 08:00:03 +0100 +Subject: Bluetooth: Fix EALREADY and ELOOP cases in bt_status() + +From: Christophe JAILLET + +[ Upstream commit 63db780a93eb802ece1bbf61ab5894ad8827b56e ] + +'err' is known to be <0 at this point. + +So, some cases can not be reached because of a missing "-". +Add it. + +Fixes: ca2045e059c3 ("Bluetooth: Add bt_status") +Signed-off-by: Christophe JAILLET +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/lib.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c +index 469a0c95b6e8..53a796ac078c 100644 +--- a/net/bluetooth/lib.c ++++ b/net/bluetooth/lib.c +@@ -170,7 +170,7 @@ __u8 bt_status(int err) + case -EMLINK: + return 0x09; + +- case EALREADY: ++ case -EALREADY: + return 0x0b; + + case -EBUSY: +@@ -191,7 +191,7 @@ __u8 bt_status(int err) + case -ECONNABORTED: + return 0x16; + +- case ELOOP: ++ case -ELOOP: + return 0x17; + + case -EPROTONOSUPPORT: +-- +2.35.1 + diff --git a/queue-6.0/bluetooth-hci_bcm-add-cyw4373a0-support.patch b/queue-6.0/bluetooth-hci_bcm-add-cyw4373a0-support.patch new file mode 100644 index 00000000000..137c4c31a32 --- /dev/null +++ b/queue-6.0/bluetooth-hci_bcm-add-cyw4373a0-support.patch @@ -0,0 +1,109 @@ +From fe2e17bcc9234182ffe35ae4372a380466604f04 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Nov 2022 17:47:05 +0100 +Subject: Bluetooth: hci_bcm: Add CYW4373A0 support + +From: Marek Vasut + +[ Upstream commit 02d056a3404e20245a69dcb4022a0930085fc5ec ] + +CYW4373A0 is a Wi-Fi + Bluetooth combo device from Cypress. +This chip is present e.g. on muRata 2AE module. + +This chip has additional quirk where the HCI command 0xfc45, used on +older chips to switch UART clock from 24 MHz to 48 MHz, to support +baudrates over 3 Mbdps, is no longer recognized by this newer chip. +This newer chip can configure the 4 Mbdps baudrate without the need +to issue HCI command 0xfc45, so add flag to indicate this and do not +issue the command on this chip to avoid failure to set 4 Mbdps baud +rate. + +It is not clear whether there is a way to determine which chip does +and which chip does not support the HCI command 0xfc45, other than +trial and error. + +Reviewed-by: Linus Walleij +Signed-off-by: Marek Vasut +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/hci_bcm.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c +index d7e0b75db8a6..2b6c0e1922cb 100644 +--- a/drivers/bluetooth/hci_bcm.c ++++ b/drivers/bluetooth/hci_bcm.c +@@ -53,11 +53,13 @@ + * struct bcm_device_data - device specific data + * @no_early_set_baudrate: Disallow set baudrate before driver setup() + * @drive_rts_on_open: drive RTS signal on ->open() when platform requires it ++ * @no_uart_clock_set: UART clock set command for >3Mbps mode is unavailable + * @max_autobaud_speed: max baudrate supported by device in autobaud mode + */ + struct bcm_device_data { + bool no_early_set_baudrate; + bool drive_rts_on_open; ++ bool no_uart_clock_set; + u32 max_autobaud_speed; + }; + +@@ -100,6 +102,7 @@ struct bcm_device_data { + * @is_suspended: whether flow control is currently disabled + * @no_early_set_baudrate: don't set_baudrate before setup() + * @drive_rts_on_open: drive RTS signal on ->open() when platform requires it ++ * @no_uart_clock_set: UART clock set command for >3Mbps mode is unavailable + * @pcm_int_params: keep the initial PCM configuration + * @use_autobaud_mode: start Bluetooth device in autobaud mode + * @max_autobaud_speed: max baudrate supported by device in autobaud mode +@@ -140,6 +143,7 @@ struct bcm_device { + #endif + bool no_early_set_baudrate; + bool drive_rts_on_open; ++ bool no_uart_clock_set; + bool use_autobaud_mode; + u8 pcm_int_params[5]; + u32 max_autobaud_speed; +@@ -172,10 +176,11 @@ static inline void host_set_baudrate(struct hci_uart *hu, unsigned int speed) + static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed) + { + struct hci_dev *hdev = hu->hdev; ++ struct bcm_data *bcm = hu->priv; + struct sk_buff *skb; + struct bcm_update_uart_baud_rate param; + +- if (speed > 3000000) { ++ if (speed > 3000000 && !bcm->dev->no_uart_clock_set) { + struct bcm_write_uart_clock_setting clock; + + clock.type = BCM_UART_CLOCK_48MHZ; +@@ -1529,6 +1534,7 @@ static int bcm_serdev_probe(struct serdev_device *serdev) + bcmdev->max_autobaud_speed = data->max_autobaud_speed; + bcmdev->no_early_set_baudrate = data->no_early_set_baudrate; + bcmdev->drive_rts_on_open = data->drive_rts_on_open; ++ bcmdev->no_uart_clock_set = data->no_uart_clock_set; + } + + return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto); +@@ -1550,6 +1556,10 @@ static struct bcm_device_data bcm43438_device_data = { + .drive_rts_on_open = true, + }; + ++static struct bcm_device_data cyw4373a0_device_data = { ++ .no_uart_clock_set = true, ++}; ++ + static struct bcm_device_data cyw55572_device_data = { + .max_autobaud_speed = 921600, + }; +@@ -1566,6 +1576,7 @@ static const struct of_device_id bcm_bluetooth_of_match[] = { + { .compatible = "brcm,bcm4349-bt", .data = &bcm43438_device_data }, + { .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data }, + { .compatible = "brcm,bcm4335a0" }, ++ { .compatible = "cypress,cyw4373a0-bt", .data = &cyw4373a0_device_data }, + { .compatible = "infineon,cyw55572-bt", .data = &cyw55572_device_data }, + { }, + }; +-- +2.35.1 + diff --git a/queue-6.0/bluetooth-hci_bcsp-don-t-call-kfree_skb-under-spin_l.patch b/queue-6.0/bluetooth-hci_bcsp-don-t-call-kfree_skb-under-spin_l.patch new file mode 100644 index 00000000000..3be2ef05bc9 --- /dev/null +++ b/queue-6.0/bluetooth-hci_bcsp-don-t-call-kfree_skb-under-spin_l.patch @@ -0,0 +1,37 @@ +From 7d125ddcba455c1c015d7330040c831e79abe805 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Dec 2022 10:18:33 +0800 +Subject: Bluetooth: hci_bcsp: don't call kfree_skb() under spin_lock_irqsave() + +From: Yang Yingliang + +[ Upstream commit 7b503e339c1a80bf0051ec2d19c3bc777014ac61 ] + +It is not allowed to call kfree_skb() from hardware interrupt +context or with interrupts being disabled. So replace kfree_skb() +with dev_kfree_skb_irq() under spin_lock_irqsave(). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Yang Yingliang +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/hci_bcsp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c +index cf4a56095817..8055f63603f4 100644 +--- a/drivers/bluetooth/hci_bcsp.c ++++ b/drivers/bluetooth/hci_bcsp.c +@@ -378,7 +378,7 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp) + i++; + + __skb_unlink(skb, &bcsp->unack); +- kfree_skb(skb); ++ dev_kfree_skb_irq(skb); + } + + if (skb_queue_empty(&bcsp->unack)) +-- +2.35.1 + diff --git a/queue-6.0/bluetooth-hci_conn-fix-crash-on-hci_create_cis_sync.patch b/queue-6.0/bluetooth-hci_conn-fix-crash-on-hci_create_cis_sync.patch new file mode 100644 index 00000000000..79a1ca205fe --- /dev/null +++ b/queue-6.0/bluetooth-hci_conn-fix-crash-on-hci_create_cis_sync.patch @@ -0,0 +1,62 @@ +From 44dc8f3b9212678f58cd3a254010cbc6a4696bab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Dec 2022 17:11:57 -0800 +Subject: Bluetooth: hci_conn: Fix crash on hci_create_cis_sync + +From: Luiz Augusto von Dentz + +[ Upstream commit 50757a259ba78c4e938b5735e76ffec6cd0c942e ] + +When attempting to connect multiple ISO sockets without using +DEFER_SETUP may result in the following crash: + +BUG: KASAN: null-ptr-deref in hci_create_cis_sync+0x18b/0x2b0 +Read of size 2 at addr 0000000000000036 by task kworker/u3:1/50 + +CPU: 0 PID: 50 Comm: kworker/u3:1 Not tainted +6.0.0-rc7-02243-gb84a13ff4eda #4373 +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), +BIOS 1.16.0-1.fc36 04/01/2014 +Workqueue: hci0 hci_cmd_sync_work +Call Trace: + + dump_stack_lvl+0x19/0x27 + kasan_report+0xbc/0xf0 + ? hci_create_cis_sync+0x18b/0x2b0 + hci_create_cis_sync+0x18b/0x2b0 + ? get_link_mode+0xd0/0xd0 + ? __ww_mutex_lock_slowpath+0x10/0x10 + ? mutex_lock+0xe0/0xe0 + ? get_link_mode+0xd0/0xd0 + hci_cmd_sync_work+0x111/0x190 + process_one_work+0x427/0x650 + worker_thread+0x87/0x750 + ? process_one_work+0x650/0x650 + kthread+0x14e/0x180 + ? kthread_exit+0x50/0x50 + ret_from_fork+0x22/0x30 + + +Fixes: 26afbd826ee3 ("Bluetooth: Add initial implementation of CIS connections") +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/hci_conn.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index f26ed278d9e3..67360444eee6 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -1817,7 +1817,7 @@ static int hci_create_cis_sync(struct hci_dev *hdev, void *data) + continue; + + /* Check if all CIS(s) belonging to a CIG are ready */ +- if (conn->link->state != BT_CONNECTED || ++ if (!conn->link || conn->link->state != BT_CONNECTED || + conn->state != BT_CONNECT) { + cmd.cp.num_cis = 0; + break; +-- +2.35.1 + diff --git a/queue-6.0/bluetooth-hci_core-don-t-call-kfree_skb-under-spin_l.patch b/queue-6.0/bluetooth-hci_core-don-t-call-kfree_skb-under-spin_l.patch new file mode 100644 index 00000000000..acd6095c925 --- /dev/null +++ b/queue-6.0/bluetooth-hci_core-don-t-call-kfree_skb-under-spin_l.patch @@ -0,0 +1,37 @@ +From 694fbaa79c39a80fcdfaa182296a3f4308b6a810 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Dec 2022 10:18:34 +0800 +Subject: Bluetooth: hci_core: don't call kfree_skb() under spin_lock_irqsave() + +From: Yang Yingliang + +[ Upstream commit 39c1eb6fcbae8ce9bb71b2ac5cb609355a2b181b ] + +It is not allowed to call kfree_skb() from hardware interrupt +context or with interrupts being disabled. So replace kfree_skb() +with dev_kfree_skb_irq() under spin_lock_irqsave(). + +Fixes: 9238f36a5a50 ("Bluetooth: Add request cmd_complete and cmd_status functions") +Signed-off-by: Yang Yingliang +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/hci_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index 995d950872af..9f8b49ff2d33 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -3978,7 +3978,7 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status, + *req_complete_skb = bt_cb(skb)->hci.req_complete_skb; + else + *req_complete = bt_cb(skb)->hci.req_complete; +- kfree_skb(skb); ++ dev_kfree_skb_irq(skb); + } + spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); + } +-- +2.35.1 + diff --git a/queue-6.0/bluetooth-hci_core-fix-error-handling-in-hci_registe.patch b/queue-6.0/bluetooth-hci_core-fix-error-handling-in-hci_registe.patch new file mode 100644 index 00000000000..b0668b60385 --- /dev/null +++ b/queue-6.0/bluetooth-hci_core-fix-error-handling-in-hci_registe.patch @@ -0,0 +1,38 @@ +From 565fdac798e53e2aa52db65c56f77fe2e3a4cf92 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Oct 2022 10:16:56 +0800 +Subject: Bluetooth: hci_core: fix error handling in hci_register_dev() + +From: Yang Yingliang + +[ Upstream commit 0d75da38e060d21f948b3df5f5e349c962cf1ed2 ] + +If hci_register_suspend_notifier() returns error, the hdev and rfkill +are leaked. We could disregard the error and print a warning message +instead to avoid leaks, as it just means we won't be handing suspend +requests. + +Fixes: 9952d90ea288 ("Bluetooth: Handle PM_SUSPEND_PREPARE and PM_POST_SUSPEND") +Signed-off-by: Yang Yingliang +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/hci_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index c8ea03edd081..995d950872af 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -2653,7 +2653,7 @@ int hci_register_dev(struct hci_dev *hdev) + + error = hci_register_suspend_notifier(hdev); + if (error) +- goto err_wqueue; ++ BT_WARN("register suspend notifier failed error:%d\n", error); + + queue_work(hdev->req_workqueue, &hdev->power_on); + +-- +2.35.1 + diff --git a/queue-6.0/bluetooth-hci_h5-don-t-call-kfree_skb-under-spin_loc.patch b/queue-6.0/bluetooth-hci_h5-don-t-call-kfree_skb-under-spin_loc.patch new file mode 100644 index 00000000000..e2e432f996f --- /dev/null +++ b/queue-6.0/bluetooth-hci_h5-don-t-call-kfree_skb-under-spin_loc.patch @@ -0,0 +1,37 @@ +From 6c50328ae2f2df422692c9ec0961e1cfd18a28ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Dec 2022 10:18:32 +0800 +Subject: Bluetooth: hci_h5: don't call kfree_skb() under spin_lock_irqsave() + +From: Yang Yingliang + +[ Upstream commit 383630cc6758d619874c2e8bb2f68a61f3f9ef6e ] + +It is not allowed to call kfree_skb() from hardware interrupt +context or with interrupts being disabled. So replace kfree_skb() +with dev_kfree_skb_irq() under spin_lock_irqsave(). + +Fixes: 43eb12d78960 ("Bluetooth: Fix/implement Three-wire reliable packet sending") +Signed-off-by: Yang Yingliang +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/hci_h5.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c +index c5a0409ef84f..6455bc4fb5bb 100644 +--- a/drivers/bluetooth/hci_h5.c ++++ b/drivers/bluetooth/hci_h5.c +@@ -313,7 +313,7 @@ static void h5_pkt_cull(struct h5 *h5) + break; + + __skb_unlink(skb, &h5->unack); +- kfree_skb(skb); ++ dev_kfree_skb_irq(skb); + } + + if (skb_queue_empty(&h5->unack)) +-- +2.35.1 + diff --git a/queue-6.0/bluetooth-hci_ll-don-t-call-kfree_skb-under-spin_loc.patch b/queue-6.0/bluetooth-hci_ll-don-t-call-kfree_skb-under-spin_loc.patch new file mode 100644 index 00000000000..c03269ae2d4 --- /dev/null +++ b/queue-6.0/bluetooth-hci_ll-don-t-call-kfree_skb-under-spin_loc.patch @@ -0,0 +1,37 @@ +From 5870ee8c5d562f95fe3106b442626e79d12500e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Dec 2022 10:18:31 +0800 +Subject: Bluetooth: hci_ll: don't call kfree_skb() under spin_lock_irqsave() + +From: Yang Yingliang + +[ Upstream commit 8f458f783dfbb19c1f1cb58ed06eeb701f52091b ] + +It is not allowed to call kfree_skb() from hardware interrupt +context or with interrupts being disabled. So replace kfree_skb() +with dev_kfree_skb_irq() under spin_lock_irqsave(). + +Fixes: 166d2f6a4332 ("[Bluetooth] Add UART driver for Texas Instruments' BRF63xx chips") +Signed-off-by: Yang Yingliang +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/hci_ll.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c +index 4eb420a9ed04..5abc01a2acf7 100644 +--- a/drivers/bluetooth/hci_ll.c ++++ b/drivers/bluetooth/hci_ll.c +@@ -345,7 +345,7 @@ static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb) + default: + BT_ERR("illegal hcill state: %ld (losing packet)", + ll->hcill_state); +- kfree_skb(skb); ++ dev_kfree_skb_irq(skb); + break; + } + +-- +2.35.1 + diff --git a/queue-6.0/bluetooth-hci_qca-don-t-call-kfree_skb-under-spin_lo.patch b/queue-6.0/bluetooth-hci_qca-don-t-call-kfree_skb-under-spin_lo.patch new file mode 100644 index 00000000000..442c158792e --- /dev/null +++ b/queue-6.0/bluetooth-hci_qca-don-t-call-kfree_skb-under-spin_lo.patch @@ -0,0 +1,37 @@ +From 5144227d6c39b0cd6f337f52941264ee8ef5d762 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Dec 2022 10:18:30 +0800 +Subject: Bluetooth: hci_qca: don't call kfree_skb() under spin_lock_irqsave() + +From: Yang Yingliang + +[ Upstream commit df4cfc91208e0a98f078223793f5871b1a82cc54 ] + +It is not allowed to call kfree_skb() from hardware interrupt +context or with interrupts being disabled. So replace kfree_skb() +with dev_kfree_skb_irq() under spin_lock_irqsave(). + +Fixes: 0ff252c1976d ("Bluetooth: hciuart: Add support QCA chipset for UART") +Signed-off-by: Yang Yingliang +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/hci_qca.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c +index 8df11016fd51..bae9b2a408d9 100644 +--- a/drivers/bluetooth/hci_qca.c ++++ b/drivers/bluetooth/hci_qca.c +@@ -912,7 +912,7 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb) + default: + BT_ERR("Illegal tx state: %d (losing packet)", + qca->tx_ibs_state); +- kfree_skb(skb); ++ dev_kfree_skb_irq(skb); + break; + } + +-- +2.35.1 + diff --git a/queue-6.0/bluetooth-mgmt-fix-error-report-for-add_ext_adv_para.patch b/queue-6.0/bluetooth-mgmt-fix-error-report-for-add_ext_adv_para.patch new file mode 100644 index 00000000000..05d69c964f8 --- /dev/null +++ b/queue-6.0/bluetooth-mgmt-fix-error-report-for-add_ext_adv_para.patch @@ -0,0 +1,37 @@ +From 656ee5864702cf22386340436e72abe52c95f9ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Oct 2022 17:48:56 -0700 +Subject: Bluetooth: MGMT: Fix error report for ADD_EXT_ADV_PARAMS + +From: Inga Stotland + +[ Upstream commit 3b1c7c00b8c22b3cb79532252c59eb0b287bb86d ] + +When validating the parameter length for MGMT_OP_ADD_EXT_ADV_PARAMS +command, use the correct op code in error status report: +was MGMT_OP_ADD_ADVERTISING, changed to MGMT_OP_ADD_EXT_ADV_PARAMS. + +Fixes: 12410572833a2 ("Bluetooth: Break add adv into two mgmt commands") +Signed-off-by: Inga Stotland +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/mgmt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c +index 3d1cd0666968..22bfeb5b2b3b 100644 +--- a/net/bluetooth/mgmt.c ++++ b/net/bluetooth/mgmt.c +@@ -8385,7 +8385,7 @@ static int add_ext_adv_params(struct sock *sk, struct hci_dev *hdev, + * extra parameters we don't know about will be ignored in this request. + */ + if (data_len < MGMT_ADD_EXT_ADV_PARAMS_MIN_SIZE) +- return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING, ++ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_EXT_ADV_PARAMS, + MGMT_STATUS_INVALID_PARAMS); + + flags = __le32_to_cpu(cp->flags); +-- +2.35.1 + diff --git a/queue-6.0/bluetooth-rfcomm-don-t-call-kfree_skb-under-spin_loc.patch b/queue-6.0/bluetooth-rfcomm-don-t-call-kfree_skb-under-spin_loc.patch new file mode 100644 index 00000000000..627a10324f7 --- /dev/null +++ b/queue-6.0/bluetooth-rfcomm-don-t-call-kfree_skb-under-spin_loc.patch @@ -0,0 +1,37 @@ +From f994bf11a1561f46bac2f6db0d23ee3bb170f26a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Dec 2022 10:18:35 +0800 +Subject: Bluetooth: RFCOMM: don't call kfree_skb() under spin_lock_irqsave() + +From: Yang Yingliang + +[ Upstream commit 0ba18967d4544955b2eff2fbc4f2a8750c4df90a ] + +It is not allowed to call kfree_skb() from hardware interrupt +context or with interrupts being disabled. So replace kfree_skb() +with dev_kfree_skb_irq() under spin_lock_irqsave(). + +Fixes: 81be03e026dc ("Bluetooth: RFCOMM: Replace use of memcpy_from_msg with bt_skb_sendmmsg") +Signed-off-by: Yang Yingliang +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/rfcomm/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c +index 7324764384b6..8d6fce9005bd 100644 +--- a/net/bluetooth/rfcomm/core.c ++++ b/net/bluetooth/rfcomm/core.c +@@ -590,7 +590,7 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb) + + ret = rfcomm_dlc_send_frag(d, frag); + if (ret < 0) { +- kfree_skb(frag); ++ dev_kfree_skb_irq(frag); + goto unlock; + } + +-- +2.35.1 + diff --git a/queue-6.0/bonding-add-missed-__rcu-annotation-for-curr_active_.patch b/queue-6.0/bonding-add-missed-__rcu-annotation-for-curr_active_.patch new file mode 100644 index 00000000000..de60ef620f4 --- /dev/null +++ b/queue-6.0/bonding-add-missed-__rcu-annotation-for-curr_active_.patch @@ -0,0 +1,37 @@ +From f1f4039c11f2672cfc15f6ca1c7b1d3a509bac2c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 12 Dec 2022 11:56:45 +0800 +Subject: bonding: add missed __rcu annotation for curr_active_slave + +From: Hangbin Liu + +[ Upstream commit 3d0b738fc5adf9f380702ac1424672e4b32c3781 ] + +There is one direct accesses to bond->curr_active_slave in +bond_miimon_commit(). Protected it by rcu_access_pointer() +since the later of this function also use this one. + +Signed-off-by: Hangbin Liu +Signed-off-by: Jakub Kicinski +Stable-dep-of: e95cc44763a4 ("bonding: do failover when high prio link up") +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 445c23e424f7..36a8db140388 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -2698,7 +2698,7 @@ static void bond_miimon_commit(struct bonding *bond) + + bond_miimon_link_change(bond, slave, BOND_LINK_UP); + +- if (!bond->curr_active_slave || slave == primary) ++ if (!rcu_access_pointer(bond->curr_active_slave) || slave == primary) + goto do_failover; + + continue; +-- +2.35.1 + diff --git a/queue-6.0/bonding-do-failover-when-high-prio-link-up.patch b/queue-6.0/bonding-do-failover-when-high-prio-link-up.patch new file mode 100644 index 00000000000..0f609018146 --- /dev/null +++ b/queue-6.0/bonding-do-failover-when-high-prio-link-up.patch @@ -0,0 +1,114 @@ +From 9aeb2b92a8a091fbb05ebbd2b9ce8dde3b071833 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 12 Dec 2022 11:56:46 +0800 +Subject: bonding: do failover when high prio link up + +From: Hangbin Liu + +[ Upstream commit e95cc44763a41d5c715ef16742bcb1d8e6524a62 ] + +Currently, when a high prio link enslaved, or when current link down, +the high prio port could be selected. But when high prio link up, the +new active slave reselection is not triggered. Fix it by checking link's +prio when getting up. Making the do_failover after looping all slaves as +there may be multi high prio slaves up. + +Reported-by: Liang Li +Fixes: 0a2ff7cc8ad4 ("Bonding: add per-port priority for failover re-selection") +Signed-off-by: Hangbin Liu +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 24 +++++++++++++++--------- + 1 file changed, 15 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 36a8db140388..771f2a533d3f 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -2653,8 +2653,9 @@ static void bond_miimon_link_change(struct bonding *bond, + + static void bond_miimon_commit(struct bonding *bond) + { +- struct list_head *iter; + struct slave *slave, *primary; ++ bool do_failover = false; ++ struct list_head *iter; + + bond_for_each_slave(bond, slave, iter) { + switch (slave->link_new_state) { +@@ -2698,8 +2699,9 @@ static void bond_miimon_commit(struct bonding *bond) + + bond_miimon_link_change(bond, slave, BOND_LINK_UP); + +- if (!rcu_access_pointer(bond->curr_active_slave) || slave == primary) +- goto do_failover; ++ if (!rcu_access_pointer(bond->curr_active_slave) || slave == primary || ++ slave->prio > rcu_dereference(bond->curr_active_slave)->prio) ++ do_failover = true; + + continue; + +@@ -2720,7 +2722,7 @@ static void bond_miimon_commit(struct bonding *bond) + bond_miimon_link_change(bond, slave, BOND_LINK_DOWN); + + if (slave == rcu_access_pointer(bond->curr_active_slave)) +- goto do_failover; ++ do_failover = true; + + continue; + +@@ -2731,8 +2733,9 @@ static void bond_miimon_commit(struct bonding *bond) + + continue; + } ++ } + +-do_failover: ++ if (do_failover) { + block_netpoll_tx(); + bond_select_active_slave(bond); + unblock_netpoll_tx(); +@@ -3530,6 +3533,7 @@ static int bond_ab_arp_inspect(struct bonding *bond) + */ + static void bond_ab_arp_commit(struct bonding *bond) + { ++ bool do_failover = false; + struct list_head *iter; + unsigned long last_tx; + struct slave *slave; +@@ -3559,8 +3563,9 @@ static void bond_ab_arp_commit(struct bonding *bond) + slave_info(bond->dev, slave->dev, "link status definitely up\n"); + + if (!rtnl_dereference(bond->curr_active_slave) || +- slave == rtnl_dereference(bond->primary_slave)) +- goto do_failover; ++ slave == rtnl_dereference(bond->primary_slave) || ++ slave->prio > rtnl_dereference(bond->curr_active_slave)->prio) ++ do_failover = true; + + } + +@@ -3579,7 +3584,7 @@ static void bond_ab_arp_commit(struct bonding *bond) + + if (slave == rtnl_dereference(bond->curr_active_slave)) { + RCU_INIT_POINTER(bond->current_arp_slave, NULL); +- goto do_failover; ++ do_failover = true; + } + + continue; +@@ -3603,8 +3608,9 @@ static void bond_ab_arp_commit(struct bonding *bond) + slave->link_new_state); + continue; + } ++ } + +-do_failover: ++ if (do_failover) { + block_netpoll_tx(); + bond_select_active_slave(bond); + unblock_netpoll_tx(); +-- +2.35.1 + diff --git a/queue-6.0/bonding-fix-link-recovery-in-mode-2-when-updelay-is-.patch b/queue-6.0/bonding-fix-link-recovery-in-mode-2-when-updelay-is-.patch new file mode 100644 index 00000000000..50c26c1abd4 --- /dev/null +++ b/queue-6.0/bonding-fix-link-recovery-in-mode-2-when-updelay-is-.patch @@ -0,0 +1,49 @@ +From 0f8fd7cc0fe32cb92852ab8fcee915f6e7974d13 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Nov 2022 16:24:29 -0500 +Subject: bonding: fix link recovery in mode 2 when updelay is nonzero + +From: Jonathan Toppins + +[ Upstream commit f8a65ab2f3ff7410921ebbf0dc55453102c33c56 ] + +Before this change when a bond in mode 2 lost link, all of its slaves +lost link, the bonding device would never recover even after the +expiration of updelay. This change removes the updelay when the bond +currently has no usable links. Conforming to bonding.txt section 13.1 +paragraph 4. + +Fixes: 41f891004063 ("bonding: ignore updelay param when there is no active slave") +Signed-off-by: Jonathan Toppins +Acked-by: Jay Vosburgh +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index c2939621b683..2ad17c840a2a 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -2536,7 +2536,16 @@ static int bond_miimon_inspect(struct bonding *bond) + struct slave *slave; + bool ignore_updelay; + +- ignore_updelay = !rcu_dereference(bond->curr_active_slave); ++ if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP) { ++ ignore_updelay = !rcu_dereference(bond->curr_active_slave); ++ } else { ++ struct bond_up_slave *usable_slaves; ++ ++ usable_slaves = rcu_dereference(bond->usable_slaves); ++ ++ if (usable_slaves && usable_slaves->count == 0) ++ ignore_updelay = true; ++ } + + bond_for_each_slave_rcu(bond, slave, iter) { + bond_propose_link_state(slave, BOND_LINK_NOCHANGE); +-- +2.35.1 + diff --git a/queue-6.0/bonding-uninitialized-variable-in-bond_miimon_inspec.patch b/queue-6.0/bonding-uninitialized-variable-in-bond_miimon_inspec.patch new file mode 100644 index 00000000000..48c83894cc4 --- /dev/null +++ b/queue-6.0/bonding-uninitialized-variable-in-bond_miimon_inspec.patch @@ -0,0 +1,41 @@ +From 54cf9ed3da53b30cd864b622eb4807d90b771e4c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Nov 2022 14:06:14 +0300 +Subject: bonding: uninitialized variable in bond_miimon_inspect() + +From: Dan Carpenter + +[ Upstream commit e5214f363dabca240446272dac54d404501ad5e5 ] + +The "ignore_updelay" variable needs to be initialized to false. + +Fixes: f8a65ab2f3ff ("bonding: fix link recovery in mode 2 when updelay is nonzero") +Signed-off-by: Dan Carpenter +Reviewed-by: Pavan Chebbi +Acked-by: Jay Vosburgh +Link: https://lore.kernel.org/r/Y4SWJlh3ohJ6EPTL@kili +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 2ad17c840a2a..445c23e424f7 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -2531,10 +2531,10 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in + /* called with rcu_read_lock() */ + static int bond_miimon_inspect(struct bonding *bond) + { ++ bool ignore_updelay = false; + int link_state, commit = 0; + struct list_head *iter; + struct slave *slave; +- bool ignore_updelay; + + if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP) { + ignore_updelay = !rcu_dereference(bond->curr_active_slave); +-- +2.35.1 + diff --git a/queue-6.0/bpf-clobber-stack-slot-when-writing-over-spilled-ptr.patch b/queue-6.0/bpf-clobber-stack-slot-when-writing-over-spilled-ptr.patch new file mode 100644 index 00000000000..cc3e29016d5 --- /dev/null +++ b/queue-6.0/bpf-clobber-stack-slot-when-writing-over-spilled-ptr.patch @@ -0,0 +1,78 @@ +From 1107217e3848acaff883e07443f59718c5a2fe5b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Nov 2022 00:39:52 +0530 +Subject: bpf: Clobber stack slot when writing over spilled PTR_TO_BTF_ID + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit 261f4664caffdeb9dff4e83ee3c0334b1c3a552f ] + +When support was added for spilled PTR_TO_BTF_ID to be accessed by +helper memory access, the stack slot was not overwritten to STACK_MISC +(and that too is only safe when env->allow_ptr_leaks is true). + +This means that helpers who take ARG_PTR_TO_MEM and write to it may +essentially overwrite the value while the verifier continues to track +the slot for spilled register. + +This can cause issues when PTR_TO_BTF_ID is spilled to stack, and then +overwritten by helper write access, which can then be passed to BPF +helpers or kfuncs. + +Handle this by falling back to the case introduced in a later commit, +which will also handle PTR_TO_BTF_ID along with other pointer types, +i.e. cd17d38f8b28 ("bpf: Permits pointers on stack for helper calls"). + +Finally, include a comment on why REG_LIVE_WRITTEN is not being set when +clobber is set to true. In short, the reason is that while when clobber +is unset, we know that we won't be writing, when it is true, we *may* +write to any of the stack slots in that range. It may be a partial or +complete write, to just one or many stack slots. + +We cannot be sure, hence to be conservative, we leave things as is and +never set REG_LIVE_WRITTEN for any stack slot. However, clobber still +needs to reset them to STACK_MISC assuming writes happened. However read +marks still need to be propagated upwards from liveness point of view, +as parent stack slot's contents may still continue to matter to child +states. + +Cc: Yonghong Song +Fixes: 1d68f22b3d53 ("bpf: Handle spilled PTR_TO_BTF_ID properly when checking stack_boundary") +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20221103191013.1236066-4-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index b781075dd510..65c627571e33 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -5142,10 +5142,6 @@ static int check_stack_range_initialized( + goto mark; + } + +- if (is_spilled_reg(&state->stack[spi]) && +- base_type(state->stack[spi].spilled_ptr.type) == PTR_TO_BTF_ID) +- goto mark; +- + if (is_spilled_reg(&state->stack[spi]) && + (state->stack[spi].spilled_ptr.type == SCALAR_VALUE || + env->allow_ptr_leaks)) { +@@ -5176,6 +5172,11 @@ static int check_stack_range_initialized( + mark_reg_read(env, &state->stack[spi].spilled_ptr, + state->stack[spi].spilled_ptr.parent, + REG_LIVE_READ64); ++ /* We do not set REG_LIVE_WRITTEN for stack slot, as we can not ++ * be sure that whether stack slot is written to or not. Hence, ++ * we must still conservatively propagate reads upwards even if ++ * helper may write to the entire memory range. ++ */ + } + return update_stack_depth(env, state, min_off); + } +-- +2.35.1 + diff --git a/queue-6.0/bpf-do-not-zero-extend-kfunc-return-values.patch b/queue-6.0/bpf-do-not-zero-extend-kfunc-return-values.patch new file mode 100644 index 00000000000..4d523fd3ddd --- /dev/null +++ b/queue-6.0/bpf-do-not-zero-extend-kfunc-return-values.patch @@ -0,0 +1,106 @@ +From e1084acae72f2dc0f26d3b996e69a86bc48beb70 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Dec 2022 11:35:40 +0100 +Subject: bpf: Do not zero-extend kfunc return values +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Björn Töpel + +[ Upstream commit d35af0a7feb077c43ff0233bba5a8c6e75b73e35 ] + +In BPF all global functions, and BPF helpers return a 64-bit +value. For kfunc calls, this is not the case, and they can return +e.g. 32-bit values. + +The return register R0 for kfuncs calls can therefore be marked as +subreg_def != DEF_NOT_SUBREG. In general, if a register is marked with +subreg_def != DEF_NOT_SUBREG, some archs (where bpf_jit_needs_zext() +returns true) require the verifier to insert explicit zero-extension +instructions. + +For kfuncs calls, however, the caller should do sign/zero extension +for return values. In other words, the compiler is responsible to +insert proper instructions, not the verifier. + +An example, provided by Yonghong Song: + +$ cat t.c +extern unsigned foo(void); +unsigned bar1(void) { + return foo(); +} +unsigned bar2(void) { + if (foo()) return 10; else return 20; +} + +$ clang -target bpf -mcpu=v3 -O2 -c t.c && llvm-objdump -d t.o +t.o: file format elf64-bpf + +Disassembly of section .text: + +0000000000000000 : + 0: 85 10 00 00 ff ff ff ff call -0x1 + 1: 95 00 00 00 00 00 00 00 exit + +0000000000000010 : + 2: 85 10 00 00 ff ff ff ff call -0x1 + 3: bc 01 00 00 00 00 00 00 w1 = w0 + 4: b4 00 00 00 14 00 00 00 w0 = 0x14 + 5: 16 01 01 00 00 00 00 00 if w1 == 0x0 goto +0x1 + 6: b4 00 00 00 0a 00 00 00 w0 = 0xa + +0000000000000038 : + 7: 95 00 00 00 00 00 00 00 exit + +If the return value of 'foo()' is used in the BPF program, the proper +zero-extension will be done. + +Currently, the verifier correctly marks, say, a 32-bit return value as +subreg_def != DEF_NOT_SUBREG, but will fail performing the actual +zero-extension, due to a verifier bug in +opt_subreg_zext_lo32_rnd_hi32(). load_reg is not properly set to R0, +and the following path will be taken: + + if (WARN_ON(load_reg == -1)) { + verbose(env, "verifier bug. zext_dst is set, but no reg is defined\n"); + return -EFAULT; + } + +A longer discussion from v1 can be found in the link below. + +Correct the verifier by avoiding doing explicit zero-extension of R0 +for kfunc calls. Note that R0 will still be marked as a sub-register +for return values smaller than 64-bit. + +Fixes: 83a2881903f3 ("bpf: Account for BPF_FETCH in insn_has_def32()") +Link: https://lore.kernel.org/bpf/20221202103620.1915679-1-bjorn@kernel.org/ +Suggested-by: Yonghong Song +Signed-off-by: Björn Töpel +Acked-by: Yonghong Song +Link: https://lore.kernel.org/r/20221207103540.396496-1-bjorn@kernel.org +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 7a1ca0e58043..57f76b597012 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -13299,6 +13299,10 @@ static int opt_subreg_zext_lo32_rnd_hi32(struct bpf_verifier_env *env, + if (!bpf_jit_needs_zext() && !is_cmpxchg_insn(&insn)) + continue; + ++ /* Zero-extension is done by the caller. */ ++ if (bpf_pseudo_kfunc_call(&insn)) ++ continue; ++ + if (WARN_ON(load_reg == -1)) { + verbose(env, "verifier bug. zext_dst is set, but no reg is defined\n"); + return -EFAULT; +-- +2.35.1 + diff --git a/queue-6.0/bpf-fix-a-btf_id_list-bug-with-config_debug_info_btf.patch b/queue-6.0/bpf-fix-a-btf_id_list-bug-with-config_debug_info_btf.patch new file mode 100644 index 00000000000..d7d69122c56 --- /dev/null +++ b/queue-6.0/bpf-fix-a-btf_id_list-bug-with-config_debug_info_btf.patch @@ -0,0 +1,61 @@ +From 401a813ee018a13f77ae9d3d81020ee20031718c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Nov 2022 07:57:59 -0800 +Subject: bpf: Fix a BTF_ID_LIST bug with CONFIG_DEBUG_INFO_BTF not set + +From: Yonghong Song + +[ Upstream commit beb3d47d1d3d7185bb401af628ad32ee204a9526 ] + +With CONFIG_DEBUG_INFO_BTF not set, we hit the following compilation error, + /.../kernel/bpf/verifier.c:8196:23: error: array index 6 is past the end of the array + (that has type 'u32[5]' (aka 'unsigned int[5]')) [-Werror,-Warray-bounds] + if (meta->func_id == special_kfunc_list[KF_bpf_cast_to_kern_ctx]) + ^ ~~~~~~~~~~~~~~~~~~~~~~~ + /.../kernel/bpf/verifier.c:8174:1: note: array 'special_kfunc_list' declared here + BTF_ID_LIST(special_kfunc_list) + ^ + /.../include/linux/btf_ids.h:207:27: note: expanded from macro 'BTF_ID_LIST' + #define BTF_ID_LIST(name) static u32 __maybe_unused name[5]; + ^ + /.../kernel/bpf/verifier.c:8443:19: error: array index 5 is past the end of the array + (that has type 'u32[5]' (aka 'unsigned int[5]')) [-Werror,-Warray-bounds] + btf_id == special_kfunc_list[KF_bpf_list_pop_back]; + ^ ~~~~~~~~~~~~~~~~~~~~ + /.../kernel/bpf/verifier.c:8174:1: note: array 'special_kfunc_list' declared here + BTF_ID_LIST(special_kfunc_list) + ^ + /.../include/linux/btf_ids.h:207:27: note: expanded from macro 'BTF_ID_LIST' + #define BTF_ID_LIST(name) static u32 __maybe_unused name[5]; + ... + +Fix the problem by increase the size of BTF_ID_LIST to 16 to avoid compilation error +and also prevent potentially unintended issue due to out-of-bound access. + +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Reported-by: Nathan Chancellor +Signed-off-by: Yonghong Song +Link: https://lore.kernel.org/r/20221123155759.2669749-1-yhs@fb.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + include/linux/btf_ids.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/btf_ids.h b/include/linux/btf_ids.h +index 2aea877d644f..2b9872008428 100644 +--- a/include/linux/btf_ids.h ++++ b/include/linux/btf_ids.h +@@ -204,7 +204,7 @@ extern struct btf_id_set8 name; + + #else + +-#define BTF_ID_LIST(name) static u32 __maybe_unused name[5]; ++#define BTF_ID_LIST(name) static u32 __maybe_unused name[16]; + #define BTF_ID(prefix, name) + #define BTF_ID_FLAGS(prefix, name, ...) + #define BTF_ID_UNUSED +-- +2.35.1 + diff --git a/queue-6.0/bpf-fix-slot-type-check-in-check_stack_write_var_off.patch b/queue-6.0/bpf-fix-slot-type-check-in-check_stack_write_var_off.patch new file mode 100644 index 00000000000..3680e4312a5 --- /dev/null +++ b/queue-6.0/bpf-fix-slot-type-check-in-check_stack_write_var_off.patch @@ -0,0 +1,57 @@ +From 5ea56a56f2211b5e5bafc33e74d6aa2f771aeb0d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Nov 2022 00:39:53 +0530 +Subject: bpf: Fix slot type check in check_stack_write_var_off + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit f5e477a861e4a20d8a1c5f7a245f3a3c3c376b03 ] + +For the case where allow_ptr_leaks is false, code is checking whether +slot type is STACK_INVALID and STACK_SPILL and rejecting other cases. +This is a consequence of incorrectly checking for register type instead +of the slot type (NOT_INIT and SCALAR_VALUE respectively). Fix the +check. + +Fixes: 01f810ace9ed ("bpf: Allow variable-offset stack access") +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20221103191013.1236066-5-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 65c627571e33..95479562a64a 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -3169,14 +3169,17 @@ static int check_stack_write_var_off(struct bpf_verifier_env *env, + stype = &state->stack[spi].slot_type[slot % BPF_REG_SIZE]; + mark_stack_slot_scratched(env, spi); + +- if (!env->allow_ptr_leaks +- && *stype != NOT_INIT +- && *stype != SCALAR_VALUE) { +- /* Reject the write if there's are spilled pointers in +- * range. If we didn't reject here, the ptr status +- * would be erased below (even though not all slots are +- * actually overwritten), possibly opening the door to +- * leaks. ++ if (!env->allow_ptr_leaks && *stype != STACK_MISC && *stype != STACK_ZERO) { ++ /* Reject the write if range we may write to has not ++ * been initialized beforehand. If we didn't reject ++ * here, the ptr status would be erased below (even ++ * though not all slots are actually overwritten), ++ * possibly opening the door to leaks. ++ * ++ * We do however catch STACK_INVALID case below, and ++ * only allow reading possibly uninitialized memory ++ * later for CAP_PERFMON, as the write may not happen to ++ * that slot. + */ + verbose(env, "spilled ptr in range of var-offset stack write; insn %d, ptr off: %d", + insn_idx, i); +-- +2.35.1 + diff --git a/queue-6.0/bpf-make-sure-skb-len-0-when-redirecting-to-a-tunnel.patch b/queue-6.0/bpf-make-sure-skb-len-0-when-redirecting-to-a-tunnel.patch new file mode 100644 index 00000000000..8d2ad848c53 --- /dev/null +++ b/queue-6.0/bpf-make-sure-skb-len-0-when-redirecting-to-a-tunnel.patch @@ -0,0 +1,73 @@ +From eda00cf3fadeab90b8881e413ade1ac76c60fbf2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Oct 2022 15:55:37 -0700 +Subject: bpf: make sure skb->len != 0 when redirecting to a tunneling device + +From: Stanislav Fomichev + +[ Upstream commit 07ec7b502800ba9f7b8b15cb01dd6556bb41aaca ] + +syzkaller managed to trigger another case where skb->len == 0 +when we enter __dev_queue_xmit: + +WARNING: CPU: 0 PID: 2470 at include/linux/skbuff.h:2576 skb_assert_len include/linux/skbuff.h:2576 [inline] +WARNING: CPU: 0 PID: 2470 at include/linux/skbuff.h:2576 __dev_queue_xmit+0x2069/0x35e0 net/core/dev.c:4295 + +Call Trace: + dev_queue_xmit+0x17/0x20 net/core/dev.c:4406 + __bpf_tx_skb net/core/filter.c:2115 [inline] + __bpf_redirect_no_mac net/core/filter.c:2140 [inline] + __bpf_redirect+0x5fb/0xda0 net/core/filter.c:2163 + ____bpf_clone_redirect net/core/filter.c:2447 [inline] + bpf_clone_redirect+0x247/0x390 net/core/filter.c:2419 + bpf_prog_48159a89cb4a9a16+0x59/0x5e + bpf_dispatcher_nop_func include/linux/bpf.h:897 [inline] + __bpf_prog_run include/linux/filter.h:596 [inline] + bpf_prog_run include/linux/filter.h:603 [inline] + bpf_test_run+0x46c/0x890 net/bpf/test_run.c:402 + bpf_prog_test_run_skb+0xbdc/0x14c0 net/bpf/test_run.c:1170 + bpf_prog_test_run+0x345/0x3c0 kernel/bpf/syscall.c:3648 + __sys_bpf+0x43a/0x6c0 kernel/bpf/syscall.c:5005 + __do_sys_bpf kernel/bpf/syscall.c:5091 [inline] + __se_sys_bpf kernel/bpf/syscall.c:5089 [inline] + __x64_sys_bpf+0x7c/0x90 kernel/bpf/syscall.c:5089 + do_syscall_64+0x54/0x70 arch/x86/entry/common.c:48 + entry_SYSCALL_64_after_hwframe+0x61/0xc6 + +The reproducer doesn't really reproduce outside of syzkaller +environment, so I'm taking a guess here. It looks like we +do generate correct ETH_HLEN-sized packet, but we redirect +the packet to the tunneling device. Before we do so, we +__skb_pull l2 header and arrive again at skb->len == 0. +Doesn't seem like we can do anything better than having +an explicit check after __skb_pull? + +Cc: Eric Dumazet +Reported-by: syzbot+f635e86ec3fa0a37e019@syzkaller.appspotmail.com +Signed-off-by: Stanislav Fomichev +Link: https://lore.kernel.org/r/20221027225537.353077-1-sdf@google.com +Signed-off-by: Martin KaFai Lau +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + net/core/filter.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/core/filter.c b/net/core/filter.c +index 5ac3ecc2edb8..3aae1885b970 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -2130,6 +2130,10 @@ static int __bpf_redirect_no_mac(struct sk_buff *skb, struct net_device *dev, + + if (mlen) { + __skb_pull(skb, mlen); ++ if (unlikely(!skb->len)) { ++ kfree_skb(skb); ++ return -ERANGE; ++ } + + /* At ingress, the mac header has already been pulled once. + * At egress, skb_pospull_rcsum has to be done in case that +-- +2.35.1 + diff --git a/queue-6.0/bpf-move-skb-len-0-checks-into-__bpf_redirect.patch b/queue-6.0/bpf-move-skb-len-0-checks-into-__bpf_redirect.patch new file mode 100644 index 00000000000..f7dbfafb390 --- /dev/null +++ b/queue-6.0/bpf-move-skb-len-0-checks-into-__bpf_redirect.patch @@ -0,0 +1,66 @@ +From 52d76b4a26087d6a90c00de82ab883da3f545e8c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Nov 2022 10:03:39 -0800 +Subject: bpf: Move skb->len == 0 checks into __bpf_redirect + +From: Stanislav Fomichev + +[ Upstream commit 114039b342014680911c35bd6b72624180fd669a ] + +To avoid potentially breaking existing users. + +Both mac/no-mac cases have to be amended; mac_header >= network_header +is not enough (verified with a new test, see next patch). + +Fixes: fd1894224407 ("bpf: Don't redirect packets with invalid pkt_len") +Signed-off-by: Stanislav Fomichev +Link: https://lore.kernel.org/r/20221121180340.1983627-1-sdf@google.com +Signed-off-by: Martin KaFai Lau +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 3 --- + net/core/filter.c | 7 ++++++- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index b422238f9f86..5d53332ea3c9 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -939,9 +939,6 @@ static int convert___skb_to_skb(struct sk_buff *skb, struct __sk_buff *__skb) + { + struct qdisc_skb_cb *cb = (struct qdisc_skb_cb *)skb->cb; + +- if (!skb->len) +- return -EINVAL; +- + if (!__skb) + return 0; + +diff --git a/net/core/filter.c b/net/core/filter.c +index c191db80ce93..5ac3ecc2edb8 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -2123,6 +2123,11 @@ static int __bpf_redirect_no_mac(struct sk_buff *skb, struct net_device *dev, + { + unsigned int mlen = skb_network_offset(skb); + ++ if (unlikely(skb->len <= mlen)) { ++ kfree_skb(skb); ++ return -ERANGE; ++ } ++ + if (mlen) { + __skb_pull(skb, mlen); + +@@ -2144,7 +2149,7 @@ static int __bpf_redirect_common(struct sk_buff *skb, struct net_device *dev, + u32 flags) + { + /* Verify that a link layer header is carried */ +- if (unlikely(skb->mac_header >= skb->network_header)) { ++ if (unlikely(skb->mac_header >= skb->network_header || skb->len == 0)) { + kfree_skb(skb); + return -ERANGE; + } +-- +2.35.1 + diff --git a/queue-6.0/bpf-prevent-decl_tag-from-being-referenced-in-func_p.patch b/queue-6.0/bpf-prevent-decl_tag-from-being-referenced-in-func_p.patch new file mode 100644 index 00000000000..1fc0359c6ea --- /dev/null +++ b/queue-6.0/bpf-prevent-decl_tag-from-being-referenced-in-func_p.patch @@ -0,0 +1,55 @@ +From 52b277e0ba2c57b32a07aea92fdaeb1de9ab64c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Nov 2022 19:54:22 -0800 +Subject: bpf: Prevent decl_tag from being referenced in func_proto arg + +From: Stanislav Fomichev + +[ Upstream commit f17472d4599697d701aa239b4c475a506bccfd19 ] + +Syzkaller managed to hit another decl_tag issue: + + btf_func_proto_check kernel/bpf/btf.c:4506 [inline] + btf_check_all_types kernel/bpf/btf.c:4734 [inline] + btf_parse_type_sec+0x1175/0x1980 kernel/bpf/btf.c:4763 + btf_parse kernel/bpf/btf.c:5042 [inline] + btf_new_fd+0x65a/0xb00 kernel/bpf/btf.c:6709 + bpf_btf_load+0x6f/0x90 kernel/bpf/syscall.c:4342 + __sys_bpf+0x50a/0x6c0 kernel/bpf/syscall.c:5034 + __do_sys_bpf kernel/bpf/syscall.c:5093 [inline] + __se_sys_bpf kernel/bpf/syscall.c:5091 [inline] + __x64_sys_bpf+0x7c/0x90 kernel/bpf/syscall.c:5091 + do_syscall_64+0x54/0x70 arch/x86/entry/common.c:48 + +This seems similar to commit ea68376c8bed ("bpf: prevent decl_tag from being +referenced in func_proto") but for the argument. + +Reported-by: syzbot+8dd0551dda6020944c5d@syzkaller.appspotmail.com +Signed-off-by: Stanislav Fomichev +Signed-off-by: Daniel Borkmann +Acked-by: Yonghong Song +Link: https://lore.kernel.org/bpf/20221123035422.872531-2-sdf@google.com +Signed-off-by: Sasha Levin +--- + kernel/bpf/btf.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c +index 0d23d4bcd81c..44e93c3abebd 100644 +--- a/kernel/bpf/btf.c ++++ b/kernel/bpf/btf.c +@@ -4481,6 +4481,11 @@ static int btf_func_proto_check(struct btf_verifier_env *env, + break; + } + ++ if (btf_type_is_resolve_source_only(arg_type)) { ++ btf_verifier_log_type(env, t, "Invalid arg#%u", i + 1); ++ return -EINVAL; ++ } ++ + if (args[i].name_off && + (!btf_name_offset_valid(btf, args[i].name_off) || + !btf_name_valid_identifier(btf, args[i].name_off))) { +-- +2.35.1 + diff --git a/queue-6.0/bpf-prevent-leak-of-lsm-program-after-failed-attach.patch b/queue-6.0/bpf-prevent-leak-of-lsm-program-after-failed-attach.patch new file mode 100644 index 00000000000..38b866480db --- /dev/null +++ b/queue-6.0/bpf-prevent-leak-of-lsm-program-after-failed-attach.patch @@ -0,0 +1,49 @@ +From eaad0dc4c83ba54e9470936ff699033a7c7d75ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Dec 2022 12:57:14 -0500 +Subject: bpf: prevent leak of lsm program after failed attach + +From: Milan Landaverde + +[ Upstream commit e89f3edffb860a0f54a9ed16deadb7a4a1fa3862 ] + +In [0], we added the ability to bpf_prog_attach LSM programs to cgroups, +but in our validation to make sure the prog is meant to be attached to +BPF_LSM_CGROUP, we return too early if the check fails. This results in +lack of decrementing prog's refcnt (through bpf_prog_put) +leaving the LSM program alive past the point of the expected lifecycle. +This fix allows for the decrement to take place. + +[0] https://lore.kernel.org/all/20220628174314.1216643-4-sdf@google.com/ + +Fixes: 69fd337a975c ("bpf: per-cgroup lsm flavor") +Signed-off-by: Milan Landaverde +Signed-off-by: Martin KaFai Lau +Signed-off-by: Daniel Borkmann +Reviewed-by: Stanislav Fomichev +Link: https://lore.kernel.org/r/20221213175714.31963-1-milan@mdaverde.com +Signed-off-by: Sasha Levin +--- + kernel/bpf/syscall.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index 0e758911d963..6b6fb7237ebe 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -3505,9 +3505,9 @@ static int bpf_prog_attach(const union bpf_attr *attr) + case BPF_PROG_TYPE_LSM: + if (ptype == BPF_PROG_TYPE_LSM && + prog->expected_attach_type != BPF_LSM_CGROUP) +- return -EINVAL; +- +- ret = cgroup_bpf_prog_attach(attr, ptype, prog); ++ ret = -EINVAL; ++ else ++ ret = cgroup_bpf_prog_attach(attr, ptype, prog); + break; + default: + ret = -EINVAL; +-- +2.35.1 + diff --git a/queue-6.0/bpf-propagate-precision-across-all-frames-not-just-t.patch b/queue-6.0/bpf-propagate-precision-across-all-frames-not-just-t.patch new file mode 100644 index 00000000000..b92c2ae17cf --- /dev/null +++ b/queue-6.0/bpf-propagate-precision-across-all-frames-not-just-t.patch @@ -0,0 +1,160 @@ +From c087704691a5b45967f4eb5bb5ea54613ecd664e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Nov 2022 09:36:45 -0700 +Subject: bpf: propagate precision across all frames, not just the last one + +From: Andrii Nakryiko + +[ Upstream commit 529409ea92d590659be487ba0839710329bd8074 ] + +When equivalent completed state is found and it has additional precision +restrictions, BPF verifier propagates precision to +currently-being-verified state chain (i.e., including parent states) so +that if some of the states in the chain are not yet completed, necessary +precision restrictions are enforced. + +Unfortunately, right now this happens only for the last frame (deepest +active subprogram's frame), not all the frames. This can lead to +incorrect matching of states due to missing precision marker. Currently +this doesn't seem possible as BPF verifier forces everything to precise +when validated BPF program has any subprograms. But with the next patch +lifting this restriction, this becomes problematic. + +In fact, without this fix, we'll start getting failure in one of the +existing test_verifier test cases: + + #906/p precise: cross frame pruning FAIL + Unexpected success to load! + verification time 48 usec + stack depth 0+0 + processed 26 insns (limit 1000000) max_states_per_insn 3 total_states 17 peak_states 17 mark_read 8 + +This patch adds precision propagation across all frames. + +Fixes: a3ce685dd01a ("bpf: fix precision tracking") +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/r/20221104163649.121784-3-andrii@kernel.org +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 71 ++++++++++++++++++++++++------------------- + 1 file changed, 39 insertions(+), 32 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 05414615c008..7a1ca0e58043 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -2751,7 +2751,7 @@ static void mark_all_scalars_precise(struct bpf_verifier_env *env, + } + } + +-static int __mark_chain_precision(struct bpf_verifier_env *env, int regno, ++static int __mark_chain_precision(struct bpf_verifier_env *env, int frame, int regno, + int spi) + { + struct bpf_verifier_state *st = env->cur_state; +@@ -2768,7 +2768,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno, + if (!env->bpf_capable) + return 0; + +- func = st->frame[st->curframe]; ++ func = st->frame[frame]; + if (regno >= 0) { + reg = &func->regs[regno]; + if (reg->type != SCALAR_VALUE) { +@@ -2849,7 +2849,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno, + break; + + new_marks = false; +- func = st->frame[st->curframe]; ++ func = st->frame[frame]; + bitmap_from_u64(mask, reg_mask); + for_each_set_bit(i, mask, 32) { + reg = &func->regs[i]; +@@ -2915,12 +2915,17 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno, + + static int mark_chain_precision(struct bpf_verifier_env *env, int regno) + { +- return __mark_chain_precision(env, regno, -1); ++ return __mark_chain_precision(env, env->cur_state->curframe, regno, -1); + } + +-static int mark_chain_precision_stack(struct bpf_verifier_env *env, int spi) ++static int mark_chain_precision_frame(struct bpf_verifier_env *env, int frame, int regno) + { +- return __mark_chain_precision(env, -1, spi); ++ return __mark_chain_precision(env, frame, regno, -1); ++} ++ ++static int mark_chain_precision_stack_frame(struct bpf_verifier_env *env, int frame, int spi) ++{ ++ return __mark_chain_precision(env, frame, -1, spi); + } + + static bool is_spillable_regtype(enum bpf_reg_type type) +@@ -11702,34 +11707,36 @@ static int propagate_precision(struct bpf_verifier_env *env, + { + struct bpf_reg_state *state_reg; + struct bpf_func_state *state; +- int i, err = 0; ++ int i, err = 0, fr; + +- state = old->frame[old->curframe]; +- state_reg = state->regs; +- for (i = 0; i < BPF_REG_FP; i++, state_reg++) { +- if (state_reg->type != SCALAR_VALUE || +- !state_reg->precise) +- continue; +- if (env->log.level & BPF_LOG_LEVEL2) +- verbose(env, "propagating r%d\n", i); +- err = mark_chain_precision(env, i); +- if (err < 0) +- return err; +- } ++ for (fr = old->curframe; fr >= 0; fr--) { ++ state = old->frame[fr]; ++ state_reg = state->regs; ++ for (i = 0; i < BPF_REG_FP; i++, state_reg++) { ++ if (state_reg->type != SCALAR_VALUE || ++ !state_reg->precise) ++ continue; ++ if (env->log.level & BPF_LOG_LEVEL2) ++ verbose(env, "frame %d: propagating r%d\n", i, fr); ++ err = mark_chain_precision_frame(env, fr, i); ++ if (err < 0) ++ return err; ++ } + +- for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) { +- if (!is_spilled_reg(&state->stack[i])) +- continue; +- state_reg = &state->stack[i].spilled_ptr; +- if (state_reg->type != SCALAR_VALUE || +- !state_reg->precise) +- continue; +- if (env->log.level & BPF_LOG_LEVEL2) +- verbose(env, "propagating fp%d\n", +- (-i - 1) * BPF_REG_SIZE); +- err = mark_chain_precision_stack(env, i); +- if (err < 0) +- return err; ++ for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) { ++ if (!is_spilled_reg(&state->stack[i])) ++ continue; ++ state_reg = &state->stack[i].spilled_ptr; ++ if (state_reg->type != SCALAR_VALUE || ++ !state_reg->precise) ++ continue; ++ if (env->log.level & BPF_LOG_LEVEL2) ++ verbose(env, "frame %d: propagating fp%d\n", ++ (-i - 1) * BPF_REG_SIZE, fr); ++ err = mark_chain_precision_stack_frame(env, fr, i); ++ if (err < 0) ++ return err; ++ } + } + return 0; + } +-- +2.35.1 + diff --git a/queue-6.0/bpf-propagate-precision-in-alu-alu64-operations.patch b/queue-6.0/bpf-propagate-precision-in-alu-alu64-operations.patch new file mode 100644 index 00000000000..04ce97fdfe7 --- /dev/null +++ b/queue-6.0/bpf-propagate-precision-in-alu-alu64-operations.patch @@ -0,0 +1,89 @@ +From 8bd2e0414d177ff2e644a30ee7acec86bbcfc48e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Nov 2022 09:36:44 -0700 +Subject: bpf: propagate precision in ALU/ALU64 operations + +From: Andrii Nakryiko + +[ Upstream commit a3b666bfa9c9edc05bca62a87abafe0936bd7f97 ] + +When processing ALU/ALU64 operations (apart from BPF_MOV, which is +handled correctly already; and BPF_NEG and BPF_END are special and don't +have source register), if destination register is already marked +precise, this causes problem with potentially missing precision tracking +for the source register. E.g., when we have r1 >>= r5 and r1 is marked +precise, but r5 isn't, this will lead to r5 staying as imprecise. This +is due to the precision backtracking logic stopping early when it sees +r1 is already marked precise. If r1 wasn't precise, we'd keep +backtracking and would add r5 to the set of registers that need to be +marked precise. So there is a discrepancy here which can lead to invalid +and incompatible states matched due to lack of precision marking on r5. +If r1 wasn't precise, precision backtracking would correctly mark both +r1 and r5 as precise. + +This is simple to fix, though. During the forward instruction simulation +pass, for arithmetic operations of `scalar = scalar` form (where + is ALU or ALU64 operations), if destination register is already +precise, mark source register as precise. This applies only when both +involved registers are SCALARs. `ptr += scalar` and `scalar += ptr` +cases are already handled correctly. + +This does have (negative) effect on some selftest programs and few +Cilium programs. ~/baseline-tmp-results.csv are veristat results with +this patch, while ~/baseline-results.csv is without it. See post +scriptum for instructions on how to make Cilium programs testable with +veristat. Correctness has a price. + +$ ./veristat -C -e file,prog,insns,states ~/baseline-results.csv ~/baseline-tmp-results.csv | grep -v '+0' +File Program Total insns (A) Total insns (B) Total insns (DIFF) Total states (A) Total states (B) Total states (DIFF) +----------------------- -------------------- --------------- --------------- ------------------ ---------------- ---------------- ------------------- +bpf_cubic.bpf.linked1.o bpf_cubic_cong_avoid 997 1700 +703 (+70.51%) 62 90 +28 (+45.16%) +test_l4lb.bpf.linked1.o balancer_ingress 4559 5469 +910 (+19.96%) 118 126 +8 (+6.78%) +----------------------- -------------------- --------------- --------------- ------------------ ---------------- ---------------- ------------------- + +$ ./veristat -C -e file,prog,verdict,insns,states ~/baseline-results-cilium.csv ~/baseline-tmp-results-cilium.csv | grep -v '+0' +File Program Total insns (A) Total insns (B) Total insns (DIFF) Total states (A) Total states (B) Total states (DIFF) +------------- ------------------------------ --------------- --------------- ------------------ ---------------- ---------------- ------------------- +bpf_host.o tail_nodeport_nat_ingress_ipv6 4448 5261 +813 (+18.28%) 234 247 +13 (+5.56%) +bpf_host.o tail_nodeport_nat_ipv6_egress 3396 3446 +50 (+1.47%) 201 203 +2 (+1.00%) +bpf_lxc.o tail_nodeport_nat_ingress_ipv6 4448 5261 +813 (+18.28%) 234 247 +13 (+5.56%) +bpf_overlay.o tail_nodeport_nat_ingress_ipv6 4448 5261 +813 (+18.28%) 234 247 +13 (+5.56%) +bpf_xdp.o tail_lb_ipv4 71736 73442 +1706 (+2.38%) 4295 4370 +75 (+1.75%) +------------- ------------------------------ --------------- --------------- ------------------ ---------------- ---------------- ------------------- + +P.S. To make Cilium ([0]) programs libbpf-compatible and thus +veristat-loadable, apply changes from topmost commit in [1], which does +minimal changes to Cilium source code, mostly around SEC() annotations +and BPF map definitions. + + [0] https://github.com/cilium/cilium/ + [1] https://github.com/anakryiko/cilium/commits/libbpf-friendliness + +Fixes: b5dc0163d8fd ("bpf: precise scalar_value tracking") +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/r/20221104163649.121784-2-andrii@kernel.org +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 95479562a64a..05414615c008 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -9061,6 +9061,11 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env, + return err; + return adjust_ptr_min_max_vals(env, insn, + dst_reg, src_reg); ++ } else if (dst_reg->precise) { ++ /* if dst_reg is precise, src_reg should be precise as well */ ++ err = mark_chain_precision(env, insn->src_reg); ++ if (err) ++ return err; + } + } else { + /* Pretend the src is a reg with a known value, since we only +-- +2.35.1 + diff --git a/queue-6.0/bpf-resolve-fext-program-type-when-checking-map-comp.patch b/queue-6.0/bpf-resolve-fext-program-type-when-checking-map-comp.patch new file mode 100644 index 00000000000..daa1de8bfd5 --- /dev/null +++ b/queue-6.0/bpf-resolve-fext-program-type-when-checking-map-comp.patch @@ -0,0 +1,73 @@ +From dda0a3ac94d50bdb6cc2b290bf467b4c31495df7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Dec 2022 00:02:53 +0100 +Subject: bpf: Resolve fext program type when checking map compatibility +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Toke Høiland-Jørgensen + +[ Upstream commit 1c123c567fb138ebd187480b7fc0610fcb0851f5 ] + +The bpf_prog_map_compatible() check makes sure that BPF program types are +not mixed inside BPF map types that can contain programs (tail call maps, +cpumaps and devmaps). It does this by setting the fields of the map->owner +struct to the values of the first program being checked against, and +rejecting any subsequent programs if the values don't match. + +One of the values being set in the map owner struct is the program type, +and since the code did not resolve the prog type for fext programs, the map +owner type would be set to PROG_TYPE_EXT and subsequent loading of programs +of the target type into the map would fail. + +This bug is seen in particular for XDP programs that are loaded as +PROG_TYPE_EXT using libxdp; these cannot insert programs into devmaps and +cpumaps because the check fails as described above. + +Fix the bug by resolving the fext program type to its target program type +as elsewhere in the verifier. + +v3: +- Add Yonghong's ACK + +Fixes: f45d5b6ce2e8 ("bpf: generalise tail call map compatibility check") +Acked-by: Yonghong Song +Signed-off-by: Toke Høiland-Jørgensen +Link: https://lore.kernel.org/r/20221214230254.790066-1-toke@redhat.com +Signed-off-by: Martin KaFai Lau +Signed-off-by: Sasha Levin +--- + kernel/bpf/core.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c +index c4600a5781de..7d315c94b80a 100644 +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -2088,6 +2088,7 @@ static unsigned int __bpf_prog_ret0_warn(const void *ctx, + bool bpf_prog_map_compatible(struct bpf_map *map, + const struct bpf_prog *fp) + { ++ enum bpf_prog_type prog_type = resolve_prog_type(fp); + bool ret; + + if (fp->kprobe_override) +@@ -2098,12 +2099,12 @@ bool bpf_prog_map_compatible(struct bpf_map *map, + /* There's no owner yet where we could check for + * compatibility. + */ +- map->owner.type = fp->type; ++ map->owner.type = prog_type; + map->owner.jited = fp->jited; + map->owner.xdp_has_frags = fp->aux->xdp_has_frags; + ret = true; + } else { +- ret = map->owner.type == fp->type && ++ ret = map->owner.type == prog_type && + map->owner.jited == fp->jited && + map->owner.xdp_has_frags == fp->aux->xdp_has_frags; + } +-- +2.35.1 + diff --git a/queue-6.0/bpf-sockmap-fix-data-loss-caused-by-using-apply_byte.patch b/queue-6.0/bpf-sockmap-fix-data-loss-caused-by-using-apply_byte.patch new file mode 100644 index 00000000000..05befe3e9a5 --- /dev/null +++ b/queue-6.0/bpf-sockmap-fix-data-loss-caused-by-using-apply_byte.patch @@ -0,0 +1,47 @@ +From 66f35310cd4f9705392e19fa3513077f23052153 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Nov 2022 18:40:40 +0800 +Subject: bpf, sockmap: Fix data loss caused by using apply_bytes on ingress + redirect + +From: Pengcheng Yang + +[ Upstream commit 9072931f020bfd907d6d89ee21ff1481cd78b407 ] + +Use apply_bytes on ingress redirect, when apply_bytes is less than +the length of msg data, some data may be skipped and lost in +bpf_tcp_ingress(). + +If there is still data in the scatterlist that has not been consumed, +we cannot move the msg iter. + +Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface") +Signed-off-by: Pengcheng Yang +Signed-off-by: Daniel Borkmann +Acked-by: Jakub Sitnicki +Link: https://lore.kernel.org/bpf/1669718441-2654-4-git-send-email-yangpc@wangsu.com +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp_bpf.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c +index 275c5ca9e04d..94aad3870c5f 100644 +--- a/net/ipv4/tcp_bpf.c ++++ b/net/ipv4/tcp_bpf.c +@@ -45,8 +45,11 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock, + tmp->sg.end = i; + if (apply) { + apply_bytes -= size; +- if (!apply_bytes) ++ if (!apply_bytes) { ++ if (sge->length) ++ sk_msg_iter_var_prev(i); + break; ++ } + } + } while (i != msg->sg.end); + +-- +2.35.1 + diff --git a/queue-6.0/bpf-sockmap-fix-missing-bpf_f_ingress-flag-when-usin.patch b/queue-6.0/bpf-sockmap-fix-missing-bpf_f_ingress-flag-when-usin.patch new file mode 100644 index 00000000000..2dc9adb7ea2 --- /dev/null +++ b/queue-6.0/bpf-sockmap-fix-missing-bpf_f_ingress-flag-when-usin.patch @@ -0,0 +1,161 @@ +From dcaff90f556d2d9e0f822480f31d3a54a917202a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Nov 2022 18:40:39 +0800 +Subject: bpf, sockmap: Fix missing BPF_F_INGRESS flag when using apply_bytes + +From: Pengcheng Yang + +[ Upstream commit a351d6087bf7d3d8440d58d3bf244ec64b89394a ] + +When redirecting, we use sk_msg_to_ingress() to get the BPF_F_INGRESS +flag from the msg->flags. If apply_bytes is used and it is larger than +the current data being processed, sk_psock_msg_verdict() will not be +called when sendmsg() is called again. At this time, the msg->flags is 0, +and we lost the BPF_F_INGRESS flag. + +So we need to save the BPF_F_INGRESS flag in sk_psock and use it when +redirection. + +Fixes: 8934ce2fd081 ("bpf: sockmap redirect ingress support") +Signed-off-by: Pengcheng Yang +Signed-off-by: Daniel Borkmann +Acked-by: Jakub Sitnicki +Link: https://lore.kernel.org/bpf/1669718441-2654-3-git-send-email-yangpc@wangsu.com +Signed-off-by: Sasha Levin +--- + include/linux/skmsg.h | 1 + + include/net/tcp.h | 4 ++-- + net/core/skmsg.c | 9 ++++++--- + net/ipv4/tcp_bpf.c | 11 ++++++----- + net/tls/tls_sw.c | 6 ++++-- + 5 files changed, 19 insertions(+), 12 deletions(-) + +diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h +index 70d6cb94e580..84f787416a54 100644 +--- a/include/linux/skmsg.h ++++ b/include/linux/skmsg.h +@@ -82,6 +82,7 @@ struct sk_psock { + u32 apply_bytes; + u32 cork_bytes; + u32 eval; ++ bool redir_ingress; /* undefined if sk_redir is null */ + struct sk_msg *cork; + struct sk_psock_progs progs; + #if IS_ENABLED(CONFIG_BPF_STREAM_PARSER) +diff --git a/include/net/tcp.h b/include/net/tcp.h +index 95c1d51393ac..3cde7b4a401f 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -2284,8 +2284,8 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore); + void tcp_bpf_clone(const struct sock *sk, struct sock *newsk); + #endif /* CONFIG_BPF_SYSCALL */ + +-int tcp_bpf_sendmsg_redir(struct sock *sk, struct sk_msg *msg, u32 bytes, +- int flags); ++int tcp_bpf_sendmsg_redir(struct sock *sk, bool ingress, ++ struct sk_msg *msg, u32 bytes, int flags); + #endif /* CONFIG_NET_SOCK_MSG */ + + #if !defined(CONFIG_BPF_SYSCALL) || !defined(CONFIG_NET_SOCK_MSG) +diff --git a/net/core/skmsg.c b/net/core/skmsg.c +index e6b9ced3eda8..53d0251788aa 100644 +--- a/net/core/skmsg.c ++++ b/net/core/skmsg.c +@@ -886,13 +886,16 @@ int sk_psock_msg_verdict(struct sock *sk, struct sk_psock *psock, + ret = sk_psock_map_verd(ret, msg->sk_redir); + psock->apply_bytes = msg->apply_bytes; + if (ret == __SK_REDIRECT) { +- if (psock->sk_redir) ++ if (psock->sk_redir) { + sock_put(psock->sk_redir); +- psock->sk_redir = msg->sk_redir; +- if (!psock->sk_redir) { ++ psock->sk_redir = NULL; ++ } ++ if (!msg->sk_redir) { + ret = __SK_DROP; + goto out; + } ++ psock->redir_ingress = sk_msg_to_ingress(msg); ++ psock->sk_redir = msg->sk_redir; + sock_hold(psock->sk_redir); + } + out: +diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c +index f3e868f4cd9e..275c5ca9e04d 100644 +--- a/net/ipv4/tcp_bpf.c ++++ b/net/ipv4/tcp_bpf.c +@@ -131,10 +131,9 @@ static int tcp_bpf_push_locked(struct sock *sk, struct sk_msg *msg, + return ret; + } + +-int tcp_bpf_sendmsg_redir(struct sock *sk, struct sk_msg *msg, +- u32 bytes, int flags) ++int tcp_bpf_sendmsg_redir(struct sock *sk, bool ingress, ++ struct sk_msg *msg, u32 bytes, int flags) + { +- bool ingress = sk_msg_to_ingress(msg); + struct sk_psock *psock = sk_psock_get(sk); + int ret; + +@@ -276,7 +275,7 @@ static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, + static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock, + struct sk_msg *msg, int *copied, int flags) + { +- bool cork = false, enospc = sk_msg_full(msg); ++ bool cork = false, enospc = sk_msg_full(msg), redir_ingress; + struct sock *sk_redir; + u32 tosend, origsize, sent, delta = 0; + u32 eval; +@@ -322,6 +321,7 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock, + sk_msg_apply_bytes(psock, tosend); + break; + case __SK_REDIRECT: ++ redir_ingress = psock->redir_ingress; + sk_redir = psock->sk_redir; + sk_msg_apply_bytes(psock, tosend); + if (!psock->apply_bytes) { +@@ -338,7 +338,8 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock, + release_sock(sk); + + origsize = msg->sg.size; +- ret = tcp_bpf_sendmsg_redir(sk_redir, msg, tosend, flags); ++ ret = tcp_bpf_sendmsg_redir(sk_redir, redir_ingress, ++ msg, tosend, flags); + sent = origsize - msg->sg.size; + + if (eval == __SK_REDIRECT) +diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c +index fe27241cd13f..0ee1df154fee 100644 +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -792,7 +792,7 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk, + struct sk_psock *psock; + struct sock *sk_redir; + struct tls_rec *rec; +- bool enospc, policy; ++ bool enospc, policy, redir_ingress; + int err = 0, send; + u32 delta = 0; + +@@ -837,6 +837,7 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk, + } + break; + case __SK_REDIRECT: ++ redir_ingress = psock->redir_ingress; + sk_redir = psock->sk_redir; + memcpy(&msg_redir, msg, sizeof(*msg)); + if (msg->apply_bytes < send) +@@ -846,7 +847,8 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk, + sk_msg_return_zero(sk, msg, send); + msg->sg.size -= send; + release_sock(sk); +- err = tcp_bpf_sendmsg_redir(sk_redir, &msg_redir, send, flags); ++ err = tcp_bpf_sendmsg_redir(sk_redir, redir_ingress, ++ &msg_redir, send, flags); + lock_sock(sk); + if (err < 0) { + *copied -= sk_msg_free_nocharge(sk, &msg_redir); +-- +2.35.1 + diff --git a/queue-6.0/bpf-sockmap-fix-race-in-sock_map_free.patch b/queue-6.0/bpf-sockmap-fix-race-in-sock_map_free.patch new file mode 100644 index 00000000000..c085224dd91 --- /dev/null +++ b/queue-6.0/bpf-sockmap-fix-race-in-sock_map_free.patch @@ -0,0 +1,87 @@ +From cd4733f78200ce4dd04011b838c3ecb4974efde1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Dec 2022 11:16:40 +0000 +Subject: bpf, sockmap: fix race in sock_map_free() + +From: Eric Dumazet + +[ Upstream commit 0a182f8d607464911756b4dbef5d6cad8de22469 ] + +sock_map_free() calls release_sock(sk) without owning a reference +on the socket. This can cause use-after-free as syzbot found [1] + +Jakub Sitnicki already took care of a similar issue +in sock_hash_free() in commit 75e68e5bf2c7 ("bpf, sockhash: +Synchronize delete from bucket list on map free") + +[1] +refcount_t: decrement hit 0; leaking memory. +WARNING: CPU: 0 PID: 3785 at lib/refcount.c:31 refcount_warn_saturate+0x17c/0x1a0 lib/refcount.c:31 +Modules linked in: +CPU: 0 PID: 3785 Comm: kworker/u4:6 Not tainted 6.1.0-rc7-syzkaller-00103-gef4d3ea40565 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 +Workqueue: events_unbound bpf_map_free_deferred +RIP: 0010:refcount_warn_saturate+0x17c/0x1a0 lib/refcount.c:31 +Code: 68 8b 31 c0 e8 75 71 15 fd 0f 0b e9 64 ff ff ff e8 d9 6e 4e fd c6 05 62 9c 3d 0a 01 48 c7 c7 80 bb 68 8b 31 c0 e8 54 71 15 fd <0f> 0b e9 43 ff ff ff 89 d9 80 e1 07 80 c1 03 38 c1 0f 8c a2 fe ff +RSP: 0018:ffffc9000456fb60 EFLAGS: 00010246 +RAX: eae59bab72dcd700 RBX: 0000000000000004 RCX: ffff8880207057c0 +RDX: 0000000000000000 RSI: 0000000000000201 RDI: 0000000000000000 +RBP: 0000000000000004 R08: ffffffff816fdabd R09: fffff520008adee5 +R10: fffff520008adee5 R11: 1ffff920008adee4 R12: 0000000000000004 +R13: dffffc0000000000 R14: ffff88807b1c6c00 R15: 1ffff1100f638dcf +FS: 0000000000000000(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000001b30c30000 CR3: 000000000d08e000 CR4: 00000000003506f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + +__refcount_dec include/linux/refcount.h:344 [inline] +refcount_dec include/linux/refcount.h:359 [inline] +__sock_put include/net/sock.h:779 [inline] +tcp_release_cb+0x2d0/0x360 net/ipv4/tcp_output.c:1092 +release_sock+0xaf/0x1c0 net/core/sock.c:3468 +sock_map_free+0x219/0x2c0 net/core/sock_map.c:356 +process_one_work+0x81c/0xd10 kernel/workqueue.c:2289 +worker_thread+0xb14/0x1330 kernel/workqueue.c:2436 +kthread+0x266/0x300 kernel/kthread.c:376 +ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:306 + + +Fixes: 7e81a3530206 ("bpf: Sockmap, ensure sock lock held during tear down") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Cc: Jakub Sitnicki +Cc: John Fastabend +Cc: Alexei Starovoitov +Cc: Daniel Borkmann +Cc: Song Liu +Acked-by: John Fastabend +Link: https://lore.kernel.org/r/20221202111640.2745533-1-edumazet@google.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + net/core/sock_map.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/core/sock_map.c b/net/core/sock_map.c +index 632df0c52562..bfc300103212 100644 +--- a/net/core/sock_map.c ++++ b/net/core/sock_map.c +@@ -349,11 +349,13 @@ static void sock_map_free(struct bpf_map *map) + + sk = xchg(psk, NULL); + if (sk) { ++ sock_hold(sk); + lock_sock(sk); + rcu_read_lock(); + sock_map_unref(sk, psk); + rcu_read_unlock(); + release_sock(sk); ++ sock_put(sk); + } + } + +-- +2.35.1 + diff --git a/queue-6.0/bpf-sockmap-fix-repeated-calls-to-sock_put-when-msg-.patch b/queue-6.0/bpf-sockmap-fix-repeated-calls-to-sock_put-when-msg-.patch new file mode 100644 index 00000000000..d633faf9790 --- /dev/null +++ b/queue-6.0/bpf-sockmap-fix-repeated-calls-to-sock_put-when-msg-.patch @@ -0,0 +1,80 @@ +From 9eaa2b8505efa8ba757f6db31a97aaf9c94cb0ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Nov 2022 18:40:38 +0800 +Subject: bpf, sockmap: Fix repeated calls to sock_put() when msg has more_data + +From: Pengcheng Yang + +[ Upstream commit 7a9841ca025275b5b0edfb0b618934abb6ceec15 ] + +In tcp_bpf_send_verdict() redirection, the eval variable is assigned to +__SK_REDIRECT after the apply_bytes data is sent, if msg has more_data, +sock_put() will be called multiple times. + +We should reset the eval variable to __SK_NONE every time more_data +starts. + +This causes: + +IPv4: Attempt to release TCP socket in state 1 00000000b4c925d7 +------------[ cut here ]------------ +refcount_t: addition on 0; use-after-free. +WARNING: CPU: 5 PID: 4482 at lib/refcount.c:25 refcount_warn_saturate+0x7d/0x110 +Modules linked in: +CPU: 5 PID: 4482 Comm: sockhash_bypass Kdump: loaded Not tainted 6.0.0 #1 +Hardware name: Red Hat KVM, BIOS 1.11.0-2.el7 04/01/2014 +Call Trace: + + __tcp_transmit_skb+0xa1b/0xb90 + ? __alloc_skb+0x8c/0x1a0 + ? __kmalloc_node_track_caller+0x184/0x320 + tcp_write_xmit+0x22a/0x1110 + __tcp_push_pending_frames+0x32/0xf0 + do_tcp_sendpages+0x62d/0x640 + tcp_bpf_push+0xae/0x2c0 + tcp_bpf_sendmsg_redir+0x260/0x410 + ? preempt_count_add+0x70/0xa0 + tcp_bpf_send_verdict+0x386/0x4b0 + tcp_bpf_sendmsg+0x21b/0x3b0 + sock_sendmsg+0x58/0x70 + __sys_sendto+0xfa/0x170 + ? xfd_validate_state+0x1d/0x80 + ? switch_fpu_return+0x59/0xe0 + __x64_sys_sendto+0x24/0x30 + do_syscall_64+0x37/0x90 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Fixes: cd9733f5d75c ("tcp_bpf: Fix one concurrency problem in the tcp_bpf_send_verdict function") +Signed-off-by: Pengcheng Yang +Signed-off-by: Daniel Borkmann +Acked-by: Jakub Sitnicki +Link: https://lore.kernel.org/bpf/1669718441-2654-2-git-send-email-yangpc@wangsu.com +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp_bpf.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c +index cf9c3e8f7ccb..f3e868f4cd9e 100644 +--- a/net/ipv4/tcp_bpf.c ++++ b/net/ipv4/tcp_bpf.c +@@ -279,7 +279,7 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock, + bool cork = false, enospc = sk_msg_full(msg); + struct sock *sk_redir; + u32 tosend, origsize, sent, delta = 0; +- u32 eval = __SK_NONE; ++ u32 eval; + int ret; + + more_data: +@@ -310,6 +310,7 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock, + tosend = msg->sg.size; + if (psock->apply_bytes && psock->apply_bytes < tosend) + tosend = psock->apply_bytes; ++ eval = __SK_NONE; + + switch (psock->eval) { + case __SK_PASS: +-- +2.35.1 + diff --git a/queue-6.0/bpftool-fix-memory-leak-in-do_build_table_cb.patch b/queue-6.0/bpftool-fix-memory-leak-in-do_build_table_cb.patch new file mode 100644 index 00000000000..5b3f27acaf0 --- /dev/null +++ b/queue-6.0/bpftool-fix-memory-leak-in-do_build_table_cb.patch @@ -0,0 +1,36 @@ +From 7c6a99583a4fd9b6bcf060a62e02760f5363d5f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Dec 2022 11:19:06 +0400 +Subject: bpftool: Fix memory leak in do_build_table_cb + +From: Miaoqian Lin + +[ Upstream commit fa55ef14ef4fe06198c0ce811b603aec24134bc2 ] + +strdup() allocates memory for path. We need to release the memory in the +following error path. Add free() to avoid memory leak. + +Fixes: 8f184732b60b ("bpftool: Switch to libbpf's hashmap for pinned paths of BPF objects") +Signed-off-by: Miaoqian Lin +Signed-off-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/20221206071906.806384-1-linmq006@gmail.com +Signed-off-by: Sasha Levin +--- + tools/bpf/bpftool/common.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c +index 3bdbc0ce75b1..e54487e4005d 100644 +--- a/tools/bpf/bpftool/common.c ++++ b/tools/bpf/bpftool/common.c +@@ -499,6 +499,7 @@ static int do_build_table_cb(const char *fpath, const struct stat *sb, + if (err) { + p_err("failed to append entry to hashmap for ID %u, path '%s': %s", + pinned_info.id, path, strerror(errno)); ++ free(path); + goto out_close; + } + +-- +2.35.1 + diff --git a/queue-6.0/brcmfmac-return-error-when-getting-invalid-max_flowr.patch b/queue-6.0/brcmfmac-return-error-when-getting-invalid-max_flowr.patch new file mode 100644 index 00000000000..66adaf27af2 --- /dev/null +++ b/queue-6.0/brcmfmac-return-error-when-getting-invalid-max_flowr.patch @@ -0,0 +1,43 @@ +From 14c059eb4ac26adb8063bf1503a688d5977c49c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 28 Sep 2022 22:10:00 -0500 +Subject: brcmfmac: return error when getting invalid max_flowrings from dongle + +From: Wright Feng + +[ Upstream commit 2aca4f3734bd717e04943ddf340d49ab62299a00 ] + +When firmware hit trap at initialization, host will read abnormal +max_flowrings number from dongle, and it will cause kernel panic when +doing iowrite to initialize dongle ring. +To detect this error at early stage, we directly return error when getting +invalid max_flowrings(>256). + +Signed-off-by: Wright Feng +Signed-off-by: Chi-hsien Lin +Signed-off-by: Ian Lin +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20220929031001.9962-3-ian.lin@infineon.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +index 7fc8d47f2281..5b1813c02411 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -1120,6 +1120,10 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo) + BRCMF_NROF_H2D_COMMON_MSGRINGS; + max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS; + } ++ if (max_flowrings > 256) { ++ brcmf_err(bus, "invalid max_flowrings(%d)\n", max_flowrings); ++ return -EIO; ++ } + + if (devinfo->dma_idx_sz != 0) { + bufsz = (max_submissionrings + max_completionrings) * +-- +2.35.1 + diff --git a/queue-6.0/can-kvaser_usb-add-struct-kvaser_usb_busparams.patch b/queue-6.0/can-kvaser_usb-add-struct-kvaser_usb_busparams.patch new file mode 100644 index 00000000000..92f4b43e364 --- /dev/null +++ b/queue-6.0/can-kvaser_usb-add-struct-kvaser_usb_busparams.patch @@ -0,0 +1,143 @@ +From 372d0cbb507eb97a8950611ec3e9ac6a3a409475 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 20:52:36 +0200 +Subject: can: kvaser_usb: Add struct kvaser_usb_busparams + +From: Jimmy Assarsson + +[ Upstream commit 00e5786177649c1e3110f9454fdd34e336597265 ] + +Add struct kvaser_usb_busparams containing the busparameters used in +CMD_{SET,GET}_BUSPARAMS* commands. + +Tested-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010185237.319219-11-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Stable-dep-of: 39d3df6b0ea8 ("can: kvaser_usb: Compare requested bittiming parameters with actual parameters in do_set_{,data}_bittiming") +Signed-off-by: Sasha Levin +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 8 +++++ + .../net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 32 +++++++------------ + .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 18 ++++------- + 3 files changed, 27 insertions(+), 31 deletions(-) + +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +index d9c5dd5da908..778b61c90c2b 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +@@ -76,6 +76,14 @@ struct kvaser_usb_tx_urb_context { + u32 echo_index; + }; + ++struct kvaser_usb_busparams { ++ __le32 bitrate; ++ u8 tseg1; ++ u8 tseg2; ++ u8 sjw; ++ u8 nsamples; ++} __packed; ++ + struct kvaser_usb { + struct usb_device *udev; + struct usb_interface *intf; +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +index 3abfaa77e893..b8ae29872217 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +@@ -196,17 +196,9 @@ struct kvaser_cmd_chip_state_event { + #define KVASER_USB_HYDRA_BUS_MODE_CANFD_ISO 0x01 + #define KVASER_USB_HYDRA_BUS_MODE_NONISO 0x02 + struct kvaser_cmd_set_busparams { +- __le32 bitrate; +- u8 tseg1; +- u8 tseg2; +- u8 sjw; +- u8 nsamples; ++ struct kvaser_usb_busparams busparams_arb; + u8 reserved0[4]; +- __le32 bitrate_d; +- u8 tseg1_d; +- u8 tseg2_d; +- u8 sjw_d; +- u8 nsamples_d; ++ struct kvaser_usb_busparams busparams_data; + u8 canfd_mode; + u8 reserved1[7]; + } __packed; +@@ -1538,11 +1530,11 @@ static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev) + return -ENOMEM; + + cmd->header.cmd_no = CMD_SET_BUSPARAMS_REQ; +- cmd->set_busparams_req.bitrate = cpu_to_le32(bt->bitrate); +- cmd->set_busparams_req.sjw = (u8)sjw; +- cmd->set_busparams_req.tseg1 = (u8)tseg1; +- cmd->set_busparams_req.tseg2 = (u8)tseg2; +- cmd->set_busparams_req.nsamples = 1; ++ cmd->set_busparams_req.busparams_arb.bitrate = cpu_to_le32(bt->bitrate); ++ cmd->set_busparams_req.busparams_arb.sjw = (u8)sjw; ++ cmd->set_busparams_req.busparams_arb.tseg1 = (u8)tseg1; ++ cmd->set_busparams_req.busparams_arb.tseg2 = (u8)tseg2; ++ cmd->set_busparams_req.busparams_arb.nsamples = 1; + + kvaser_usb_hydra_set_cmd_dest_he + (cmd, dev->card_data.hydra.channel_to_he[priv->channel]); +@@ -1572,11 +1564,11 @@ static int kvaser_usb_hydra_set_data_bittiming(struct net_device *netdev) + return -ENOMEM; + + cmd->header.cmd_no = CMD_SET_BUSPARAMS_FD_REQ; +- cmd->set_busparams_req.bitrate_d = cpu_to_le32(dbt->bitrate); +- cmd->set_busparams_req.sjw_d = (u8)sjw; +- cmd->set_busparams_req.tseg1_d = (u8)tseg1; +- cmd->set_busparams_req.tseg2_d = (u8)tseg2; +- cmd->set_busparams_req.nsamples_d = 1; ++ cmd->set_busparams_req.busparams_data.bitrate = cpu_to_le32(dbt->bitrate); ++ cmd->set_busparams_req.busparams_data.sjw = (u8)sjw; ++ cmd->set_busparams_req.busparams_data.tseg1 = (u8)tseg1; ++ cmd->set_busparams_req.busparams_data.tseg2 = (u8)tseg2; ++ cmd->set_busparams_req.busparams_data.nsamples = 1; + + if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { + if (priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +index fa940be4e1b0..996d58b97af1 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -164,11 +164,7 @@ struct usbcan_cmd_softinfo { + struct kvaser_cmd_busparams { + u8 tid; + u8 channel; +- __le32 bitrate; +- u8 tseg1; +- u8 tseg2; +- u8 sjw; +- u8 no_samp; ++ struct kvaser_usb_busparams busparams; + } __packed; + + struct kvaser_cmd_tx_can { +@@ -1699,15 +1695,15 @@ static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev) + cmd->len = CMD_HEADER_LEN + sizeof(struct kvaser_cmd_busparams); + cmd->u.busparams.channel = priv->channel; + cmd->u.busparams.tid = 0xff; +- cmd->u.busparams.bitrate = cpu_to_le32(bt->bitrate); +- cmd->u.busparams.sjw = bt->sjw; +- cmd->u.busparams.tseg1 = bt->prop_seg + bt->phase_seg1; +- cmd->u.busparams.tseg2 = bt->phase_seg2; ++ cmd->u.busparams.busparams.bitrate = cpu_to_le32(bt->bitrate); ++ cmd->u.busparams.busparams.sjw = bt->sjw; ++ cmd->u.busparams.busparams.tseg1 = bt->prop_seg + bt->phase_seg1; ++ cmd->u.busparams.busparams.tseg2 = bt->phase_seg2; + + if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) +- cmd->u.busparams.no_samp = 3; ++ cmd->u.busparams.busparams.nsamples = 3; + else +- cmd->u.busparams.no_samp = 1; ++ cmd->u.busparams.busparams.nsamples = 1; + + rc = kvaser_usb_send_cmd(dev, cmd, cmd->len); + +-- +2.35.1 + diff --git a/queue-6.0/can-kvaser_usb-compare-requested-bittiming-parameter.patch b/queue-6.0/can-kvaser_usb-compare-requested-bittiming-parameter.patch new file mode 100644 index 00000000000..0e3d1f91198 --- /dev/null +++ b/queue-6.0/can-kvaser_usb-compare-requested-bittiming-parameter.patch @@ -0,0 +1,598 @@ +From 5a576806939506527fd89cab558908e1f89fdf0d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 20:52:37 +0200 +Subject: can: kvaser_usb: Compare requested bittiming parameters with actual + parameters in do_set_{,data}_bittiming + +From: Jimmy Assarsson + +[ Upstream commit 39d3df6b0ea80f9b515c632ca07b39b1c156edee ] + +The device will respond with a CMD_ERROR_EVENT command, with error_code +KVASER_USB_{LEAF,HYDRA}_ERROR_EVENT_PARAM, if the CMD_SET_BUSPARAMS_REQ +contains invalid bittiming parameters. +However, this command does not contain any channel reference. + +To check if the CMD_SET_BUSPARAMS_REQ was successful, redback and compare +the requested bittiming parameters with the device reported parameters. + +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Fixes: aec5fb2268b7 ("can: kvaser_usb: Add support for Kvaser USB hydra family") +Tested-by: Anssi Hannula +Co-developed-by: Anssi Hannula +Signed-off-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010185237.319219-12-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 15 +- + .../net/can/usb/kvaser_usb/kvaser_usb_core.c | 96 ++++++++++- + .../net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 150 +++++++++++++++--- + .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 64 ++++++-- + 4 files changed, 284 insertions(+), 41 deletions(-) + +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +index 778b61c90c2b..ff10b3790d84 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +@@ -119,9 +119,12 @@ struct kvaser_usb_net_priv { + struct net_device *netdev; + int channel; + +- struct completion start_comp, stop_comp, flush_comp; ++ struct completion start_comp, stop_comp, flush_comp, ++ get_busparams_comp; + struct usb_anchor tx_submitted; + ++ struct kvaser_usb_busparams busparams_nominal, busparams_data; ++ + spinlock_t tx_contexts_lock; /* lock for active_tx_contexts */ + int active_tx_contexts; + struct kvaser_usb_tx_urb_context tx_contexts[]; +@@ -131,7 +134,9 @@ struct kvaser_usb_net_priv { + * struct kvaser_usb_dev_ops - Device specific functions + * @dev_set_mode: used for can.do_set_mode + * @dev_set_bittiming: used for can.do_set_bittiming ++ * @dev_get_busparams: readback arbitration busparams + * @dev_set_data_bittiming: used for can.do_set_data_bittiming ++ * @dev_get_data_busparams: readback data busparams + * @dev_get_berr_counter: used for can.do_get_berr_counter + * + * @dev_setup_endpoints: setup USB in and out endpoints +@@ -153,8 +158,12 @@ struct kvaser_usb_net_priv { + */ + struct kvaser_usb_dev_ops { + int (*dev_set_mode)(struct net_device *netdev, enum can_mode mode); +- int (*dev_set_bittiming)(struct net_device *netdev); +- int (*dev_set_data_bittiming)(struct net_device *netdev); ++ int (*dev_set_bittiming)(const struct net_device *netdev, ++ const struct kvaser_usb_busparams *busparams); ++ int (*dev_get_busparams)(struct kvaser_usb_net_priv *priv); ++ int (*dev_set_data_bittiming)(const struct net_device *netdev, ++ const struct kvaser_usb_busparams *busparams); ++ int (*dev_get_data_busparams)(struct kvaser_usb_net_priv *priv); + int (*dev_get_berr_counter)(const struct net_device *netdev, + struct can_berr_counter *bec); + int (*dev_setup_endpoints)(struct kvaser_usb *dev); +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +index 0ebdfb77c50f..3a2bfaad1406 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +@@ -440,10 +440,6 @@ static int kvaser_usb_open(struct net_device *netdev) + if (err) + return err; + +- err = kvaser_usb_setup_rx_urbs(dev); +- if (err) +- goto error; +- + err = ops->dev_set_opt_mode(priv); + if (err) + goto error; +@@ -534,6 +530,93 @@ static int kvaser_usb_close(struct net_device *netdev) + return 0; + } + ++static int kvaser_usb_set_bittiming(struct net_device *netdev) ++{ ++ struct kvaser_usb_net_priv *priv = netdev_priv(netdev); ++ struct kvaser_usb *dev = priv->dev; ++ const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; ++ struct can_bittiming *bt = &priv->can.bittiming; ++ ++ struct kvaser_usb_busparams busparams; ++ int tseg1 = bt->prop_seg + bt->phase_seg1; ++ int tseg2 = bt->phase_seg2; ++ int sjw = bt->sjw; ++ int err = -EOPNOTSUPP; ++ ++ busparams.bitrate = cpu_to_le32(bt->bitrate); ++ busparams.sjw = (u8)sjw; ++ busparams.tseg1 = (u8)tseg1; ++ busparams.tseg2 = (u8)tseg2; ++ if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ++ busparams.nsamples = 3; ++ else ++ busparams.nsamples = 1; ++ ++ err = ops->dev_set_bittiming(netdev, &busparams); ++ if (err) ++ return err; ++ ++ err = kvaser_usb_setup_rx_urbs(priv->dev); ++ if (err) ++ return err; ++ ++ err = ops->dev_get_busparams(priv); ++ if (err) { ++ /* Treat EOPNOTSUPP as success */ ++ if (err == -EOPNOTSUPP) ++ err = 0; ++ return err; ++ } ++ ++ if (memcmp(&busparams, &priv->busparams_nominal, ++ sizeof(priv->busparams_nominal)) != 0) ++ err = -EINVAL; ++ ++ return err; ++} ++ ++static int kvaser_usb_set_data_bittiming(struct net_device *netdev) ++{ ++ struct kvaser_usb_net_priv *priv = netdev_priv(netdev); ++ struct kvaser_usb *dev = priv->dev; ++ const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; ++ struct can_bittiming *dbt = &priv->can.data_bittiming; ++ ++ struct kvaser_usb_busparams busparams; ++ int tseg1 = dbt->prop_seg + dbt->phase_seg1; ++ int tseg2 = dbt->phase_seg2; ++ int sjw = dbt->sjw; ++ int err; ++ ++ if (!ops->dev_set_data_bittiming || ++ !ops->dev_get_data_busparams) ++ return -EOPNOTSUPP; ++ ++ busparams.bitrate = cpu_to_le32(dbt->bitrate); ++ busparams.sjw = (u8)sjw; ++ busparams.tseg1 = (u8)tseg1; ++ busparams.tseg2 = (u8)tseg2; ++ busparams.nsamples = 1; ++ ++ err = ops->dev_set_data_bittiming(netdev, &busparams); ++ if (err) ++ return err; ++ ++ err = kvaser_usb_setup_rx_urbs(priv->dev); ++ if (err) ++ return err; ++ ++ err = ops->dev_get_data_busparams(priv); ++ if (err) ++ return err; ++ ++ if (memcmp(&busparams, &priv->busparams_data, ++ sizeof(priv->busparams_data)) != 0) ++ err = -EINVAL; ++ ++ return err; ++} ++ + static void kvaser_usb_write_bulk_callback(struct urb *urb) + { + struct kvaser_usb_tx_urb_context *context = urb->context; +@@ -734,6 +817,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel) + init_completion(&priv->start_comp); + init_completion(&priv->stop_comp); + init_completion(&priv->flush_comp); ++ init_completion(&priv->get_busparams_comp); + priv->can.ctrlmode_supported = 0; + + priv->dev = dev; +@@ -746,7 +830,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel) + priv->can.state = CAN_STATE_STOPPED; + priv->can.clock.freq = dev->cfg->clock.freq; + priv->can.bittiming_const = dev->cfg->bittiming_const; +- priv->can.do_set_bittiming = ops->dev_set_bittiming; ++ priv->can.do_set_bittiming = kvaser_usb_set_bittiming; + priv->can.do_set_mode = ops->dev_set_mode; + if ((driver_info->quirks & KVASER_USB_QUIRK_HAS_TXRX_ERRORS) || + (priv->dev->card_data.capabilities & KVASER_USB_CAP_BERR_CAP)) +@@ -758,7 +842,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel) + + if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) { + priv->can.data_bittiming_const = dev->cfg->data_bittiming_const; +- priv->can.do_set_data_bittiming = ops->dev_set_data_bittiming; ++ priv->can.do_set_data_bittiming = kvaser_usb_set_data_bittiming; + } + + netdev->flags |= IFF_ECHO; +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +index b8ae29872217..52ef76bd9bdb 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +@@ -45,6 +45,8 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt; + + /* Minihydra command IDs */ + #define CMD_SET_BUSPARAMS_REQ 16 ++#define CMD_GET_BUSPARAMS_REQ 17 ++#define CMD_GET_BUSPARAMS_RESP 18 + #define CMD_GET_CHIP_STATE_REQ 19 + #define CMD_CHIP_STATE_EVENT 20 + #define CMD_SET_DRIVERMODE_REQ 21 +@@ -196,13 +198,26 @@ struct kvaser_cmd_chip_state_event { + #define KVASER_USB_HYDRA_BUS_MODE_CANFD_ISO 0x01 + #define KVASER_USB_HYDRA_BUS_MODE_NONISO 0x02 + struct kvaser_cmd_set_busparams { +- struct kvaser_usb_busparams busparams_arb; ++ struct kvaser_usb_busparams busparams_nominal; + u8 reserved0[4]; + struct kvaser_usb_busparams busparams_data; + u8 canfd_mode; + u8 reserved1[7]; + } __packed; + ++/* Busparam type */ ++#define KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN 0x00 ++#define KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD 0x01 ++struct kvaser_cmd_get_busparams_req { ++ u8 type; ++ u8 reserved[27]; ++} __packed; ++ ++struct kvaser_cmd_get_busparams_res { ++ struct kvaser_usb_busparams busparams; ++ u8 reserved[20]; ++} __packed; ++ + /* Ctrl modes */ + #define KVASER_USB_HYDRA_CTRLMODE_NORMAL 0x01 + #define KVASER_USB_HYDRA_CTRLMODE_LISTEN 0x02 +@@ -273,6 +288,8 @@ struct kvaser_cmd { + struct kvaser_cmd_error_event error_event; + + struct kvaser_cmd_set_busparams set_busparams_req; ++ struct kvaser_cmd_get_busparams_req get_busparams_req; ++ struct kvaser_cmd_get_busparams_res get_busparams_res; + + struct kvaser_cmd_chip_state_event chip_state_event; + +@@ -355,6 +372,10 @@ struct kvaser_cmd_ext { + } __packed; + } __packed; + ++struct kvaser_usb_net_hydra_priv { ++ int pending_get_busparams_type; ++}; ++ + static const struct can_bittiming_const kvaser_usb_hydra_kcan_bittiming_c = { + .name = "kvaser_usb_kcan", + .tseg1_min = 1, +@@ -832,6 +853,39 @@ static void kvaser_usb_hydra_flush_queue_reply(const struct kvaser_usb *dev, + complete(&priv->flush_comp); + } + ++static void kvaser_usb_hydra_get_busparams_reply(const struct kvaser_usb *dev, ++ const struct kvaser_cmd *cmd) ++{ ++ struct kvaser_usb_net_priv *priv; ++ struct kvaser_usb_net_hydra_priv *hydra; ++ ++ priv = kvaser_usb_hydra_net_priv_from_cmd(dev, cmd); ++ if (!priv) ++ return; ++ ++ hydra = priv->sub_priv; ++ if (!hydra) ++ return; ++ ++ switch (hydra->pending_get_busparams_type) { ++ case KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN: ++ memcpy(&priv->busparams_nominal, &cmd->get_busparams_res.busparams, ++ sizeof(priv->busparams_nominal)); ++ break; ++ case KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD: ++ memcpy(&priv->busparams_data, &cmd->get_busparams_res.busparams, ++ sizeof(priv->busparams_nominal)); ++ break; ++ default: ++ dev_warn(&dev->intf->dev, "Unknown get_busparams_type %d\n", ++ hydra->pending_get_busparams_type); ++ break; ++ } ++ hydra->pending_get_busparams_type = -1; ++ ++ complete(&priv->get_busparams_comp); ++} ++ + static void + kvaser_usb_hydra_bus_status_to_can_state(const struct kvaser_usb_net_priv *priv, + u8 bus_status, +@@ -1318,6 +1372,10 @@ static void kvaser_usb_hydra_handle_cmd_std(const struct kvaser_usb *dev, + kvaser_usb_hydra_state_event(dev, cmd); + break; + ++ case CMD_GET_BUSPARAMS_RESP: ++ kvaser_usb_hydra_get_busparams_reply(dev, cmd); ++ break; ++ + case CMD_ERROR_EVENT: + kvaser_usb_hydra_error_event(dev, cmd); + break; +@@ -1514,15 +1572,58 @@ static int kvaser_usb_hydra_set_mode(struct net_device *netdev, + return err; + } + +-static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev) ++static int kvaser_usb_hydra_get_busparams(struct kvaser_usb_net_priv *priv, ++ int busparams_type) ++{ ++ struct kvaser_usb *dev = priv->dev; ++ struct kvaser_usb_net_hydra_priv *hydra = priv->sub_priv; ++ struct kvaser_cmd *cmd; ++ int err; ++ ++ if (!hydra) ++ return -EINVAL; ++ ++ cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL); ++ if (!cmd) ++ return -ENOMEM; ++ ++ cmd->header.cmd_no = CMD_GET_BUSPARAMS_REQ; ++ kvaser_usb_hydra_set_cmd_dest_he ++ (cmd, dev->card_data.hydra.channel_to_he[priv->channel]); ++ kvaser_usb_hydra_set_cmd_transid ++ (cmd, kvaser_usb_hydra_get_next_transid(dev)); ++ cmd->get_busparams_req.type = busparams_type; ++ hydra->pending_get_busparams_type = busparams_type; ++ ++ reinit_completion(&priv->get_busparams_comp); ++ ++ err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd)); ++ if (err) ++ return err; ++ ++ if (!wait_for_completion_timeout(&priv->get_busparams_comp, ++ msecs_to_jiffies(KVASER_USB_TIMEOUT))) ++ return -ETIMEDOUT; ++ ++ return err; ++} ++ ++static int kvaser_usb_hydra_get_nominal_busparams(struct kvaser_usb_net_priv *priv) ++{ ++ return kvaser_usb_hydra_get_busparams(priv, KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN); ++} ++ ++static int kvaser_usb_hydra_get_data_busparams(struct kvaser_usb_net_priv *priv) ++{ ++ return kvaser_usb_hydra_get_busparams(priv, KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD); ++} ++ ++static int kvaser_usb_hydra_set_bittiming(const struct net_device *netdev, ++ const struct kvaser_usb_busparams *busparams) + { + struct kvaser_cmd *cmd; + struct kvaser_usb_net_priv *priv = netdev_priv(netdev); +- struct can_bittiming *bt = &priv->can.bittiming; + struct kvaser_usb *dev = priv->dev; +- int tseg1 = bt->prop_seg + bt->phase_seg1; +- int tseg2 = bt->phase_seg2; +- int sjw = bt->sjw; + int err; + + cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL); +@@ -1530,11 +1631,8 @@ static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev) + return -ENOMEM; + + cmd->header.cmd_no = CMD_SET_BUSPARAMS_REQ; +- cmd->set_busparams_req.busparams_arb.bitrate = cpu_to_le32(bt->bitrate); +- cmd->set_busparams_req.busparams_arb.sjw = (u8)sjw; +- cmd->set_busparams_req.busparams_arb.tseg1 = (u8)tseg1; +- cmd->set_busparams_req.busparams_arb.tseg2 = (u8)tseg2; +- cmd->set_busparams_req.busparams_arb.nsamples = 1; ++ memcpy(&cmd->set_busparams_req.busparams_nominal, busparams, ++ sizeof(cmd->set_busparams_req.busparams_nominal)); + + kvaser_usb_hydra_set_cmd_dest_he + (cmd, dev->card_data.hydra.channel_to_he[priv->channel]); +@@ -1548,15 +1646,12 @@ static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev) + return err; + } + +-static int kvaser_usb_hydra_set_data_bittiming(struct net_device *netdev) ++static int kvaser_usb_hydra_set_data_bittiming(const struct net_device *netdev, ++ const struct kvaser_usb_busparams *busparams) + { + struct kvaser_cmd *cmd; + struct kvaser_usb_net_priv *priv = netdev_priv(netdev); +- struct can_bittiming *dbt = &priv->can.data_bittiming; + struct kvaser_usb *dev = priv->dev; +- int tseg1 = dbt->prop_seg + dbt->phase_seg1; +- int tseg2 = dbt->phase_seg2; +- int sjw = dbt->sjw; + int err; + + cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL); +@@ -1564,11 +1659,8 @@ static int kvaser_usb_hydra_set_data_bittiming(struct net_device *netdev) + return -ENOMEM; + + cmd->header.cmd_no = CMD_SET_BUSPARAMS_FD_REQ; +- cmd->set_busparams_req.busparams_data.bitrate = cpu_to_le32(dbt->bitrate); +- cmd->set_busparams_req.busparams_data.sjw = (u8)sjw; +- cmd->set_busparams_req.busparams_data.tseg1 = (u8)tseg1; +- cmd->set_busparams_req.busparams_data.tseg2 = (u8)tseg2; +- cmd->set_busparams_req.busparams_data.nsamples = 1; ++ memcpy(&cmd->set_busparams_req.busparams_data, busparams, ++ sizeof(cmd->set_busparams_req.busparams_data)); + + if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { + if (priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) +@@ -1675,6 +1767,19 @@ static int kvaser_usb_hydra_init_card(struct kvaser_usb *dev) + return 0; + } + ++static int kvaser_usb_hydra_init_channel(struct kvaser_usb_net_priv *priv) ++{ ++ struct kvaser_usb_net_hydra_priv *hydra; ++ ++ hydra = devm_kzalloc(&priv->dev->intf->dev, sizeof(*hydra), GFP_KERNEL); ++ if (!hydra) ++ return -ENOMEM; ++ ++ priv->sub_priv = hydra; ++ ++ return 0; ++} ++ + static int kvaser_usb_hydra_get_software_info(struct kvaser_usb *dev) + { + struct kvaser_cmd cmd; +@@ -2019,10 +2124,13 @@ kvaser_usb_hydra_frame_to_cmd(const struct kvaser_usb_net_priv *priv, + const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops = { + .dev_set_mode = kvaser_usb_hydra_set_mode, + .dev_set_bittiming = kvaser_usb_hydra_set_bittiming, ++ .dev_get_busparams = kvaser_usb_hydra_get_nominal_busparams, + .dev_set_data_bittiming = kvaser_usb_hydra_set_data_bittiming, ++ .dev_get_data_busparams = kvaser_usb_hydra_get_data_busparams, + .dev_get_berr_counter = kvaser_usb_hydra_get_berr_counter, + .dev_setup_endpoints = kvaser_usb_hydra_setup_endpoints, + .dev_init_card = kvaser_usb_hydra_init_card, ++ .dev_init_channel = kvaser_usb_hydra_init_channel, + .dev_get_software_info = kvaser_usb_hydra_get_software_info, + .dev_get_software_details = kvaser_usb_hydra_get_software_details, + .dev_get_card_info = kvaser_usb_hydra_get_card_info, +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +index 996d58b97af1..b423fd4c7989 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -57,6 +57,8 @@ + #define CMD_RX_EXT_MESSAGE 14 + #define CMD_TX_EXT_MESSAGE 15 + #define CMD_SET_BUS_PARAMS 16 ++#define CMD_GET_BUS_PARAMS 17 ++#define CMD_GET_BUS_PARAMS_REPLY 18 + #define CMD_GET_CHIP_STATE 19 + #define CMD_CHIP_STATE_EVENT 20 + #define CMD_SET_CTRL_MODE 21 +@@ -376,6 +378,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = { + [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.leaf.chip_state_event), + [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.leaf.can_error_event), + [CMD_GET_CAPABILITIES_RESP] = kvaser_fsize(u.leaf.cap_res), ++ [CMD_GET_BUS_PARAMS_REPLY] = kvaser_fsize(u.busparams), + [CMD_ERROR_EVENT] = kvaser_fsize(u.leaf.error_event), + /* ignored events: */ + [CMD_FLUSH_QUEUE_REPLY] = CMD_SIZE_ANY, +@@ -1463,6 +1466,25 @@ static void kvaser_usb_leaf_stop_chip_reply(const struct kvaser_usb *dev, + complete(&priv->stop_comp); + } + ++static void kvaser_usb_leaf_get_busparams_reply(const struct kvaser_usb *dev, ++ const struct kvaser_cmd *cmd) ++{ ++ struct kvaser_usb_net_priv *priv; ++ u8 channel = cmd->u.busparams.channel; ++ ++ if (channel >= dev->nchannels) { ++ dev_err(&dev->intf->dev, ++ "Invalid channel number (%d)\n", channel); ++ return; ++ } ++ ++ priv = dev->nets[channel]; ++ memcpy(&priv->busparams_nominal, &cmd->u.busparams.busparams, ++ sizeof(priv->busparams_nominal)); ++ ++ complete(&priv->get_busparams_comp); ++} ++ + static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev, + const struct kvaser_cmd *cmd) + { +@@ -1505,6 +1527,10 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev, + kvaser_usb_leaf_error_event(dev, cmd); + break; + ++ case CMD_GET_BUS_PARAMS_REPLY: ++ kvaser_usb_leaf_get_busparams_reply(dev, cmd); ++ break; ++ + /* Ignored commands */ + case CMD_USBCAN_CLOCK_OVERFLOW_EVENT: + if (dev->driver_info->family != KVASER_USBCAN) +@@ -1679,10 +1705,10 @@ static void kvaser_usb_leaf_remove_channel(struct kvaser_usb_net_priv *priv) + cancel_delayed_work_sync(&leaf->chip_state_req_work); + } + +-static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev) ++static int kvaser_usb_leaf_set_bittiming(const struct net_device *netdev, ++ const struct kvaser_usb_busparams *busparams) + { + struct kvaser_usb_net_priv *priv = netdev_priv(netdev); +- struct can_bittiming *bt = &priv->can.bittiming; + struct kvaser_usb *dev = priv->dev; + struct kvaser_cmd *cmd; + int rc; +@@ -1695,15 +1721,8 @@ static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev) + cmd->len = CMD_HEADER_LEN + sizeof(struct kvaser_cmd_busparams); + cmd->u.busparams.channel = priv->channel; + cmd->u.busparams.tid = 0xff; +- cmd->u.busparams.busparams.bitrate = cpu_to_le32(bt->bitrate); +- cmd->u.busparams.busparams.sjw = bt->sjw; +- cmd->u.busparams.busparams.tseg1 = bt->prop_seg + bt->phase_seg1; +- cmd->u.busparams.busparams.tseg2 = bt->phase_seg2; +- +- if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) +- cmd->u.busparams.busparams.nsamples = 3; +- else +- cmd->u.busparams.busparams.nsamples = 1; ++ memcpy(&cmd->u.busparams.busparams, busparams, ++ sizeof(cmd->u.busparams.busparams)); + + rc = kvaser_usb_send_cmd(dev, cmd, cmd->len); + +@@ -1711,6 +1730,27 @@ static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev) + return rc; + } + ++static int kvaser_usb_leaf_get_busparams(struct kvaser_usb_net_priv *priv) ++{ ++ int err; ++ ++ if (priv->dev->driver_info->family == KVASER_USBCAN) ++ return -EOPNOTSUPP; ++ ++ reinit_completion(&priv->get_busparams_comp); ++ ++ err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_GET_BUS_PARAMS, ++ priv->channel); ++ if (err) ++ return err; ++ ++ if (!wait_for_completion_timeout(&priv->get_busparams_comp, ++ msecs_to_jiffies(KVASER_USB_TIMEOUT))) ++ return -ETIMEDOUT; ++ ++ return 0; ++} ++ + static int kvaser_usb_leaf_set_mode(struct net_device *netdev, + enum can_mode mode) + { +@@ -1772,7 +1812,9 @@ static int kvaser_usb_leaf_setup_endpoints(struct kvaser_usb *dev) + const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops = { + .dev_set_mode = kvaser_usb_leaf_set_mode, + .dev_set_bittiming = kvaser_usb_leaf_set_bittiming, ++ .dev_get_busparams = kvaser_usb_leaf_get_busparams, + .dev_set_data_bittiming = NULL, ++ .dev_get_data_busparams = NULL, + .dev_get_berr_counter = kvaser_usb_leaf_get_berr_counter, + .dev_setup_endpoints = kvaser_usb_leaf_setup_endpoints, + .dev_init_card = kvaser_usb_leaf_init_card, +-- +2.35.1 + diff --git a/queue-6.0/can-kvaser_usb-kvaser_usb_leaf-get-capabilities-from.patch b/queue-6.0/can-kvaser_usb-kvaser_usb_leaf-get-capabilities-from.patch new file mode 100644 index 00000000000..e91fdd81564 --- /dev/null +++ b/queue-6.0/can-kvaser_usb-kvaser_usb_leaf-get-capabilities-from.patch @@ -0,0 +1,231 @@ +From ea2ab31ebeffd1ae03eb9b2bdc43cc73ed0df71f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 20:52:28 +0200 +Subject: can: kvaser_usb: kvaser_usb_leaf: Get capabilities from device + +From: Jimmy Assarsson + +[ Upstream commit 35364f5b41a4917fe94a3f393d149b63ec583297 ] + +Use the CMD_GET_CAPABILITIES_REQ command to query the device for certain +capabilities. We are only interested in LISTENONLY mode and wither the +device reports CAN error counters. + +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Reported-by: Anssi Hannula +Tested-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010185237.319219-3-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 144 +++++++++++++++++- + 1 file changed, 143 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +index 19958037720f..33ff62cd1729 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -74,6 +74,8 @@ + #define CMD_TX_ACKNOWLEDGE 50 + #define CMD_CAN_ERROR_EVENT 51 + #define CMD_FLUSH_QUEUE_REPLY 68 ++#define CMD_GET_CAPABILITIES_REQ 95 ++#define CMD_GET_CAPABILITIES_RESP 96 + + #define CMD_LEAF_LOG_MESSAGE 106 + +@@ -83,6 +85,8 @@ + #define KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK BIT(5) + #define KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK BIT(6) + ++#define KVASER_USB_LEAF_SWOPTION_EXT_CAP BIT(12) ++ + /* error factors */ + #define M16C_EF_ACKE BIT(0) + #define M16C_EF_CRCE BIT(1) +@@ -278,6 +282,28 @@ struct leaf_cmd_log_message { + u8 data[8]; + } __packed; + ++/* Sub commands for cap_req and cap_res */ ++#define KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE 0x02 ++#define KVASER_USB_LEAF_CAP_CMD_ERR_REPORT 0x05 ++struct kvaser_cmd_cap_req { ++ __le16 padding0; ++ __le16 cap_cmd; ++ __le16 padding1; ++ __le16 channel; ++} __packed; ++ ++/* Status codes for cap_res */ ++#define KVASER_USB_LEAF_CAP_STAT_OK 0x00 ++#define KVASER_USB_LEAF_CAP_STAT_NOT_IMPL 0x01 ++#define KVASER_USB_LEAF_CAP_STAT_UNAVAIL 0x02 ++struct kvaser_cmd_cap_res { ++ __le16 padding; ++ __le16 cap_cmd; ++ __le16 status; ++ __le32 mask; ++ __le32 value; ++} __packed; ++ + struct kvaser_cmd { + u8 len; + u8 id; +@@ -295,6 +321,8 @@ struct kvaser_cmd { + struct leaf_cmd_chip_state_event chip_state_event; + struct leaf_cmd_error_event error_event; + struct leaf_cmd_log_message log_message; ++ struct kvaser_cmd_cap_req cap_req; ++ struct kvaser_cmd_cap_res cap_res; + } __packed leaf; + + union { +@@ -324,6 +352,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = { + [CMD_LEAF_LOG_MESSAGE] = kvaser_fsize(u.leaf.log_message), + [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.leaf.chip_state_event), + [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.leaf.error_event), ++ [CMD_GET_CAPABILITIES_RESP] = kvaser_fsize(u.leaf.cap_res), + /* ignored events: */ + [CMD_FLUSH_QUEUE_REPLY] = CMD_SIZE_ANY, + }; +@@ -606,6 +635,9 @@ static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev, + dev->fw_version = le32_to_cpu(softinfo->fw_version); + dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx); + ++ if (sw_options & KVASER_USB_LEAF_SWOPTION_EXT_CAP) ++ dev->card_data.capabilities |= KVASER_USB_CAP_EXT_CAP; ++ + if (dev->driver_info->quirks & KVASER_USB_QUIRK_IGNORE_CLK_FREQ) { + /* Firmware expects bittiming parameters calculated for 16MHz + * clock, regardless of the actual clock +@@ -693,6 +725,116 @@ static int kvaser_usb_leaf_get_card_info(struct kvaser_usb *dev) + return 0; + } + ++static int kvaser_usb_leaf_get_single_capability(struct kvaser_usb *dev, ++ u16 cap_cmd_req, u16 *status) ++{ ++ struct kvaser_usb_dev_card_data *card_data = &dev->card_data; ++ struct kvaser_cmd *cmd; ++ u32 value = 0; ++ u32 mask = 0; ++ u16 cap_cmd_res; ++ int err; ++ int i; ++ ++ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); ++ if (!cmd) ++ return -ENOMEM; ++ ++ cmd->id = CMD_GET_CAPABILITIES_REQ; ++ cmd->u.leaf.cap_req.cap_cmd = cpu_to_le16(cap_cmd_req); ++ cmd->len = CMD_HEADER_LEN + sizeof(struct kvaser_cmd_cap_req); ++ ++ err = kvaser_usb_send_cmd(dev, cmd, cmd->len); ++ if (err) ++ goto end; ++ ++ err = kvaser_usb_leaf_wait_cmd(dev, CMD_GET_CAPABILITIES_RESP, cmd); ++ if (err) ++ goto end; ++ ++ *status = le16_to_cpu(cmd->u.leaf.cap_res.status); ++ ++ if (*status != KVASER_USB_LEAF_CAP_STAT_OK) ++ goto end; ++ ++ cap_cmd_res = le16_to_cpu(cmd->u.leaf.cap_res.cap_cmd); ++ switch (cap_cmd_res) { ++ case KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE: ++ case KVASER_USB_LEAF_CAP_CMD_ERR_REPORT: ++ value = le32_to_cpu(cmd->u.leaf.cap_res.value); ++ mask = le32_to_cpu(cmd->u.leaf.cap_res.mask); ++ break; ++ default: ++ dev_warn(&dev->intf->dev, "Unknown capability command %u\n", ++ cap_cmd_res); ++ break; ++ } ++ ++ for (i = 0; i < dev->nchannels; i++) { ++ if (BIT(i) & (value & mask)) { ++ switch (cap_cmd_res) { ++ case KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE: ++ card_data->ctrlmode_supported |= ++ CAN_CTRLMODE_LISTENONLY; ++ break; ++ case KVASER_USB_LEAF_CAP_CMD_ERR_REPORT: ++ card_data->capabilities |= ++ KVASER_USB_CAP_BERR_CAP; ++ break; ++ } ++ } ++ } ++ ++end: ++ kfree(cmd); ++ ++ return err; ++} ++ ++static int kvaser_usb_leaf_get_capabilities_leaf(struct kvaser_usb *dev) ++{ ++ int err; ++ u16 status; ++ ++ if (!(dev->card_data.capabilities & KVASER_USB_CAP_EXT_CAP)) { ++ dev_info(&dev->intf->dev, ++ "No extended capability support. Upgrade device firmware.\n"); ++ return 0; ++ } ++ ++ err = kvaser_usb_leaf_get_single_capability(dev, ++ KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE, ++ &status); ++ if (err) ++ return err; ++ if (status) ++ dev_info(&dev->intf->dev, ++ "KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE failed %u\n", ++ status); ++ ++ err = kvaser_usb_leaf_get_single_capability(dev, ++ KVASER_USB_LEAF_CAP_CMD_ERR_REPORT, ++ &status); ++ if (err) ++ return err; ++ if (status) ++ dev_info(&dev->intf->dev, ++ "KVASER_USB_LEAF_CAP_CMD_ERR_REPORT failed %u\n", ++ status); ++ ++ return 0; ++} ++ ++static int kvaser_usb_leaf_get_capabilities(struct kvaser_usb *dev) ++{ ++ int err = 0; ++ ++ if (dev->driver_info->family == KVASER_LEAF) ++ err = kvaser_usb_leaf_get_capabilities_leaf(dev); ++ ++ return err; ++} ++ + static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev, + const struct kvaser_cmd *cmd) + { +@@ -1486,7 +1628,7 @@ const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops = { + .dev_get_software_info = kvaser_usb_leaf_get_software_info, + .dev_get_software_details = NULL, + .dev_get_card_info = kvaser_usb_leaf_get_card_info, +- .dev_get_capabilities = NULL, ++ .dev_get_capabilities = kvaser_usb_leaf_get_capabilities, + .dev_set_opt_mode = kvaser_usb_leaf_set_opt_mode, + .dev_start_chip = kvaser_usb_leaf_start_chip, + .dev_stop_chip = kvaser_usb_leaf_stop_chip, +-- +2.35.1 + diff --git a/queue-6.0/can-kvaser_usb-kvaser_usb_leaf-handle-cmd_error_even.patch b/queue-6.0/can-kvaser_usb-kvaser_usb_leaf-handle-cmd_error_even.patch new file mode 100644 index 00000000000..8a2eca25793 --- /dev/null +++ b/queue-6.0/can-kvaser_usb-kvaser_usb_leaf-handle-cmd_error_even.patch @@ -0,0 +1,186 @@ +From ab5472acde86866df753ae5695d8dc690024702b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 20:52:30 +0200 +Subject: can: kvaser_usb: kvaser_usb_leaf: Handle CMD_ERROR_EVENT + +From: Jimmy Assarsson + +[ Upstream commit b24cb2d169e0c9dce664a959e1f2aa9781285dc9 ] + +The device will send an error event command, to indicate certain errors. +This indicates a misbehaving driver, and should never occur. + +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Tested-by: Anssi Hannula +Co-developed-by: Anssi Hannula +Signed-off-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010185237.319219-5-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 99 +++++++++++++++++++ + 1 file changed, 99 insertions(+) + +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +index a1d4ac8d4a08..5d96ab85d04c 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -70,6 +70,7 @@ + #define CMD_GET_CARD_INFO_REPLY 35 + #define CMD_GET_SOFTWARE_INFO 38 + #define CMD_GET_SOFTWARE_INFO_REPLY 39 ++#define CMD_ERROR_EVENT 45 + #define CMD_FLUSH_QUEUE 48 + #define CMD_TX_ACKNOWLEDGE 50 + #define CMD_CAN_ERROR_EVENT 51 +@@ -258,6 +259,28 @@ struct usbcan_cmd_can_error_event { + __le16 time; + } __packed; + ++/* CMD_ERROR_EVENT error codes */ ++#define KVASER_USB_LEAF_ERROR_EVENT_TX_QUEUE_FULL 0x8 ++#define KVASER_USB_LEAF_ERROR_EVENT_PARAM 0x9 ++ ++struct leaf_cmd_error_event { ++ u8 tid; ++ u8 error_code; ++ __le16 timestamp[3]; ++ __le16 padding; ++ __le16 info1; ++ __le16 info2; ++} __packed; ++ ++struct usbcan_cmd_error_event { ++ u8 tid; ++ u8 error_code; ++ __le16 info1; ++ __le16 info2; ++ __le16 timestamp; ++ __le16 padding; ++} __packed; ++ + struct kvaser_cmd_ctrl_mode { + u8 tid; + u8 channel; +@@ -321,6 +344,7 @@ struct kvaser_cmd { + struct leaf_cmd_chip_state_event chip_state_event; + struct leaf_cmd_can_error_event can_error_event; + struct leaf_cmd_log_message log_message; ++ struct leaf_cmd_error_event error_event; + struct kvaser_cmd_cap_req cap_req; + struct kvaser_cmd_cap_res cap_res; + } __packed leaf; +@@ -330,6 +354,7 @@ struct kvaser_cmd { + struct usbcan_cmd_rx_can rx_can; + struct usbcan_cmd_chip_state_event chip_state_event; + struct usbcan_cmd_can_error_event can_error_event; ++ struct usbcan_cmd_error_event error_event; + } __packed usbcan; + + struct kvaser_cmd_tx_can tx_can; +@@ -353,6 +378,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = { + [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.leaf.chip_state_event), + [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.leaf.can_error_event), + [CMD_GET_CAPABILITIES_RESP] = kvaser_fsize(u.leaf.cap_res), ++ [CMD_ERROR_EVENT] = kvaser_fsize(u.leaf.error_event), + /* ignored events: */ + [CMD_FLUSH_QUEUE_REPLY] = CMD_SIZE_ANY, + }; +@@ -367,6 +393,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] = { + [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.usbcan.rx_can), + [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.usbcan.chip_state_event), + [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.usbcan.can_error_event), ++ [CMD_ERROR_EVENT] = kvaser_fsize(u.usbcan.error_event), + /* ignored events: */ + [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = CMD_SIZE_ANY, + }; +@@ -1304,6 +1331,74 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev, + netif_rx(skb); + } + ++static void kvaser_usb_leaf_error_event_parameter(const struct kvaser_usb *dev, ++ const struct kvaser_cmd *cmd) ++{ ++ u16 info1 = 0; ++ ++ switch (dev->driver_info->family) { ++ case KVASER_LEAF: ++ info1 = le16_to_cpu(cmd->u.leaf.error_event.info1); ++ break; ++ case KVASER_USBCAN: ++ info1 = le16_to_cpu(cmd->u.usbcan.error_event.info1); ++ break; ++ } ++ ++ /* info1 will contain the offending cmd_no */ ++ switch (info1) { ++ case CMD_SET_CTRL_MODE: ++ dev_warn(&dev->intf->dev, ++ "CMD_SET_CTRL_MODE error in parameter\n"); ++ break; ++ ++ case CMD_SET_BUS_PARAMS: ++ dev_warn(&dev->intf->dev, ++ "CMD_SET_BUS_PARAMS error in parameter\n"); ++ break; ++ ++ default: ++ dev_warn(&dev->intf->dev, ++ "Unhandled parameter error event cmd_no (%u)\n", ++ info1); ++ break; ++ } ++} ++ ++static void kvaser_usb_leaf_error_event(const struct kvaser_usb *dev, ++ const struct kvaser_cmd *cmd) ++{ ++ u8 error_code = 0; ++ ++ switch (dev->driver_info->family) { ++ case KVASER_LEAF: ++ error_code = cmd->u.leaf.error_event.error_code; ++ break; ++ case KVASER_USBCAN: ++ error_code = cmd->u.usbcan.error_event.error_code; ++ break; ++ } ++ ++ switch (error_code) { ++ case KVASER_USB_LEAF_ERROR_EVENT_TX_QUEUE_FULL: ++ /* Received additional CAN message, when firmware TX queue is ++ * already full. Something is wrong with the driver. ++ * This should never happen! ++ */ ++ dev_err(&dev->intf->dev, ++ "Received error event TX_QUEUE_FULL\n"); ++ break; ++ case KVASER_USB_LEAF_ERROR_EVENT_PARAM: ++ kvaser_usb_leaf_error_event_parameter(dev, cmd); ++ break; ++ ++ default: ++ dev_warn(&dev->intf->dev, ++ "Unhandled error event (%d)\n", error_code); ++ break; ++ } ++} ++ + static void kvaser_usb_leaf_start_chip_reply(const struct kvaser_usb *dev, + const struct kvaser_cmd *cmd) + { +@@ -1382,6 +1477,10 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev, + kvaser_usb_leaf_tx_acknowledge(dev, cmd); + break; + ++ case CMD_ERROR_EVENT: ++ kvaser_usb_leaf_error_event(dev, cmd); ++ break; ++ + /* Ignored commands */ + case CMD_USBCAN_CLOCK_OVERFLOW_EVENT: + if (dev->driver_info->family != KVASER_USBCAN) +-- +2.35.1 + diff --git a/queue-6.0/can-kvaser_usb-kvaser_usb_leaf-rename-leaf-usbcan-_c.patch b/queue-6.0/can-kvaser_usb-kvaser_usb_leaf-rename-leaf-usbcan-_c.patch new file mode 100644 index 00000000000..2a40933a52b --- /dev/null +++ b/queue-6.0/can-kvaser_usb-kvaser_usb_leaf-rename-leaf-usbcan-_c.patch @@ -0,0 +1,136 @@ +From 362749bc7748c61e609c86f7be241352f9995fab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 20:52:29 +0200 +Subject: can: kvaser_usb: kvaser_usb_leaf: Rename + {leaf,usbcan}_cmd_error_event to {leaf,usbcan}_cmd_can_error_event + +From: Jimmy Assarsson + +[ Upstream commit 7ea56128dbf904a3359bcf9289cccdfa3c85c7e8 ] + +Prepare for handling CMD_ERROR_EVENT. Rename struct +{leaf,usbcan}_cmd_error_event to {leaf,usbcan}_cmd_can_error_event. + +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Reported-by: Anssi Hannula +Tested-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010185237.319219-4-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 38 +++++++++---------- + 1 file changed, 19 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +index 33ff62cd1729..a1d4ac8d4a08 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -234,7 +234,7 @@ struct kvaser_cmd_tx_acknowledge_header { + u8 tid; + } __packed; + +-struct leaf_cmd_error_event { ++struct leaf_cmd_can_error_event { + u8 tid; + u8 flags; + __le16 time[3]; +@@ -246,7 +246,7 @@ struct leaf_cmd_error_event { + u8 error_factor; + } __packed; + +-struct usbcan_cmd_error_event { ++struct usbcan_cmd_can_error_event { + u8 tid; + u8 padding; + u8 tx_errors_count_ch0; +@@ -319,7 +319,7 @@ struct kvaser_cmd { + struct leaf_cmd_softinfo softinfo; + struct leaf_cmd_rx_can rx_can; + struct leaf_cmd_chip_state_event chip_state_event; +- struct leaf_cmd_error_event error_event; ++ struct leaf_cmd_can_error_event can_error_event; + struct leaf_cmd_log_message log_message; + struct kvaser_cmd_cap_req cap_req; + struct kvaser_cmd_cap_res cap_res; +@@ -329,7 +329,7 @@ struct kvaser_cmd { + struct usbcan_cmd_softinfo softinfo; + struct usbcan_cmd_rx_can rx_can; + struct usbcan_cmd_chip_state_event chip_state_event; +- struct usbcan_cmd_error_event error_event; ++ struct usbcan_cmd_can_error_event can_error_event; + } __packed usbcan; + + struct kvaser_cmd_tx_can tx_can; +@@ -351,7 +351,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = { + [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.leaf.rx_can), + [CMD_LEAF_LOG_MESSAGE] = kvaser_fsize(u.leaf.log_message), + [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.leaf.chip_state_event), +- [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.leaf.error_event), ++ [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.leaf.can_error_event), + [CMD_GET_CAPABILITIES_RESP] = kvaser_fsize(u.leaf.cap_res), + /* ignored events: */ + [CMD_FLUSH_QUEUE_REPLY] = CMD_SIZE_ANY, +@@ -366,7 +366,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] = { + [CMD_RX_STD_MESSAGE] = kvaser_fsize(u.usbcan.rx_can), + [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.usbcan.rx_can), + [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.usbcan.chip_state_event), +- [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.usbcan.error_event), ++ [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.usbcan.can_error_event), + /* ignored events: */ + [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = CMD_SIZE_ANY, + }; +@@ -1132,11 +1132,11 @@ static void kvaser_usb_leaf_usbcan_rx_error(const struct kvaser_usb *dev, + + case CMD_CAN_ERROR_EVENT: + es.channel = 0; +- es.status = cmd->u.usbcan.error_event.status_ch0; +- es.txerr = cmd->u.usbcan.error_event.tx_errors_count_ch0; +- es.rxerr = cmd->u.usbcan.error_event.rx_errors_count_ch0; ++ es.status = cmd->u.usbcan.can_error_event.status_ch0; ++ es.txerr = cmd->u.usbcan.can_error_event.tx_errors_count_ch0; ++ es.rxerr = cmd->u.usbcan.can_error_event.rx_errors_count_ch0; + es.usbcan.other_ch_status = +- cmd->u.usbcan.error_event.status_ch1; ++ cmd->u.usbcan.can_error_event.status_ch1; + kvaser_usb_leaf_usbcan_conditionally_rx_error(dev, &es); + + /* The USBCAN firmware supports up to 2 channels. +@@ -1144,13 +1144,13 @@ static void kvaser_usb_leaf_usbcan_rx_error(const struct kvaser_usb *dev, + */ + if (dev->nchannels == MAX_USBCAN_NET_DEVICES) { + es.channel = 1; +- es.status = cmd->u.usbcan.error_event.status_ch1; ++ es.status = cmd->u.usbcan.can_error_event.status_ch1; + es.txerr = +- cmd->u.usbcan.error_event.tx_errors_count_ch1; ++ cmd->u.usbcan.can_error_event.tx_errors_count_ch1; + es.rxerr = +- cmd->u.usbcan.error_event.rx_errors_count_ch1; ++ cmd->u.usbcan.can_error_event.rx_errors_count_ch1; + es.usbcan.other_ch_status = +- cmd->u.usbcan.error_event.status_ch0; ++ cmd->u.usbcan.can_error_event.status_ch0; + kvaser_usb_leaf_usbcan_conditionally_rx_error(dev, &es); + } + break; +@@ -1167,11 +1167,11 @@ static void kvaser_usb_leaf_leaf_rx_error(const struct kvaser_usb *dev, + + switch (cmd->id) { + case CMD_CAN_ERROR_EVENT: +- es.channel = cmd->u.leaf.error_event.channel; +- es.status = cmd->u.leaf.error_event.status; +- es.txerr = cmd->u.leaf.error_event.tx_errors_count; +- es.rxerr = cmd->u.leaf.error_event.rx_errors_count; +- es.leaf.error_factor = cmd->u.leaf.error_event.error_factor; ++ es.channel = cmd->u.leaf.can_error_event.channel; ++ es.status = cmd->u.leaf.can_error_event.status; ++ es.txerr = cmd->u.leaf.can_error_event.tx_errors_count; ++ es.rxerr = cmd->u.leaf.can_error_event.rx_errors_count; ++ es.leaf.error_factor = cmd->u.leaf.can_error_event.error_factor; + break; + case CMD_LEAF_LOG_MESSAGE: + es.channel = cmd->u.leaf.log_message.channel; +-- +2.35.1 + diff --git a/queue-6.0/can-kvaser_usb_leaf-fix-bogus-restart-events.patch b/queue-6.0/can-kvaser_usb_leaf-fix-bogus-restart-events.patch new file mode 100644 index 00000000000..e7107f03399 --- /dev/null +++ b/queue-6.0/can-kvaser_usb_leaf-fix-bogus-restart-events.patch @@ -0,0 +1,66 @@ +From e108c65c08424372ad166376575722b90c27e991 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 20:52:35 +0200 +Subject: can: kvaser_usb_leaf: Fix bogus restart events + +From: Anssi Hannula + +[ Upstream commit 90904d326269a38fe5dd895fb2db7c03199654c4 ] + +When auto-restart is enabled, the kvaser_usb_leaf driver considers +transition from any state >= CAN_STATE_BUS_OFF as a bus-off recovery +event (restart). + +However, these events may occur at interface startup time before +kvaser_usb_open() has set the state to CAN_STATE_ERROR_ACTIVE, causing +restarts counter to increase and CAN_ERR_RESTARTED to be sent despite no +actual restart having occurred. + +Fix that by making the auto-restart condition checks more strict so that +they only trigger when the interface was actually in the BUS_OFF state. + +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Tested-by: Jimmy Assarsson +Signed-off-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010185237.319219-10-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +index 4f9c76f4d0da..fa940be4e1b0 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -898,7 +898,7 @@ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev, + context = &priv->tx_contexts[tid % dev->max_tx_urbs]; + + /* Sometimes the state change doesn't come after a bus-off event */ +- if (priv->can.restart_ms && priv->can.state >= CAN_STATE_BUS_OFF) { ++ if (priv->can.restart_ms && priv->can.state == CAN_STATE_BUS_OFF) { + struct sk_buff *skb; + struct can_frame *cf; + +@@ -998,7 +998,7 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv, + } + + if (priv->can.restart_ms && +- cur_state >= CAN_STATE_BUS_OFF && ++ cur_state == CAN_STATE_BUS_OFF && + new_state < CAN_STATE_BUS_OFF) + priv->can.can_stats.restarts++; + +@@ -1088,7 +1088,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev, + } + + if (priv->can.restart_ms && +- old_state >= CAN_STATE_BUS_OFF && ++ old_state == CAN_STATE_BUS_OFF && + new_state < CAN_STATE_BUS_OFF) { + cf->can_id |= CAN_ERR_RESTARTED; + netif_carrier_on(priv->netdev); +-- +2.35.1 + diff --git a/queue-6.0/can-kvaser_usb_leaf-fix-improved-state-not-being-rep.patch b/queue-6.0/can-kvaser_usb_leaf-fix-improved-state-not-being-rep.patch new file mode 100644 index 00000000000..7d4ec74e4b1 --- /dev/null +++ b/queue-6.0/can-kvaser_usb_leaf-fix-improved-state-not-being-rep.patch @@ -0,0 +1,259 @@ +From 4aaa6d1a8df17df0994d55fd5e0478e473158d3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 20:52:32 +0200 +Subject: can: kvaser_usb_leaf: Fix improved state not being reported + +From: Anssi Hannula + +[ Upstream commit 8d21f5927ae604881f98587fabf6753f88730968 ] + +The tested 0bfd:0017 Kvaser Memorator Professional HS/HS FW 2.0.50 and +0bfd:0124 Kvaser Mini PCI Express 2xHS FW 4.18.778 do not seem to send +any unsolicited events when error counters decrease or when the device +transitions from ERROR_PASSIVE to ERROR_ACTIVE (or WARNING). + +This causes the interface to e.g. indefinitely stay in the ERROR_PASSIVE +state. + +Fix that by asking for chip state (inc. counters) event every 0.5 secs +when error counters are non-zero. + +Since there are non-error-counter devices, also always poll in +ERROR_PASSIVE even if the counters show zero. + +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Tested-by: Jimmy Assarsson +Signed-off-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010185237.319219-7-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 7 +++ + .../net/can/usb/kvaser_usb/kvaser_usb_core.c | 19 +++++- + .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 58 +++++++++++++++++++ + 3 files changed, 81 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +index f6c0938027ec..d9c5dd5da908 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +@@ -104,6 +104,9 @@ struct kvaser_usb_net_priv { + struct can_priv can; + struct can_berr_counter bec; + ++ /* subdriver-specific data */ ++ void *sub_priv; ++ + struct kvaser_usb *dev; + struct net_device *netdev; + int channel; +@@ -125,6 +128,8 @@ struct kvaser_usb_net_priv { + * + * @dev_setup_endpoints: setup USB in and out endpoints + * @dev_init_card: initialize card ++ * @dev_init_channel: initialize channel ++ * @dev_remove_channel: uninitialize channel + * @dev_get_software_info: get software info + * @dev_get_software_details: get software details + * @dev_get_card_info: get card info +@@ -146,6 +151,8 @@ struct kvaser_usb_dev_ops { + struct can_berr_counter *bec); + int (*dev_setup_endpoints)(struct kvaser_usb *dev); + int (*dev_init_card)(struct kvaser_usb *dev); ++ int (*dev_init_channel)(struct kvaser_usb_net_priv *priv); ++ void (*dev_remove_channel)(struct kvaser_usb_net_priv *priv); + int (*dev_get_software_info)(struct kvaser_usb *dev); + int (*dev_get_software_details)(struct kvaser_usb *dev); + int (*dev_get_card_info)(struct kvaser_usb *dev); +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +index 802e27c0eced..0ebdfb77c50f 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +@@ -684,6 +684,7 @@ static const struct ethtool_ops kvaser_usb_ethtool_ops_hwts = { + + static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev) + { ++ const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; + int i; + + for (i = 0; i < dev->nchannels; i++) { +@@ -699,6 +700,9 @@ static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev) + if (!dev->nets[i]) + continue; + ++ if (ops->dev_remove_channel) ++ ops->dev_remove_channel(dev->nets[i]); ++ + free_candev(dev->nets[i]->netdev); + } + } +@@ -772,17 +776,26 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel) + + dev->nets[channel] = priv; + ++ if (ops->dev_init_channel) { ++ err = ops->dev_init_channel(priv); ++ if (err) ++ goto err; ++ } ++ + err = register_candev(netdev); + if (err) { + dev_err(&dev->intf->dev, "Failed to register CAN device\n"); +- free_candev(netdev); +- dev->nets[channel] = NULL; +- return err; ++ goto err; + } + + netdev_dbg(netdev, "device registered\n"); + + return 0; ++ ++err: ++ free_candev(netdev); ++ dev->nets[channel] = NULL; ++ return err; + } + + static int kvaser_usb_probe(struct usb_interface *intf, +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +index a6a26085bc15..993fcc19637d 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -56,6 +57,7 @@ + #define CMD_RX_EXT_MESSAGE 14 + #define CMD_TX_EXT_MESSAGE 15 + #define CMD_SET_BUS_PARAMS 16 ++#define CMD_GET_CHIP_STATE 19 + #define CMD_CHIP_STATE_EVENT 20 + #define CMD_SET_CTRL_MODE 21 + #define CMD_RESET_CHIP 24 +@@ -421,6 +423,12 @@ struct kvaser_usb_err_summary { + }; + }; + ++struct kvaser_usb_net_leaf_priv { ++ struct kvaser_usb_net_priv *net; ++ ++ struct delayed_work chip_state_req_work; ++}; ++ + static const struct can_bittiming_const kvaser_usb_leaf_m16c_bittiming_const = { + .name = "kvaser_usb_ucii", + .tseg1_min = 4, +@@ -943,6 +951,16 @@ static int kvaser_usb_leaf_simple_cmd_async(struct kvaser_usb_net_priv *priv, + return err; + } + ++static void kvaser_usb_leaf_chip_state_req_work(struct work_struct *work) ++{ ++ struct kvaser_usb_net_leaf_priv *leaf = ++ container_of(work, struct kvaser_usb_net_leaf_priv, ++ chip_state_req_work.work); ++ struct kvaser_usb_net_priv *priv = leaf->net; ++ ++ kvaser_usb_leaf_simple_cmd_async(priv, CMD_GET_CHIP_STATE); ++} ++ + static void + kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv, + const struct kvaser_usb_err_summary *es, +@@ -1014,6 +1032,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev, + struct sk_buff *skb; + struct net_device_stats *stats; + struct kvaser_usb_net_priv *priv; ++ struct kvaser_usb_net_leaf_priv *leaf; + enum can_state old_state, new_state; + + if (es->channel >= dev->nchannels) { +@@ -1023,6 +1042,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev, + } + + priv = dev->nets[es->channel]; ++ leaf = priv->sub_priv; + stats = &priv->netdev->stats; + + /* Update all of the CAN interface's state and error counters before +@@ -1039,6 +1059,14 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev, + kvaser_usb_leaf_rx_error_update_can_state(priv, es, &tmp_cf); + new_state = priv->can.state; + ++ /* If there are errors, request status updates periodically as we do ++ * not get automatic notifications of improved state. ++ */ ++ if (new_state < CAN_STATE_BUS_OFF && ++ (es->rxerr || es->txerr || new_state == CAN_STATE_ERROR_PASSIVE)) ++ schedule_delayed_work(&leaf->chip_state_req_work, ++ msecs_to_jiffies(500)); ++ + skb = alloc_can_err_skb(priv->netdev, &cf); + if (!skb) { + stats->rx_dropped++; +@@ -1573,10 +1601,13 @@ static int kvaser_usb_leaf_start_chip(struct kvaser_usb_net_priv *priv) + + static int kvaser_usb_leaf_stop_chip(struct kvaser_usb_net_priv *priv) + { ++ struct kvaser_usb_net_leaf_priv *leaf = priv->sub_priv; + int err; + + reinit_completion(&priv->stop_comp); + ++ cancel_delayed_work(&leaf->chip_state_req_work); ++ + err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_STOP_CHIP, + priv->channel); + if (err) +@@ -1623,6 +1654,31 @@ static int kvaser_usb_leaf_init_card(struct kvaser_usb *dev) + return 0; + } + ++static int kvaser_usb_leaf_init_channel(struct kvaser_usb_net_priv *priv) ++{ ++ struct kvaser_usb_net_leaf_priv *leaf; ++ ++ leaf = devm_kzalloc(&priv->dev->intf->dev, sizeof(*leaf), GFP_KERNEL); ++ if (!leaf) ++ return -ENOMEM; ++ ++ leaf->net = priv; ++ INIT_DELAYED_WORK(&leaf->chip_state_req_work, ++ kvaser_usb_leaf_chip_state_req_work); ++ ++ priv->sub_priv = leaf; ++ ++ return 0; ++} ++ ++static void kvaser_usb_leaf_remove_channel(struct kvaser_usb_net_priv *priv) ++{ ++ struct kvaser_usb_net_leaf_priv *leaf = priv->sub_priv; ++ ++ if (leaf) ++ cancel_delayed_work_sync(&leaf->chip_state_req_work); ++} ++ + static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev) + { + struct kvaser_usb_net_priv *priv = netdev_priv(netdev); +@@ -1720,6 +1776,8 @@ const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops = { + .dev_get_berr_counter = kvaser_usb_leaf_get_berr_counter, + .dev_setup_endpoints = kvaser_usb_leaf_setup_endpoints, + .dev_init_card = kvaser_usb_leaf_init_card, ++ .dev_init_channel = kvaser_usb_leaf_init_channel, ++ .dev_remove_channel = kvaser_usb_leaf_remove_channel, + .dev_get_software_info = kvaser_usb_leaf_get_software_info, + .dev_get_software_details = NULL, + .dev_get_card_info = kvaser_usb_leaf_get_card_info, +-- +2.35.1 + diff --git a/queue-6.0/can-kvaser_usb_leaf-fix-wrong-can-state-after-stoppi.patch b/queue-6.0/can-kvaser_usb_leaf-fix-wrong-can-state-after-stoppi.patch new file mode 100644 index 00000000000..09000d67344 --- /dev/null +++ b/queue-6.0/can-kvaser_usb_leaf-fix-wrong-can-state-after-stoppi.patch @@ -0,0 +1,45 @@ +From 0c622ae066bc6236e9fb6b51d827fd62b4184a94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 20:52:33 +0200 +Subject: can: kvaser_usb_leaf: Fix wrong CAN state after stopping + +From: Anssi Hannula + +[ Upstream commit a11249acf802341294557895d8e5f6aef080253f ] + +0bfd:0124 Kvaser Mini PCI Express 2xHS FW 4.18.778 sends a +CMD_CHIP_STATE_EVENT indicating bus-off after stopping the device, +causing a stopped device to appear as CAN_STATE_BUS_OFF instead of +CAN_STATE_STOPPED. + +Fix that by not handling error events on stopped devices. + +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Tested-by: Jimmy Assarsson +Signed-off-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010185237.319219-8-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +index 993fcc19637d..4f9c76f4d0da 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -1045,6 +1045,10 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev, + leaf = priv->sub_priv; + stats = &priv->netdev->stats; + ++ /* Ignore e.g. state change to bus-off reported just after stopping */ ++ if (!netif_running(priv->netdev)) ++ return; ++ + /* Update all of the CAN interface's state and error counters before + * trying any memory allocation that can actually fail with -ENOMEM. + * +-- +2.35.1 + diff --git a/queue-6.0/can-kvaser_usb_leaf-set-warning-state-even-without-b.patch b/queue-6.0/can-kvaser_usb_leaf-set-warning-state-even-without-b.patch new file mode 100644 index 00000000000..d476ebc6cd3 --- /dev/null +++ b/queue-6.0/can-kvaser_usb_leaf-set-warning-state-even-without-b.patch @@ -0,0 +1,76 @@ +From d74fd8c12b34a18144a145cf8ad0016da4f063d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 20:52:31 +0200 +Subject: can: kvaser_usb_leaf: Set Warning state even without bus errors + +From: Anssi Hannula + +[ Upstream commit df1b7af2761b935f63b4a53e789d41ed859edf61 ] + +kvaser_usb_leaf_rx_error_update_can_state() sets error state according +to error counters when the hardware does not indicate a specific state +directly. + +However, this is currently gated behind a check for +M16C_STATE_BUS_ERROR which does not always seem to be set when error +counters are increasing, and may not be set when error counters are +decreasing. + +This causes the CAN_STATE_ERROR_WARNING state to not be set in some +cases even when appropriate. + +Change the code to set error state from counters even without +M16C_STATE_BUS_ERROR. + +The Error-Passive case seems superfluous as it is already set via +M16C_STATE_BUS_PASSIVE flag above, but it is kept for now. + +Tested with 0bfd:0124 Kvaser Mini PCI Express 2xHS FW 4.18.778. + +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Tested-by: Jimmy Assarsson +Signed-off-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010185237.319219-6-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 20 ++++++++----------- + 1 file changed, 8 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +index 5d96ab85d04c..a6a26085bc15 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -961,20 +961,16 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv, + new_state = CAN_STATE_BUS_OFF; + } else if (es->status & M16C_STATE_BUS_PASSIVE) { + new_state = CAN_STATE_ERROR_PASSIVE; +- } else if (es->status & M16C_STATE_BUS_ERROR) { ++ } else if ((es->status & M16C_STATE_BUS_ERROR) && ++ cur_state >= CAN_STATE_BUS_OFF) { + /* Guard against spurious error events after a busoff */ +- if (cur_state < CAN_STATE_BUS_OFF) { +- if (es->txerr >= 128 || es->rxerr >= 128) +- new_state = CAN_STATE_ERROR_PASSIVE; +- else if (es->txerr >= 96 || es->rxerr >= 96) +- new_state = CAN_STATE_ERROR_WARNING; +- else if (cur_state > CAN_STATE_ERROR_ACTIVE) +- new_state = CAN_STATE_ERROR_ACTIVE; +- } +- } +- +- if (!es->status) ++ } else if (es->txerr >= 128 || es->rxerr >= 128) { ++ new_state = CAN_STATE_ERROR_PASSIVE; ++ } else if (es->txerr >= 96 || es->rxerr >= 96) { ++ new_state = CAN_STATE_ERROR_WARNING; ++ } else { + new_state = CAN_STATE_ERROR_ACTIVE; ++ } + + if (new_state != cur_state) { + tx_state = (es->txerr >= es->rxerr) ? new_state : 0; +-- +2.35.1 + diff --git a/queue-6.0/can-m_can-call-the-ram-init-directly-from-m_can_chip.patch b/queue-6.0/can-m_can-call-the-ram-init-directly-from-m_can_chip.patch new file mode 100644 index 00000000000..7639e54c3c0 --- /dev/null +++ b/queue-6.0/can-m_can-call-the-ram-init-directly-from-m_can_chip.patch @@ -0,0 +1,141 @@ +From d8332c62dbcb87905c3537b1557e275afd169789 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Dec 2022 15:36:31 +0530 +Subject: can: m_can: Call the RAM init directly from m_can_chip_config + +From: Vivek Yadav + +[ Upstream commit eaacfeaca7ad0804b9a6eff7afeba93a87db7638 ] + +When we try to access the mcan message ram addresses during the probe, +hclk is gated by any other drivers or disabled, because of that probe +gets failed. + +Move the mram init functionality to mcan chip config called by +m_can_start from mcan open function, by that time clocks are +enabled. + +Suggested-by: Marc Kleine-Budde +Signed-off-by: Vivek Yadav +Link: https://lore.kernel.org/all/20221207100632.96200-2-vivek.2311@samsung.com +Signed-off-by: Marc Kleine-Budde +Stable-dep-of: 67727a17a6b3 ("can: tcan4x5x: Fix use of register error status mask") +Signed-off-by: Sasha Levin +--- + drivers/net/can/m_can/m_can.c | 32 +++++++++++++++++++++----- + drivers/net/can/m_can/m_can_platform.c | 4 ---- + drivers/net/can/m_can/tcan4x5x-core.c | 5 ---- + 3 files changed, 26 insertions(+), 15 deletions(-) + +diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c +index 153d8fd08bd8..a562f36a99f8 100644 +--- a/drivers/net/can/m_can/m_can.c ++++ b/drivers/net/can/m_can/m_can.c +@@ -1233,10 +1233,17 @@ static int m_can_set_bittiming(struct net_device *dev) + * - setup bittiming + * - configure timestamp generation + */ +-static void m_can_chip_config(struct net_device *dev) ++static int m_can_chip_config(struct net_device *dev) + { + struct m_can_classdev *cdev = netdev_priv(dev); + u32 cccr, test; ++ int err; ++ ++ err = m_can_init_ram(cdev); ++ if (err) { ++ dev_err(cdev->dev, "Message RAM configuration failed\n"); ++ return err; ++ } + + m_can_config_endisable(cdev, true); + +@@ -1360,18 +1367,25 @@ static void m_can_chip_config(struct net_device *dev) + + if (cdev->ops->init) + cdev->ops->init(cdev); ++ ++ return 0; + } + +-static void m_can_start(struct net_device *dev) ++static int m_can_start(struct net_device *dev) + { + struct m_can_classdev *cdev = netdev_priv(dev); ++ int ret; + + /* basic m_can configuration */ +- m_can_chip_config(dev); ++ ret = m_can_chip_config(dev); ++ if (ret) ++ return ret; + + cdev->can.state = CAN_STATE_ERROR_ACTIVE; + + m_can_enable_all_interrupts(cdev); ++ ++ return 0; + } + + static int m_can_set_mode(struct net_device *dev, enum can_mode mode) +@@ -1800,7 +1814,9 @@ static int m_can_open(struct net_device *dev) + } + + /* start the m_can controller */ +- m_can_start(dev); ++ err = m_can_start(dev); ++ if (err) ++ goto exit_irq_fail; + + if (!cdev->is_peripheral) + napi_enable(&cdev->napi); +@@ -2059,9 +2075,13 @@ int m_can_class_resume(struct device *dev) + ret = m_can_clk_start(cdev); + if (ret) + return ret; ++ ret = m_can_start(ndev); ++ if (ret) { ++ m_can_clk_stop(cdev); ++ ++ return ret; ++ } + +- m_can_init_ram(cdev); +- m_can_start(ndev); + netif_device_attach(ndev); + netif_start_queue(ndev); + } +diff --git a/drivers/net/can/m_can/m_can_platform.c b/drivers/net/can/m_can/m_can_platform.c +index eee47bad0592..de6d8e01bf2e 100644 +--- a/drivers/net/can/m_can/m_can_platform.c ++++ b/drivers/net/can/m_can/m_can_platform.c +@@ -140,10 +140,6 @@ static int m_can_plat_probe(struct platform_device *pdev) + + platform_set_drvdata(pdev, mcan_class); + +- ret = m_can_init_ram(mcan_class); +- if (ret) +- goto probe_fail; +- + pm_runtime_enable(mcan_class->dev); + ret = m_can_class_register(mcan_class); + if (ret) +diff --git a/drivers/net/can/m_can/tcan4x5x-core.c b/drivers/net/can/m_can/tcan4x5x-core.c +index 1fec394b3517..a77f4d4f6299 100644 +--- a/drivers/net/can/m_can/tcan4x5x-core.c ++++ b/drivers/net/can/m_can/tcan4x5x-core.c +@@ -229,11 +229,6 @@ static int tcan4x5x_init(struct m_can_classdev *cdev) + if (ret) + return ret; + +- /* Zero out the MCAN buffers */ +- ret = m_can_init_ram(cdev); +- if (ret) +- return ret; +- + ret = regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG, + TCAN4X5X_MODE_SEL_MASK, TCAN4X5X_MODE_NORMAL); + if (ret) +-- +2.35.1 + diff --git a/queue-6.0/can-tcan4x5x-fix-use-of-register-error-status-mask.patch b/queue-6.0/can-tcan4x5x-fix-use-of-register-error-status-mask.patch new file mode 100644 index 00000000000..eefbba1a9f0 --- /dev/null +++ b/queue-6.0/can-tcan4x5x-fix-use-of-register-error-status-mask.patch @@ -0,0 +1,68 @@ +From 9b09d7047b7e1f137db323fb6656cea900bd7e2d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Dec 2022 12:57:26 +0100 +Subject: can: tcan4x5x: Fix use of register error status mask + +From: Markus Schneider-Pargmann + +[ Upstream commit 67727a17a6b375d68fe569b77e6516b034b834c0 ] + +TCAN4X5X_ERROR_STATUS is not a status register that needs clearing +during interrupt handling. Instead this is a masking register that masks +error interrupts. Writing TCAN4X5X_CLEAR_ALL_INT to this register +effectively masks everything. + +Rename the register and mask all error interrupts only once by writing +to the register in tcan4x5x_init. + +Fixes: 5443c226ba91 ("can: tcan4x5x: Add tcan4x5x driver to the kernel") +Signed-off-by: Markus Schneider-Pargmann +Link: https://lore.kernel.org/all/20221206115728.1056014-10-msp@baylibre.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/m_can/tcan4x5x-core.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/can/m_can/tcan4x5x-core.c b/drivers/net/can/m_can/tcan4x5x-core.c +index a77f4d4f6299..2342aa011647 100644 +--- a/drivers/net/can/m_can/tcan4x5x-core.c ++++ b/drivers/net/can/m_can/tcan4x5x-core.c +@@ -10,7 +10,7 @@ + #define TCAN4X5X_DEV_ID1 0x04 + #define TCAN4X5X_REV 0x08 + #define TCAN4X5X_STATUS 0x0C +-#define TCAN4X5X_ERROR_STATUS 0x10 ++#define TCAN4X5X_ERROR_STATUS_MASK 0x10 + #define TCAN4X5X_CONTROL 0x14 + + #define TCAN4X5X_CONFIG 0x800 +@@ -204,12 +204,7 @@ static int tcan4x5x_clear_interrupts(struct m_can_classdev *cdev) + if (ret) + return ret; + +- ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_INT_FLAGS, +- TCAN4X5X_CLEAR_ALL_INT); +- if (ret) +- return ret; +- +- return tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_ERROR_STATUS, ++ return tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_INT_FLAGS, + TCAN4X5X_CLEAR_ALL_INT); + } + +@@ -229,6 +224,11 @@ static int tcan4x5x_init(struct m_can_classdev *cdev) + if (ret) + return ret; + ++ ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_ERROR_STATUS_MASK, ++ TCAN4X5X_CLEAR_ALL_INT); ++ if (ret) ++ return ret; ++ + ret = regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG, + TCAN4X5X_MODE_SEL_MASK, TCAN4X5X_MODE_NORMAL); + if (ret) +-- +2.35.1 + diff --git a/queue-6.0/can-tcan4x5x-remove-invalid-write-in-clear_interrupt.patch b/queue-6.0/can-tcan4x5x-remove-invalid-write-in-clear_interrupt.patch new file mode 100644 index 00000000000..70083557b0c --- /dev/null +++ b/queue-6.0/can-tcan4x5x-remove-invalid-write-in-clear_interrupt.patch @@ -0,0 +1,44 @@ +From 53642df9a2f9fadf53d9183962e091bb79bd4d4f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Dec 2022 12:57:25 +0100 +Subject: can: tcan4x5x: Remove invalid write in clear_interrupts + +From: Markus Schneider-Pargmann + +[ Upstream commit 40c9e4f676abbe194541d88e796341c92d5a13c0 ] + +Register 0x824 TCAN4X5X_MCAN_INT_REG is a read-only register. Any writes +to this register do not have any effect. + +Remove this write. The m_can driver aldready clears the interrupts in +m_can_isr() by writing to M_CAN_IR which is translated to register +0x1050 which is a writable version of this register. + +Fixes: 5443c226ba91 ("can: tcan4x5x: Add tcan4x5x driver to the kernel") +Signed-off-by: Markus Schneider-Pargmann +Link: https://lore.kernel.org/all/20221206115728.1056014-9-msp@baylibre.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/m_can/tcan4x5x-core.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/drivers/net/can/m_can/tcan4x5x-core.c b/drivers/net/can/m_can/tcan4x5x-core.c +index 41645a24384c..1fec394b3517 100644 +--- a/drivers/net/can/m_can/tcan4x5x-core.c ++++ b/drivers/net/can/m_can/tcan4x5x-core.c +@@ -204,11 +204,6 @@ static int tcan4x5x_clear_interrupts(struct m_can_classdev *cdev) + if (ret) + return ret; + +- ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_MCAN_INT_REG, +- TCAN4X5X_ENABLE_MCAN_INT); +- if (ret) +- return ret; +- + ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_INT_FLAGS, + TCAN4X5X_CLEAR_ALL_INT); + if (ret) +-- +2.35.1 + diff --git a/queue-6.0/chardev-fix-error-handling-in-cdev_device_add.patch b/queue-6.0/chardev-fix-error-handling-in-cdev_device_add.patch new file mode 100644 index 00000000000..5109b3ecff6 --- /dev/null +++ b/queue-6.0/chardev-fix-error-handling-in-cdev_device_add.patch @@ -0,0 +1,54 @@ +From 1ad5f9ad6df0f4c7948a76fe250f80c11d72f5be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Dec 2022 11:02:37 +0800 +Subject: chardev: fix error handling in cdev_device_add() + +From: Yang Yingliang + +[ Upstream commit 11fa7fefe3d8fac7da56bc9aa3dd5fb3081ca797 ] + +While doing fault injection test, I got the following report: + +------------[ cut here ]------------ +kobject: '(null)' (0000000039956980): is not initialized, yet kobject_put() is being called. +WARNING: CPU: 3 PID: 6306 at kobject_put+0x23d/0x4e0 +CPU: 3 PID: 6306 Comm: 283 Tainted: G W 6.1.0-rc2-00005-g307c1086d7c9 #1253 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 +RIP: 0010:kobject_put+0x23d/0x4e0 +Call Trace: + + cdev_device_add+0x15e/0x1b0 + __iio_device_register+0x13b4/0x1af0 [industrialio] + __devm_iio_device_register+0x22/0x90 [industrialio] + max517_probe+0x3d8/0x6b4 [max517] + i2c_device_probe+0xa81/0xc00 + +When device_add() is injected fault and returns error, if dev->devt is not set, +cdev_add() is not called, cdev_del() is not needed. Fix this by checking dev->devt +in error path. + +Fixes: 233ed09d7fda ("chardev: add helper function to register char devs with a struct device") +Signed-off-by: Yang Yingliang +Link: https://lore.kernel.org/r/20221202030237.520280-1-yangyingliang@huawei.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + fs/char_dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/char_dev.c b/fs/char_dev.c +index ba0ded7842a7..3f667292608c 100644 +--- a/fs/char_dev.c ++++ b/fs/char_dev.c +@@ -547,7 +547,7 @@ int cdev_device_add(struct cdev *cdev, struct device *dev) + } + + rc = device_add(dev); +- if (rc) ++ if (rc && dev->devt) + cdev_del(cdev); + + return rc; +-- +2.35.1 + diff --git a/queue-6.0/cifs-fix-oops-during-encryption.patch b/queue-6.0/cifs-fix-oops-during-encryption.patch new file mode 100644 index 00000000000..1e180597c64 --- /dev/null +++ b/queue-6.0/cifs-fix-oops-during-encryption.patch @@ -0,0 +1,402 @@ +From 1a5c40748621f21be26569d1fbf3fc2466e2ad20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 11 Dec 2022 18:18:55 -0300 +Subject: cifs: fix oops during encryption + +From: Paulo Alcantara + +[ Upstream commit f7f291e14dde32a07b1f0aa06921d28f875a7b54 ] + +When running xfstests against Azure the following oops occurred on an +arm64 system + + Unable to handle kernel write to read-only memory at virtual address + ffff0001221cf000 + Mem abort info: + ESR = 0x9600004f + EC = 0x25: DABT (current EL), IL = 32 bits + SET = 0, FnV = 0 + EA = 0, S1PTW = 0 + FSC = 0x0f: level 3 permission fault + Data abort info: + ISV = 0, ISS = 0x0000004f + CM = 0, WnR = 1 + swapper pgtable: 4k pages, 48-bit VAs, pgdp=00000000294f3000 + [ffff0001221cf000] pgd=18000001ffff8003, p4d=18000001ffff8003, + pud=18000001ff82e003, pmd=18000001ff71d003, pte=00600001221cf787 + Internal error: Oops: 9600004f [#1] PREEMPT SMP + ... + pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--) + pc : __memcpy+0x40/0x230 + lr : scatterwalk_copychunks+0xe0/0x200 + sp : ffff800014e92de0 + x29: ffff800014e92de0 x28: ffff000114f9de80 x27: 0000000000000008 + x26: 0000000000000008 x25: ffff800014e92e78 x24: 0000000000000008 + x23: 0000000000000001 x22: 0000040000000000 x21: ffff000000000000 + x20: 0000000000000001 x19: ffff0001037c4488 x18: 0000000000000014 + x17: 235e1c0d6efa9661 x16: a435f9576b6edd6c x15: 0000000000000058 + x14: 0000000000000001 x13: 0000000000000008 x12: ffff000114f2e590 + x11: ffffffffffffffff x10: 0000040000000000 x9 : ffff8000105c3580 + x8 : 2e9413b10000001a x7 : 534b4410fb86b005 x6 : 534b4410fb86b005 + x5 : ffff0001221cf008 x4 : ffff0001037c4490 x3 : 0000000000000001 + x2 : 0000000000000008 x1 : ffff0001037c4488 x0 : ffff0001221cf000 + Call trace: + __memcpy+0x40/0x230 + scatterwalk_map_and_copy+0x98/0x100 + crypto_ccm_encrypt+0x150/0x180 + crypto_aead_encrypt+0x2c/0x40 + crypt_message+0x750/0x880 + smb3_init_transform_rq+0x298/0x340 + smb_send_rqst.part.11+0xd8/0x180 + smb_send_rqst+0x3c/0x100 + compound_send_recv+0x534/0xbc0 + smb2_query_info_compound+0x32c/0x440 + smb2_set_ea+0x438/0x4c0 + cifs_xattr_set+0x5d4/0x7c0 + +This is because in scatterwalk_copychunks(), we attempted to write to +a buffer (@sign) that was allocated in the stack (vmalloc area) by +crypt_message() and thus accessing its remaining 8 (x2) bytes ended up +crossing a page boundary. + +To simply fix it, we could just pass @sign kmalloc'd from +crypt_message() and then we're done. Luckily, we don't seem to pass +any other vmalloc'd buffers in smb_rqst::rq_iov... + +Instead, let's map the correct pages and offsets from vmalloc buffers +as well in cifs_sg_set_buf() and then avoiding such oopses. + +Signed-off-by: Paulo Alcantara (SUSE) +Cc: stable@vger.kernel.org +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/cifs/cifsglob.h | 68 +++++++++++++++++++++ + fs/cifs/cifsproto.h | 4 +- + fs/cifs/misc.c | 4 +- + fs/cifs/smb2ops.c | 143 +++++++++++++++++++++----------------------- + 4 files changed, 140 insertions(+), 79 deletions(-) + +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index 333022028bb0..b52dca800eac 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -13,6 +13,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -2147,4 +2149,70 @@ static inline void move_cifs_info_to_smb2(struct smb2_file_all_info *dst, const + dst->FileNameLength = src->FileNameLength; + } + ++static inline unsigned int cifs_get_num_sgs(const struct smb_rqst *rqst, ++ int num_rqst, ++ const u8 *sig) ++{ ++ unsigned int len, skip; ++ unsigned int nents = 0; ++ unsigned long addr; ++ int i, j; ++ ++ /* Assumes the first rqst has a transform header as the first iov. ++ * I.e. ++ * rqst[0].rq_iov[0] is transform header ++ * rqst[0].rq_iov[1+] data to be encrypted/decrypted ++ * rqst[1+].rq_iov[0+] data to be encrypted/decrypted ++ */ ++ for (i = 0; i < num_rqst; i++) { ++ /* ++ * The first rqst has a transform header where the ++ * first 20 bytes are not part of the encrypted blob. ++ */ ++ for (j = 0; j < rqst[i].rq_nvec; j++) { ++ struct kvec *iov = &rqst[i].rq_iov[j]; ++ ++ skip = (i == 0) && (j == 0) ? 20 : 0; ++ addr = (unsigned long)iov->iov_base + skip; ++ if (unlikely(is_vmalloc_addr((void *)addr))) { ++ len = iov->iov_len - skip; ++ nents += DIV_ROUND_UP(offset_in_page(addr) + len, ++ PAGE_SIZE); ++ } else { ++ nents++; ++ } ++ } ++ nents += rqst[i].rq_npages; ++ } ++ nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE); ++ return nents; ++} ++ ++/* We can not use the normal sg_set_buf() as we will sometimes pass a ++ * stack object as buf. ++ */ ++static inline struct scatterlist *cifs_sg_set_buf(struct scatterlist *sg, ++ const void *buf, ++ unsigned int buflen) ++{ ++ unsigned long addr = (unsigned long)buf; ++ unsigned int off = offset_in_page(addr); ++ ++ addr &= PAGE_MASK; ++ if (unlikely(is_vmalloc_addr((void *)addr))) { ++ do { ++ unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off); ++ ++ sg_set_page(sg++, vmalloc_to_page((void *)addr), len, off); ++ ++ off = 0; ++ addr += PAGE_SIZE; ++ buflen -= len; ++ } while (buflen); ++ } else { ++ sg_set_page(sg++, virt_to_page(addr), buflen, off); ++ } ++ return sg; ++} ++ + #endif /* _CIFS_GLOB_H */ +diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h +index 372ff64a285b..edf6f18ec8b7 100644 +--- a/fs/cifs/cifsproto.h ++++ b/fs/cifs/cifsproto.h +@@ -601,8 +601,8 @@ int cifs_alloc_hash(const char *name, struct crypto_shash **shash, + struct sdesc **sdesc); + void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc); + +-extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page, +- unsigned int *len, unsigned int *offset); ++void rqst_page_get_length(const struct smb_rqst *rqst, unsigned int page, ++ unsigned int *len, unsigned int *offset); + struct cifs_chan * + cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server); + int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses); +diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c +index 3a117e2269a0..1efb5ca9fd80 100644 +--- a/fs/cifs/misc.c ++++ b/fs/cifs/misc.c +@@ -1137,8 +1137,8 @@ cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc) + * @len: Where to store the length for this page: + * @offset: Where to store the offset for this page + */ +-void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page, +- unsigned int *len, unsigned int *offset) ++void rqst_page_get_length(const struct smb_rqst *rqst, unsigned int page, ++ unsigned int *len, unsigned int *offset) + { + *len = rqst->rq_pagesz; + *offset = (page == 0) ? rqst->rq_offset : 0; +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index d454164e7f48..74052b51655e 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -4182,69 +4182,82 @@ fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int orig_len, + memcpy(&tr_hdr->SessionId, &shdr->SessionId, 8); + } + +-/* We can not use the normal sg_set_buf() as we will sometimes pass a +- * stack object as buf. +- */ +-static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf, +- unsigned int buflen) ++static void *smb2_aead_req_alloc(struct crypto_aead *tfm, const struct smb_rqst *rqst, ++ int num_rqst, const u8 *sig, u8 **iv, ++ struct aead_request **req, struct scatterlist **sgl, ++ unsigned int *num_sgs) + { +- void *addr; +- /* +- * VMAP_STACK (at least) puts stack into the vmalloc address space +- */ +- if (is_vmalloc_addr(buf)) +- addr = vmalloc_to_page(buf); +- else +- addr = virt_to_page(buf); +- sg_set_page(sg, addr, buflen, offset_in_page(buf)); ++ unsigned int req_size = sizeof(**req) + crypto_aead_reqsize(tfm); ++ unsigned int iv_size = crypto_aead_ivsize(tfm); ++ unsigned int len; ++ u8 *p; ++ ++ *num_sgs = cifs_get_num_sgs(rqst, num_rqst, sig); ++ ++ len = iv_size; ++ len += crypto_aead_alignmask(tfm) & ~(crypto_tfm_ctx_alignment() - 1); ++ len = ALIGN(len, crypto_tfm_ctx_alignment()); ++ len += req_size; ++ len = ALIGN(len, __alignof__(struct scatterlist)); ++ len += *num_sgs * sizeof(**sgl); ++ ++ p = kmalloc(len, GFP_ATOMIC); ++ if (!p) ++ return NULL; ++ ++ *iv = (u8 *)PTR_ALIGN(p, crypto_aead_alignmask(tfm) + 1); ++ *req = (struct aead_request *)PTR_ALIGN(*iv + iv_size, ++ crypto_tfm_ctx_alignment()); ++ *sgl = (struct scatterlist *)PTR_ALIGN((u8 *)*req + req_size, ++ __alignof__(struct scatterlist)); ++ return p; + } + +-/* Assumes the first rqst has a transform header as the first iov. +- * I.e. +- * rqst[0].rq_iov[0] is transform header +- * rqst[0].rq_iov[1+] data to be encrypted/decrypted +- * rqst[1+].rq_iov[0+] data to be encrypted/decrypted +- */ +-static struct scatterlist * +-init_sg(int num_rqst, struct smb_rqst *rqst, u8 *sign) ++static void *smb2_get_aead_req(struct crypto_aead *tfm, const struct smb_rqst *rqst, ++ int num_rqst, const u8 *sig, u8 **iv, ++ struct aead_request **req, struct scatterlist **sgl) + { +- unsigned int sg_len; ++ unsigned int off, len, skip; + struct scatterlist *sg; +- unsigned int i; +- unsigned int j; +- unsigned int idx = 0; +- int skip; +- +- sg_len = 1; +- for (i = 0; i < num_rqst; i++) +- sg_len += rqst[i].rq_nvec + rqst[i].rq_npages; ++ unsigned int num_sgs; ++ unsigned long addr; ++ int i, j; ++ void *p; + +- sg = kmalloc_array(sg_len, sizeof(struct scatterlist), GFP_KERNEL); +- if (!sg) ++ p = smb2_aead_req_alloc(tfm, rqst, num_rqst, sig, iv, req, sgl, &num_sgs); ++ if (!p) + return NULL; + +- sg_init_table(sg, sg_len); ++ sg_init_table(*sgl, num_sgs); ++ sg = *sgl; ++ ++ /* Assumes the first rqst has a transform header as the first iov. ++ * I.e. ++ * rqst[0].rq_iov[0] is transform header ++ * rqst[0].rq_iov[1+] data to be encrypted/decrypted ++ * rqst[1+].rq_iov[0+] data to be encrypted/decrypted ++ */ + for (i = 0; i < num_rqst; i++) { ++ /* ++ * The first rqst has a transform header where the ++ * first 20 bytes are not part of the encrypted blob. ++ */ + for (j = 0; j < rqst[i].rq_nvec; j++) { +- /* +- * The first rqst has a transform header where the +- * first 20 bytes are not part of the encrypted blob +- */ +- skip = (i == 0) && (j == 0) ? 20 : 0; +- smb2_sg_set_buf(&sg[idx++], +- rqst[i].rq_iov[j].iov_base + skip, +- rqst[i].rq_iov[j].iov_len - skip); +- } ++ struct kvec *iov = &rqst[i].rq_iov[j]; + ++ skip = (i == 0) && (j == 0) ? 20 : 0; ++ addr = (unsigned long)iov->iov_base + skip; ++ len = iov->iov_len - skip; ++ sg = cifs_sg_set_buf(sg, (void *)addr, len); ++ } + for (j = 0; j < rqst[i].rq_npages; j++) { +- unsigned int len, offset; +- +- rqst_page_get_length(&rqst[i], j, &len, &offset); +- sg_set_page(&sg[idx++], rqst[i].rq_pages[j], len, offset); ++ rqst_page_get_length(&rqst[i], j, &len, &off); ++ sg_set_page(sg++, rqst[i].rq_pages[j], len, off); + } + } +- smb2_sg_set_buf(&sg[idx], sign, SMB2_SIGNATURE_SIZE); +- return sg; ++ cifs_sg_set_buf(sg, sig, SMB2_SIGNATURE_SIZE); ++ ++ return p; + } + + static int +@@ -4290,11 +4303,11 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, + u8 sign[SMB2_SIGNATURE_SIZE] = {}; + u8 key[SMB3_ENC_DEC_KEY_SIZE]; + struct aead_request *req; +- char *iv; +- unsigned int iv_len; ++ u8 *iv; + DECLARE_CRYPTO_WAIT(wait); + struct crypto_aead *tfm; + unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize); ++ void *creq; + + rc = smb2_get_enc_key(server, le64_to_cpu(tr_hdr->SessionId), enc, key); + if (rc) { +@@ -4329,32 +4342,15 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, + return rc; + } + +- req = aead_request_alloc(tfm, GFP_KERNEL); +- if (!req) { +- cifs_server_dbg(VFS, "%s: Failed to alloc aead request\n", __func__); ++ creq = smb2_get_aead_req(tfm, rqst, num_rqst, sign, &iv, &req, &sg); ++ if (unlikely(!creq)) + return -ENOMEM; +- } + + if (!enc) { + memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE); + crypt_len += SMB2_SIGNATURE_SIZE; + } + +- sg = init_sg(num_rqst, rqst, sign); +- if (!sg) { +- cifs_server_dbg(VFS, "%s: Failed to init sg\n", __func__); +- rc = -ENOMEM; +- goto free_req; +- } +- +- iv_len = crypto_aead_ivsize(tfm); +- iv = kzalloc(iv_len, GFP_KERNEL); +- if (!iv) { +- cifs_server_dbg(VFS, "%s: Failed to alloc iv\n", __func__); +- rc = -ENOMEM; +- goto free_sg; +- } +- + if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) || + (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) + memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE); +@@ -4363,6 +4359,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, + memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE); + } + ++ aead_request_set_tfm(req, tfm); + aead_request_set_crypt(req, sg, sg, crypt_len, iv); + aead_request_set_ad(req, assoc_data_len); + +@@ -4375,11 +4372,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, + if (!rc && enc) + memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE); + +- kfree_sensitive(iv); +-free_sg: +- kfree_sensitive(sg); +-free_req: +- kfree_sensitive(req); ++ kfree_sensitive(creq); + return rc; + } + +-- +2.35.1 + diff --git a/queue-6.0/cifs-improve-symlink-handling-for-smb2.patch b/queue-6.0/cifs-improve-symlink-handling-for-smb2.patch new file mode 100644 index 00000000000..6d7db2308f9 --- /dev/null +++ b/queue-6.0/cifs-improve-symlink-handling-for-smb2.patch @@ -0,0 +1,1905 @@ +From e4469058d117d3c5541e98f30ef5510239c0a71d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Oct 2022 18:43:50 -0300 +Subject: cifs: improve symlink handling for smb2+ + +From: Paulo Alcantara + +[ Upstream commit 76894f3e2f71177747b8b4763fb180e800279585 ] + +When creating inode for symlink, the client used to send below +requests to fill it in: + + * create+query_info+close (STATUS_STOPPED_ON_SYMLINK) + * create(+reparse_flag)+query_info+close (set file attrs) + * create+ioctl(get_reparse)+close (query reparse tag) + +and then for every access to the symlink dentry, the ->link() method +would send another: + + * create+ioctl(get_reparse)+close (parse symlink) + +So, in order to improve: + + (i) Get rid of unnecessary roundtrips and then resolve symlinks as + follows: + + * create+query_info+close (STATUS_STOPPED_ON_SYMLINK + + parse symlink + get reparse tag) + * create(+reparse_flag)+query_info+close (set file attrs) + + (ii) Set the resolved symlink target directly in inode->i_link and + use simple_get_link() for ->link() to simply return it. + +Signed-off-by: Paulo Alcantara (SUSE) +Reviewed-by: Ronnie Sahlberg +Signed-off-by: Steve French +Stable-dep-of: f7f291e14dde ("cifs: fix oops during encryption") +Signed-off-by: Sasha Levin +--- + fs/cifs/cifsfs.c | 9 ++- + fs/cifs/cifsglob.h | 46 +++++++++--- + fs/cifs/cifsproto.h | 13 ++-- + fs/cifs/dir.c | 30 +++----- + fs/cifs/file.c | 41 ++++++----- + fs/cifs/inode.c | 170 ++++++++++++++++++++++++++------------------ + fs/cifs/link.c | 107 +--------------------------- + fs/cifs/readdir.c | 2 + + fs/cifs/smb1ops.c | 56 +++++++++------ + fs/cifs/smb2file.c | 127 +++++++++++++++++++++++++++------ + fs/cifs/smb2inode.c | 169 ++++++++++++++++++++++--------------------- + fs/cifs/smb2ops.c | 109 ++++++---------------------- + fs/cifs/smb2pdu.h | 3 + + fs/cifs/smb2proto.h | 22 +++--- + 14 files changed, 451 insertions(+), 453 deletions(-) + +diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c +index ccad85feb24e..ad683048e5ce 100644 +--- a/fs/cifs/cifsfs.c ++++ b/fs/cifs/cifsfs.c +@@ -396,6 +396,7 @@ cifs_alloc_inode(struct super_block *sb) + cifs_inode->epoch = 0; + spin_lock_init(&cifs_inode->open_file_lock); + generate_random_uuid(cifs_inode->lease_key); ++ cifs_inode->symlink_target = NULL; + + /* + * Can not set i_flags here - they get immediately overwritten to zero +@@ -412,7 +413,11 @@ cifs_alloc_inode(struct super_block *sb) + static void + cifs_free_inode(struct inode *inode) + { +- kmem_cache_free(cifs_inode_cachep, CIFS_I(inode)); ++ struct cifsInodeInfo *cinode = CIFS_I(inode); ++ ++ if (S_ISLNK(inode->i_mode)) ++ kfree(cinode->symlink_target); ++ kmem_cache_free(cifs_inode_cachep, cinode); + } + + static void +@@ -1139,7 +1144,7 @@ const struct inode_operations cifs_file_inode_ops = { + }; + + const struct inode_operations cifs_symlink_inode_ops = { +- .get_link = cifs_get_link, ++ .get_link = simple_get_link, + .permission = cifs_permission, + .listxattr = cifs_listxattr, + }; +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index ae7f571a7dba..333022028bb0 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -195,6 +195,19 @@ struct cifs_cred { + struct cifs_ace *aces; + }; + ++struct cifs_open_info_data { ++ char *symlink_target; ++ union { ++ struct smb2_file_all_info fi; ++ struct smb311_posix_qinfo posix_fi; ++ }; ++}; ++ ++static inline void cifs_free_open_info(struct cifs_open_info_data *data) ++{ ++ kfree(data->symlink_target); ++} ++ + /* + ***************************************************************** + * Except the CIFS PDUs themselves all the +@@ -317,20 +330,20 @@ struct smb_version_operations { + int (*is_path_accessible)(const unsigned int, struct cifs_tcon *, + struct cifs_sb_info *, const char *); + /* query path data from the server */ +- int (*query_path_info)(const unsigned int, struct cifs_tcon *, +- struct cifs_sb_info *, const char *, +- FILE_ALL_INFO *, bool *, bool *); ++ int (*query_path_info)(const unsigned int xid, struct cifs_tcon *tcon, ++ struct cifs_sb_info *cifs_sb, const char *full_path, ++ struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse); + /* query file data from the server */ +- int (*query_file_info)(const unsigned int, struct cifs_tcon *, +- struct cifs_fid *, FILE_ALL_INFO *); ++ int (*query_file_info)(const unsigned int xid, struct cifs_tcon *tcon, ++ struct cifsFileInfo *cfile, struct cifs_open_info_data *data); + /* query reparse tag from srv to determine which type of special file */ + int (*query_reparse_tag)(const unsigned int xid, struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, const char *path, + __u32 *reparse_tag); + /* get server index number */ +- int (*get_srv_inum)(const unsigned int, struct cifs_tcon *, +- struct cifs_sb_info *, const char *, +- u64 *uniqueid, FILE_ALL_INFO *); ++ int (*get_srv_inum)(const unsigned int xid, struct cifs_tcon *tcon, ++ struct cifs_sb_info *cifs_sb, const char *full_path, u64 *uniqueid, ++ struct cifs_open_info_data *data); + /* set size by path */ + int (*set_path_size)(const unsigned int, struct cifs_tcon *, + const char *, __u64, struct cifs_sb_info *, bool); +@@ -379,8 +392,8 @@ struct smb_version_operations { + struct cifs_sb_info *, const char *, + char **, bool); + /* open a file for non-posix mounts */ +- int (*open)(const unsigned int, struct cifs_open_parms *, +- __u32 *, FILE_ALL_INFO *); ++ int (*open)(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock, ++ void *buf); + /* set fid protocol-specific info */ + void (*set_fid)(struct cifsFileInfo *, struct cifs_fid *, __u32); + /* close a file */ +@@ -1133,6 +1146,7 @@ struct cifs_fattr { + struct timespec64 cf_mtime; + struct timespec64 cf_ctime; + u32 cf_cifstag; ++ char *cf_symlink_target; + }; + + /* +@@ -1395,6 +1409,7 @@ struct cifsFileInfo { + struct work_struct put; /* work for the final part of _put */ + struct delayed_work deferred; + bool deferred_close_scheduled; /* Flag to indicate close is scheduled */ ++ char *symlink_target; + }; + + struct cifs_io_parms { +@@ -1553,6 +1568,7 @@ struct cifsInodeInfo { + struct list_head deferred_closes; /* list of deferred closes */ + spinlock_t deferred_lock; /* protection on deferred list */ + bool lease_granted; /* Flag to indicate whether lease or oplock is granted. */ ++ char *symlink_target; + }; + + static inline struct cifsInodeInfo * +@@ -2121,4 +2137,14 @@ static inline size_t ntlmssp_workstation_name_size(const struct cifs_ses *ses) + return sizeof(ses->workstation_name); + } + ++static inline void move_cifs_info_to_smb2(struct smb2_file_all_info *dst, const FILE_ALL_INFO *src) ++{ ++ memcpy(dst, src, (size_t)((u8 *)&src->AccessFlags - (u8 *)src)); ++ dst->AccessFlags = src->AccessFlags; ++ dst->CurrentByteOffset = src->CurrentByteOffset; ++ dst->Mode = src->Mode; ++ dst->AlignmentRequirement = src->AlignmentRequirement; ++ dst->FileNameLength = src->FileNameLength; ++} ++ + #endif /* _CIFS_GLOB_H */ +diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h +index 71386978858e..372ff64a285b 100644 +--- a/fs/cifs/cifsproto.h ++++ b/fs/cifs/cifsproto.h +@@ -182,10 +182,9 @@ extern int cifs_unlock_range(struct cifsFileInfo *cfile, + extern int cifs_push_mandatory_locks(struct cifsFileInfo *cfile); + + extern void cifs_down_write(struct rw_semaphore *sem); +-extern struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, +- struct file *file, +- struct tcon_link *tlink, +- __u32 oplock); ++struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, ++ struct tcon_link *tlink, __u32 oplock, ++ const char *symlink_target); + extern int cifs_posix_open(const char *full_path, struct inode **inode, + struct super_block *sb, int mode, + unsigned int f_flags, __u32 *oplock, __u16 *netfid, +@@ -200,9 +199,9 @@ extern int cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr); + extern struct inode *cifs_iget(struct super_block *sb, + struct cifs_fattr *fattr); + +-extern int cifs_get_inode_info(struct inode **inode, const char *full_path, +- FILE_ALL_INFO *data, struct super_block *sb, +- int xid, const struct cifs_fid *fid); ++int cifs_get_inode_info(struct inode **inode, const char *full_path, ++ struct cifs_open_info_data *data, struct super_block *sb, int xid, ++ const struct cifs_fid *fid); + extern int smb311_posix_get_inode_info(struct inode **pinode, const char *search_path, + struct super_block *sb, unsigned int xid); + extern int cifs_get_inode_info_unix(struct inode **pinode, +diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c +index 05c78a18ade0..c85816cf2d9b 100644 +--- a/fs/cifs/dir.c ++++ b/fs/cifs/dir.c +@@ -165,10 +165,9 @@ check_name(struct dentry *direntry, struct cifs_tcon *tcon) + + /* Inode operations in similar order to how they appear in Linux file fs.h */ + +-static int +-cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, +- struct tcon_link *tlink, unsigned oflags, umode_t mode, +- __u32 *oplock, struct cifs_fid *fid) ++static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, ++ struct tcon_link *tlink, unsigned int oflags, umode_t mode, __u32 *oplock, ++ struct cifs_fid *fid, struct cifs_open_info_data *buf) + { + int rc = -ENOENT; + int create_options = CREATE_NOT_DIR; +@@ -177,7 +176,6 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, + struct cifs_tcon *tcon = tlink_tcon(tlink); + const char *full_path; + void *page = alloc_dentry_path(); +- FILE_ALL_INFO *buf = NULL; + struct inode *newinode = NULL; + int disposition; + struct TCP_Server_Info *server = tcon->ses->server; +@@ -290,12 +288,6 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, + goto out; + } + +- buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); +- if (buf == NULL) { +- rc = -ENOMEM; +- goto out; +- } +- + /* + * if we're not using unix extensions, see if we need to set + * ATTR_READONLY on the create call +@@ -364,8 +356,7 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, + { + #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ + /* TODO: Add support for calling POSIX query info here, but passing in fid */ +- rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb, +- xid, fid); ++ rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb, xid, fid); + if (newinode) { + if (server->ops->set_lease_key) + server->ops->set_lease_key(newinode, fid); +@@ -402,7 +393,6 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, + d_add(direntry, newinode); + + out: +- kfree(buf); + free_dentry_path(page); + return rc; + +@@ -427,6 +417,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, + struct cifs_pending_open open; + __u32 oplock; + struct cifsFileInfo *file_info; ++ struct cifs_open_info_data buf = {}; + + if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) + return -EIO; +@@ -484,8 +475,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, + cifs_add_pending_open(&fid, tlink, &open); + + rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, +- &oplock, &fid); +- ++ &oplock, &fid, &buf); + if (rc) { + cifs_del_pending_open(&open); + goto out; +@@ -510,7 +500,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, + file->f_op = &cifs_file_direct_ops; + } + +- file_info = cifs_new_fileinfo(&fid, file, tlink, oplock); ++ file_info = cifs_new_fileinfo(&fid, file, tlink, oplock, buf.symlink_target); + if (file_info == NULL) { + if (server->ops->close) + server->ops->close(xid, tcon, &fid); +@@ -526,6 +516,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, + cifs_put_tlink(tlink); + out_free_xid: + free_xid(xid); ++ cifs_free_open_info(&buf); + return rc; + } + +@@ -547,6 +538,7 @@ int cifs_create(struct user_namespace *mnt_userns, struct inode *inode, + struct TCP_Server_Info *server; + struct cifs_fid fid; + __u32 oplock; ++ struct cifs_open_info_data buf = {}; + + cifs_dbg(FYI, "cifs_create parent inode = 0x%p name is: %pd and dentry = 0x%p\n", + inode, direntry, direntry); +@@ -567,11 +559,11 @@ int cifs_create(struct user_namespace *mnt_userns, struct inode *inode, + if (server->ops->new_lease_key) + server->ops->new_lease_key(&fid); + +- rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, +- &oplock, &fid); ++ rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, &oplock, &fid, &buf); + if (!rc && server->ops->close) + server->ops->close(xid, tcon, &fid); + ++ cifs_free_open_info(&buf); + cifs_put_tlink(tlink); + out_free_xid: + free_xid(xid); +diff --git a/fs/cifs/file.c b/fs/cifs/file.c +index 5c045dd69784..391fd2580dab 100644 +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -209,16 +209,14 @@ int cifs_posix_open(const char *full_path, struct inode **pinode, + } + #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ + +-static int +-cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, +- struct cifs_tcon *tcon, unsigned int f_flags, __u32 *oplock, +- struct cifs_fid *fid, unsigned int xid) ++static int cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, ++ struct cifs_tcon *tcon, unsigned int f_flags, __u32 *oplock, ++ struct cifs_fid *fid, unsigned int xid, struct cifs_open_info_data *buf) + { + int rc; + int desired_access; + int disposition; + int create_options = CREATE_NOT_DIR; +- FILE_ALL_INFO *buf; + struct TCP_Server_Info *server = tcon->ses->server; + struct cifs_open_parms oparms; + +@@ -255,10 +253,6 @@ cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *ci + + /* BB pass O_SYNC flag through on file attributes .. BB */ + +- buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); +- if (!buf) +- return -ENOMEM; +- + /* O_SYNC also has bit for O_DSYNC so following check picks up either */ + if (f_flags & O_SYNC) + create_options |= CREATE_WRITE_THROUGH; +@@ -276,9 +270,8 @@ cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *ci + oparms.reconnect = false; + + rc = server->ops->open(xid, &oparms, oplock, buf); +- + if (rc) +- goto out; ++ return rc; + + /* TODO: Add support for calling posix query info but with passing in fid */ + if (tcon->unix_ext) +@@ -294,8 +287,6 @@ cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *ci + rc = -EOPENSTALE; + } + +-out: +- kfree(buf); + return rc; + } + +@@ -325,9 +316,9 @@ cifs_down_write(struct rw_semaphore *sem) + + static void cifsFileInfo_put_work(struct work_struct *work); + +-struct cifsFileInfo * +-cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, +- struct tcon_link *tlink, __u32 oplock) ++struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, ++ struct tcon_link *tlink, __u32 oplock, ++ const char *symlink_target) + { + struct dentry *dentry = file_dentry(file); + struct inode *inode = d_inode(dentry); +@@ -347,6 +338,15 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, + return NULL; + } + ++ if (symlink_target) { ++ cfile->symlink_target = kstrdup(symlink_target, GFP_KERNEL); ++ if (!cfile->symlink_target) { ++ kfree(fdlocks); ++ kfree(cfile); ++ return NULL; ++ } ++ } ++ + INIT_LIST_HEAD(&fdlocks->locks); + fdlocks->cfile = cfile; + cfile->llist = fdlocks; +@@ -440,6 +440,7 @@ static void cifsFileInfo_put_final(struct cifsFileInfo *cifs_file) + cifs_put_tlink(cifs_file->tlink); + dput(cifs_file->dentry); + cifs_sb_deactive(sb); ++ kfree(cifs_file->symlink_target); + kfree(cifs_file); + } + +@@ -572,6 +573,7 @@ int cifs_open(struct inode *inode, struct file *file) + bool posix_open_ok = false; + struct cifs_fid fid; + struct cifs_pending_open open; ++ struct cifs_open_info_data data = {}; + + xid = get_xid(); + +@@ -662,15 +664,15 @@ int cifs_open(struct inode *inode, struct file *file) + if (server->ops->get_lease_key) + server->ops->get_lease_key(inode, &fid); + +- rc = cifs_nt_open(full_path, inode, cifs_sb, tcon, +- file->f_flags, &oplock, &fid, xid); ++ rc = cifs_nt_open(full_path, inode, cifs_sb, tcon, file->f_flags, &oplock, &fid, ++ xid, &data); + if (rc) { + cifs_del_pending_open(&open); + goto out; + } + } + +- cfile = cifs_new_fileinfo(&fid, file, tlink, oplock); ++ cfile = cifs_new_fileinfo(&fid, file, tlink, oplock, data.symlink_target); + if (cfile == NULL) { + if (server->ops->close) + server->ops->close(xid, tcon, &fid); +@@ -712,6 +714,7 @@ int cifs_open(struct inode *inode, struct file *file) + free_dentry_path(page); + free_xid(xid); + cifs_put_tlink(tlink); ++ cifs_free_open_info(&data); + return rc; + } + +diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c +index bac08c20f559..c1ea821899f8 100644 +--- a/fs/cifs/inode.c ++++ b/fs/cifs/inode.c +@@ -210,6 +210,17 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) + */ + inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9; + } ++ ++ if (S_ISLNK(fattr->cf_mode)) { ++ kfree(cifs_i->symlink_target); ++ cifs_i->symlink_target = fattr->cf_symlink_target; ++ fattr->cf_symlink_target = NULL; ++ ++ if (unlikely(!cifs_i->symlink_target)) ++ inode->i_link = ERR_PTR(-EOPNOTSUPP); ++ else ++ inode->i_link = cifs_i->symlink_target; ++ } + spin_unlock(&inode->i_lock); + + if (fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL) +@@ -347,13 +358,20 @@ cifs_get_file_info_unix(struct file *filp) + int rc; + unsigned int xid; + FILE_UNIX_BASIC_INFO find_data; +- struct cifs_fattr fattr; ++ struct cifs_fattr fattr = {}; + struct inode *inode = file_inode(filp); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifsFileInfo *cfile = filp->private_data; + struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); + + xid = get_xid(); ++ ++ if (cfile->symlink_target) { ++ fattr.cf_symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL); ++ if (!fattr.cf_symlink_target) ++ return -ENOMEM; ++ } ++ + rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->fid.netfid, &find_data); + if (!rc) { + cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb); +@@ -378,6 +396,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, + FILE_UNIX_BASIC_INFO find_data; + struct cifs_fattr fattr; + struct cifs_tcon *tcon; ++ struct TCP_Server_Info *server; + struct tcon_link *tlink; + struct cifs_sb_info *cifs_sb = CIFS_SB(sb); + +@@ -387,10 +406,12 @@ int cifs_get_inode_info_unix(struct inode **pinode, + if (IS_ERR(tlink)) + return PTR_ERR(tlink); + tcon = tlink_tcon(tlink); ++ server = tcon->ses->server; + + /* could have done a find first instead but this returns more info */ + rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data, + cifs_sb->local_nls, cifs_remap(cifs_sb)); ++ cifs_dbg(FYI, "%s: query path info: rc = %d\n", __func__, rc); + cifs_put_tlink(tlink); + + if (!rc) { +@@ -410,6 +431,17 @@ int cifs_get_inode_info_unix(struct inode **pinode, + cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc); + } + ++ if (S_ISLNK(fattr.cf_mode) && !fattr.cf_symlink_target) { ++ if (!server->ops->query_symlink) ++ return -EOPNOTSUPP; ++ rc = server->ops->query_symlink(xid, tcon, cifs_sb, full_path, ++ &fattr.cf_symlink_target, false); ++ if (rc) { ++ cifs_dbg(FYI, "%s: query_symlink: %d\n", __func__, rc); ++ goto cgiiu_exit; ++ } ++ } ++ + if (*pinode == NULL) { + /* get new inode */ + cifs_fill_uniqueid(sb, &fattr); +@@ -432,6 +464,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, + } + + cgiiu_exit: ++ kfree(fattr.cf_symlink_target); + return rc; + } + #else +@@ -601,10 +634,10 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path, + } + + /* Fill a cifs_fattr struct with info from POSIX info struct */ +-static void +-smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct smb311_posix_qinfo *info, +- struct super_block *sb, bool adjust_tz, bool symlink) ++static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct cifs_open_info_data *data, ++ struct super_block *sb, bool adjust_tz, bool symlink) + { ++ struct smb311_posix_qinfo *info = &data->posix_fi; + struct cifs_sb_info *cifs_sb = CIFS_SB(sb); + struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); + +@@ -639,6 +672,8 @@ smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct smb311_posix_qinfo * + if (symlink) { + fattr->cf_mode |= S_IFLNK; + fattr->cf_dtype = DT_LNK; ++ fattr->cf_symlink_target = data->symlink_target; ++ data->symlink_target = NULL; + } else if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { + fattr->cf_mode |= S_IFDIR; + fattr->cf_dtype = DT_DIR; +@@ -655,13 +690,11 @@ smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct smb311_posix_qinfo * + fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink); + } + +- +-/* Fill a cifs_fattr struct with info from FILE_ALL_INFO */ +-static void +-cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, +- struct super_block *sb, bool adjust_tz, +- bool symlink, u32 reparse_tag) ++static void cifs_open_info_to_fattr(struct cifs_fattr *fattr, struct cifs_open_info_data *data, ++ struct super_block *sb, bool adjust_tz, bool symlink, ++ u32 reparse_tag) + { ++ struct smb2_file_all_info *info = &data->fi; + struct cifs_sb_info *cifs_sb = CIFS_SB(sb); + struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); + +@@ -703,7 +736,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, + } else if (reparse_tag == IO_REPARSE_TAG_LX_BLK) { + fattr->cf_mode |= S_IFBLK | cifs_sb->ctx->file_mode; + fattr->cf_dtype = DT_BLK; +- } else if (symlink) { /* TODO add more reparse tag checks */ ++ } else if (symlink || reparse_tag == IO_REPARSE_TAG_SYMLINK || ++ reparse_tag == IO_REPARSE_TAG_NFS) { + fattr->cf_mode = S_IFLNK; + fattr->cf_dtype = DT_LNK; + } else if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { +@@ -735,6 +769,11 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, + } + } + ++ if (S_ISLNK(fattr->cf_mode)) { ++ fattr->cf_symlink_target = data->symlink_target; ++ data->symlink_target = NULL; ++ } ++ + fattr->cf_uid = cifs_sb->ctx->linux_uid; + fattr->cf_gid = cifs_sb->ctx->linux_gid; + } +@@ -744,23 +783,28 @@ cifs_get_file_info(struct file *filp) + { + int rc; + unsigned int xid; +- FILE_ALL_INFO find_data; ++ struct cifs_open_info_data data = {}; + struct cifs_fattr fattr; + struct inode *inode = file_inode(filp); + struct cifsFileInfo *cfile = filp->private_data; + struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); + struct TCP_Server_Info *server = tcon->ses->server; ++ bool symlink = false; ++ u32 tag = 0; + + if (!server->ops->query_file_info) + return -ENOSYS; + + xid = get_xid(); +- rc = server->ops->query_file_info(xid, tcon, &cfile->fid, &find_data); ++ rc = server->ops->query_file_info(xid, tcon, cfile, &data); + switch (rc) { + case 0: + /* TODO: add support to query reparse tag */ +- cifs_all_info_to_fattr(&fattr, &find_data, inode->i_sb, false, +- false, 0 /* no reparse tag */); ++ if (data.symlink_target) { ++ symlink = true; ++ tag = IO_REPARSE_TAG_SYMLINK; ++ } ++ cifs_open_info_to_fattr(&fattr, &data, inode->i_sb, false, symlink, tag); + break; + case -EREMOTE: + cifs_create_dfs_fattr(&fattr, inode->i_sb); +@@ -789,6 +833,7 @@ cifs_get_file_info(struct file *filp) + /* if filetype is different, return error */ + rc = cifs_fattr_to_inode(inode, &fattr); + cgfi_exit: ++ cifs_free_open_info(&data); + free_xid(xid); + return rc; + } +@@ -860,14 +905,9 @@ cifs_backup_query_path_info(int xid, + } + #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ + +-static void +-cifs_set_fattr_ino(int xid, +- struct cifs_tcon *tcon, +- struct super_block *sb, +- struct inode **inode, +- const char *full_path, +- FILE_ALL_INFO *data, +- struct cifs_fattr *fattr) ++static void cifs_set_fattr_ino(int xid, struct cifs_tcon *tcon, struct super_block *sb, ++ struct inode **inode, const char *full_path, ++ struct cifs_open_info_data *data, struct cifs_fattr *fattr) + { + struct cifs_sb_info *cifs_sb = CIFS_SB(sb); + struct TCP_Server_Info *server = tcon->ses->server; +@@ -885,11 +925,8 @@ cifs_set_fattr_ino(int xid, + * If we have an inode pass a NULL tcon to ensure we don't + * make a round trip to the server. This only works for SMB2+. + */ +- rc = server->ops->get_srv_inum(xid, +- *inode ? NULL : tcon, +- cifs_sb, full_path, +- &fattr->cf_uniqueid, +- data); ++ rc = server->ops->get_srv_inum(xid, *inode ? NULL : tcon, cifs_sb, full_path, ++ &fattr->cf_uniqueid, data); + if (rc) { + /* + * If that fails reuse existing ino or generate one +@@ -923,14 +960,10 @@ static inline bool is_inode_cache_good(struct inode *ino) + return ino && CIFS_CACHE_READ(CIFS_I(ino)) && CIFS_I(ino)->time != 0; + } + +-int +-cifs_get_inode_info(struct inode **inode, +- const char *full_path, +- FILE_ALL_INFO *in_data, +- struct super_block *sb, int xid, +- const struct cifs_fid *fid) ++int cifs_get_inode_info(struct inode **inode, const char *full_path, ++ struct cifs_open_info_data *data, struct super_block *sb, int xid, ++ const struct cifs_fid *fid) + { +- + struct cifs_tcon *tcon; + struct TCP_Server_Info *server; + struct tcon_link *tlink; +@@ -938,8 +971,7 @@ cifs_get_inode_info(struct inode **inode, + bool adjust_tz = false; + struct cifs_fattr fattr = {0}; + bool is_reparse_point = false; +- FILE_ALL_INFO *data = in_data; +- FILE_ALL_INFO *tmp_data = NULL; ++ struct cifs_open_info_data tmp_data = {}; + void *smb1_backup_rsp_buf = NULL; + int rc = 0; + int tmprc = 0; +@@ -960,21 +992,15 @@ cifs_get_inode_info(struct inode **inode, + cifs_dbg(FYI, "No need to revalidate cached inode sizes\n"); + goto out; + } +- tmp_data = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); +- if (!tmp_data) { +- rc = -ENOMEM; +- goto out; +- } +- rc = server->ops->query_path_info(xid, tcon, cifs_sb, +- full_path, tmp_data, +- &adjust_tz, &is_reparse_point); ++ rc = server->ops->query_path_info(xid, tcon, cifs_sb, full_path, &tmp_data, ++ &adjust_tz, &is_reparse_point); + #ifdef CONFIG_CIFS_DFS_UPCALL + if (rc == -ENOENT && is_tcon_dfs(tcon)) + rc = cifs_dfs_query_info_nonascii_quirk(xid, tcon, + cifs_sb, + full_path); + #endif +- data = tmp_data; ++ data = &tmp_data; + } + + /* +@@ -988,14 +1014,24 @@ cifs_get_inode_info(struct inode **inode, + * since we have to check if its reparse tag matches a known + * special file type e.g. symlink or fifo or char etc. + */ +- if ((le32_to_cpu(data->Attributes) & ATTR_REPARSE) && +- server->ops->query_reparse_tag) { +- rc = server->ops->query_reparse_tag(xid, tcon, cifs_sb, +- full_path, &reparse_tag); +- cifs_dbg(FYI, "reparse tag 0x%x\n", reparse_tag); ++ if (is_reparse_point && data->symlink_target) { ++ reparse_tag = IO_REPARSE_TAG_SYMLINK; ++ } else if ((le32_to_cpu(data->fi.Attributes) & ATTR_REPARSE) && ++ server->ops->query_reparse_tag) { ++ tmprc = server->ops->query_reparse_tag(xid, tcon, cifs_sb, full_path, ++ &reparse_tag); ++ if (tmprc) ++ cifs_dbg(FYI, "%s: query_reparse_tag: rc = %d\n", __func__, tmprc); ++ if (server->ops->query_symlink) { ++ tmprc = server->ops->query_symlink(xid, tcon, cifs_sb, full_path, ++ &data->symlink_target, ++ is_reparse_point); ++ if (tmprc) ++ cifs_dbg(FYI, "%s: query_symlink: rc = %d\n", __func__, ++ tmprc); ++ } + } +- cifs_all_info_to_fattr(&fattr, data, sb, adjust_tz, +- is_reparse_point, reparse_tag); ++ cifs_open_info_to_fattr(&fattr, data, sb, adjust_tz, is_reparse_point, reparse_tag); + break; + case -EREMOTE: + /* DFS link, no metadata available on this server */ +@@ -1014,18 +1050,20 @@ cifs_get_inode_info(struct inode **inode, + */ + if (backup_cred(cifs_sb) && is_smb1_server(server)) { + /* for easier reading */ ++ FILE_ALL_INFO *fi; + FILE_DIRECTORY_INFO *fdi; + SEARCH_ID_FULL_DIR_INFO *si; + + rc = cifs_backup_query_path_info(xid, tcon, sb, + full_path, + &smb1_backup_rsp_buf, +- &data); ++ &fi); + if (rc) + goto out; + +- fdi = (FILE_DIRECTORY_INFO *)data; +- si = (SEARCH_ID_FULL_DIR_INFO *)data; ++ move_cifs_info_to_smb2(&data->fi, fi); ++ fdi = (FILE_DIRECTORY_INFO *)fi; ++ si = (SEARCH_ID_FULL_DIR_INFO *)fi; + + cifs_dir_info_to_fattr(&fattr, fdi, cifs_sb); + fattr.cf_uniqueid = le64_to_cpu(si->UniqueId); +@@ -1123,7 +1161,8 @@ cifs_get_inode_info(struct inode **inode, + out: + cifs_buf_release(smb1_backup_rsp_buf); + cifs_put_tlink(tlink); +- kfree(tmp_data); ++ cifs_free_open_info(&tmp_data); ++ kfree(fattr.cf_symlink_target); + return rc; + } + +@@ -1138,7 +1177,7 @@ smb311_posix_get_inode_info(struct inode **inode, + bool adjust_tz = false; + struct cifs_fattr fattr = {0}; + bool symlink = false; +- struct smb311_posix_qinfo *data = NULL; ++ struct cifs_open_info_data data = {}; + int rc = 0; + int tmprc = 0; + +@@ -1155,15 +1194,9 @@ smb311_posix_get_inode_info(struct inode **inode, + cifs_dbg(FYI, "No need to revalidate cached inode sizes\n"); + goto out; + } +- data = kmalloc(sizeof(struct smb311_posix_qinfo), GFP_KERNEL); +- if (!data) { +- rc = -ENOMEM; +- goto out; +- } + +- rc = smb311_posix_query_path_info(xid, tcon, cifs_sb, +- full_path, data, +- &adjust_tz, &symlink); ++ rc = smb311_posix_query_path_info(xid, tcon, cifs_sb, full_path, &data, &adjust_tz, ++ &symlink); + + /* + * 2. Convert it to internal cifs metadata (fattr) +@@ -1171,7 +1204,7 @@ smb311_posix_get_inode_info(struct inode **inode, + + switch (rc) { + case 0: +- smb311_posix_info_to_fattr(&fattr, data, sb, adjust_tz, symlink); ++ smb311_posix_info_to_fattr(&fattr, &data, sb, adjust_tz, symlink); + break; + case -EREMOTE: + /* DFS link, no metadata available on this server */ +@@ -1228,7 +1261,8 @@ smb311_posix_get_inode_info(struct inode **inode, + } + out: + cifs_put_tlink(tlink); +- kfree(data); ++ cifs_free_open_info(&data); ++ kfree(fattr.cf_symlink_target); + return rc; + } + +diff --git a/fs/cifs/link.c b/fs/cifs/link.c +index 6803cb27eecc..8042dbdd182b 100644 +--- a/fs/cifs/link.c ++++ b/fs/cifs/link.c +@@ -202,40 +202,6 @@ create_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon, + return rc; + } + +-static int +-query_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon, +- struct cifs_sb_info *cifs_sb, const unsigned char *path, +- char **symlinkinfo) +-{ +- int rc; +- u8 *buf = NULL; +- unsigned int link_len = 0; +- unsigned int bytes_read = 0; +- +- buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); +- if (!buf) +- return -ENOMEM; +- +- if (tcon->ses->server->ops->query_mf_symlink) +- rc = tcon->ses->server->ops->query_mf_symlink(xid, tcon, +- cifs_sb, path, buf, &bytes_read); +- else +- rc = -ENOSYS; +- +- if (rc) +- goto out; +- +- if (bytes_read == 0) { /* not a symlink */ +- rc = -EINVAL; +- goto out; +- } +- +- rc = parse_mf_symlink(buf, bytes_read, &link_len, symlinkinfo); +-out: +- kfree(buf); +- return rc; +-} +- + int + check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, +@@ -245,6 +211,7 @@ check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, + u8 *buf = NULL; + unsigned int link_len = 0; + unsigned int bytes_read = 0; ++ char *symlink = NULL; + + if (!couldbe_mf_symlink(fattr)) + /* it's not a symlink */ +@@ -266,7 +233,7 @@ check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, + if (bytes_read == 0) /* not a symlink */ + goto out; + +- rc = parse_mf_symlink(buf, bytes_read, &link_len, NULL); ++ rc = parse_mf_symlink(buf, bytes_read, &link_len, &symlink); + if (rc == -EINVAL) { + /* it's not a symlink */ + rc = 0; +@@ -281,6 +248,7 @@ check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, + fattr->cf_mode &= ~S_IFMT; + fattr->cf_mode |= S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO; + fattr->cf_dtype = DT_LNK; ++ fattr->cf_symlink_target = symlink; + out: + kfree(buf); + return rc; +@@ -600,75 +568,6 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, + return rc; + } + +-const char * +-cifs_get_link(struct dentry *direntry, struct inode *inode, +- struct delayed_call *done) +-{ +- int rc = -ENOMEM; +- unsigned int xid; +- const char *full_path; +- void *page; +- char *target_path = NULL; +- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); +- struct tcon_link *tlink = NULL; +- struct cifs_tcon *tcon; +- struct TCP_Server_Info *server; +- +- if (!direntry) +- return ERR_PTR(-ECHILD); +- +- xid = get_xid(); +- +- tlink = cifs_sb_tlink(cifs_sb); +- if (IS_ERR(tlink)) { +- free_xid(xid); +- return ERR_CAST(tlink); +- } +- tcon = tlink_tcon(tlink); +- server = tcon->ses->server; +- +- page = alloc_dentry_path(); +- full_path = build_path_from_dentry(direntry, page); +- if (IS_ERR(full_path)) { +- free_xid(xid); +- cifs_put_tlink(tlink); +- free_dentry_path(page); +- return ERR_CAST(full_path); +- } +- +- cifs_dbg(FYI, "Full path: %s inode = 0x%p\n", full_path, inode); +- +- rc = -EACCES; +- /* +- * First try Minshall+French Symlinks, if configured +- * and fallback to UNIX Extensions Symlinks. +- */ +- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) +- rc = query_mf_symlink(xid, tcon, cifs_sb, full_path, +- &target_path); +- +- if (rc != 0 && server->ops->query_symlink) { +- struct cifsInodeInfo *cifsi = CIFS_I(inode); +- bool reparse_point = false; +- +- if (cifsi->cifsAttrs & ATTR_REPARSE) +- reparse_point = true; +- +- rc = server->ops->query_symlink(xid, tcon, cifs_sb, full_path, +- &target_path, reparse_point); +- } +- +- free_dentry_path(page); +- free_xid(xid); +- cifs_put_tlink(tlink); +- if (rc != 0) { +- kfree(target_path); +- return ERR_PTR(rc); +- } +- set_delayed_call(done, kfree_link, target_path); +- return target_path; +-} +- + int + cifs_symlink(struct user_namespace *mnt_userns, struct inode *inode, + struct dentry *direntry, const char *symname) +diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c +index 8e060c00c969..6a78bcc51e81 100644 +--- a/fs/cifs/readdir.c ++++ b/fs/cifs/readdir.c +@@ -994,6 +994,8 @@ static int cifs_filldir(char *find_entry, struct file *file, + cifs_unix_basic_to_fattr(&fattr, + &((FILE_UNIX_INFO *)find_entry)->basic, + cifs_sb); ++ if (S_ISLNK(fattr.cf_mode)) ++ fattr.cf_flags |= CIFS_FATTR_NEED_REVAL; + break; + case SMB_FIND_FILE_INFO_STANDARD: + cifs_std_info_to_fattr(&fattr, +diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c +index f36b2d2d40ca..50480751e521 100644 +--- a/fs/cifs/smb1ops.c ++++ b/fs/cifs/smb1ops.c +@@ -542,31 +542,32 @@ cifs_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, + return rc; + } + +-static int +-cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, +- struct cifs_sb_info *cifs_sb, const char *full_path, +- FILE_ALL_INFO *data, bool *adjustTZ, bool *symlink) ++static int cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, ++ struct cifs_sb_info *cifs_sb, const char *full_path, ++ struct cifs_open_info_data *data, bool *adjustTZ, bool *symlink) + { + int rc; ++ FILE_ALL_INFO fi = {}; + + *symlink = false; + + /* could do find first instead but this returns more info */ +- rc = CIFSSMBQPathInfo(xid, tcon, full_path, data, 0 /* not legacy */, +- cifs_sb->local_nls, cifs_remap(cifs_sb)); ++ rc = CIFSSMBQPathInfo(xid, tcon, full_path, &fi, 0 /* not legacy */, cifs_sb->local_nls, ++ cifs_remap(cifs_sb)); + /* + * BB optimize code so we do not make the above call when server claims + * no NT SMB support and the above call failed at least once - set flag + * in tcon or mount. + */ + if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) { +- rc = SMBQueryInformation(xid, tcon, full_path, data, +- cifs_sb->local_nls, ++ rc = SMBQueryInformation(xid, tcon, full_path, &fi, cifs_sb->local_nls, + cifs_remap(cifs_sb)); ++ if (!rc) ++ move_cifs_info_to_smb2(&data->fi, &fi); + *adjustTZ = true; + } + +- if (!rc && (le32_to_cpu(data->Attributes) & ATTR_REPARSE)) { ++ if (!rc && (le32_to_cpu(fi.Attributes) & ATTR_REPARSE)) { + int tmprc; + int oplock = 0; + struct cifs_fid fid; +@@ -592,10 +593,9 @@ cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, + return rc; + } + +-static int +-cifs_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon, +- struct cifs_sb_info *cifs_sb, const char *full_path, +- u64 *uniqueid, FILE_ALL_INFO *data) ++static int cifs_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon, ++ struct cifs_sb_info *cifs_sb, const char *full_path, ++ u64 *uniqueid, struct cifs_open_info_data *unused) + { + /* + * We can not use the IndexNumber field by default from Windows or +@@ -613,11 +613,22 @@ cifs_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon, + cifs_remap(cifs_sb)); + } + +-static int +-cifs_query_file_info(const unsigned int xid, struct cifs_tcon *tcon, +- struct cifs_fid *fid, FILE_ALL_INFO *data) ++static int cifs_query_file_info(const unsigned int xid, struct cifs_tcon *tcon, ++ struct cifsFileInfo *cfile, struct cifs_open_info_data *data) + { +- return CIFSSMBQFileInfo(xid, tcon, fid->netfid, data); ++ int rc; ++ FILE_ALL_INFO fi = {}; ++ ++ if (cfile->symlink_target) { ++ data->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL); ++ if (!data->symlink_target) ++ return -ENOMEM; ++ } ++ ++ rc = CIFSSMBQFileInfo(xid, tcon, cfile->fid.netfid, &fi); ++ if (!rc) ++ move_cifs_info_to_smb2(&data->fi, &fi); ++ return rc; + } + + static void +@@ -702,19 +713,20 @@ cifs_mkdir_setinfo(struct inode *inode, const char *full_path, + cifsInode->cifsAttrs = dosattrs; + } + +-static int +-cifs_open_file(const unsigned int xid, struct cifs_open_parms *oparms, +- __u32 *oplock, FILE_ALL_INFO *buf) ++static int cifs_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock, ++ void *buf) + { ++ FILE_ALL_INFO *fi = buf; ++ + if (!(oparms->tcon->ses->capabilities & CAP_NT_SMBS)) + return SMBLegacyOpen(xid, oparms->tcon, oparms->path, + oparms->disposition, + oparms->desired_access, + oparms->create_options, +- &oparms->fid->netfid, oplock, buf, ++ &oparms->fid->netfid, oplock, fi, + oparms->cifs_sb->local_nls, + cifs_remap(oparms->cifs_sb)); +- return CIFS_open(xid, oparms, oplock, buf); ++ return CIFS_open(xid, oparms, oplock, fi); + } + + static void +diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c +index 9dfd2dd612c2..4992b43616a7 100644 +--- a/fs/cifs/smb2file.c ++++ b/fs/cifs/smb2file.c +@@ -20,40 +20,125 @@ + #include "cifs_unicode.h" + #include "fscache.h" + #include "smb2proto.h" ++#include "smb2status.h" + +-int +-smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, +- __u32 *oplock, FILE_ALL_INFO *buf) ++static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov) ++{ ++ struct smb2_err_rsp *err = iov->iov_base; ++ struct smb2_symlink_err_rsp *sym = ERR_PTR(-EINVAL); ++ u32 len; ++ ++ if (err->ErrorContextCount) { ++ struct smb2_error_context_rsp *p, *end; ++ ++ len = (u32)err->ErrorContextCount * (offsetof(struct smb2_error_context_rsp, ++ ErrorContextData) + ++ sizeof(struct smb2_symlink_err_rsp)); ++ if (le32_to_cpu(err->ByteCount) < len || iov->iov_len < len + sizeof(*err)) ++ return ERR_PTR(-EINVAL); ++ ++ p = (struct smb2_error_context_rsp *)err->ErrorData; ++ end = (struct smb2_error_context_rsp *)((u8 *)err + iov->iov_len); ++ do { ++ if (le32_to_cpu(p->ErrorId) == SMB2_ERROR_ID_DEFAULT) { ++ sym = (struct smb2_symlink_err_rsp *)&p->ErrorContextData; ++ break; ++ } ++ cifs_dbg(FYI, "%s: skipping unhandled error context: 0x%x\n", ++ __func__, le32_to_cpu(p->ErrorId)); ++ ++ len = ALIGN(le32_to_cpu(p->ErrorDataLength), 8); ++ p = (struct smb2_error_context_rsp *)((u8 *)&p->ErrorContextData + len); ++ } while (p < end); ++ } else if (le32_to_cpu(err->ByteCount) >= sizeof(*sym) && ++ iov->iov_len >= SMB2_SYMLINK_STRUCT_SIZE) { ++ sym = (struct smb2_symlink_err_rsp *)err->ErrorData; ++ } ++ ++ if (!IS_ERR(sym) && (le32_to_cpu(sym->SymLinkErrorTag) != SYMLINK_ERROR_TAG || ++ le32_to_cpu(sym->ReparseTag) != IO_REPARSE_TAG_SYMLINK)) ++ sym = ERR_PTR(-EINVAL); ++ ++ return sym; ++} ++ ++int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec *iov, char **path) ++{ ++ struct smb2_symlink_err_rsp *sym; ++ unsigned int sub_offs, sub_len; ++ unsigned int print_offs, print_len; ++ char *s; ++ ++ if (!cifs_sb || !iov || !iov->iov_base || !iov->iov_len || !path) ++ return -EINVAL; ++ ++ sym = symlink_data(iov); ++ if (IS_ERR(sym)) ++ return PTR_ERR(sym); ++ ++ sub_len = le16_to_cpu(sym->SubstituteNameLength); ++ sub_offs = le16_to_cpu(sym->SubstituteNameOffset); ++ print_len = le16_to_cpu(sym->PrintNameLength); ++ print_offs = le16_to_cpu(sym->PrintNameOffset); ++ ++ if (iov->iov_len < SMB2_SYMLINK_STRUCT_SIZE + sub_offs + sub_len || ++ iov->iov_len < SMB2_SYMLINK_STRUCT_SIZE + print_offs + print_len) ++ return -EINVAL; ++ ++ s = cifs_strndup_from_utf16((char *)sym->PathBuffer + sub_offs, sub_len, true, ++ cifs_sb->local_nls); ++ if (!s) ++ return -ENOMEM; ++ convert_delimiter(s, '/'); ++ cifs_dbg(FYI, "%s: symlink target: %s\n", __func__, s); ++ ++ *path = s; ++ return 0; ++} ++ ++int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock, void *buf) + { + int rc; + __le16 *smb2_path; +- struct smb2_file_all_info *smb2_data = NULL; + __u8 smb2_oplock; ++ struct cifs_open_info_data *data = buf; ++ struct smb2_file_all_info file_info = {}; ++ struct smb2_file_all_info *smb2_data = data ? &file_info : NULL; ++ struct kvec err_iov = {}; ++ int err_buftype = CIFS_NO_BUFFER; + struct cifs_fid *fid = oparms->fid; + struct network_resiliency_req nr_ioctl_req; + + smb2_path = cifs_convert_path_to_utf16(oparms->path, oparms->cifs_sb); +- if (smb2_path == NULL) { +- rc = -ENOMEM; +- goto out; +- } +- +- smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2, +- GFP_KERNEL); +- if (smb2_data == NULL) { +- rc = -ENOMEM; +- goto out; +- } ++ if (smb2_path == NULL) ++ return -ENOMEM; + + oparms->desired_access |= FILE_READ_ATTRIBUTES; + smb2_oplock = SMB2_OPLOCK_LEVEL_BATCH; + +- rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, +- NULL, NULL); ++ rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov, ++ &err_buftype); ++ if (rc && data) { ++ struct smb2_hdr *hdr = err_iov.iov_base; ++ ++ if (unlikely(!err_iov.iov_base || err_buftype == CIFS_NO_BUFFER)) ++ rc = -ENOMEM; ++ else if (hdr->Status == STATUS_STOPPED_ON_SYMLINK && oparms->cifs_sb) { ++ rc = smb2_parse_symlink_response(oparms->cifs_sb, &err_iov, ++ &data->symlink_target); ++ if (!rc) { ++ memset(smb2_data, 0, sizeof(*smb2_data)); ++ oparms->create_options |= OPEN_REPARSE_POINT; ++ rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, ++ NULL, NULL, NULL); ++ oparms->create_options &= ~OPEN_REPARSE_POINT; ++ } ++ } ++ } ++ + if (rc) + goto out; + +- + if (oparms->tcon->use_resilient) { + /* default timeout is 0, servers pick default (120 seconds) */ + nr_ioctl_req.Timeout = +@@ -73,7 +158,7 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, + rc = 0; + } + +- if (buf) { ++ if (smb2_data) { + /* if open response does not have IndexNumber field - get it */ + if (smb2_data->IndexNumber == 0) { + rc = SMB2_get_srv_num(xid, oparms->tcon, +@@ -89,12 +174,12 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, + rc = 0; + } + } +- move_smb2_info_to_cifs(buf, smb2_data); ++ memcpy(&data->fi, smb2_data, sizeof(data->fi)); + } + + *oplock = smb2_oplock; + out: +- kfree(smb2_data); ++ free_rsp_buf(err_buftype, err_iov.iov_base); + kfree(smb2_path); + return rc; + } +diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c +index b83f59051b26..7b14ece0d895 100644 +--- a/fs/cifs/smb2inode.c ++++ b/fs/cifs/smb2inode.c +@@ -24,6 +24,7 @@ + #include "smb2pdu.h" + #include "smb2proto.h" + #include "cached_dir.h" ++#include "smb2status.h" + + static void + free_set_inf_compound(struct smb_rqst *rqst) +@@ -50,13 +51,15 @@ struct cop_vars { + /* + * note: If cfile is passed, the reference to it is dropped here. + * So make sure that you do not reuse cfile after return from this func. ++ * ++ * If passing @err_iov and @err_buftype, ensure to make them both large enough (>= 3) to hold all ++ * error responses. Caller is also responsible for freeing them up. + */ +-static int +-smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, +- struct cifs_sb_info *cifs_sb, const char *full_path, +- __u32 desired_access, __u32 create_disposition, +- __u32 create_options, umode_t mode, void *ptr, int command, +- struct cifsFileInfo *cfile) ++static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, ++ struct cifs_sb_info *cifs_sb, const char *full_path, ++ __u32 desired_access, __u32 create_disposition, __u32 create_options, ++ umode_t mode, void *ptr, int command, struct cifsFileInfo *cfile, ++ struct kvec *err_iov, int *err_buftype) + { + struct cop_vars *vars = NULL; + struct kvec *rsp_iov; +@@ -70,6 +73,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + int num_rqst = 0; + int resp_buftype[3]; + struct smb2_query_info_rsp *qi_rsp = NULL; ++ struct cifs_open_info_data *idata; + int flags = 0; + __u8 delete_pending[8] = {1, 0, 0, 0, 0, 0, 0, 0}; + unsigned int size[2]; +@@ -385,14 +389,19 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + + switch (command) { + case SMB2_OP_QUERY_INFO: ++ idata = ptr; ++ if (rc == 0 && cfile && cfile->symlink_target) { ++ idata->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL); ++ if (!idata->symlink_target) ++ rc = -ENOMEM; ++ } + if (rc == 0) { + qi_rsp = (struct smb2_query_info_rsp *) + rsp_iov[1].iov_base; + rc = smb2_validate_and_copy_iov( + le16_to_cpu(qi_rsp->OutputBufferOffset), + le32_to_cpu(qi_rsp->OutputBufferLength), +- &rsp_iov[1], sizeof(struct smb2_file_all_info), +- ptr); ++ &rsp_iov[1], sizeof(idata->fi), (char *)&idata->fi); + } + if (rqst[1].rq_iov) + SMB2_query_info_free(&rqst[1]); +@@ -406,13 +415,19 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + tcon->tid); + break; + case SMB2_OP_POSIX_QUERY_INFO: ++ if (rc == 0 && cfile && cfile->symlink_target) { ++ idata->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL); ++ if (!idata->symlink_target) ++ rc = -ENOMEM; ++ } + if (rc == 0) { + qi_rsp = (struct smb2_query_info_rsp *) + rsp_iov[1].iov_base; + rc = smb2_validate_and_copy_iov( + le16_to_cpu(qi_rsp->OutputBufferOffset), + le32_to_cpu(qi_rsp->OutputBufferLength), +- &rsp_iov[1], sizeof(struct smb311_posix_qinfo) /* add SIDs */, ptr); ++ &rsp_iov[1], sizeof(idata->posix_fi) /* add SIDs */, ++ (char *)&idata->posix_fi); + } + if (rqst[1].rq_iov) + SMB2_query_info_free(&rqst[1]); +@@ -477,42 +492,33 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + free_set_inf_compound(rqst); + break; + } +- free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); +- free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); +- free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base); ++ ++ if (rc && err_iov && err_buftype) { ++ memcpy(err_iov, rsp_iov, 3 * sizeof(*err_iov)); ++ memcpy(err_buftype, resp_buftype, 3 * sizeof(*err_buftype)); ++ } else { ++ free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); ++ free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); ++ free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base); ++ } + kfree(vars); + return rc; + } + +-void +-move_smb2_info_to_cifs(FILE_ALL_INFO *dst, struct smb2_file_all_info *src) +-{ +- memcpy(dst, src, (size_t)(&src->CurrentByteOffset) - (size_t)src); +- dst->CurrentByteOffset = src->CurrentByteOffset; +- dst->Mode = src->Mode; +- dst->AlignmentRequirement = src->AlignmentRequirement; +- dst->IndexNumber1 = 0; /* we don't use it */ +-} +- +-int +-smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, +- struct cifs_sb_info *cifs_sb, const char *full_path, +- FILE_ALL_INFO *data, bool *adjust_tz, bool *reparse) ++int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, ++ struct cifs_sb_info *cifs_sb, const char *full_path, ++ struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse) + { + int rc; +- struct smb2_file_all_info *smb2_data; + __u32 create_options = 0; + struct cifsFileInfo *cfile; + struct cached_fid *cfid = NULL; ++ struct kvec err_iov[3] = {}; ++ int err_buftype[3] = {}; + + *adjust_tz = false; + *reparse = false; + +- smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2, +- GFP_KERNEL); +- if (smb2_data == NULL) +- return -ENOMEM; +- + if (strcmp(full_path, "")) + rc = -ENOENT; + else +@@ -520,63 +526,58 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, + /* If it is a root and its handle is cached then use it */ + if (!rc) { + if (cfid->file_all_info_is_valid) { +- move_smb2_info_to_cifs(data, +- &cfid->file_all_info); ++ memcpy(&data->fi, &cfid->file_all_info, sizeof(data->fi)); + } else { +- rc = SMB2_query_info(xid, tcon, +- cfid->fid.persistent_fid, +- cfid->fid.volatile_fid, smb2_data); +- if (!rc) +- move_smb2_info_to_cifs(data, smb2_data); ++ rc = SMB2_query_info(xid, tcon, cfid->fid.persistent_fid, ++ cfid->fid.volatile_fid, &data->fi); + } + close_cached_dir(cfid); +- goto out; ++ return rc; + } + + cifs_get_readable_path(tcon, full_path, &cfile); +- rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, +- FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, +- ACL_NO_MODE, smb2_data, SMB2_OP_QUERY_INFO, cfile); ++ rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, ++ create_options, ACL_NO_MODE, data, SMB2_OP_QUERY_INFO, cfile, ++ err_iov, err_buftype); + if (rc == -EOPNOTSUPP) { ++ if (err_iov[0].iov_base && err_buftype[0] != CIFS_NO_BUFFER && ++ ((struct smb2_hdr *)err_iov[0].iov_base)->Command == SMB2_CREATE && ++ ((struct smb2_hdr *)err_iov[0].iov_base)->Status == STATUS_STOPPED_ON_SYMLINK) { ++ rc = smb2_parse_symlink_response(cifs_sb, err_iov, &data->symlink_target); ++ if (rc) ++ goto out; ++ } + *reparse = true; + create_options |= OPEN_REPARSE_POINT; + + /* Failed on a symbolic link - query a reparse point info */ + cifs_get_readable_path(tcon, full_path, &cfile); +- rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, +- FILE_READ_ATTRIBUTES, FILE_OPEN, +- create_options, ACL_NO_MODE, +- smb2_data, SMB2_OP_QUERY_INFO, cfile); ++ rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, ++ FILE_OPEN, create_options, ACL_NO_MODE, data, ++ SMB2_OP_QUERY_INFO, cfile, NULL, NULL); + } +- if (rc) +- goto out; + +- move_smb2_info_to_cifs(data, smb2_data); + out: +- kfree(smb2_data); ++ free_rsp_buf(err_buftype[0], err_iov[0].iov_base); ++ free_rsp_buf(err_buftype[1], err_iov[1].iov_base); ++ free_rsp_buf(err_buftype[2], err_iov[2].iov_base); + return rc; + } + + +-int +-smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, +- struct cifs_sb_info *cifs_sb, const char *full_path, +- struct smb311_posix_qinfo *data, bool *adjust_tz, bool *reparse) ++int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, ++ struct cifs_sb_info *cifs_sb, const char *full_path, ++ struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse) + { + int rc; + __u32 create_options = 0; + struct cifsFileInfo *cfile; +- struct smb311_posix_qinfo *smb2_data; ++ struct kvec err_iov[3] = {}; ++ int err_buftype[3] = {}; + + *adjust_tz = false; + *reparse = false; + +- /* BB TODO: Make struct larger when add support for parsing owner SIDs */ +- smb2_data = kzalloc(sizeof(struct smb311_posix_qinfo), +- GFP_KERNEL); +- if (smb2_data == NULL) +- return -ENOMEM; +- + /* + * BB TODO: Add support for using the cached root handle. + * Create SMB2_query_posix_info worker function to do non-compounded query +@@ -585,29 +586,32 @@ smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, + */ + + cifs_get_readable_path(tcon, full_path, &cfile); +- rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, +- FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, +- ACL_NO_MODE, smb2_data, SMB2_OP_POSIX_QUERY_INFO, cfile); ++ rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, ++ create_options, ACL_NO_MODE, data, SMB2_OP_POSIX_QUERY_INFO, cfile, ++ err_iov, err_buftype); + if (rc == -EOPNOTSUPP) { + /* BB TODO: When support for special files added to Samba re-verify this path */ ++ if (err_iov[0].iov_base && err_buftype[0] != CIFS_NO_BUFFER && ++ ((struct smb2_hdr *)err_iov[0].iov_base)->Command == SMB2_CREATE && ++ ((struct smb2_hdr *)err_iov[0].iov_base)->Status == STATUS_STOPPED_ON_SYMLINK) { ++ rc = smb2_parse_symlink_response(cifs_sb, err_iov, &data->symlink_target); ++ if (rc) ++ goto out; ++ } + *reparse = true; + create_options |= OPEN_REPARSE_POINT; + + /* Failed on a symbolic link - query a reparse point info */ + cifs_get_readable_path(tcon, full_path, &cfile); +- rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, +- FILE_READ_ATTRIBUTES, FILE_OPEN, +- create_options, ACL_NO_MODE, +- smb2_data, SMB2_OP_POSIX_QUERY_INFO, cfile); ++ rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, ++ FILE_OPEN, create_options, ACL_NO_MODE, data, ++ SMB2_OP_POSIX_QUERY_INFO, cfile, NULL, NULL); + } +- if (rc) +- goto out; +- +- /* TODO: will need to allow for the 2 SIDs when add support for getting owner UID/GID */ +- memcpy(data, smb2_data, sizeof(struct smb311_posix_qinfo)); + + out: +- kfree(smb2_data); ++ free_rsp_buf(err_buftype[0], err_iov[0].iov_base); ++ free_rsp_buf(err_buftype[1], err_iov[1].iov_base); ++ free_rsp_buf(err_buftype[2], err_iov[2].iov_base); + return rc; + } + +@@ -619,7 +623,7 @@ smb2_mkdir(const unsigned int xid, struct inode *parent_inode, umode_t mode, + return smb2_compound_op(xid, tcon, cifs_sb, name, + FILE_WRITE_ATTRIBUTES, FILE_CREATE, + CREATE_NOT_FILE, mode, NULL, SMB2_OP_MKDIR, +- NULL); ++ NULL, NULL, NULL); + } + + void +@@ -641,7 +645,7 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name, + tmprc = smb2_compound_op(xid, tcon, cifs_sb, name, + FILE_WRITE_ATTRIBUTES, FILE_CREATE, + CREATE_NOT_FILE, ACL_NO_MODE, +- &data, SMB2_OP_SET_INFO, cfile); ++ &data, SMB2_OP_SET_INFO, cfile, NULL, NULL); + if (tmprc == 0) + cifs_i->cifsAttrs = dosattrs; + } +@@ -652,7 +656,7 @@ smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, + { + return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN, + CREATE_NOT_FILE, ACL_NO_MODE, +- NULL, SMB2_OP_RMDIR, NULL); ++ NULL, SMB2_OP_RMDIR, NULL, NULL, NULL); + } + + int +@@ -661,7 +665,7 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name, + { + return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN, + CREATE_DELETE_ON_CLOSE | OPEN_REPARSE_POINT, +- ACL_NO_MODE, NULL, SMB2_OP_DELETE, NULL); ++ ACL_NO_MODE, NULL, SMB2_OP_DELETE, NULL, NULL, NULL); + } + + static int +@@ -680,7 +684,7 @@ smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon, + } + rc = smb2_compound_op(xid, tcon, cifs_sb, from_name, access, + FILE_OPEN, 0, ACL_NO_MODE, smb2_to_name, +- command, cfile); ++ command, cfile, NULL, NULL); + smb2_rename_path: + kfree(smb2_to_name); + return rc; +@@ -720,7 +724,7 @@ smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon, + cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); + return smb2_compound_op(xid, tcon, cifs_sb, full_path, + FILE_WRITE_DATA, FILE_OPEN, 0, ACL_NO_MODE, +- &eof, SMB2_OP_SET_EOF, cfile); ++ &eof, SMB2_OP_SET_EOF, cfile, NULL, NULL); + } + + int +@@ -746,7 +750,8 @@ smb2_set_file_info(struct inode *inode, const char *full_path, + cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); + rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, + FILE_WRITE_ATTRIBUTES, FILE_OPEN, +- 0, ACL_NO_MODE, buf, SMB2_OP_SET_INFO, cfile); ++ 0, ACL_NO_MODE, buf, SMB2_OP_SET_INFO, cfile, ++ NULL, NULL); + cifs_put_tlink(tlink); + return rc; + } +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index 2a0eb9b7dd7a..d454164e7f48 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -831,33 +831,25 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, + return rc; + } + +-static int +-smb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon, +- struct cifs_sb_info *cifs_sb, const char *full_path, +- u64 *uniqueid, FILE_ALL_INFO *data) ++static int smb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon, ++ struct cifs_sb_info *cifs_sb, const char *full_path, ++ u64 *uniqueid, struct cifs_open_info_data *data) + { +- *uniqueid = le64_to_cpu(data->IndexNumber); ++ *uniqueid = le64_to_cpu(data->fi.IndexNumber); + return 0; + } + +-static int +-smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon, +- struct cifs_fid *fid, FILE_ALL_INFO *data) ++static int smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon, ++ struct cifsFileInfo *cfile, struct cifs_open_info_data *data) + { +- int rc; +- struct smb2_file_all_info *smb2_data; ++ struct cifs_fid *fid = &cfile->fid; + +- smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2, +- GFP_KERNEL); +- if (smb2_data == NULL) +- return -ENOMEM; +- +- rc = SMB2_query_info(xid, tcon, fid->persistent_fid, fid->volatile_fid, +- smb2_data); +- if (!rc) +- move_smb2_info_to_cifs(data, smb2_data); +- kfree(smb2_data); +- return rc; ++ if (cfile->symlink_target) { ++ data->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL); ++ if (!data->symlink_target) ++ return -ENOMEM; ++ } ++ return SMB2_query_info(xid, tcon, fid->persistent_fid, fid->volatile_fid, &data->fi); + } + + #ifdef CONFIG_CIFS_XATTR +@@ -2836,9 +2828,6 @@ parse_reparse_point(struct reparse_data_buffer *buf, + } + } + +-#define SMB2_SYMLINK_STRUCT_SIZE \ +- (sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp)) +- + static int + smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, const char *full_path, +@@ -2850,13 +2839,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, + struct cifs_open_parms oparms; + struct cifs_fid fid; + struct kvec err_iov = {NULL, 0}; +- struct smb2_err_rsp *err_buf = NULL; +- struct smb2_symlink_err_rsp *symlink; + struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses); +- unsigned int sub_len; +- unsigned int sub_offset; +- unsigned int print_len; +- unsigned int print_offset; + int flags = CIFS_CP_CREATE_CLOSE_OP; + struct smb_rqst rqst[3]; + int resp_buftype[3]; +@@ -2973,47 +2956,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, + goto querty_exit; + } + +- err_buf = err_iov.iov_base; +- if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) || +- err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE) { +- rc = -EINVAL; +- goto querty_exit; +- } +- +- symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData; +- if (le32_to_cpu(symlink->SymLinkErrorTag) != SYMLINK_ERROR_TAG || +- le32_to_cpu(symlink->ReparseTag) != IO_REPARSE_TAG_SYMLINK) { +- rc = -EINVAL; +- goto querty_exit; +- } +- +- /* open must fail on symlink - reset rc */ +- rc = 0; +- sub_len = le16_to_cpu(symlink->SubstituteNameLength); +- sub_offset = le16_to_cpu(symlink->SubstituteNameOffset); +- print_len = le16_to_cpu(symlink->PrintNameLength); +- print_offset = le16_to_cpu(symlink->PrintNameOffset); +- +- if (err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) { +- rc = -EINVAL; +- goto querty_exit; +- } +- +- if (err_iov.iov_len < +- SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) { +- rc = -EINVAL; +- goto querty_exit; +- } +- +- *target_path = cifs_strndup_from_utf16( +- (char *)symlink->PathBuffer + sub_offset, +- sub_len, true, cifs_sb->local_nls); +- if (!(*target_path)) { +- rc = -ENOMEM; +- goto querty_exit; +- } +- convert_delimiter(*target_path, '/'); +- cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path); ++ rc = smb2_parse_symlink_response(cifs_sb, &err_iov, target_path); + + querty_exit: + cifs_dbg(FYI, "query symlink rc %d\n", rc); +@@ -5124,7 +5067,7 @@ smb2_make_node(unsigned int xid, struct inode *inode, + { + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + int rc = -EPERM; +- FILE_ALL_INFO *buf = NULL; ++ struct cifs_open_info_data buf = {}; + struct cifs_io_parms io_parms = {0}; + __u32 oplock = 0; + struct cifs_fid fid; +@@ -5140,7 +5083,7 @@ smb2_make_node(unsigned int xid, struct inode *inode, + * and was used by default in earlier versions of Windows + */ + if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) +- goto out; ++ return rc; + + /* + * TODO: Add ability to create instead via reparse point. Windows (e.g. +@@ -5149,16 +5092,10 @@ smb2_make_node(unsigned int xid, struct inode *inode, + */ + + if (!S_ISCHR(mode) && !S_ISBLK(mode)) +- goto out; ++ return rc; + + cifs_dbg(FYI, "sfu compat create special file\n"); + +- buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); +- if (buf == NULL) { +- rc = -ENOMEM; +- goto out; +- } +- + oparms.tcon = tcon; + oparms.cifs_sb = cifs_sb; + oparms.desired_access = GENERIC_WRITE; +@@ -5173,21 +5110,21 @@ smb2_make_node(unsigned int xid, struct inode *inode, + oplock = REQ_OPLOCK; + else + oplock = 0; +- rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, buf); ++ rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, &buf); + if (rc) +- goto out; ++ return rc; + + /* + * BB Do not bother to decode buf since no local inode yet to put + * timestamps in, but we can reuse it safely. + */ + +- pdev = (struct win_dev *)buf; ++ pdev = (struct win_dev *)&buf.fi; + io_parms.pid = current->tgid; + io_parms.tcon = tcon; + io_parms.offset = 0; + io_parms.length = sizeof(struct win_dev); +- iov[1].iov_base = buf; ++ iov[1].iov_base = &buf.fi; + iov[1].iov_len = sizeof(struct win_dev); + if (S_ISCHR(mode)) { + memcpy(pdev->type, "IntxCHR", 8); +@@ -5206,8 +5143,8 @@ smb2_make_node(unsigned int xid, struct inode *inode, + d_drop(dentry); + + /* FIXME: add code here to set EAs */ +-out: +- kfree(buf); ++ ++ cifs_free_open_info(&buf); + return rc; + } + +diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h +index f57881b8464f..1237bb86e93a 100644 +--- a/fs/cifs/smb2pdu.h ++++ b/fs/cifs/smb2pdu.h +@@ -56,6 +56,9 @@ struct smb2_rdma_crypto_transform { + + #define COMPOUND_FID 0xFFFFFFFFFFFFFFFFULL + ++#define SMB2_SYMLINK_STRUCT_SIZE \ ++ (sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp)) ++ + #define SYMLINK_ERROR_TAG 0x4c4d5953 + + struct smb2_symlink_err_rsp { +diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h +index 3f740f24b96a..7818d0b83567 100644 +--- a/fs/cifs/smb2proto.h ++++ b/fs/cifs/smb2proto.h +@@ -53,16 +53,12 @@ extern bool smb2_is_valid_oplock_break(char *buffer, + struct TCP_Server_Info *srv); + extern int smb3_handle_read_data(struct TCP_Server_Info *server, + struct mid_q_entry *mid); +- +-extern void move_smb2_info_to_cifs(FILE_ALL_INFO *dst, +- struct smb2_file_all_info *src); + extern int smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, const char *path, + __u32 *reparse_tag); +-extern int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, +- struct cifs_sb_info *cifs_sb, +- const char *full_path, FILE_ALL_INFO *data, +- bool *adjust_tz, bool *symlink); ++int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, ++ struct cifs_sb_info *cifs_sb, const char *full_path, ++ struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse); + extern int smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon, + const char *full_path, __u64 size, + struct cifs_sb_info *cifs_sb, bool set_alloc); +@@ -95,9 +91,9 @@ extern int smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + const unsigned char *path, char *pbuf, + unsigned int *pbytes_read); +-extern int smb2_open_file(const unsigned int xid, +- struct cifs_open_parms *oparms, +- __u32 *oplock, FILE_ALL_INFO *buf); ++int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec *iov, char **path); ++int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock, ++ void *buf); + extern int smb2_unlock_range(struct cifsFileInfo *cfile, + struct file_lock *flock, const unsigned int xid); + extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile); +@@ -278,9 +274,9 @@ extern int smb2_query_info_compound(const unsigned int xid, + struct kvec *rsp, int *buftype, + struct cifs_sb_info *cifs_sb); + /* query path info from the server using SMB311 POSIX extensions*/ +-extern int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, +- struct cifs_sb_info *sb, const char *path, struct smb311_posix_qinfo *qinf, +- bool *adjust_tx, bool *symlink); ++int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, ++ struct cifs_sb_info *cifs_sb, const char *full_path, ++ struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse); + int posix_info_parse(const void *beg, const void *end, + struct smb2_posix_info_parsed *out); + int posix_info_sid_size(const void *beg, const void *end); +-- +2.35.1 + diff --git a/queue-6.0/cifs-replace-kfree-with-kfree_sensitive-for-sensitiv.patch b/queue-6.0/cifs-replace-kfree-with-kfree_sensitive-for-sensitiv.patch new file mode 100644 index 00000000000..6ba8c08dbbd --- /dev/null +++ b/queue-6.0/cifs-replace-kfree-with-kfree_sensitive-for-sensitiv.patch @@ -0,0 +1,326 @@ +From 32b54aef7a4481967d9bedabf05e003a3b84f45a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Sep 2022 15:10:35 -0300 +Subject: cifs: replace kfree() with kfree_sensitive() for sensitive data + +From: Enzo Matsumiya + +[ Upstream commit a4e430c8c8ba96be8c6ec4f2eb108bb8bcbee069 ] + +Replace kfree with kfree_sensitive, or prepend memzero_explicit() in +other cases, when freeing sensitive material that could still be left +in memory. + +Signed-off-by: Enzo Matsumiya +Reported-by: kernel test robot +Link: https://lore.kernel.org/r/202209201529.ec633796-oliver.sang@intel.com +Reviewed-by: Paulo Alcantara (SUSE) +Reviewed-by: Ronnie Sahlberg +Signed-off-by: Steve French +Stable-dep-of: f7f291e14dde ("cifs: fix oops during encryption") +Signed-off-by: Sasha Levin +--- + fs/cifs/cifsencrypt.c | 12 ++++++------ + fs/cifs/connect.c | 6 +++--- + fs/cifs/fs_context.c | 12 ++++++++++-- + fs/cifs/misc.c | 2 +- + fs/cifs/sess.c | 24 +++++++++++++++--------- + fs/cifs/smb2ops.c | 6 +++--- + fs/cifs/smb2pdu.c | 19 ++++++++++++++----- + 7 files changed, 52 insertions(+), 29 deletions(-) + +diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c +index 46f5718754f9..d848bc0aac27 100644 +--- a/fs/cifs/cifsencrypt.c ++++ b/fs/cifs/cifsencrypt.c +@@ -679,7 +679,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) + unlock: + cifs_server_unlock(ses->server); + setup_ntlmv2_rsp_ret: +- kfree(tiblob); ++ kfree_sensitive(tiblob); + + return rc; + } +@@ -753,14 +753,14 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server) + server->secmech.ccmaesdecrypt = NULL; + } + +- kfree(server->secmech.sdesccmacaes); ++ kfree_sensitive(server->secmech.sdesccmacaes); + server->secmech.sdesccmacaes = NULL; +- kfree(server->secmech.sdeschmacsha256); ++ kfree_sensitive(server->secmech.sdeschmacsha256); + server->secmech.sdeschmacsha256 = NULL; +- kfree(server->secmech.sdeschmacmd5); ++ kfree_sensitive(server->secmech.sdeschmacmd5); + server->secmech.sdeschmacmd5 = NULL; +- kfree(server->secmech.sdescmd5); ++ kfree_sensitive(server->secmech.sdescmd5); + server->secmech.sdescmd5 = NULL; +- kfree(server->secmech.sdescsha512); ++ kfree_sensitive(server->secmech.sdescsha512); + server->secmech.sdescsha512 = NULL; + } +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index 317ca1be9c4c..816161f51b29 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -311,7 +311,7 @@ cifs_abort_connection(struct TCP_Server_Info *server) + } + server->sequence_number = 0; + server->session_estab = false; +- kfree(server->session_key.response); ++ kfree_sensitive(server->session_key.response); + server->session_key.response = NULL; + server->session_key.len = 0; + server->lstrp = jiffies; +@@ -1580,7 +1580,7 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect) + + cifs_crypto_secmech_release(server); + +- kfree(server->session_key.response); ++ kfree_sensitive(server->session_key.response); + server->session_key.response = NULL; + server->session_key.len = 0; + kfree(server->hostname); +@@ -4141,7 +4141,7 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, + if (ses->auth_key.response) { + cifs_dbg(FYI, "Free previous auth_key.response = %p\n", + ses->auth_key.response); +- kfree(ses->auth_key.response); ++ kfree_sensitive(ses->auth_key.response); + ses->auth_key.response = NULL; + ses->auth_key.len = 0; + } +diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c +index 0e13dec86b25..45119597c765 100644 +--- a/fs/cifs/fs_context.c ++++ b/fs/cifs/fs_context.c +@@ -791,6 +791,13 @@ do { \ + cifs_sb->ctx->field = NULL; \ + } while (0) + ++#define STEAL_STRING_SENSITIVE(cifs_sb, ctx, field) \ ++do { \ ++ kfree_sensitive(ctx->field); \ ++ ctx->field = cifs_sb->ctx->field; \ ++ cifs_sb->ctx->field = NULL; \ ++} while (0) ++ + static int smb3_reconfigure(struct fs_context *fc) + { + struct smb3_fs_context *ctx = smb3_fc2context(fc); +@@ -811,7 +818,7 @@ static int smb3_reconfigure(struct fs_context *fc) + STEAL_STRING(cifs_sb, ctx, UNC); + STEAL_STRING(cifs_sb, ctx, source); + STEAL_STRING(cifs_sb, ctx, username); +- STEAL_STRING(cifs_sb, ctx, password); ++ STEAL_STRING_SENSITIVE(cifs_sb, ctx, password); + STEAL_STRING(cifs_sb, ctx, domainname); + STEAL_STRING(cifs_sb, ctx, nodename); + STEAL_STRING(cifs_sb, ctx, iocharset); +@@ -1162,7 +1169,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, + } + break; + case Opt_pass: +- kfree(ctx->password); ++ kfree_sensitive(ctx->password); + ctx->password = NULL; + if (strlen(param->string) == 0) + break; +@@ -1470,6 +1477,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, + return 0; + + cifs_parse_mount_err: ++ kfree_sensitive(ctx->password); + return -EINVAL; + } + +diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c +index 35085fa86636..3a117e2269a0 100644 +--- a/fs/cifs/misc.c ++++ b/fs/cifs/misc.c +@@ -1123,7 +1123,7 @@ cifs_alloc_hash(const char *name, + void + cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc) + { +- kfree(*sdesc); ++ kfree_sensitive(*sdesc); + *sdesc = NULL; + if (*shash) + crypto_free_shash(*shash); +diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c +index 6a85136da27c..22e281bc65ad 100644 +--- a/fs/cifs/sess.c ++++ b/fs/cifs/sess.c +@@ -1214,6 +1214,12 @@ sess_alloc_buffer(struct sess_data *sess_data, int wct) + static void + sess_free_buffer(struct sess_data *sess_data) + { ++ int i; ++ ++ /* zero the session data before freeing, as it might contain sensitive info (keys, etc) */ ++ for (i = 0; i < 3; i++) ++ if (sess_data->iov[i].iov_base) ++ memzero_explicit(sess_data->iov[i].iov_base, sess_data->iov[i].iov_len); + + free_rsp_buf(sess_data->buf0_type, sess_data->iov[0].iov_base); + sess_data->buf0_type = CIFS_NO_BUFFER; +@@ -1375,7 +1381,7 @@ sess_auth_ntlmv2(struct sess_data *sess_data) + sess_data->result = rc; + sess_data->func = NULL; + sess_free_buffer(sess_data); +- kfree(ses->auth_key.response); ++ kfree_sensitive(ses->auth_key.response); + ses->auth_key.response = NULL; + } + +@@ -1514,7 +1520,7 @@ sess_auth_kerberos(struct sess_data *sess_data) + sess_data->result = rc; + sess_data->func = NULL; + sess_free_buffer(sess_data); +- kfree(ses->auth_key.response); ++ kfree_sensitive(ses->auth_key.response); + ses->auth_key.response = NULL; + } + +@@ -1649,7 +1655,7 @@ sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data) + rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses); + + out_free_ntlmsspblob: +- kfree(ntlmsspblob); ++ kfree_sensitive(ntlmsspblob); + out: + sess_free_buffer(sess_data); + +@@ -1659,9 +1665,9 @@ sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data) + } + + /* Else error. Cleanup */ +- kfree(ses->auth_key.response); ++ kfree_sensitive(ses->auth_key.response); + ses->auth_key.response = NULL; +- kfree(ses->ntlmssp); ++ kfree_sensitive(ses->ntlmssp); + ses->ntlmssp = NULL; + + sess_data->func = NULL; +@@ -1760,7 +1766,7 @@ sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data) + } + + out_free_ntlmsspblob: +- kfree(ntlmsspblob); ++ kfree_sensitive(ntlmsspblob); + out: + sess_free_buffer(sess_data); + +@@ -1768,9 +1774,9 @@ sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data) + rc = sess_establish_session(sess_data); + + /* Cleanup */ +- kfree(ses->auth_key.response); ++ kfree_sensitive(ses->auth_key.response); + ses->auth_key.response = NULL; +- kfree(ses->ntlmssp); ++ kfree_sensitive(ses->ntlmssp); + ses->ntlmssp = NULL; + + sess_data->func = NULL; +@@ -1846,7 +1852,7 @@ int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses, + rc = sess_data->result; + + out: +- kfree(sess_data); ++ kfree_sensitive(sess_data); + return rc; + } + #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index b724bf42b540..2a0eb9b7dd7a 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -4432,11 +4432,11 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, + if (!rc && enc) + memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE); + +- kfree(iv); ++ kfree_sensitive(iv); + free_sg: +- kfree(sg); ++ kfree_sensitive(sg); + free_req: +- kfree(req); ++ kfree_sensitive(req); + return rc; + } + +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index 92a1d0695ebd..dd1aeb2316ac 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -1345,6 +1345,13 @@ SMB2_sess_alloc_buffer(struct SMB2_sess_data *sess_data) + static void + SMB2_sess_free_buffer(struct SMB2_sess_data *sess_data) + { ++ int i; ++ ++ /* zero the session data before freeing, as it might contain sensitive info (keys, etc) */ ++ for (i = 0; i < 2; i++) ++ if (sess_data->iov[i].iov_base) ++ memzero_explicit(sess_data->iov[i].iov_base, sess_data->iov[i].iov_len); ++ + free_rsp_buf(sess_data->buf0_type, sess_data->iov[0].iov_base); + sess_data->buf0_type = CIFS_NO_BUFFER; + } +@@ -1477,6 +1484,8 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data) + out_put_spnego_key: + key_invalidate(spnego_key); + key_put(spnego_key); ++ if (rc) ++ kfree_sensitive(ses->auth_key.response); + out: + sess_data->result = rc; + sess_data->func = NULL; +@@ -1573,7 +1582,7 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data) + } + + out: +- kfree(ntlmssp_blob); ++ memzero_explicit(ntlmssp_blob, blob_length); + SMB2_sess_free_buffer(sess_data); + if (!rc) { + sess_data->result = 0; +@@ -1581,7 +1590,7 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data) + return; + } + out_err: +- kfree(ses->ntlmssp); ++ kfree_sensitive(ses->ntlmssp); + ses->ntlmssp = NULL; + sess_data->result = rc; + sess_data->func = NULL; +@@ -1657,9 +1666,9 @@ SMB2_sess_auth_rawntlmssp_authenticate(struct SMB2_sess_data *sess_data) + } + #endif + out: +- kfree(ntlmssp_blob); ++ memzero_explicit(ntlmssp_blob, blob_length); + SMB2_sess_free_buffer(sess_data); +- kfree(ses->ntlmssp); ++ kfree_sensitive(ses->ntlmssp); + ses->ntlmssp = NULL; + sess_data->result = rc; + sess_data->func = NULL; +@@ -1737,7 +1746,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses, + cifs_server_dbg(VFS, "signing requested but authenticated as guest\n"); + rc = sess_data->result; + out: +- kfree(sess_data); ++ kfree_sensitive(sess_data); + return rc; + } + +-- +2.35.1 + diff --git a/queue-6.0/class-fix-possible-memory-leak-in-__class_register.patch b/queue-6.0/class-fix-possible-memory-leak-in-__class_register.patch new file mode 100644 index 00000000000..eaf13820ca5 --- /dev/null +++ b/queue-6.0/class-fix-possible-memory-leak-in-__class_register.patch @@ -0,0 +1,71 @@ +From a773fd5fbeb8eb22f089947c050597c9110dfaae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 16:28:03 +0800 +Subject: class: fix possible memory leak in __class_register() + +From: Yang Yingliang + +[ Upstream commit 8c3e8a6bdb5253b97ad532570f8b5db5f7a06407 ] + +If class_add_groups() returns error, the 'cp->subsys' need be +unregister, and the 'cp' need be freed. + +We can not call kset_unregister() here, because the 'cls' will +be freed in callback function class_release() and it's also +freed in caller's error path, it will cause double free. + +So fix this by calling kobject_del() and kfree_const(name) to +cleanup kobject. Besides, call kfree() to free the 'cp'. + +Fault injection test can trigger this: + +unreferenced object 0xffff888102fa8190 (size 8): + comm "modprobe", pid 502, jiffies 4294906074 (age 49.296s) + hex dump (first 8 bytes): + 70 6b 74 63 64 76 64 00 pktcdvd. + backtrace: + [<00000000e7c7703d>] __kmalloc_track_caller+0x1ae/0x320 + [<000000005e4d70bc>] kstrdup+0x3a/0x70 + [<00000000c2e5e85a>] kstrdup_const+0x68/0x80 + [<000000000049a8c7>] kvasprintf_const+0x10b/0x190 + [<0000000029123163>] kobject_set_name_vargs+0x56/0x150 + [<00000000747219c9>] kobject_set_name+0xab/0xe0 + [<0000000005f1ea4e>] __class_register+0x15c/0x49a + +unreferenced object 0xffff888037274000 (size 1024): + comm "modprobe", pid 502, jiffies 4294906074 (age 49.296s) + hex dump (first 32 bytes): + 00 40 27 37 80 88 ff ff 00 40 27 37 80 88 ff ff .@'7.....@'7.... + 00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00 .....N.......... + backtrace: + [<00000000151f9600>] kmem_cache_alloc_trace+0x17c/0x2f0 + [<00000000ecf3dd95>] __class_register+0x86/0x49a + +Fixes: ced6473e7486 ("driver core: class: add class_groups support") +Signed-off-by: Yang Yingliang +Link: https://lore.kernel.org/r/20221026082803.3458760-1-yangyingliang@huawei.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/base/class.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/base/class.c b/drivers/base/class.c +index 8feb85e186e3..e394e3e473b5 100644 +--- a/drivers/base/class.c ++++ b/drivers/base/class.c +@@ -192,6 +192,11 @@ int __class_register(struct class *cls, struct lock_class_key *key) + } + error = class_add_groups(class_get(cls), cls->class_groups); + class_put(cls); ++ if (error) { ++ kobject_del(&cp->subsys.kobj); ++ kfree_const(cp->subsys.kobj.name); ++ kfree(cp); ++ } + return error; + } + EXPORT_SYMBOL_GPL(__class_register); +-- +2.35.1 + diff --git a/queue-6.0/clk-imx-imxrt1050-fix-imxrt1050_clk_lcdif_apb-offset.patch b/queue-6.0/clk-imx-imxrt1050-fix-imxrt1050_clk_lcdif_apb-offset.patch new file mode 100644 index 00000000000..793b4ba23d6 --- /dev/null +++ b/queue-6.0/clk-imx-imxrt1050-fix-imxrt1050_clk_lcdif_apb-offset.patch @@ -0,0 +1,38 @@ +From 98ea8fee391a93efde8f2a46791d048e987db567 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 19:10:11 +0100 +Subject: clk: imx: imxrt1050: fix IMXRT1050_CLK_LCDIF_APB offsets + +From: Giulio Benetti + +[ Upstream commit 3095c02f95e537c553e0b30948c2f6c7cbed87ee ] + +Fix IMXRT1050_CLK_LCDIF_APB offsets. + +Fixes: 7154b046d8f3 ("clk: imx: Add initial support for i.MXRT1050 clock driver") +Cc: Jesse Taube +Signed-off-by: Giulio Benetti +Reviewed-by: Abel Vesa +Signed-off-by: Abel Vesa +Link: https://lore.kernel.org/r/20221117181014.851505-1-giulio.benetti@benettiengineering.com +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imxrt1050.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c +index 9539d35588ee..26108e9f7e67 100644 +--- a/drivers/clk/imx/clk-imxrt1050.c ++++ b/drivers/clk/imx/clk-imxrt1050.c +@@ -140,7 +140,7 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev) + hws[IMXRT1050_CLK_USDHC1] = imx_clk_hw_gate2("usdhc1", "usdhc1_podf", ccm_base + 0x80, 2); + hws[IMXRT1050_CLK_USDHC2] = imx_clk_hw_gate2("usdhc2", "usdhc2_podf", ccm_base + 0x80, 4); + hws[IMXRT1050_CLK_LPUART1] = imx_clk_hw_gate2("lpuart1", "lpuart_podf", ccm_base + 0x7c, 24); +- hws[IMXRT1050_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif", "lcdif_podf", ccm_base + 0x74, 10); ++ hws[IMXRT1050_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif", "lcdif_podf", ccm_base + 0x70, 28); + hws[IMXRT1050_CLK_DMA] = imx_clk_hw_gate("dma", "ipg", ccm_base + 0x7C, 6); + hws[IMXRT1050_CLK_DMA_MUX] = imx_clk_hw_gate("dmamux0", "ipg", ccm_base + 0x7C, 7); + imx_check_clk_hws(hws, IMXRT1050_CLK_END); +-- +2.35.1 + diff --git a/queue-6.0/clk-imx-rename-video_pll1-to-video_pll.patch b/queue-6.0/clk-imx-rename-video_pll1-to-video_pll.patch new file mode 100644 index 00000000000..53477514cb6 --- /dev/null +++ b/queue-6.0/clk-imx-rename-video_pll1-to-video_pll.patch @@ -0,0 +1,372 @@ +From bfa535cd0340325126b1041c598dd0f13e311624 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 12:36:35 +0100 +Subject: clk: imx: rename video_pll1 to video_pll + +From: Dario Binacchi + +[ Upstream commit bedcf9d1dcf88ed38731f0ac9620e5a421e1e9d6 ] + +Unlike audio_pll1 and audio_pll2, there is no video_pll2. Further, the +name used in the RM is video_pll. So, let's rename "video_pll1" to +"video_pll" to be consistent with the RM and avoid misunderstandings. + +The IMX8MN_VIDEO_PLL1* constants have not been removed to ensure +backward compatibility of the patch. + +No functional changes intended. + +Fixes: 96d6392b54dbb ("clk: imx: Add support for i.MX8MN clock driver") +Signed-off-by: Dario Binacchi +Acked-by: Marco Felsch +Reviewed-by: Abel Vesa +Signed-off-by: Abel Vesa +Link: https://lore.kernel.org/r/20221117113637.1978703-4-dario.binacchi@amarulasolutions.com +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imx8mn.c | 96 ++++++++++++------------ + include/dt-bindings/clock/imx8mn-clock.h | 12 ++- + 2 files changed, 56 insertions(+), 52 deletions(-) + +diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c +index 0fae97e61e2c..b80af5d1ef46 100644 +--- a/drivers/clk/imx/clk-imx8mn.c ++++ b/drivers/clk/imx/clk-imx8mn.c +@@ -27,7 +27,7 @@ static u32 share_count_nand; + static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", }; + static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", }; + static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", }; +-static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", }; ++static const char * const video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", }; + static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", }; + static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", }; + static const char * const m7_alt_pll_bypass_sels[] = {"m7_alt_pll", "m7_alt_pll_ref_sel", }; +@@ -41,23 +41,23 @@ static const char * const imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pl + static const char * const imx8mn_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", }; + + static const char * const imx8mn_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "m7_alt_pll_out", +- "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", }; ++ "sys_pll1_800m", "audio_pll1_out", "video_pll_out", "sys_pll3_out", }; + + static const char * const imx8mn_gpu_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", +- "video_pll1_out", "audio_pll2_out", }; ++ "video_pll_out", "audio_pll2_out", }; + + static const char * const imx8mn_gpu_shader_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", +- "video_pll1_out", "audio_pll2_out", }; ++ "video_pll_out", "audio_pll2_out", }; + + static const char * const imx8mn_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m", + "sys_pll2_250m", "sys_pll2_1000m", "audio_pll1_out", +- "video_pll1_out", "sys_pll1_100m",}; ++ "video_pll_out", "sys_pll1_100m",}; + + static const char * const imx8mn_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", + "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out", +- "video_pll1_out", "sys_pll3_out", }; ++ "video_pll_out", "sys_pll3_out", }; + + static const char * const imx8mn_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", + "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out", +@@ -77,23 +77,23 @@ static const char * const imx8mn_usb_bus_sels[] = {"osc_24m", "sys_pll2_500m", " + + static const char * const imx8mn_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", +- "video_pll1_out", "audio_pll2_out", }; ++ "video_pll_out", "audio_pll2_out", }; + + static const char * const imx8mn_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", + "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", +- "video_pll1_out", "audio_pll2_out", }; ++ "video_pll_out", "audio_pll2_out", }; + + static const char * const imx8mn_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out", + "sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out", +- "video_pll1_out", "audio_pll2_out", }; ++ "video_pll_out", "audio_pll2_out", }; + + static const char * const imx8mn_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m", + "sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out", +- "audio_pll1_out", "video_pll1_out", }; ++ "audio_pll1_out", "video_pll_out", }; + + static const char * const imx8mn_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", + "sys_pll2_1000m", "sys_pll2_166m", "sys_pll3_out", +- "audio_pll1_out", "video_pll1_out", }; ++ "audio_pll1_out", "video_pll_out", }; + + static const char * const imx8mn_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m", + "sys_pll2_500m", "sys_pll2_1000m", "sys_pll3_out", +@@ -103,49 +103,49 @@ static const char * const imx8mn_dram_apb_sels[] = {"osc_24m", "sys_pll2_200m", + "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", + "sys_pll2_250m", "audio_pll2_out", }; + +-static const char * const imx8mn_disp_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", ++static const char * const imx8mn_disp_pixel_sels[] = {"osc_24m", "video_pll_out", "audio_pll2_out", + "audio_pll1_out", "sys_pll1_800m", "sys_pll2_1000m", + "sys_pll3_out", "clk_ext4", }; + + static const char * const imx8mn_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "dummy", ++ "video_pll_out", "sys_pll1_133m", "dummy", + "clk_ext3", "clk_ext4", }; + + static const char * const imx8mn_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "dummy", ++ "video_pll_out", "sys_pll1_133m", "dummy", + "clk_ext3", "clk_ext4", }; + + static const char * const imx8mn_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "dummy", ++ "video_pll_out", "sys_pll1_133m", "dummy", + "clk_ext2", "clk_ext3", }; + + static const char * const imx8mn_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "dummy", ++ "video_pll_out", "sys_pll1_133m", "dummy", + "clk_ext3", "clk_ext4", }; + + static const char * const imx8mn_sai7_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "dummy", ++ "video_pll_out", "sys_pll1_133m", "dummy", + "clk_ext3", "clk_ext4", }; + + static const char * const imx8mn_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "dummy", ++ "video_pll_out", "sys_pll1_133m", "dummy", + "clk_ext2", "clk_ext3", }; + + static const char * const imx8mn_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m", + "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out", +- "video_pll1_out", "clk_ext4", }; ++ "video_pll_out", "clk_ext4", }; + + static const char * const imx8mn_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", + "clk_ext1", "clk_ext2", "clk_ext3", +- "clk_ext4", "video_pll1_out", }; ++ "clk_ext4", "video_pll_out", }; + + static const char * const imx8mn_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m", +- "sys_pll2_200m", "sys_pll2_500m", "video_pll1_out", ++ "sys_pll2_200m", "sys_pll2_500m", "video_pll_out", + "audio_pll2_out", }; + + static const char * const imx8mn_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out", + "sys_pll1_400m", "audio_pll2_out", "sys_pll3_out", +- "sys_pll2_250m", "video_pll1_out", }; ++ "sys_pll2_250m", "video_pll_out", }; + + static const char * const imx8mn_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll2_333m", + "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m", +@@ -160,19 +160,19 @@ static const char * const imx8mn_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "s + "audio_pll2_out", "sys_pll1_100m", }; + + static const char * const imx8mn_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", +- "sys_pll3_out", "audio_pll1_out", "video_pll1_out", ++ "sys_pll3_out", "audio_pll1_out", "video_pll_out", + "audio_pll2_out", "sys_pll1_133m", }; + + static const char * const imx8mn_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", +- "sys_pll3_out", "audio_pll1_out", "video_pll1_out", ++ "sys_pll3_out", "audio_pll1_out", "video_pll_out", + "audio_pll2_out", "sys_pll1_133m", }; + + static const char * const imx8mn_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", +- "sys_pll3_out", "audio_pll1_out", "video_pll1_out", ++ "sys_pll3_out", "audio_pll1_out", "video_pll_out", + "audio_pll2_out", "sys_pll1_133m", }; + + static const char * const imx8mn_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", +- "sys_pll3_out", "audio_pll1_out", "video_pll1_out", ++ "sys_pll3_out", "audio_pll1_out", "video_pll_out", + "audio_pll2_out", "sys_pll1_133m", }; + + static const char * const imx8mn_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", +@@ -213,42 +213,42 @@ static const char * const imx8mn_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "s + + static const char * const imx8mn_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", + "sys_pll1_40m", "sys_pll3_out", "clk_ext1", +- "sys_pll1_80m", "video_pll1_out", }; ++ "sys_pll1_80m", "video_pll_out", }; + + static const char * const imx8mn_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", + "sys_pll1_40m", "sys_pll3_out", "clk_ext1", +- "sys_pll1_80m", "video_pll1_out", }; ++ "sys_pll1_80m", "video_pll_out", }; + + static const char * const imx8mn_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", + "sys_pll1_40m", "sys_pll3_out", "clk_ext2", +- "sys_pll1_80m", "video_pll1_out", }; ++ "sys_pll1_80m", "video_pll_out", }; + + static const char * const imx8mn_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", + "sys_pll1_40m", "sys_pll3_out", "clk_ext2", +- "sys_pll1_80m", "video_pll1_out", }; ++ "sys_pll1_80m", "video_pll_out", }; + + static const char * const imx8mn_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", +- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", ++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + + static const char * const imx8mn_gpt2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", +- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", ++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + + static const char * const imx8mn_gpt3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", +- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", ++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + + static const char * const imx8mn_gpt4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", +- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", ++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + + static const char * const imx8mn_gpt5_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", +- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", ++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + + static const char * const imx8mn_gpt6_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", +- "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", ++ "sys_pll1_40m", "video_pll_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + + static const char * const imx8mn_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m", +@@ -261,15 +261,15 @@ static const char * const imx8mn_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "m7_ + + static const char * const imx8mn_dsi_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", + "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", +- "audio_pll2_out", "video_pll1_out", }; ++ "audio_pll2_out", "video_pll_out", }; + + static const char * const imx8mn_dsi_phy_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_100m", + "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2", +- "audio_pll2_out", "video_pll1_out", }; ++ "audio_pll2_out", "video_pll_out", }; + + static const char * const imx8mn_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_100m", + "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", +- "audio_pll2_out", "video_pll1_out", }; ++ "audio_pll2_out", "video_pll_out", }; + + static const char * const imx8mn_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", + "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", +@@ -277,15 +277,15 @@ static const char * const imx8mn_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "s + + static const char * const imx8mn_camera_pixel_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", + "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", +- "audio_pll2_out", "video_pll1_out", }; ++ "audio_pll2_out", "video_pll_out", }; + + static const char * const imx8mn_csi1_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", + "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2", +- "audio_pll2_out", "video_pll1_out", }; ++ "audio_pll2_out", "video_pll_out", }; + + static const char * const imx8mn_csi2_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", + "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2", +- "audio_pll2_out", "video_pll1_out", }; ++ "audio_pll2_out", "video_pll_out", }; + + static const char * const imx8mn_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", + "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", +@@ -306,9 +306,9 @@ static const char * const imx8mn_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "du + "dummy", "sys_pll1_80m", }; + static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m", + "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", +- "video_pll1_out", "osc_32k", }; ++ "video_pll_out", "osc_32k", }; + +-static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out", ++static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll_out", + "dummy", "dummy", "gpu_pll_out", "dummy", + "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3", + "dummy", "dummy", "osc_24m", "dummy", "osc_32k"}; +@@ -349,7 +349,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) + + hws[IMX8MN_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +- hws[IMX8MN_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); ++ hws[IMX8MN_VIDEO_PLL_REF_SEL] = imx_clk_hw_mux("video_pll_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_M7_ALT_PLL_REF_SEL] = imx_clk_hw_mux("m7_alt_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +@@ -358,7 +358,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) + + hws[IMX8MN_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll); + hws[IMX8MN_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll); +- hws[IMX8MN_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll); ++ hws[IMX8MN_VIDEO_PLL] = imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel", base + 0x28, &imx_1443x_pll); + hws[IMX8MN_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll); + hws[IMX8MN_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll); + hws[IMX8MN_M7_ALT_PLL] = imx_clk_hw_pll14xx("m7_alt_pll", "m7_alt_pll_ref_sel", base + 0x74, &imx_1416x_pll); +@@ -370,7 +370,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) + /* PLL bypass out */ + hws[IMX8MN_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT); +- hws[IMX8MN_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT); ++ hws[IMX8MN_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_M7_ALT_PLL_BYPASS] = imx_clk_hw_mux_flags("m7_alt_pll_bypass", base + 0x74, 28, 1, m7_alt_pll_bypass_sels, ARRAY_SIZE(m7_alt_pll_bypass_sels), CLK_SET_RATE_PARENT); +@@ -380,7 +380,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) + /* PLL out gate */ + hws[IMX8MN_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base, 13); + hws[IMX8MN_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13); +- hws[IMX8MN_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13); ++ hws[IMX8MN_VIDEO_PLL_OUT] = imx_clk_hw_gate("video_pll_out", "video_pll_bypass", base + 0x28, 13); + hws[IMX8MN_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13); + hws[IMX8MN_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11); + hws[IMX8MN_M7_ALT_PLL_OUT] = imx_clk_hw_gate("m7_alt_pll_out", "m7_alt_pll_bypass", base + 0x74, 11); +diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h +index 694e3c050d04..04809edab33c 100644 +--- a/include/dt-bindings/clock/imx8mn-clock.h ++++ b/include/dt-bindings/clock/imx8mn-clock.h +@@ -16,7 +16,8 @@ + #define IMX8MN_CLK_EXT4 7 + #define IMX8MN_AUDIO_PLL1_REF_SEL 8 + #define IMX8MN_AUDIO_PLL2_REF_SEL 9 +-#define IMX8MN_VIDEO_PLL1_REF_SEL 10 ++#define IMX8MN_VIDEO_PLL_REF_SEL 10 ++#define IMX8MN_VIDEO_PLL1_REF_SEL IMX8MN_VIDEO_PLL_REF_SEL + #define IMX8MN_DRAM_PLL_REF_SEL 11 + #define IMX8MN_GPU_PLL_REF_SEL 12 + #define IMX8MN_M7_ALT_PLL_REF_SEL 13 +@@ -27,7 +28,8 @@ + #define IMX8MN_SYS_PLL3_REF_SEL 17 + #define IMX8MN_AUDIO_PLL1 18 + #define IMX8MN_AUDIO_PLL2 19 +-#define IMX8MN_VIDEO_PLL1 20 ++#define IMX8MN_VIDEO_PLL 20 ++#define IMX8MN_VIDEO_PLL1 IMX8MN_VIDEO_PLL + #define IMX8MN_DRAM_PLL 21 + #define IMX8MN_GPU_PLL 22 + #define IMX8MN_M7_ALT_PLL 23 +@@ -38,7 +40,8 @@ + #define IMX8MN_SYS_PLL3 27 + #define IMX8MN_AUDIO_PLL1_BYPASS 28 + #define IMX8MN_AUDIO_PLL2_BYPASS 29 +-#define IMX8MN_VIDEO_PLL1_BYPASS 30 ++#define IMX8MN_VIDEO_PLL_BYPASS 30 ++#define IMX8MN_VIDEO_PLL1_BYPASS IMX8MN_VIDEO_PLL_BYPASS + #define IMX8MN_DRAM_PLL_BYPASS 31 + #define IMX8MN_GPU_PLL_BYPASS 32 + #define IMX8MN_M7_ALT_PLL_BYPASS 33 +@@ -49,7 +52,8 @@ + #define IMX8MN_SYS_PLL3_BYPASS 37 + #define IMX8MN_AUDIO_PLL1_OUT 38 + #define IMX8MN_AUDIO_PLL2_OUT 39 +-#define IMX8MN_VIDEO_PLL1_OUT 40 ++#define IMX8MN_VIDEO_PLL_OUT 40 ++#define IMX8MN_VIDEO_PLL1_OUT IMX8MN_VIDEO_PLL_OUT + #define IMX8MN_DRAM_PLL_OUT 41 + #define IMX8MN_GPU_PLL_OUT 42 + #define IMX8MN_M7_ALT_PLL_OUT 43 +-- +2.35.1 + diff --git a/queue-6.0/clk-imx-replace-osc_hdmi-with-dummy.patch b/queue-6.0/clk-imx-replace-osc_hdmi-with-dummy.patch new file mode 100644 index 00000000000..1f1e7dd89df --- /dev/null +++ b/queue-6.0/clk-imx-replace-osc_hdmi-with-dummy.patch @@ -0,0 +1,70 @@ +From a5870707181cfe099bf7a2da10ea690d99884449 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 12:36:34 +0100 +Subject: clk: imx: replace osc_hdmi with dummy + +From: Dario Binacchi + +[ Upstream commit e7fa365ff66f16772dc06b480cd78f858d10856b ] + +There is no occurrence of the hdmi oscillator in the reference manual +(document IMX8MNRM Rev 2, 07/2022). Further, if we consider the indexes +76-81 and 134 of the "Clock Root" table of chapter 5 of the RM, there is +no entry for the source select bits 101b, which is the setting referenced +by "osc_hdmi". +Fix by renaming "osc_hdmi" with "dummy", a clock which has already been +used for missing source select bits. + +Tested on the BSH SystemMaster (SMM) S2 board. + +Fixes: 96d6392b54dbb ("clk: imx: Add support for i.MX8MN clock driver") +Signed-off-by: Dario Binacchi +Acked-by: Marco Felsch +Signed-off-by: Abel Vesa +Link: https://lore.kernel.org/r/20221117113637.1978703-3-dario.binacchi@amarulasolutions.com +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imx8mn.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c +index 72f9563a0ff6..0fae97e61e2c 100644 +--- a/drivers/clk/imx/clk-imx8mn.c ++++ b/drivers/clk/imx/clk-imx8mn.c +@@ -108,27 +108,27 @@ static const char * const imx8mn_disp_pixel_sels[] = {"osc_24m", "video_pll1_out + "sys_pll3_out", "clk_ext4", }; + + static const char * const imx8mn_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "osc_hdmi", ++ "video_pll1_out", "sys_pll1_133m", "dummy", + "clk_ext3", "clk_ext4", }; + + static const char * const imx8mn_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "osc_hdmi", ++ "video_pll1_out", "sys_pll1_133m", "dummy", + "clk_ext3", "clk_ext4", }; + + static const char * const imx8mn_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "osc_hdmi", ++ "video_pll1_out", "sys_pll1_133m", "dummy", + "clk_ext2", "clk_ext3", }; + + static const char * const imx8mn_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "osc_hdmi", ++ "video_pll1_out", "sys_pll1_133m", "dummy", + "clk_ext3", "clk_ext4", }; + + static const char * const imx8mn_sai7_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "osc_hdmi", ++ "video_pll1_out", "sys_pll1_133m", "dummy", + "clk_ext3", "clk_ext4", }; + + static const char * const imx8mn_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", +- "video_pll1_out", "sys_pll1_133m", "osc_hdmi", ++ "video_pll1_out", "sys_pll1_133m", "dummy", + "clk_ext2", "clk_ext3", }; + + static const char * const imx8mn_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m", +-- +2.35.1 + diff --git a/queue-6.0/clk-imx8mn-fix-imx8mn_enet_phy_sels-clocks-list.patch b/queue-6.0/clk-imx8mn-fix-imx8mn_enet_phy_sels-clocks-list.patch new file mode 100644 index 00000000000..c8af8e3aa84 --- /dev/null +++ b/queue-6.0/clk-imx8mn-fix-imx8mn_enet_phy_sels-clocks-list.patch @@ -0,0 +1,56 @@ +From 4969b07b621af12602aaee5bf0f9f0bba8301643 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 12:36:37 +0100 +Subject: clk: imx8mn: fix imx8mn_enet_phy_sels clocks list + +From: Dario Binacchi + +[ Upstream commit 2626cf67f20b28446dfc3a5b9493dd535cdb747b ] + +According to the "Clock Root" table of the reference manual (document +IMX8MNRM Rev 2, 07/2022): + + Clock Root offset Source Select (CCM_TARGET_ROOTn[MUX]) + ... ... ... + ENET_PHY_REF_CLK_ROOT 0xAA80 000 - 24M_REF_CLK + 001 - SYSTEM_PLL2_DIV20 + 010 - SYSTEM_PLL2_DIV8 + 011 - SYSTEM_PLL2_DIV5 + 100 - SYSTEM_PLL2_DIV2 + 101 - AUDIO_PLL1_CLK + 110 - VIDEO_PLL_CLK + 111 - AUDIO_PLL2_CLK + ... ... ... + +while the imx8mn_enet_phy_sels list didn't contained audio_pll1_out for +source select bits 101b. + +Fixes: 96d6392b54dbb ("clk: imx: Add support for i.MX8MN clock driver") +Signed-off-by: Dario Binacchi +Acked-by: Marco Felsch +Reviewed-by: Abel Vesa +Signed-off-by: Abel Vesa +Link: https://lore.kernel.org/r/20221117113637.1978703-6-dario.binacchi@amarulasolutions.com +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imx8mn.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c +index 37128c35198d..2afea905f7f3 100644 +--- a/drivers/clk/imx/clk-imx8mn.c ++++ b/drivers/clk/imx/clk-imx8mn.c +@@ -140,8 +140,8 @@ static const char * const imx8mn_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m" + "clk_ext4", "video_pll_out", }; + + static const char * const imx8mn_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m", +- "sys_pll2_200m", "sys_pll2_500m", "video_pll_out", +- "audio_pll2_out", }; ++ "sys_pll2_200m", "sys_pll2_500m", "audio_pll1_out", ++ "video_pll_out", "audio_pll2_out", }; + + static const char * const imx8mn_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out", + "sys_pll1_400m", "audio_pll2_out", "sys_pll3_out", +-- +2.35.1 + diff --git a/queue-6.0/clk-imx8mn-fix-imx8mn_sai2_sels-clocks-list.patch b/queue-6.0/clk-imx8mn-fix-imx8mn_sai2_sels-clocks-list.patch new file mode 100644 index 00000000000..de786599bc5 --- /dev/null +++ b/queue-6.0/clk-imx8mn-fix-imx8mn_sai2_sels-clocks-list.patch @@ -0,0 +1,53 @@ +From dbec7a555da6926892a27fdf58c7f01a5f928268 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 12:36:36 +0100 +Subject: clk: imx8mn: fix imx8mn_sai2_sels clocks list + +From: Dario Binacchi + +[ Upstream commit 34d996747a74e3a86990f9f9c48de09159d78edb ] + +According to the "Clock Root" table of the reference manual (document +IMX8MNRM Rev 2, 07/2022): + + Clock Root offset Source Select (CCM_TARGET_ROOTn[MUX]) + ... ... ... + SAI2_CLK_ROOT 0xA600 000 - 24M_REF_CLK + 001 - AUDIO_PLL1_CLK + 010 - AUDIO_PLL2_CLK + 011 - VIDEO_PLL_CLK + 100 - SYSTEM_PLL1_DIV6 + 110 - EXT_CLK_2 + 111 - EXT_CLK_3 + ... ... ... + +while the imx8mn_sai2_sels list contained clk_ext3 and clk_ext4 for +source select bits 110b and 111b. + +Fixes: 96d6392b54dbb ("clk: imx: Add support for i.MX8MN clock driver") +Signed-off-by: Dario Binacchi +Acked-by: Marco Felsch +Reviewed-by: Abel Vesa +Signed-off-by: Abel Vesa +Link: https://lore.kernel.org/r/20221117113637.1978703-5-dario.binacchi@amarulasolutions.com +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imx8mn.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c +index b80af5d1ef46..37128c35198d 100644 +--- a/drivers/clk/imx/clk-imx8mn.c ++++ b/drivers/clk/imx/clk-imx8mn.c +@@ -109,7 +109,7 @@ static const char * const imx8mn_disp_pixel_sels[] = {"osc_24m", "video_pll_out" + + static const char * const imx8mn_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", + "video_pll_out", "sys_pll1_133m", "dummy", +- "clk_ext3", "clk_ext4", }; ++ "clk_ext2", "clk_ext3", }; + + static const char * const imx8mn_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", + "video_pll_out", "sys_pll1_133m", "dummy", +-- +2.35.1 + diff --git a/queue-6.0/clk-imx8mn-rename-vpu_pll-to-m7_alt_pll.patch b/queue-6.0/clk-imx8mn-rename-vpu_pll-to-m7_alt_pll.patch new file mode 100644 index 00000000000..18664fec15e --- /dev/null +++ b/queue-6.0/clk-imx8mn-rename-vpu_pll-to-m7_alt_pll.patch @@ -0,0 +1,170 @@ +From 48a7d132f402c2902736e9bfedf80bc5f36d538c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 12:36:33 +0100 +Subject: clk: imx8mn: rename vpu_pll to m7_alt_pll + +From: Dario Binacchi + +[ Upstream commit a429c60baefd95ab43a2ce7f25d5b2d7a2e431df ] + +The IMX8MN platform does not have any video processing unit (VPU), and +indeed in the reference manual (document IMX8MNRM Rev 2, 07/2022) there +is no occurrence of its pll. From an analysis of the code and the RM +itself, I think vpu pll is used instead of m7 alternate pll, probably +for copy and paste of code taken from modules of similar architectures. + +As an example for all, if we consider the second row of the "Clock Root" +table of chapter 5 (Clocks and Power Management) of the RM: + + Clock Root offset Source Select (CCM_TARGET_ROOTn[MUX]) + ... ... ... + ARM_M7_CLK_ROOT 0x8080 000 - 24M_REF_CLK + 001 - SYSTEM_PLL2_DIV5 + 010 - SYSTEM_PLL2_DIV4 + 011 - M7_ALT_PLL_CLK + 100 - SYSTEM_PLL1_CLK + 101 - AUDIO_PLL1_CLK + 110 - VIDEO_PLL_CLK + 111 - SYSTEM_PLL3_CLK + ... ... ... + +but in the source code, the imx8mn_m7_sels clocks list contains vpu_pll +for the source select bits 011b. + +So, let's rename "vpu_pll" to "m7_alt_pll" to be consistent with the RM. + +The IMX8MN_VPU_* constants have not been removed to ensure backward +compatibility of the patch. + +No functional changes intended. + +Fixes: 96d6392b54dbb ("clk: imx: Add support for i.MX8MN clock driver") +Signed-off-by: Dario Binacchi +Acked-by: Marco Felsch +Reviewed-by: Abel Vesa +Signed-off-by: Abel Vesa +Link: https://lore.kernel.org/r/20221117113637.1978703-2-dario.binacchi@amarulasolutions.com +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imx8mn.c | 16 ++++++++-------- + include/dt-bindings/clock/imx8mn-clock.h | 12 ++++++++---- + 2 files changed, 16 insertions(+), 12 deletions(-) + +diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c +index d37c45b676ab..72f9563a0ff6 100644 +--- a/drivers/clk/imx/clk-imx8mn.c ++++ b/drivers/clk/imx/clk-imx8mn.c +@@ -30,7 +30,7 @@ static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ + static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", }; + static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", }; + static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", }; +-static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", }; ++static const char * const m7_alt_pll_bypass_sels[] = {"m7_alt_pll", "m7_alt_pll_ref_sel", }; + static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", }; + static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", }; + +@@ -40,7 +40,7 @@ static const char * const imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pl + + static const char * const imx8mn_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", }; + +-static const char * const imx8mn_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "vpu_pll_out", ++static const char * const imx8mn_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "m7_alt_pll_out", + "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", }; + + static const char * const imx8mn_gpu_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", +@@ -252,10 +252,10 @@ static const char * const imx8mn_gpt6_sels[] = {"osc_24m", "sys_pll2_100m", "sys + "audio_pll1_out", "clk_ext1", }; + + static const char * const imx8mn_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m", +- "vpu_pll_out", "sys_pll2_125m", "sys_pll3_out", ++ "m7_alt_pll_out", "sys_pll2_125m", "sys_pll3_out", + "sys_pll1_80m", "sys_pll2_166m", }; + +-static const char * const imx8mn_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_out", ++static const char * const imx8mn_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "m7_alt_pll_out", + "sys_pll3_out", "sys_pll2_200m", "sys_pll1_266m", + "sys_pll2_500m", "sys_pll1_100m", }; + +@@ -352,7 +352,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) + hws[IMX8MN_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +- hws[IMX8MN_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); ++ hws[IMX8MN_M7_ALT_PLL_REF_SEL] = imx_clk_hw_mux("m7_alt_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + +@@ -361,7 +361,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) + hws[IMX8MN_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll); + hws[IMX8MN_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll); + hws[IMX8MN_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll); +- hws[IMX8MN_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll); ++ hws[IMX8MN_M7_ALT_PLL] = imx_clk_hw_pll14xx("m7_alt_pll", "m7_alt_pll_ref_sel", base + 0x74, &imx_1416x_pll); + hws[IMX8MN_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll); + hws[IMX8MN_SYS_PLL1] = imx_clk_hw_fixed("sys_pll1", 800000000); + hws[IMX8MN_SYS_PLL2] = imx_clk_hw_fixed("sys_pll2", 1000000000); +@@ -373,7 +373,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) + hws[IMX8MN_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT); +- hws[IMX8MN_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT); ++ hws[IMX8MN_M7_ALT_PLL_BYPASS] = imx_clk_hw_mux_flags("m7_alt_pll_bypass", base + 0x74, 28, 1, m7_alt_pll_bypass_sels, ARRAY_SIZE(m7_alt_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); + hws[IMX8MN_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT); + +@@ -383,7 +383,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) + hws[IMX8MN_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13); + hws[IMX8MN_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13); + hws[IMX8MN_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11); +- hws[IMX8MN_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11); ++ hws[IMX8MN_M7_ALT_PLL_OUT] = imx_clk_hw_gate("m7_alt_pll_out", "m7_alt_pll_bypass", base + 0x74, 11); + hws[IMX8MN_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11); + hws[IMX8MN_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11); + +diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h +index 07b8a282c268..694e3c050d04 100644 +--- a/include/dt-bindings/clock/imx8mn-clock.h ++++ b/include/dt-bindings/clock/imx8mn-clock.h +@@ -19,7 +19,8 @@ + #define IMX8MN_VIDEO_PLL1_REF_SEL 10 + #define IMX8MN_DRAM_PLL_REF_SEL 11 + #define IMX8MN_GPU_PLL_REF_SEL 12 +-#define IMX8MN_VPU_PLL_REF_SEL 13 ++#define IMX8MN_M7_ALT_PLL_REF_SEL 13 ++#define IMX8MN_VPU_PLL_REF_SEL IMX8MN_M7_ALT_PLL_REF_SEL + #define IMX8MN_ARM_PLL_REF_SEL 14 + #define IMX8MN_SYS_PLL1_REF_SEL 15 + #define IMX8MN_SYS_PLL2_REF_SEL 16 +@@ -29,7 +30,8 @@ + #define IMX8MN_VIDEO_PLL1 20 + #define IMX8MN_DRAM_PLL 21 + #define IMX8MN_GPU_PLL 22 +-#define IMX8MN_VPU_PLL 23 ++#define IMX8MN_M7_ALT_PLL 23 ++#define IMX8MN_VPU_PLL IMX8MN_M7_ALT_PLL + #define IMX8MN_ARM_PLL 24 + #define IMX8MN_SYS_PLL1 25 + #define IMX8MN_SYS_PLL2 26 +@@ -39,7 +41,8 @@ + #define IMX8MN_VIDEO_PLL1_BYPASS 30 + #define IMX8MN_DRAM_PLL_BYPASS 31 + #define IMX8MN_GPU_PLL_BYPASS 32 +-#define IMX8MN_VPU_PLL_BYPASS 33 ++#define IMX8MN_M7_ALT_PLL_BYPASS 33 ++#define IMX8MN_VPU_PLL_BYPASS IMX8MN_M7_ALT_PLL_BYPASS + #define IMX8MN_ARM_PLL_BYPASS 34 + #define IMX8MN_SYS_PLL1_BYPASS 35 + #define IMX8MN_SYS_PLL2_BYPASS 36 +@@ -49,7 +52,8 @@ + #define IMX8MN_VIDEO_PLL1_OUT 40 + #define IMX8MN_DRAM_PLL_OUT 41 + #define IMX8MN_GPU_PLL_OUT 42 +-#define IMX8MN_VPU_PLL_OUT 43 ++#define IMX8MN_M7_ALT_PLL_OUT 43 ++#define IMX8MN_VPU_PLL_OUT IMX8MN_M7_ALT_PLL_OUT + #define IMX8MN_ARM_PLL_OUT 44 + #define IMX8MN_SYS_PLL1_OUT 45 + #define IMX8MN_SYS_PLL2_OUT 46 +-- +2.35.1 + diff --git a/queue-6.0/clk-imx93-correct-enet-clock.patch b/queue-6.0/clk-imx93-correct-enet-clock.patch new file mode 100644 index 00000000000..579bc4584e9 --- /dev/null +++ b/queue-6.0/clk-imx93-correct-enet-clock.patch @@ -0,0 +1,39 @@ +From c5335b2c95c08290bdee422fc18dc1cd8eb79bfc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Oct 2022 17:52:07 +0800 +Subject: clk: imx93: correct enet clock + +From: Peng Fan + +[ Upstream commit 4be5d91b9433f1dc76de485e240ca6aaa2d19f65 ] + +Per update Reference Mannual, correct the enet clock parent to +wakeup_axi_root. + +Fixes: 24defbe194b6 ("clk: imx: add i.MX93 clk") +Reviewed-by: Ye Li +Signed-off-by: Peng Fan +Reviewed-by: Abel Vesa +Signed-off-by: Abel Vesa +Link: https://lore.kernel.org/r/20221028095211.2598312-3-peng.fan@oss.nxp.com +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imx93.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c +index 8d67b065f7b6..2e99c3443d3c 100644 +--- a/drivers/clk/imx/clk-imx93.c ++++ b/drivers/clk/imx/clk-imx93.c +@@ -229,7 +229,7 @@ static const struct imx93_clk_ccgr { + { IMX93_CLK_AUD_XCVR_GATE, "aud_xcvr", "audio_xcvr_root", 0x9b80, }, + { IMX93_CLK_SPDIF_GATE, "spdif", "spdif_root", 0x9c00, }, + { IMX93_CLK_HSIO_32K_GATE, "hsio_32k", "osc_32k", 0x9dc0, }, +- { IMX93_CLK_ENET1_GATE, "enet1", "enet_root", 0x9e00, }, ++ { IMX93_CLK_ENET1_GATE, "enet1", "wakeup_axi_root", 0x9e00, }, + { IMX93_CLK_ENET_QOS_GATE, "enet_qos", "wakeup_axi_root", 0x9e40, }, + { IMX93_CLK_SYS_CNT_GATE, "sys_cnt", "osc_24m", 0x9e80, }, + { IMX93_CLK_TSTMR1_GATE, "tstmr1", "bus_aon_root", 0x9ec0, }, +-- +2.35.1 + diff --git a/queue-6.0/clk-imx93-correct-the-flexspi1-clock-setting.patch b/queue-6.0/clk-imx93-correct-the-flexspi1-clock-setting.patch new file mode 100644 index 00000000000..07c0b960a3a --- /dev/null +++ b/queue-6.0/clk-imx93-correct-the-flexspi1-clock-setting.patch @@ -0,0 +1,39 @@ +From 0553be03fccf61183baf22d82d1290a31ebe82b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Oct 2022 13:26:39 +0800 +Subject: clk: imx93: correct the flexspi1 clock setting + +From: Haibo Chen + +[ Upstream commit 62dfdbcc16e767b91ed35d4fc0428c86d4688505 ] + +Correct IMX93_CLK_FLEXSPI1_GATE CCGR setting. Otherwise the flexspi +always can't be assigned to a parent clock when dump the clock tree. + +Fixes: 24defbe194b6 ("clk: imx: add i.MX93 clk") +Reviewed-by: Peng Fan +Signed-off-by: Haibo Chen +Reviewed-by: Abel Vesa +Signed-off-by: Abel Vesa +Link: https://lore.kernel.org/r/1666589199-1199-1-git-send-email-haibo.chen@nxp.com +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imx93.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c +index dcc41d178238..4d2524addc3e 100644 +--- a/drivers/clk/imx/clk-imx93.c ++++ b/drivers/clk/imx/clk-imx93.c +@@ -162,7 +162,7 @@ static const struct imx93_clk_ccgr { + { IMX93_CLK_MU_B_GATE, "mu_b", "bus_aon_root", 0x8500, }, + { IMX93_CLK_EDMA1_GATE, "edma1", "m33_root", 0x8540, }, + { IMX93_CLK_EDMA2_GATE, "edma2", "wakeup_axi_root", 0x8580, }, +- { IMX93_CLK_FLEXSPI1_GATE, "flexspi", "flexspi_root", 0x8640, }, ++ { IMX93_CLK_FLEXSPI1_GATE, "flexspi1", "flexspi1_root", 0x8640, }, + { IMX93_CLK_GPIO1_GATE, "gpio1", "m33_root", 0x8880, }, + { IMX93_CLK_GPIO2_GATE, "gpio2", "bus_wakeup_root", 0x88c0, }, + { IMX93_CLK_GPIO3_GATE, "gpio3", "bus_wakeup_root", 0x8900, }, +-- +2.35.1 + diff --git a/queue-6.0/clk-imx93-unmap-anatop-base-in-error-handling-path.patch b/queue-6.0/clk-imx93-unmap-anatop-base-in-error-handling-path.patch new file mode 100644 index 00000000000..6c61b8b625d --- /dev/null +++ b/queue-6.0/clk-imx93-unmap-anatop-base-in-error-handling-path.patch @@ -0,0 +1,74 @@ +From b5b4b03782b3250a777b79eefc64ff76d3d62197 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Oct 2022 17:52:06 +0800 +Subject: clk: imx93: unmap anatop base in error handling path + +From: Peng Fan + +[ Upstream commit bda7b7f396f94d8df89ecacc88f2826908e8762c ] + +The anatop base is not unmapped during error handling path, fix it. + +Fixes: 24defbe194b6 ("clk: imx: add i.MX93 clk") +Reported-by: Dan Carpenter +Signed-off-by: Peng Fan +Reviewed-by: Abel Vesa +Signed-off-by: Abel Vesa +Link: https://lore.kernel.org/r/20221028095211.2598312-2-peng.fan@oss.nxp.com +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imx93.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c +index 4d2524addc3e..8d67b065f7b6 100644 +--- a/drivers/clk/imx/clk-imx93.c ++++ b/drivers/clk/imx/clk-imx93.c +@@ -247,7 +247,7 @@ static int imx93_clocks_probe(struct platform_device *pdev) + struct device_node *np = dev->of_node; + const struct imx93_clk_root *root; + const struct imx93_clk_ccgr *ccgr; +- void __iomem *base = NULL; ++ void __iomem *base, *anatop_base; + int i, ret; + + clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, +@@ -274,20 +274,22 @@ static int imx93_clocks_probe(struct platform_device *pdev) + "sys_pll_pfd2", 1, 2); + + np = of_find_compatible_node(NULL, NULL, "fsl,imx93-anatop"); +- base = of_iomap(np, 0); ++ anatop_base = of_iomap(np, 0); + of_node_put(np); +- if (WARN_ON(!base)) ++ if (WARN_ON(!anatop_base)) + return -ENOMEM; + +- clks[IMX93_CLK_AUDIO_PLL] = imx_clk_fracn_gppll("audio_pll", "osc_24m", base + 0x1200, ++ clks[IMX93_CLK_AUDIO_PLL] = imx_clk_fracn_gppll("audio_pll", "osc_24m", anatop_base + 0x1200, + &imx_fracn_gppll); +- clks[IMX93_CLK_VIDEO_PLL] = imx_clk_fracn_gppll("video_pll", "osc_24m", base + 0x1400, ++ clks[IMX93_CLK_VIDEO_PLL] = imx_clk_fracn_gppll("video_pll", "osc_24m", anatop_base + 0x1400, + &imx_fracn_gppll); + + np = dev->of_node; + base = devm_platform_ioremap_resource(pdev, 0); +- if (WARN_ON(IS_ERR(base))) ++ if (WARN_ON(IS_ERR(base))) { ++ iounmap(anatop_base); + return PTR_ERR(base); ++ } + + for (i = 0; i < ARRAY_SIZE(root_array); i++) { + root = &root_array[i]; +@@ -317,6 +319,7 @@ static int imx93_clocks_probe(struct platform_device *pdev) + + unregister_hws: + imx_unregister_hw_clocks(clks, IMX93_CLK_END); ++ iounmap(anatop_base); + + return ret; + } +-- +2.35.1 + diff --git a/queue-6.0/clk-mediatek-fix-dependency-of-mt7986-adc-clocks.patch b/queue-6.0/clk-mediatek-fix-dependency-of-mt7986-adc-clocks.patch new file mode 100644 index 00000000000..a1374f7e3c2 --- /dev/null +++ b/queue-6.0/clk-mediatek-fix-dependency-of-mt7986-adc-clocks.patch @@ -0,0 +1,41 @@ +From 089b6c171ffbb4aad421fbf8956750dde69c6811 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 17:18:07 +0100 +Subject: clk: mediatek: fix dependency of MT7986 ADC clocks + +From: Daniel Golle + +[ Upstream commit a46315295489933209e902638cd287aeb5f982ab ] + +It seems like CLK_INFRA_ADC_FRC_CK always need to be enabled for +CLK_INFRA_ADC_26M_CK to work. Instead of adding this dependency to the +mtk-thermal and mt6577_auxadc drivers, add dependency to the clock +driver clk-mt7986-infracfg.c. + +Fixes: ec97d23c8e22 ("clk: mediatek: add mt7986 clock support") +Suggested-by: AngeloGioacchino Del Regno +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/5e55012567da74870e1fb2edc2dc513b5821e523.1666801017.git.daniel@makrotopia.org +Signed-off-by: Chen-Yu Tsai +Signed-off-by: Sasha Levin +--- + drivers/clk/mediatek/clk-mt7986-infracfg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/mediatek/clk-mt7986-infracfg.c b/drivers/clk/mediatek/clk-mt7986-infracfg.c +index d90727a53283..49666047bf0e 100644 +--- a/drivers/clk/mediatek/clk-mt7986-infracfg.c ++++ b/drivers/clk/mediatek/clk-mt7986-infracfg.c +@@ -153,7 +153,7 @@ static const struct mtk_gate infra_clks[] = { + 18), + GATE_INFRA1(CLK_INFRA_MSDC_66M_CK, "infra_msdc_66m", "infra_sysaxi_d2", + 19), +- GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m", "csw_f26m_sel", 20), ++ GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m", "infra_adc_frc", 20), + GATE_INFRA1(CLK_INFRA_ADC_FRC_CK, "infra_adc_frc", "csw_f26m_sel", 21), + GATE_INFRA1(CLK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", "nfi1x_sel", 23), + /* INFRA2 */ +-- +2.35.1 + diff --git a/queue-6.0/clk-qcom-clk-krait-fix-wrong-div2-functions.patch b/queue-6.0/clk-qcom-clk-krait-fix-wrong-div2-functions.patch new file mode 100644 index 00000000000..38baf5ee19b --- /dev/null +++ b/queue-6.0/clk-qcom-clk-krait-fix-wrong-div2-functions.patch @@ -0,0 +1,40 @@ +From a9739d33ac8dc2737905cebf412502c55f5c9d4d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Nov 2022 22:56:25 +0100 +Subject: clk: qcom: clk-krait: fix wrong div2 functions + +From: Christian Marangi + +[ Upstream commit d676d3a3717cf726d3affedbe5ba98fc4ccad7b3 ] + +Currently div2 value is applied to the wrong bits. This is caused by a +bug in the code where the shift is done only for lpl, for anything +else the mask is not shifted to the correct bits. + +Fix this by correctly shift if lpl is not supported. + +Fixes: 4d7dc77babfe ("clk: qcom: Add support for Krait clocks") +Signed-off-by: Christian Marangi +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221108215625.30186-1-ansuelsmth@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/clk-krait.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/clk/qcom/clk-krait.c b/drivers/clk/qcom/clk-krait.c +index 45da736bd5f4..293a9dfa7151 100644 +--- a/drivers/clk/qcom/clk-krait.c ++++ b/drivers/clk/qcom/clk-krait.c +@@ -114,6 +114,8 @@ static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate, + + if (d->lpl) + mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift; ++ else ++ mask <<= d->shift; + + spin_lock_irqsave(&krait_clock_reg_lock, flags); + val = krait_get_l2_indirect_reg(d->offset); +-- +2.35.1 + diff --git a/queue-6.0/clk-qcom-dispcc-sm6350-add-clk_ops_parent_enable-to-.patch b/queue-6.0/clk-qcom-dispcc-sm6350-add-clk_ops_parent_enable-to-.patch new file mode 100644 index 00000000000..8b785c150de --- /dev/null +++ b/queue-6.0/clk-qcom-dispcc-sm6350-add-clk_ops_parent_enable-to-.patch @@ -0,0 +1,46 @@ +From f8a8e879a408843a2c4ff6acfd7bde7ebe0a6647 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 17:55:46 +0200 +Subject: clk: qcom: dispcc-sm6350: Add CLK_OPS_PARENT_ENABLE to pixel&byte src + +From: Konrad Dybcio + +[ Upstream commit 92039e8c080c63748f8e133e7cfad33a75daefb6 ] + +Add the CLK_OPS_PARENT_ENABLE flag to pixel and byte clk srcs to +ensure set_rate can succeed. + +Signed-off-by: Konrad Dybcio +Fixes: 837519775f1d ("clk: qcom: Add display clock controller driver for SM6350") +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221010155546.73884-1-konrad.dybcio@somainline.org +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/dispcc-sm6350.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/qcom/dispcc-sm6350.c b/drivers/clk/qcom/dispcc-sm6350.c +index 0c3c2e26ede9..ea6f54ed846e 100644 +--- a/drivers/clk/qcom/dispcc-sm6350.c ++++ b/drivers/clk/qcom/dispcc-sm6350.c +@@ -306,7 +306,7 @@ static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { + .name = "disp_cc_mdss_pclk0_clk_src", + .parent_data = disp_cc_parent_data_5, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), +- .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, ++ .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE | CLK_OPS_PARENT_ENABLE, + .ops = &clk_pixel_ops, + }, + }; +@@ -385,7 +385,7 @@ static struct clk_branch disp_cc_mdss_byte0_clk = { + &disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, +- .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, ++ .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE | CLK_OPS_PARENT_ENABLE, + .ops = &clk_branch2_ops, + }, + }, +-- +2.35.1 + diff --git a/queue-6.0/clk-qcom-gcc-ipq806x-use-parent_data-for-the-last-re.patch b/queue-6.0/clk-qcom-gcc-ipq806x-use-parent_data-for-the-last-re.patch new file mode 100644 index 00000000000..b93b55c3402 --- /dev/null +++ b/queue-6.0/clk-qcom-gcc-ipq806x-use-parent_data-for-the-last-re.patch @@ -0,0 +1,40 @@ +From 566eddd95216396574fc01f539e9d435d4701c44 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Sep 2022 14:38:25 +0300 +Subject: clk: qcom: gcc-ipq806x: use parent_data for the last remaining entry + +From: Dmitry Baryshkov + +[ Upstream commit 55307e522cc7a4dddc3d231ca5cb7e68e9668f66 ] + +Use parent_data for the last remaining entry (pll4). This clock is +provided by the lcc device. + +Fixes: cb02866f9a74 ("clk: qcom: gcc-ipq806x: convert parent_names to parent_data") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220927113826.246241-3-dmitry.baryshkov@linaro.org +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-ipq806x.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c +index 718de17a1e60..6447f3e81b55 100644 +--- a/drivers/clk/qcom/gcc-ipq806x.c ++++ b/drivers/clk/qcom/gcc-ipq806x.c +@@ -79,7 +79,9 @@ static struct clk_regmap pll4_vote = { + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "pll4_vote", +- .parent_names = (const char *[]){ "pll4" }, ++ .parent_data = &(const struct clk_parent_data){ ++ .fw_name = "pll4", .name = "pll4", ++ }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +-- +2.35.1 + diff --git a/queue-6.0/clk-qcom-gcc-sm8250-use-retention-mode-for-usb-gdscs.patch b/queue-6.0/clk-qcom-gcc-sm8250-use-retention-mode-for-usb-gdscs.patch new file mode 100644 index 00000000000..bd53455588a --- /dev/null +++ b/queue-6.0/clk-qcom-gcc-sm8250-use-retention-mode-for-usb-gdscs.patch @@ -0,0 +1,48 @@ +From daaea5e34cd6e0147121d001d89077f069d1526c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Nov 2022 14:43:20 +0530 +Subject: clk: qcom: gcc-sm8250: Use retention mode for USB GDSCs + +From: Manivannan Sadhasivam + +[ Upstream commit ac1c5a03d3772b1db25e8092f771aa33f6ae2f7e ] + +USB controllers on SM8250 doesn't work after coming back from suspend. +This can be fixed by keeping the USB GDSCs in retention mode so that +hardware can keep them ON and put into rentention mode once the parent +domain goes to a low power state. + +Fixes: 3e5770921a88 ("clk: qcom: gcc: Add global clock controller driver for SM8250") +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221102091320.66007-1-manivannan.sadhasivam@linaro.org +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-sm8250.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-sm8250.c b/drivers/clk/qcom/gcc-sm8250.c +index 9755ef4888c1..a0ba37656b07 100644 +--- a/drivers/clk/qcom/gcc-sm8250.c ++++ b/drivers/clk/qcom/gcc-sm8250.c +@@ -3267,7 +3267,7 @@ static struct gdsc usb30_prim_gdsc = { + .pd = { + .name = "usb30_prim_gdsc", + }, +- .pwrsts = PWRSTS_OFF_ON, ++ .pwrsts = PWRSTS_RET_ON, + }; + + static struct gdsc usb30_sec_gdsc = { +@@ -3275,7 +3275,7 @@ static struct gdsc usb30_sec_gdsc = { + .pd = { + .name = "usb30_sec_gdsc", + }, +- .pwrsts = PWRSTS_OFF_ON, ++ .pwrsts = PWRSTS_RET_ON, + }; + + static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = { +-- +2.35.1 + diff --git a/queue-6.0/clk-qcom-lpass-add-support-for-resets-external-mclk-.patch b/queue-6.0/clk-qcom-lpass-add-support-for-resets-external-mclk-.patch new file mode 100644 index 00000000000..72245c2379a --- /dev/null +++ b/queue-6.0/clk-qcom-lpass-add-support-for-resets-external-mclk-.patch @@ -0,0 +1,152 @@ +From be1cc7bfd4cbfc1f6529deb0b06a3ed9e9da3e07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Sep 2022 09:47:26 +0530 +Subject: clk: qcom: lpass: Add support for resets & external mclk for SC7280 + +From: Taniya Das + +[ Upstream commit 7c6a6641c24d30ab6f5456d19e15e64bea971b82 ] + +The clock gating control for TX/RX/WSA core bus clocks would be required +to be reset(moved from hardware control) from audio core driver. Thus +add the support for the reset clocks. + +Update the lpass_aon_cc_main_rcg_clk_src ops to park the RCG at XO after +disable as this clock signal is used by hardware to turn ON memories in +LPASS. Also add the external mclk to interface external MI2S. + +Fixes: a9dd26639d05 ("clk: qcom: lpass: Add support for LPASS clock controller for SC7280") +Signed-off-by: Taniya Das +Reviewed-by: Stephen Boyd +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/1662005846-4838-6-git-send-email-quic_c_skakit@quicinc.com +Stable-dep-of: d470be3c4f30 ("clk: qcom: lpass-sc7280: Fix pm_runtime usage") +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/lpassaudiocc-sc7280.c | 24 +++++++++++++++++-- + drivers/clk/qcom/lpasscorecc-sc7280.c | 33 ++++++++++++++++++++++++++ + 2 files changed, 55 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/qcom/lpassaudiocc-sc7280.c b/drivers/clk/qcom/lpassaudiocc-sc7280.c +index 606732879fea..5d4bc563073c 100644 +--- a/drivers/clk/qcom/lpassaudiocc-sc7280.c ++++ b/drivers/clk/qcom/lpassaudiocc-sc7280.c +@@ -23,6 +23,7 @@ + #include "clk-regmap-mux.h" + #include "common.h" + #include "gdsc.h" ++#include "reset.h" + + enum { + P_BI_TCXO, +@@ -248,7 +249,7 @@ static struct clk_rcg2 lpass_aon_cc_main_rcg_clk_src = { + .parent_data = lpass_aon_cc_parent_data_0, + .num_parents = ARRAY_SIZE(lpass_aon_cc_parent_data_0), + .flags = CLK_OPS_PARENT_ENABLE, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -703,6 +704,18 @@ static const struct qcom_cc_desc lpass_audio_cc_sc7280_desc = { + .num_clks = ARRAY_SIZE(lpass_audio_cc_sc7280_clocks), + }; + ++static const struct qcom_reset_map lpass_audio_cc_sc7280_resets[] = { ++ [LPASS_AUDIO_SWR_RX_CGCR] = { 0xa0, 1 }, ++ [LPASS_AUDIO_SWR_TX_CGCR] = { 0xa8, 1 }, ++ [LPASS_AUDIO_SWR_WSA_CGCR] = { 0xb0, 1 }, ++}; ++ ++static const struct qcom_cc_desc lpass_audio_cc_reset_sc7280_desc = { ++ .config = &lpass_audio_cc_sc7280_regmap_config, ++ .resets = lpass_audio_cc_sc7280_resets, ++ .num_resets = ARRAY_SIZE(lpass_audio_cc_sc7280_resets), ++}; ++ + static const struct of_device_id lpass_audio_cc_sc7280_match_table[] = { + { .compatible = "qcom,sc7280-lpassaudiocc" }, + { } +@@ -772,13 +785,20 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev) + regmap_write(regmap, 0x4, 0x3b); + regmap_write(regmap, 0x8, 0xff05); + +- ret = qcom_cc_really_probe(pdev, &lpass_audio_cc_sc7280_desc, regmap); ++ ret = qcom_cc_probe_by_index(pdev, 0, &lpass_audio_cc_sc7280_desc); + if (ret) { + dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC clocks\n"); + pm_runtime_disable(&pdev->dev); + return ret; + } + ++ ret = qcom_cc_probe_by_index(pdev, 1, &lpass_audio_cc_reset_sc7280_desc); ++ if (ret) { ++ dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC Resets\n"); ++ pm_runtime_disable(&pdev->dev); ++ return ret; ++ } ++ + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_put_autosuspend(&pdev->dev); + pm_runtime_put_sync(&pdev->dev); +diff --git a/drivers/clk/qcom/lpasscorecc-sc7280.c b/drivers/clk/qcom/lpasscorecc-sc7280.c +index 1f1f1bd1b68e..6ad19b06b1ce 100644 +--- a/drivers/clk/qcom/lpasscorecc-sc7280.c ++++ b/drivers/clk/qcom/lpasscorecc-sc7280.c +@@ -190,6 +190,19 @@ static struct clk_rcg2 lpass_core_cc_ext_if1_clk_src = { + }, + }; + ++static struct clk_rcg2 lpass_core_cc_ext_mclk0_clk_src = { ++ .cmd_rcgr = 0x20000, ++ .mnd_width = 8, ++ .hid_width = 5, ++ .parent_map = lpass_core_cc_parent_map_0, ++ .freq_tbl = ftbl_lpass_core_cc_ext_if0_clk_src, ++ .clkr.hw.init = &(const struct clk_init_data){ ++ .name = "lpass_core_cc_ext_mclk0_clk_src", ++ .parent_data = lpass_core_cc_parent_data_0, ++ .num_parents = ARRAY_SIZE(lpass_core_cc_parent_data_0), ++ .ops = &clk_rcg2_ops, ++ }, ++}; + + static struct clk_branch lpass_core_cc_core_clk = { + .halt_reg = 0x1f000, +@@ -283,6 +296,24 @@ static struct clk_branch lpass_core_cc_lpm_mem0_core_clk = { + }, + }; + ++static struct clk_branch lpass_core_cc_ext_mclk0_clk = { ++ .halt_reg = 0x20014, ++ .halt_check = BRANCH_HALT, ++ .clkr = { ++ .enable_reg = 0x20014, ++ .enable_mask = BIT(0), ++ .hw.init = &(const struct clk_init_data){ ++ .name = "lpass_core_cc_ext_mclk0_clk", ++ .parent_hws = (const struct clk_hw*[]){ ++ &lpass_core_cc_ext_mclk0_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ + static struct clk_branch lpass_core_cc_sysnoc_mport_core_clk = { + .halt_reg = 0x23000, + .halt_check = BRANCH_HALT_VOTED, +@@ -326,6 +357,8 @@ static struct clk_regmap *lpass_core_cc_sc7280_clocks[] = { + [LPASS_CORE_CC_LPM_CORE_CLK] = &lpass_core_cc_lpm_core_clk.clkr, + [LPASS_CORE_CC_LPM_MEM0_CORE_CLK] = &lpass_core_cc_lpm_mem0_core_clk.clkr, + [LPASS_CORE_CC_SYSNOC_MPORT_CORE_CLK] = &lpass_core_cc_sysnoc_mport_core_clk.clkr, ++ [LPASS_CORE_CC_EXT_MCLK0_CLK] = &lpass_core_cc_ext_mclk0_clk.clkr, ++ [LPASS_CORE_CC_EXT_MCLK0_CLK_SRC] = &lpass_core_cc_ext_mclk0_clk_src.clkr, + }; + + static struct regmap_config lpass_core_cc_sc7280_regmap_config = { +-- +2.35.1 + diff --git a/queue-6.0/clk-qcom-lpass-handle-the-regmap-overlap-of-lpasscc-.patch b/queue-6.0/clk-qcom-lpass-handle-the-regmap-overlap-of-lpasscc-.patch new file mode 100644 index 00000000000..70f352d17bb --- /dev/null +++ b/queue-6.0/clk-qcom-lpass-handle-the-regmap-overlap-of-lpasscc-.patch @@ -0,0 +1,180 @@ +From bbd3bcb4683566d5710bd8dfb1d906a04b39c3e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Sep 2022 09:47:23 +0530 +Subject: clk: qcom: lpass: Handle the regmap overlap of lpasscc and lpass_aon + +From: Taniya Das + +[ Upstream commit 0cbcfbe50cbff331c775982a53bc4fa66c875b36 ] + +Move registration of lpass_q6ss_ahbm_clk and lpass_q6ss_ahbs_clk to +lpass_aon_cc_sc7280_probe and register them only if "qcom,adsp-pil-mode" +is enabled in the lpass_aon DT node. + +Signed-off-by: Taniya Das +Signed-off-by: Satya Priya +Reviewed-by: Stephen Boyd +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/1662005846-4838-3-git-send-email-quic_c_skakit@quicinc.com +Stable-dep-of: d470be3c4f30 ("clk: qcom: lpass-sc7280: Fix pm_runtime usage") +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/lpassaudiocc-sc7280.c | 44 ++++++++++++++++++++++++++ + drivers/clk/qcom/lpasscc-sc7280.c | 44 -------------------------- + 2 files changed, 44 insertions(+), 44 deletions(-) + +diff --git a/drivers/clk/qcom/lpassaudiocc-sc7280.c b/drivers/clk/qcom/lpassaudiocc-sc7280.c +index 6ab6e5a34c72..606732879fea 100644 +--- a/drivers/clk/qcom/lpassaudiocc-sc7280.c ++++ b/drivers/clk/qcom/lpassaudiocc-sc7280.c +@@ -12,6 +12,7 @@ + #include + #include + ++#include + #include + + #include "clk-alpha-pll.h" +@@ -38,6 +39,32 @@ static const struct pll_vco zonda_vco[] = { + { 595200000UL, 3600000000UL, 0 }, + }; + ++static struct clk_branch lpass_q6ss_ahbm_clk = { ++ .halt_reg = 0x901c, ++ .halt_check = BRANCH_HALT, ++ .clkr = { ++ .enable_reg = 0x901c, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "lpass_q6ss_ahbm_clk", ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch lpass_q6ss_ahbs_clk = { ++ .halt_reg = 0x9020, ++ .halt_check = BRANCH_HALT_VOTED, ++ .clkr = { ++ .enable_reg = 0x9020, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "lpass_q6ss_ahbs_clk", ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ + /* 1128.96MHz configuration */ + static const struct alpha_pll_config lpass_audio_cc_pll_config = { + .l = 0x3a, +@@ -614,6 +641,11 @@ static struct gdsc lpass_aon_cc_lpass_audio_hm_gdsc = { + .flags = RETAIN_FF_ENABLE, + }; + ++static struct clk_regmap *lpass_cc_sc7280_clocks[] = { ++ [LPASS_Q6SS_AHBM_CLK] = &lpass_q6ss_ahbm_clk.clkr, ++ [LPASS_Q6SS_AHBS_CLK] = &lpass_q6ss_ahbs_clk.clkr, ++}; ++ + static struct clk_regmap *lpass_aon_cc_sc7280_clocks[] = { + [LPASS_AON_CC_AUDIO_HM_H_CLK] = &lpass_aon_cc_audio_hm_h_clk.clkr, + [LPASS_AON_CC_VA_MEM0_CLK] = &lpass_aon_cc_va_mem0_clk.clkr, +@@ -659,6 +691,12 @@ static struct regmap_config lpass_audio_cc_sc7280_regmap_config = { + .fast_io = true, + }; + ++static const struct qcom_cc_desc lpass_cc_sc7280_desc = { ++ .config = &lpass_audio_cc_sc7280_regmap_config, ++ .clks = lpass_cc_sc7280_clocks, ++ .num_clks = ARRAY_SIZE(lpass_cc_sc7280_clocks), ++}; ++ + static const struct qcom_cc_desc lpass_audio_cc_sc7280_desc = { + .config = &lpass_audio_cc_sc7280_regmap_config, + .clks = lpass_audio_cc_sc7280_clocks, +@@ -785,6 +823,12 @@ static int lpass_aon_cc_sc7280_probe(struct platform_device *pdev) + if (ret) + return ret; + ++ if (of_property_read_bool(pdev->dev.of_node, "qcom,adsp-pil-mode")) { ++ lpass_audio_cc_sc7280_regmap_config.name = "cc"; ++ desc = &lpass_cc_sc7280_desc; ++ return qcom_cc_probe(pdev, desc); ++ } ++ + lpass_audio_cc_sc7280_regmap_config.name = "lpasscc_aon"; + lpass_audio_cc_sc7280_regmap_config.max_register = 0xa0008; + desc = &lpass_aon_cc_sc7280_desc; +diff --git a/drivers/clk/qcom/lpasscc-sc7280.c b/drivers/clk/qcom/lpasscc-sc7280.c +index b39ee1c9647b..5c1e17bd0d76 100644 +--- a/drivers/clk/qcom/lpasscc-sc7280.c ++++ b/drivers/clk/qcom/lpasscc-sc7280.c +@@ -17,32 +17,6 @@ + #include "clk-branch.h" + #include "common.h" + +-static struct clk_branch lpass_q6ss_ahbm_clk = { +- .halt_reg = 0x1c, +- .halt_check = BRANCH_HALT, +- .clkr = { +- .enable_reg = 0x1c, +- .enable_mask = BIT(0), +- .hw.init = &(struct clk_init_data){ +- .name = "lpass_q6ss_ahbm_clk", +- .ops = &clk_branch2_ops, +- }, +- }, +-}; +- +-static struct clk_branch lpass_q6ss_ahbs_clk = { +- .halt_reg = 0x20, +- .halt_check = BRANCH_HALT_VOTED, +- .clkr = { +- .enable_reg = 0x20, +- .enable_mask = BIT(0), +- .hw.init = &(struct clk_init_data){ +- .name = "lpass_q6ss_ahbs_clk", +- .ops = &clk_branch2_ops, +- }, +- }, +-}; +- + static struct clk_branch lpass_top_cc_lpi_q6_axim_hs_clk = { + .halt_reg = 0x0, + .halt_check = BRANCH_HALT, +@@ -105,17 +79,6 @@ static struct regmap_config lpass_regmap_config = { + .fast_io = true, + }; + +-static struct clk_regmap *lpass_cc_sc7280_clocks[] = { +- [LPASS_Q6SS_AHBM_CLK] = &lpass_q6ss_ahbm_clk.clkr, +- [LPASS_Q6SS_AHBS_CLK] = &lpass_q6ss_ahbs_clk.clkr, +-}; +- +-static const struct qcom_cc_desc lpass_cc_sc7280_desc = { +- .config = &lpass_regmap_config, +- .clks = lpass_cc_sc7280_clocks, +- .num_clks = ARRAY_SIZE(lpass_cc_sc7280_clocks), +-}; +- + static struct clk_regmap *lpass_cc_top_sc7280_clocks[] = { + [LPASS_TOP_CC_LPI_Q6_AXIM_HS_CLK] = + &lpass_top_cc_lpi_q6_axim_hs_clk.clkr, +@@ -169,13 +132,6 @@ static int lpass_cc_sc7280_probe(struct platform_device *pdev) + if (ret) + goto destroy_pm_clk; + +- lpass_regmap_config.name = "cc"; +- desc = &lpass_cc_sc7280_desc; +- +- ret = qcom_cc_probe_by_index(pdev, 2, desc); +- if (ret) +- goto destroy_pm_clk; +- + return 0; + + destroy_pm_clk: +-- +2.35.1 + diff --git a/queue-6.0/clk-qcom-lpass-sc7180-fix-pm_runtime-usage.patch b/queue-6.0/clk-qcom-lpass-sc7180-fix-pm_runtime-usage.patch new file mode 100644 index 00000000000..b1e450b3354 --- /dev/null +++ b/queue-6.0/clk-qcom-lpass-sc7180-fix-pm_runtime-usage.patch @@ -0,0 +1,135 @@ +From a1529af3d1a8a295523a0cca02a32cf30fd57c4a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Nov 2022 06:56:29 -0700 +Subject: clk: qcom: lpass-sc7180: Fix pm_runtime usage + +From: Douglas Anderson + +[ Upstream commit ff1ccf59eaffd192efe21f7de9fb0c130faf1b1b ] + +The sc7180 lpass clock controller's pm_runtime usage wasn't broken +quite as spectacularly as the sc7280's pm_runtime usage, but it was +still broken. Putting some printouts in at boot showed me this (with +serial console enabled, which makes the prints slow and thus changes +timing): + [ 3.109951] DOUG: my_pm_clk_resume, usage=1 + [ 3.114767] DOUG: my_pm_clk_resume, usage=1 + [ 3.664443] DOUG: my_pm_clk_suspend, usage=0 + [ 3.897566] DOUG: my_pm_clk_suspend, usage=0 + [ 3.910137] DOUG: my_pm_clk_resume, usage=1 + [ 3.923217] DOUG: my_pm_clk_resume, usage=0 + [ 4.440116] DOUG: my_pm_clk_suspend, usage=-1 + [ 4.444982] DOUG: my_pm_clk_suspend, usage=0 + [ 14.170501] DOUG: my_pm_clk_resume, usage=1 + [ 14.176245] DOUG: my_pm_clk_resume, usage=0 + +...or this w/out serial console: + [ 0.556139] DOUG: my_pm_clk_resume, usage=1 + [ 0.556279] DOUG: my_pm_clk_resume, usage=1 + [ 1.058422] DOUG: my_pm_clk_suspend, usage=-1 + [ 1.058464] DOUG: my_pm_clk_suspend, usage=0 + [ 1.186250] DOUG: my_pm_clk_resume, usage=1 + [ 1.186292] DOUG: my_pm_clk_resume, usage=0 + [ 1.731536] DOUG: my_pm_clk_suspend, usage=-1 + [ 1.731557] DOUG: my_pm_clk_suspend, usage=0 + [ 10.288910] DOUG: my_pm_clk_resume, usage=1 + [ 10.289496] DOUG: my_pm_clk_resume, usage=0 + +It seems to be doing roughly the right sequence of calls, but just +like with sc7280 this is more by luck than anything. Having a usage of +-1 is just not OK. + +Let's fix this like we did with sc7280. + +Signed-off-by: Douglas Anderson +Fixes: ce8c195e652f ("clk: qcom: lpasscc: Introduce pm autosuspend for SC7180") +Reviewed-by: Stephen Boyd +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221104064055.2.I49b25b9bda9430fc7ea21e5a708ca5a0aced2798@changeid +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/lpasscorecc-sc7180.c | 24 ++++++++++++++++-------- + 1 file changed, 16 insertions(+), 8 deletions(-) + +diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c +index ac09b7b840ab..a5731994cbed 100644 +--- a/drivers/clk/qcom/lpasscorecc-sc7180.c ++++ b/drivers/clk/qcom/lpasscorecc-sc7180.c +@@ -356,7 +356,7 @@ static const struct qcom_cc_desc lpass_audio_hm_sc7180_desc = { + .num_gdscs = ARRAY_SIZE(lpass_audio_hm_sc7180_gdscs), + }; + +-static int lpass_create_pm_clks(struct platform_device *pdev) ++static int lpass_setup_runtime_pm(struct platform_device *pdev) + { + int ret; + +@@ -375,7 +375,7 @@ static int lpass_create_pm_clks(struct platform_device *pdev) + if (ret < 0) + dev_err(&pdev->dev, "failed to acquire iface clock\n"); + +- return ret; ++ return pm_runtime_resume_and_get(&pdev->dev); + } + + static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) +@@ -384,7 +384,7 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) + struct regmap *regmap; + int ret; + +- ret = lpass_create_pm_clks(pdev); ++ ret = lpass_setup_runtime_pm(pdev); + if (ret) + return ret; + +@@ -392,12 +392,14 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) + desc = &lpass_audio_hm_sc7180_desc; + ret = qcom_cc_probe_by_index(pdev, 1, desc); + if (ret) +- return ret; ++ goto exit; + + lpass_core_cc_sc7180_regmap_config.name = "lpass_core_cc"; + regmap = qcom_cc_map(pdev, &lpass_core_cc_sc7180_desc); +- if (IS_ERR(regmap)) +- return PTR_ERR(regmap); ++ if (IS_ERR(regmap)) { ++ ret = PTR_ERR(regmap); ++ goto exit; ++ } + + /* + * Keep the CLK always-ON +@@ -415,6 +417,7 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) + ret = qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap); + + pm_runtime_mark_last_busy(&pdev->dev); ++exit: + pm_runtime_put_autosuspend(&pdev->dev); + + return ret; +@@ -425,14 +428,19 @@ static int lpass_hm_core_probe(struct platform_device *pdev) + const struct qcom_cc_desc *desc; + int ret; + +- ret = lpass_create_pm_clks(pdev); ++ ret = lpass_setup_runtime_pm(pdev); + if (ret) + return ret; + + lpass_core_cc_sc7180_regmap_config.name = "lpass_hm_core"; + desc = &lpass_core_hm_sc7180_desc; + +- return qcom_cc_probe_by_index(pdev, 0, desc); ++ ret = qcom_cc_probe_by_index(pdev, 0, desc); ++ ++ pm_runtime_mark_last_busy(&pdev->dev); ++ pm_runtime_put_autosuspend(&pdev->dev); ++ ++ return ret; + } + + static const struct of_device_id lpass_hm_sc7180_match_table[] = { +-- +2.35.1 + diff --git a/queue-6.0/clk-qcom-lpass-sc7280-fix-pm_runtime-usage.patch b/queue-6.0/clk-qcom-lpass-sc7280-fix-pm_runtime-usage.patch new file mode 100644 index 00000000000..4f8e901c416 --- /dev/null +++ b/queue-6.0/clk-qcom-lpass-sc7280-fix-pm_runtime-usage.patch @@ -0,0 +1,238 @@ +From ebb552c5ca64a47349e34f0ec2f7687a1d9aeb82 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Nov 2022 06:56:28 -0700 +Subject: clk: qcom: lpass-sc7280: Fix pm_runtime usage + +From: Douglas Anderson + +[ Upstream commit d470be3c4f30b4666e43eef6bab80f543563cdb0 ] + +The pm_runtime usage in lpass-sc7280 was broken in quite a few +ways. Specifically: + +1. At the end of probe it called "put" twice. This is a no-no and will + end us up with a negative usage count. Even worse than calling + "put" twice, it never called "get" once. Thus after bootup it could + be seen that the runtime usage of the devices managed by this + driver was -2. +2. In some error cases it manually called pm_runtime_disable() even + though it had previously used devm_add_action_or_reset() to set + this up to be called automatically. This meant that in these error + cases we'd double-call pm_runtime_disable(). +3. It forgot to call undo pm_runtime_use_autosuspend(), which can + sometimes have subtle problems (and the docs specifically mention + that you need to undo this function). + +Overall the above seriously calls into question how this driver is +working. It seems like a combination of "it doesn't", "by luck", and +"because of the weirdness of runtime_pm". Specifically I put a +printout to the serial console every time the runtime suspend/resume +was called for the two devices created by this driver (I wrapped the +pm_clk calls). When I had serial console enabled, I found that the +calls got resumed at bootup (when the clk core probed and before our +double-put) and then never touched again. That's no good. + [ 0.829997] DOUG: my_pm_clk_resume, usage=1 + [ 0.835487] DOUG: my_pm_clk_resume, usage=1 + +When I disabled serial console (speeding up boot), I got a different +pattern, which I guess (?) is better: + [ 0.089767] DOUG: my_pm_clk_resume, usage=1 + [ 0.090507] DOUG: my_pm_clk_resume, usage=1 + [ 0.151885] DOUG: my_pm_clk_suspend, usage=-2 + [ 0.151914] DOUG: my_pm_clk_suspend, usage=-2 + [ 1.825747] DOUG: my_pm_clk_resume, usage=-1 + [ 1.825774] DOUG: my_pm_clk_resume, usage=-1 + [ 1.888269] DOUG: my_pm_clk_suspend, usage=-2 + [ 1.888282] DOUG: my_pm_clk_suspend, usage=-2 + +These different patterns have to do with the fact that the core PM +Runtime code really isn't designed to be robust to negative usage +counts and sometimes may happen to stumble upon a behavior that +happens to "work". For instance, you can see that +__pm_runtime_suspend() will treat any non-zero value (including +negative numbers) as if the device is in use. + +In any case, let's fix the driver to be correct. We'll hold a +pm_runtime reference for the whole probe and then drop it (once!) at +the end. We'll get rid of manual pm_runtime_disable() calls in the +error handling. We'll also switch to devm_pm_runtime_enable(), which +magically handles undoing pm_runtime_use_autosuspend() as of commit +b4060db9251f ("PM: runtime: Have devm_pm_runtime_enable() handle +pm_runtime_dont_use_autosuspend()"). + +While we're at this, let's also use devm_pm_clk_create() instead of +rolling it ourselves. + +Note that the above changes make it obvious that +lpassaudio_create_pm_clks() was doing more than just creating +clocks. It was also setting up pm_runtime parameters. Let's rename it. + +All of these problems were found by code inspection. I started looking +at this driver because it was involved in a deadlock that I reported a +while ago [1]. Though I bisected the deadlock to commit 1b771839de05 +("clk: qcom: gdsc: enable optional power domain support"), it was +never really clear why that patch affected it other than a luck of +timing changes. I'll also note that by fixing the timing (as done in +this change) we also seem to aboid the deadlock, which is a nice +benefit. + +Also note that some of the fixes here are much the same type of stuff +that Dmitry did in commit 72cfc73f4663 ("clk: qcom: use +devm_pm_runtime_enable and devm_pm_clk_create"), but I guess +lpassaudiocc-sc7280.c didn't exist then. + +[1] https://lore.kernel.org/r/20220922154354.2486595-1-dianders@chromium.org + +Fixes: a9dd26639d05 ("clk: qcom: lpass: Add support for LPASS clock controller for SC7280") +Signed-off-by: Douglas Anderson +Reviewed-by: Dmitry Baryshkov +Reviewed-by: Stephen Boyd +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20221104064055.1.I00a0e4564a25489e85328ec41636497775627564@changeid +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/lpassaudiocc-sc7280.c | 55 ++++++++++---------------- + 1 file changed, 21 insertions(+), 34 deletions(-) + +diff --git a/drivers/clk/qcom/lpassaudiocc-sc7280.c b/drivers/clk/qcom/lpassaudiocc-sc7280.c +index 5d4bc563073c..b2646b7e13c9 100644 +--- a/drivers/clk/qcom/lpassaudiocc-sc7280.c ++++ b/drivers/clk/qcom/lpassaudiocc-sc7280.c +@@ -722,33 +722,17 @@ static const struct of_device_id lpass_audio_cc_sc7280_match_table[] = { + }; + MODULE_DEVICE_TABLE(of, lpass_audio_cc_sc7280_match_table); + +-static void lpassaudio_pm_runtime_disable(void *data) +-{ +- pm_runtime_disable(data); +-} +- +-static void lpassaudio_pm_clk_destroy(void *data) +-{ +- pm_clk_destroy(data); +-} +- +-static int lpassaudio_create_pm_clks(struct platform_device *pdev) ++static int lpass_audio_setup_runtime_pm(struct platform_device *pdev) + { + int ret; + + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, 50); +- pm_runtime_enable(&pdev->dev); +- +- ret = devm_add_action_or_reset(&pdev->dev, lpassaudio_pm_runtime_disable, &pdev->dev); +- if (ret) +- return ret; +- +- ret = pm_clk_create(&pdev->dev); ++ ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return ret; + +- ret = devm_add_action_or_reset(&pdev->dev, lpassaudio_pm_clk_destroy, &pdev->dev); ++ ret = devm_pm_clk_create(&pdev->dev); + if (ret) + return ret; + +@@ -756,7 +740,7 @@ static int lpassaudio_create_pm_clks(struct platform_device *pdev) + if (ret < 0) + dev_err(&pdev->dev, "failed to acquire iface clock\n"); + +- return ret; ++ return pm_runtime_resume_and_get(&pdev->dev); + } + + static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev) +@@ -765,7 +749,7 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev) + struct regmap *regmap; + int ret; + +- ret = lpassaudio_create_pm_clks(pdev); ++ ret = lpass_audio_setup_runtime_pm(pdev); + if (ret) + return ret; + +@@ -775,8 +759,8 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev) + + regmap = qcom_cc_map(pdev, desc); + if (IS_ERR(regmap)) { +- pm_runtime_disable(&pdev->dev); +- return PTR_ERR(regmap); ++ ret = PTR_ERR(regmap); ++ goto exit; + } + + clk_zonda_pll_configure(&lpass_audio_cc_pll, regmap, &lpass_audio_cc_pll_config); +@@ -788,20 +772,18 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev) + ret = qcom_cc_probe_by_index(pdev, 0, &lpass_audio_cc_sc7280_desc); + if (ret) { + dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC clocks\n"); +- pm_runtime_disable(&pdev->dev); +- return ret; ++ goto exit; + } + + ret = qcom_cc_probe_by_index(pdev, 1, &lpass_audio_cc_reset_sc7280_desc); + if (ret) { + dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC Resets\n"); +- pm_runtime_disable(&pdev->dev); +- return ret; ++ goto exit; + } + + pm_runtime_mark_last_busy(&pdev->dev); ++exit: + pm_runtime_put_autosuspend(&pdev->dev); +- pm_runtime_put_sync(&pdev->dev); + + return ret; + } +@@ -839,14 +821,15 @@ static int lpass_aon_cc_sc7280_probe(struct platform_device *pdev) + struct regmap *regmap; + int ret; + +- ret = lpassaudio_create_pm_clks(pdev); ++ ret = lpass_audio_setup_runtime_pm(pdev); + if (ret) + return ret; + + if (of_property_read_bool(pdev->dev.of_node, "qcom,adsp-pil-mode")) { + lpass_audio_cc_sc7280_regmap_config.name = "cc"; + desc = &lpass_cc_sc7280_desc; +- return qcom_cc_probe(pdev, desc); ++ ret = qcom_cc_probe(pdev, desc); ++ goto exit; + } + + lpass_audio_cc_sc7280_regmap_config.name = "lpasscc_aon"; +@@ -854,18 +837,22 @@ static int lpass_aon_cc_sc7280_probe(struct platform_device *pdev) + desc = &lpass_aon_cc_sc7280_desc; + + regmap = qcom_cc_map(pdev, desc); +- if (IS_ERR(regmap)) +- return PTR_ERR(regmap); ++ if (IS_ERR(regmap)) { ++ ret = PTR_ERR(regmap); ++ goto exit; ++ } + + clk_lucid_pll_configure(&lpass_aon_cc_pll, regmap, &lpass_aon_cc_pll_config); + + ret = qcom_cc_really_probe(pdev, &lpass_aon_cc_sc7280_desc, regmap); +- if (ret) ++ if (ret) { + dev_err(&pdev->dev, "Failed to register LPASS AON CC clocks\n"); ++ goto exit; ++ } + + pm_runtime_mark_last_busy(&pdev->dev); ++exit: + pm_runtime_put_autosuspend(&pdev->dev); +- pm_runtime_put_sync(&pdev->dev); + + return ret; + } +-- +2.35.1 + diff --git a/queue-6.0/clk-renesas-r8a779a0-fix-sd0h-clock-name.patch b/queue-6.0/clk-renesas-r8a779a0-fix-sd0h-clock-name.patch new file mode 100644 index 00000000000..3825627b852 --- /dev/null +++ b/queue-6.0/clk-renesas-r8a779a0-fix-sd0h-clock-name.patch @@ -0,0 +1,37 @@ +From 88ee093ca204f1fcb2d3732be01254b2fc1fa3e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Oct 2022 20:48:30 +0200 +Subject: clk: renesas: r8a779a0: Fix SD0H clock name + +From: Wolfram Sang + +[ Upstream commit db7076d5a7f0ca7dcf08f5095c74f86d4d0085ff ] + +Correct the misspelled textual name of the SD0H clock. + +Fixes: 470e3f0d0b15 ("clk: renesas: rcar-gen4: Introduce R-Car Gen4 CPG driver") +Reported-by: Geert Uytterhoeven +Signed-off-by: Wolfram Sang +Link: https://lore.kernel.org/r/20221012184830.3199-1-wsa+renesas@sang-engineering.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r8a779a0-cpg-mssr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c +index d74d46833012..e02542ca24a0 100644 +--- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c ++++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c +@@ -116,7 +116,7 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { + DEF_FIXED("cp", R8A779A0_CLK_CP, CLK_EXTAL, 2, 1), + DEF_FIXED("cl16mck", R8A779A0_CLK_CL16MCK, CLK_PLL1_DIV2, 64, 1), + +- DEF_GEN4_SDH("sdh0", R8A779A0_CLK_SD0H, CLK_SDSRC, 0x870), ++ DEF_GEN4_SDH("sd0h", R8A779A0_CLK_SD0H, CLK_SDSRC, 0x870), + DEF_GEN4_SD("sd0", R8A779A0_CLK_SD0, R8A779A0_CLK_SD0H, 0x870), + + DEF_BASE("rpc", R8A779A0_CLK_RPC, CLK_TYPE_GEN4_RPC, CLK_RPCSRC), +-- +2.35.1 + diff --git a/queue-6.0/clk-renesas-r8a779f0-fix-hscif-parent-clocks.patch b/queue-6.0/clk-renesas-r8a779f0-fix-hscif-parent-clocks.patch new file mode 100644 index 00000000000..b8fb6f08aa8 --- /dev/null +++ b/queue-6.0/clk-renesas-r8a779f0-fix-hscif-parent-clocks.patch @@ -0,0 +1,49 @@ +From 0625573b20ff0d945a5f1a1e9588aaaf72a9ad37 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Nov 2022 15:34:37 +0100 +Subject: clk: renesas: r8a779f0: Fix HSCIF parent clocks + +From: Wolfram Sang + +[ Upstream commit c258e3ab639112d8f5ae9df9a873750ae2623ce2 ] + +As serial communication requires a clean clock signal, the High Speed +Serial Communication Interfaces with FIFO (HSCIF) are clocked by a clock +that is not affected by Spread Spectrum or Fractional Multiplication. + +Hence change the parent clocks for the HSCIF modules from the S0D3_PER +clock to the SASYNCPERD1 clock (which has the same clock rate), cfr. +R-Car S4-8 Hardware User's Manual rev. 0.81. + +Fixes: 080bcd8d5997 ("clk: renesas: r8a779f0: Add HSCIF clocks") +Reported-by: Geert Uytterhoeven +Signed-off-by: Wolfram Sang +Link: https://lore.kernel.org/r/20221103143440.46449-2-wsa+renesas@sang-engineering.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r8a779f0-cpg-mssr.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/clk/renesas/r8a779f0-cpg-mssr.c b/drivers/clk/renesas/r8a779f0-cpg-mssr.c +index cd80b6084ece..90cac3f8b2ed 100644 +--- a/drivers/clk/renesas/r8a779f0-cpg-mssr.c ++++ b/drivers/clk/renesas/r8a779f0-cpg-mssr.c +@@ -120,10 +120,10 @@ static const struct cpg_core_clk r8a779f0_core_clks[] __initconst = { + }; + + static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = { +- DEF_MOD("hscif0", 514, R8A779F0_CLK_S0D3), +- DEF_MOD("hscif1", 515, R8A779F0_CLK_S0D3), +- DEF_MOD("hscif2", 516, R8A779F0_CLK_S0D3), +- DEF_MOD("hscif3", 517, R8A779F0_CLK_S0D3), ++ DEF_MOD("hscif0", 514, R8A779F0_CLK_SASYNCPERD1), ++ DEF_MOD("hscif1", 515, R8A779F0_CLK_SASYNCPERD1), ++ DEF_MOD("hscif2", 516, R8A779F0_CLK_SASYNCPERD1), ++ DEF_MOD("hscif3", 517, R8A779F0_CLK_SASYNCPERD1), + DEF_MOD("i2c0", 518, R8A779F0_CLK_S0D6_PER), + DEF_MOD("i2c1", 519, R8A779F0_CLK_S0D6_PER), + DEF_MOD("i2c2", 520, R8A779F0_CLK_S0D6_PER), +-- +2.35.1 + diff --git a/queue-6.0/clk-renesas-r8a779f0-fix-scif-parent-clocks.patch b/queue-6.0/clk-renesas-r8a779f0-fix-scif-parent-clocks.patch new file mode 100644 index 00000000000..3ce33e88251 --- /dev/null +++ b/queue-6.0/clk-renesas-r8a779f0-fix-scif-parent-clocks.patch @@ -0,0 +1,49 @@ +From 372d5277cd445da9aede3ec06531a80b51880067 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Nov 2022 15:34:38 +0100 +Subject: clk: renesas: r8a779f0: Fix SCIF parent clocks + +From: Wolfram Sang + +[ Upstream commit 2e0d7d3eabce3babae1fd66d7650e00c848a3b45 ] + +As serial communication requires a clean clock signal, the Serial +Communication Interfaces with FIFO (SCIF) are clocked by a clock that is +not affected by Spread Spectrum or Fractional Multiplication. + +Hence change the parent clocks for the SCIF modules from the S0D12_PER +clock to the SASYNCPERD4 clock (which has the same clock rate), cfr. +R-Car S4-8 Hardware User's Manual rev. 0.81. + +Fixes: 24aaff6a6ce4 ("clk: renesas: cpg-mssr: Add support for R-Car S4-8") +Reported-by: Geert Uytterhoeven +Signed-off-by: Wolfram Sang +Link: https://lore.kernel.org/r/20221103143440.46449-3-wsa+renesas@sang-engineering.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r8a779f0-cpg-mssr.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/clk/renesas/r8a779f0-cpg-mssr.c b/drivers/clk/renesas/r8a779f0-cpg-mssr.c +index 90cac3f8b2ed..b7936f422c27 100644 +--- a/drivers/clk/renesas/r8a779f0-cpg-mssr.c ++++ b/drivers/clk/renesas/r8a779f0-cpg-mssr.c +@@ -132,10 +132,10 @@ static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = { + DEF_MOD("i2c5", 523, R8A779F0_CLK_S0D6_PER), + DEF_MOD("pcie0", 624, R8A779F0_CLK_S0D2), + DEF_MOD("pcie1", 625, R8A779F0_CLK_S0D2), +- DEF_MOD("scif0", 702, R8A779F0_CLK_S0D12_PER), +- DEF_MOD("scif1", 703, R8A779F0_CLK_S0D12_PER), +- DEF_MOD("scif3", 704, R8A779F0_CLK_S0D12_PER), +- DEF_MOD("scif4", 705, R8A779F0_CLK_S0D12_PER), ++ DEF_MOD("scif0", 702, R8A779F0_CLK_SASYNCPERD4), ++ DEF_MOD("scif1", 703, R8A779F0_CLK_SASYNCPERD4), ++ DEF_MOD("scif3", 704, R8A779F0_CLK_SASYNCPERD4), ++ DEF_MOD("scif4", 705, R8A779F0_CLK_SASYNCPERD4), + DEF_MOD("sdhi0", 706, R8A779F0_CLK_SD0), + DEF_MOD("sys-dmac0", 709, R8A779F0_CLK_S0D3_PER), + DEF_MOD("sys-dmac1", 710, R8A779F0_CLK_S0D3_PER), +-- +2.35.1 + diff --git a/queue-6.0/clk-renesas-r9a06g032-repair-grave-increment-error.patch b/queue-6.0/clk-renesas-r9a06g032-repair-grave-increment-error.patch new file mode 100644 index 00000000000..85e9d5a1c6c --- /dev/null +++ b/queue-6.0/clk-renesas-r9a06g032-repair-grave-increment-error.patch @@ -0,0 +1,47 @@ +From 1cc19f3122568aae190ab9bed862dea5708d6f40 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Oct 2022 13:38:34 +0200 +Subject: clk: renesas: r9a06g032: Repair grave increment error + +From: Marek Vasut + +[ Upstream commit 02693e11611e082e3c4d8653e8af028e43d31164 ] + +If condition (clkspec.np != pd->dev.of_node) is true, then the driver +ends up in an endless loop, forever, locking up the machine. + +Fixes: aad03a66f902 ("clk: renesas: r9a06g032: Add clock domain support") +Reviewed-by: Ralph Siemsen +Signed-off-by: Marek Vasut +Reviewed-by: Gareth Williams +Link: https://lore.kernel.org/r/20221028113834.7496-1-marex@denx.de +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r9a06g032-clocks.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c +index 1488c9d6e639..983faa5707b9 100644 +--- a/drivers/clk/renesas/r9a06g032-clocks.c ++++ b/drivers/clk/renesas/r9a06g032-clocks.c +@@ -412,7 +412,7 @@ static int r9a06g032_attach_dev(struct generic_pm_domain *pd, + int error; + int index; + +- while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, ++ while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i++, + &clkspec)) { + if (clkspec.np != pd->dev.of_node) + continue; +@@ -425,7 +425,6 @@ static int r9a06g032_attach_dev(struct generic_pm_domain *pd, + if (error) + return error; + } +- i++; + } + + return 0; +-- +2.35.1 + diff --git a/queue-6.0/clk-rockchip-fix-memory-leak-in-rockchip_clk_registe.patch b/queue-6.0/clk-rockchip-fix-memory-leak-in-rockchip_clk_registe.patch new file mode 100644 index 00000000000..593b449a3fb --- /dev/null +++ b/queue-6.0/clk-rockchip-fix-memory-leak-in-rockchip_clk_registe.patch @@ -0,0 +1,37 @@ +From 8485c0d5f570fa34c62e348a371bf75a67c3fa18 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Nov 2022 17:12:01 +0800 +Subject: clk: rockchip: Fix memory leak in rockchip_clk_register_pll() + +From: Xiu Jianfeng + +[ Upstream commit 739a6a6bbdb793bd57938cb24aa5a6df89983546 ] + +If clk_register() fails, @pll->rate_table may have allocated memory by +kmemdup(), so it needs to be freed, otherwise will cause memory leak +issue, this patch fixes it. + +Fixes: 90c590254051 ("clk: rockchip: add clock type for pll clocks and pll used on rk3066") +Signed-off-by: Xiu Jianfeng +Link: https://lore.kernel.org/r/20221123091201.199819-1-xiujianfeng@huawei.com +Signed-off-by: Heiko Stuebner +Signed-off-by: Sasha Levin +--- + drivers/clk/rockchip/clk-pll.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c +index f7827b3b7fc1..6e5e502be44a 100644 +--- a/drivers/clk/rockchip/clk-pll.c ++++ b/drivers/clk/rockchip/clk-pll.c +@@ -981,6 +981,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, + return mux_clk; + + err_pll: ++ kfree(pll->rate_table); + clk_unregister(mux_clk); + mux_clk = pll_clk; + err_mux: +-- +2.35.1 + diff --git a/queue-6.0/clk-samsung-fix-memory-leak-in-_samsung_clk_register.patch b/queue-6.0/clk-samsung-fix-memory-leak-in-_samsung_clk_register.patch new file mode 100644 index 00000000000..d2d7792a108 --- /dev/null +++ b/queue-6.0/clk-samsung-fix-memory-leak-in-_samsung_clk_register.patch @@ -0,0 +1,38 @@ +From a9904627d2315d8a580226fb04ea489ddd880152 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Nov 2022 11:20:15 +0800 +Subject: clk: samsung: Fix memory leak in _samsung_clk_register_pll() + +From: Xiu Jianfeng + +[ Upstream commit 5174e5b0d1b669a489524192b6adcbb3c54ebc72 ] + +If clk_register() fails, @pll->rate_table may have allocated memory by +kmemdup(), so it needs to be freed, otherwise will cause memory leak +issue, this patch fixes it. + +Fixes: 3ff6e0d8d64d ("clk: samsung: Add support to register rate_table for samsung plls") +Signed-off-by: Xiu Jianfeng +Link: https://lore.kernel.org/r/20221123032015.63980-1-xiujianfeng@huawei.com +Reviewed-by: Alim Akhtar +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/samsung/clk-pll.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c +index fe383471c5f0..0ff28938943f 100644 +--- a/drivers/clk/samsung/clk-pll.c ++++ b/drivers/clk/samsung/clk-pll.c +@@ -1583,6 +1583,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, + if (ret) { + pr_err("%s: failed to register pll clock %s : %d\n", + __func__, pll_clk->name, ret); ++ kfree(pll->rate_table); + kfree(pll); + return; + } +-- +2.35.1 + diff --git a/queue-6.0/clk-socfpga-fix-memory-leak-in-socfpga_gate_init.patch b/queue-6.0/clk-socfpga-fix-memory-leak-in-socfpga_gate_init.patch new file mode 100644 index 00000000000..70e84c16045 --- /dev/null +++ b/queue-6.0/clk-socfpga-fix-memory-leak-in-socfpga_gate_init.patch @@ -0,0 +1,48 @@ +From fb3d697c9e601fdd08a45045c8e31352044d32f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Nov 2022 11:16:22 +0800 +Subject: clk: socfpga: Fix memory leak in socfpga_gate_init() + +From: Xiu Jianfeng + +[ Upstream commit 0b8ba891ad4d1ef6bfa4c72efc83f9f9f855f68b ] + +Free @socfpga_clk and @ops on the error path to avoid memory leak issue. + +Fixes: a30a67be7b6e ("clk: socfpga: Don't have get_parent for single parent ops") +Signed-off-by: Xiu Jianfeng +Link: https://lore.kernel.org/r/20221123031622.63171-1-xiujianfeng@huawei.com +Acked-by: Dinh Nguyen +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/socfpga/clk-gate.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c +index 53d6e3ec4309..c94b59b80dd4 100644 +--- a/drivers/clk/socfpga/clk-gate.c ++++ b/drivers/clk/socfpga/clk-gate.c +@@ -188,8 +188,10 @@ void __init socfpga_gate_init(struct device_node *node) + return; + + ops = kmemdup(&gateclk_ops, sizeof(gateclk_ops), GFP_KERNEL); +- if (WARN_ON(!ops)) ++ if (WARN_ON(!ops)) { ++ kfree(socfpga_clk); + return; ++ } + + rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2); + if (rc) +@@ -243,6 +245,7 @@ void __init socfpga_gate_init(struct device_node *node) + + err = clk_hw_register(NULL, hw_clk); + if (err) { ++ kfree(ops); + kfree(socfpga_clk); + return; + } +-- +2.35.1 + diff --git a/queue-6.0/clk-st-fix-memory-leak-in-st_of_quadfs_setup.patch b/queue-6.0/clk-st-fix-memory-leak-in-st_of_quadfs_setup.patch new file mode 100644 index 00000000000..d33ec48ad23 --- /dev/null +++ b/queue-6.0/clk-st-fix-memory-leak-in-st_of_quadfs_setup.patch @@ -0,0 +1,41 @@ +From aa3be47d4318d8a7cac5bd46540623dfa1665825 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Nov 2022 21:36:14 +0800 +Subject: clk: st: Fix memory leak in st_of_quadfs_setup() + +From: Xiu Jianfeng + +[ Upstream commit cfd3ffb36f0d566846163118651d868e607300ba ] + +If st_clk_register_quadfs_pll() fails, @lock should be freed before goto +@err_exit, otherwise will cause meory leak issue, fix it. + +Signed-off-by: Xiu Jianfeng +Link: https://lore.kernel.org/r/20221122133614.184910-1-xiujianfeng@huawei.com +Reviewed-by: Patrice Chotard +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/st/clkgen-fsyn.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c +index d820292a381d..40df1db102a7 100644 +--- a/drivers/clk/st/clkgen-fsyn.c ++++ b/drivers/clk/st/clkgen-fsyn.c +@@ -1020,9 +1020,10 @@ static void __init st_of_quadfs_setup(struct device_node *np, + + clk = st_clk_register_quadfs_pll(pll_name, clk_parent_name, datac->data, + reg, lock); +- if (IS_ERR(clk)) ++ if (IS_ERR(clk)) { ++ kfree(lock); + goto err_exit; +- else ++ } else + pr_debug("%s: parent %s rate %u\n", + __clk_get_name(clk), + __clk_get_name(clk_get_parent(clk)), +-- +2.35.1 + diff --git a/queue-6.0/clk-visconti-fix-memory-leak-in-visconti_register_pl.patch b/queue-6.0/clk-visconti-fix-memory-leak-in-visconti_register_pl.patch new file mode 100644 index 00000000000..4a1a21a7227 --- /dev/null +++ b/queue-6.0/clk-visconti-fix-memory-leak-in-visconti_register_pl.patch @@ -0,0 +1,38 @@ +From b82da2eabdb6814af6d8f881974edf0de36a43b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Nov 2022 23:23:53 +0800 +Subject: clk: visconti: Fix memory leak in visconti_register_pll() + +From: Xiu Jianfeng + +[ Upstream commit b55226f8553d255f5002c751c7c6ba9291f34bf2 ] + +@pll->rate_table has allocated memory by kmemdup(), if clk_hw_register() +fails, it should be freed, otherwise it will cause memory leak issue, +this patch fixes it. + +Fixes: b4cbe606dc36 ("clk: visconti: Add support common clock driver and reset driver") +Signed-off-by: Xiu Jianfeng +Link: https://lore.kernel.org/r/20221122152353.204132-1-xiujianfeng@huawei.com +Acked-by: Nobuhiro Iwamatsu +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/visconti/pll.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/visconti/pll.c b/drivers/clk/visconti/pll.c +index a484cb945d67..1f3234f22667 100644 +--- a/drivers/clk/visconti/pll.c ++++ b/drivers/clk/visconti/pll.c +@@ -277,6 +277,7 @@ static struct clk_hw *visconti_register_pll(struct visconti_pll_provider *ctx, + ret = clk_hw_register(NULL, &pll->hw); + if (ret) { + pr_err("failed to register pll clock %s : %d\n", name, ret); ++ kfree(pll->rate_table); + kfree(pll); + pll_hw_clk = ERR_PTR(ret); + } +-- +2.35.1 + diff --git a/queue-6.0/clocksource-drivers-sh_cmt-access-registers-accordin.patch b/queue-6.0/clocksource-drivers-sh_cmt-access-registers-accordin.patch new file mode 100644 index 00000000000..01bf1f02926 --- /dev/null +++ b/queue-6.0/clocksource-drivers-sh_cmt-access-registers-accordin.patch @@ -0,0 +1,195 @@ +From 70d7f2b61d6c2174ab09b9df021470e63047aa45 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Nov 2022 22:06:09 +0100 +Subject: clocksource/drivers/sh_cmt: Access registers according to spec + +From: Wolfram Sang + +[ Upstream commit 3f44f7156f59cae06e9160eafb5d8b2dfd09e639 ] + +Documentation for most CMTs say that it takes two input clocks before +changes propagate to the timer. This is especially relevant when the timer +is stopped to change further settings. + +Implement the delays according to the spec. To avoid unnecessary delays in +atomic mode, also check if the to-be-written value actually differs. + +CMCNT is a bit special because testing showed that it requires 3 cycles to +propagate, which affects all CMTs. Also, the WRFLAG needs to be checked +before writing. This fixes "cannot clear CMCNT" messages which occur often +on R-Car Gen4 SoCs, but only very rarely on older SoCs for some reason. + +Fixes: 81b3b2711072 ("clocksource: sh_cmt: Add support for multiple channels per device") +Signed-off-by: Wolfram Sang +Signed-off-by: Thomas Gleixner +Link: https://lore.kernel.org/r/20221130210609.7718-1-wsa+renesas@sang-engineering.com +Signed-off-by: Sasha Levin +--- + drivers/clocksource/sh_cmt.c | 88 ++++++++++++++++++++++-------------- + 1 file changed, 55 insertions(+), 33 deletions(-) + +diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c +index 64dcb082d4cf..7b952aa52c0b 100644 +--- a/drivers/clocksource/sh_cmt.c ++++ b/drivers/clocksource/sh_cmt.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -116,6 +117,7 @@ struct sh_cmt_device { + void __iomem *mapbase; + struct clk *clk; + unsigned long rate; ++ unsigned int reg_delay; + + raw_spinlock_t lock; /* Protect the shared start/stop register */ + +@@ -247,10 +249,17 @@ static inline u32 sh_cmt_read_cmstr(struct sh_cmt_channel *ch) + + static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch, u32 value) + { +- if (ch->iostart) +- ch->cmt->info->write_control(ch->iostart, 0, value); +- else +- ch->cmt->info->write_control(ch->cmt->mapbase, 0, value); ++ u32 old_value = sh_cmt_read_cmstr(ch); ++ ++ if (value != old_value) { ++ if (ch->iostart) { ++ ch->cmt->info->write_control(ch->iostart, 0, value); ++ udelay(ch->cmt->reg_delay); ++ } else { ++ ch->cmt->info->write_control(ch->cmt->mapbase, 0, value); ++ udelay(ch->cmt->reg_delay); ++ } ++ } + } + + static inline u32 sh_cmt_read_cmcsr(struct sh_cmt_channel *ch) +@@ -260,7 +269,12 @@ static inline u32 sh_cmt_read_cmcsr(struct sh_cmt_channel *ch) + + static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch, u32 value) + { +- ch->cmt->info->write_control(ch->ioctrl, CMCSR, value); ++ u32 old_value = sh_cmt_read_cmcsr(ch); ++ ++ if (value != old_value) { ++ ch->cmt->info->write_control(ch->ioctrl, CMCSR, value); ++ udelay(ch->cmt->reg_delay); ++ } + } + + static inline u32 sh_cmt_read_cmcnt(struct sh_cmt_channel *ch) +@@ -268,14 +282,33 @@ static inline u32 sh_cmt_read_cmcnt(struct sh_cmt_channel *ch) + return ch->cmt->info->read_count(ch->ioctrl, CMCNT); + } + +-static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch, u32 value) ++static inline int sh_cmt_write_cmcnt(struct sh_cmt_channel *ch, u32 value) + { ++ /* Tests showed that we need to wait 3 clocks here */ ++ unsigned int cmcnt_delay = DIV_ROUND_UP(3 * ch->cmt->reg_delay, 2); ++ u32 reg; ++ ++ if (ch->cmt->info->model > SH_CMT_16BIT) { ++ int ret = read_poll_timeout_atomic(sh_cmt_read_cmcsr, reg, ++ !(reg & SH_CMT32_CMCSR_WRFLG), ++ 1, cmcnt_delay, false, ch); ++ if (ret < 0) ++ return ret; ++ } ++ + ch->cmt->info->write_count(ch->ioctrl, CMCNT, value); ++ udelay(cmcnt_delay); ++ return 0; + } + + static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch, u32 value) + { +- ch->cmt->info->write_count(ch->ioctrl, CMCOR, value); ++ u32 old_value = ch->cmt->info->read_count(ch->ioctrl, CMCOR); ++ ++ if (value != old_value) { ++ ch->cmt->info->write_count(ch->ioctrl, CMCOR, value); ++ udelay(ch->cmt->reg_delay); ++ } + } + + static u32 sh_cmt_get_counter(struct sh_cmt_channel *ch, u32 *has_wrapped) +@@ -319,7 +352,7 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start) + + static int sh_cmt_enable(struct sh_cmt_channel *ch) + { +- int k, ret; ++ int ret; + + dev_pm_syscore_device(&ch->cmt->pdev->dev, true); + +@@ -347,26 +380,9 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch) + } + + sh_cmt_write_cmcor(ch, 0xffffffff); +- sh_cmt_write_cmcnt(ch, 0); +- +- /* +- * According to the sh73a0 user's manual, as CMCNT can be operated +- * only by the RCLK (Pseudo 32 kHz), there's one restriction on +- * modifying CMCNT register; two RCLK cycles are necessary before +- * this register is either read or any modification of the value +- * it holds is reflected in the LSI's actual operation. +- * +- * While at it, we're supposed to clear out the CMCNT as of this +- * moment, so make sure it's processed properly here. This will +- * take RCLKx2 at maximum. +- */ +- for (k = 0; k < 100; k++) { +- if (!sh_cmt_read_cmcnt(ch)) +- break; +- udelay(1); +- } ++ ret = sh_cmt_write_cmcnt(ch, 0); + +- if (sh_cmt_read_cmcnt(ch)) { ++ if (ret || sh_cmt_read_cmcnt(ch)) { + dev_err(&ch->cmt->pdev->dev, "ch%u: cannot clear CMCNT\n", + ch->index); + ret = -ETIMEDOUT; +@@ -995,8 +1011,8 @@ MODULE_DEVICE_TABLE(of, sh_cmt_of_table); + + static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev) + { +- unsigned int mask; +- unsigned int i; ++ unsigned int mask, i; ++ unsigned long rate; + int ret; + + cmt->pdev = pdev; +@@ -1032,10 +1048,16 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev) + if (ret < 0) + goto err_clk_unprepare; + +- if (cmt->info->width == 16) +- cmt->rate = clk_get_rate(cmt->clk) / 512; +- else +- cmt->rate = clk_get_rate(cmt->clk) / 8; ++ rate = clk_get_rate(cmt->clk); ++ if (!rate) { ++ ret = -EINVAL; ++ goto err_clk_disable; ++ } ++ ++ /* We shall wait 2 input clks after register writes */ ++ if (cmt->info->model >= SH_CMT_48BIT) ++ cmt->reg_delay = DIV_ROUND_UP(2UL * USEC_PER_SEC, rate); ++ cmt->rate = rate / (cmt->info->width == 16 ? 512 : 8); + + /* Map the memory resource(s). */ + ret = sh_cmt_map_memory(cmt); +-- +2.35.1 + diff --git a/queue-6.0/clocksource-drivers-timer-ti-dm-fix-missing-clk_disa.patch b/queue-6.0/clocksource-drivers-timer-ti-dm-fix-missing-clk_disa.patch new file mode 100644 index 00000000000..55b17dfd75a --- /dev/null +++ b/queue-6.0/clocksource-drivers-timer-ti-dm-fix-missing-clk_disa.patch @@ -0,0 +1,43 @@ +From 5c2709dc1cd3d76295ad5c58149e61dbd40c2dda Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 29 Oct 2022 19:44:27 +0800 +Subject: clocksource/drivers/timer-ti-dm: Fix missing clk_disable_unprepare in + dmtimer_systimer_init_clock() + +From: Yang Yingliang + +[ Upstream commit 180d35a7c05d520314a590c99ad8643d0213f28b ] + +If clk_get_rate() fails which is called after clk_prepare_enable(), +clk_disable_unprepare() need be called in error path to disable the +clock in dmtimer_systimer_init_clock(). + +Fixes: 52762fbd1c47 ("clocksource/drivers/timer-ti-dm: Add clockevent and clocksource support") +Signed-off-by: Yang Yingliang +Reviewed-by: Tony Lindgren +Link: https://lore.kernel.org/r/20221029114427.946520-1-yangyingliang@huawei.com +Signed-off-by: Daniel Lezcano +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-ti-dm-systimer.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/clocksource/timer-ti-dm-systimer.c b/drivers/clocksource/timer-ti-dm-systimer.c +index 2737407ff069..632523c1232f 100644 +--- a/drivers/clocksource/timer-ti-dm-systimer.c ++++ b/drivers/clocksource/timer-ti-dm-systimer.c +@@ -345,8 +345,10 @@ static int __init dmtimer_systimer_init_clock(struct dmtimer_systimer *t, + return error; + + r = clk_get_rate(clock); +- if (!r) ++ if (!r) { ++ clk_disable_unprepare(clock); + return -ENODEV; ++ } + + if (is_ick) + t->ick = clock; +-- +2.35.1 + diff --git a/queue-6.0/clocksource-drivers-timer-ti-dm-fix-warning-for-omap.patch b/queue-6.0/clocksource-drivers-timer-ti-dm-fix-warning-for-omap.patch new file mode 100644 index 00000000000..1570bed080e --- /dev/null +++ b/queue-6.0/clocksource-drivers-timer-ti-dm-fix-warning-for-omap.patch @@ -0,0 +1,38 @@ +From b97a8d995576f8dff5967b6eb1bec121c1ee6a83 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Oct 2022 13:35:26 +0300 +Subject: clocksource/drivers/timer-ti-dm: Fix warning for omap_timer_match + +From: Tony Lindgren + +[ Upstream commit 9688498b1648aa98a3ee45d9f07763c099f6fb12 ] + +We can now get a warning for 'omap_timer_match' defined but not used. +Let's fix this by dropping of_match_ptr for omap_timer_match. + +Reported-by: kernel test robot +Fixes: ab0bbef3ae0f ("clocksource/drivers/timer-ti-dm: Make timer selectable for ARCH_K3") +Signed-off-by: Tony Lindgren +Link: https://lore.kernel.org/r/20221028103526.40319-1-tony@atomide.com +Signed-off-by: Daniel Lezcano +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-ti-dm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c +index 469f7c91564b..78c2c038d3ae 100644 +--- a/drivers/clocksource/timer-ti-dm.c ++++ b/drivers/clocksource/timer-ti-dm.c +@@ -1081,7 +1081,7 @@ static struct platform_driver omap_dm_timer_driver = { + .remove = omap_dm_timer_remove, + .driver = { + .name = "omap_timer", +- .of_match_table = of_match_ptr(omap_timer_match), ++ .of_match_table = omap_timer_match, + .pm = &omap_dm_timer_pm_ops, + }, + }; +-- +2.35.1 + diff --git a/queue-6.0/configfs-fix-possible-memory-leak-in-configfs_create.patch b/queue-6.0/configfs-fix-possible-memory-leak-in-configfs_create.patch new file mode 100644 index 00000000000..2eeb3f93dc2 --- /dev/null +++ b/queue-6.0/configfs-fix-possible-memory-leak-in-configfs_create.patch @@ -0,0 +1,102 @@ +From 90c9bb39277f59257162786ef4ca7872dcb53c1a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Oct 2022 09:42:30 +0800 +Subject: configfs: fix possible memory leak in configfs_create_dir() + +From: Chen Zhongjin + +[ Upstream commit c65234b283a65cfbfc94619655e820a5e55199eb ] + +kmemleak reported memory leaks in configfs_create_dir(): + +unreferenced object 0xffff888009f6af00 (size 192): + comm "modprobe", pid 3777, jiffies 4295537735 (age 233.784s) + backtrace: + kmem_cache_alloc (mm/slub.c:3250 mm/slub.c:3256 mm/slub.c:3263 mm/slub.c:3273) + new_fragment (./include/linux/slab.h:600 fs/configfs/dir.c:163) + configfs_register_subsystem (fs/configfs/dir.c:1857) + basic_write (drivers/hwtracing/stm/p_basic.c:14) stm_p_basic + do_one_initcall (init/main.c:1296) + do_init_module (kernel/module/main.c:2455) + ... + +unreferenced object 0xffff888003ba7180 (size 96): + comm "modprobe", pid 3777, jiffies 4295537735 (age 233.784s) + backtrace: + kmem_cache_alloc (mm/slub.c:3250 mm/slub.c:3256 mm/slub.c:3263 mm/slub.c:3273) + configfs_new_dirent (./include/linux/slab.h:723 fs/configfs/dir.c:194) + configfs_make_dirent (fs/configfs/dir.c:248) + configfs_create_dir (fs/configfs/dir.c:296) + configfs_attach_group.isra.28 (fs/configfs/dir.c:816 fs/configfs/dir.c:852) + configfs_register_subsystem (fs/configfs/dir.c:1881) + basic_write (drivers/hwtracing/stm/p_basic.c:14) stm_p_basic + do_one_initcall (init/main.c:1296) + do_init_module (kernel/module/main.c:2455) + ... + +This is because the refcount is not correct in configfs_make_dirent(). +For normal stage, the refcount is changing as: + +configfs_register_subsystem() + configfs_create_dir() + configfs_make_dirent() + configfs_new_dirent() # set s_count = 1 + dentry->d_fsdata = configfs_get(sd); # s_count = 2 +... +configfs_unregister_subsystem() + configfs_remove_dir() + remove_dir() + configfs_remove_dirent() # s_count = 1 + dput() ... + *dentry_unlink_inode()* + configfs_d_iput() # s_count = 0, release + +However, if we failed in configfs_create(): + +configfs_register_subsystem() + configfs_create_dir() + configfs_make_dirent() # s_count = 2 + ... + configfs_create() # fail + ->out_remove: + configfs_remove_dirent(dentry) + configfs_put(sd) # s_count = 1 + return PTR_ERR(inode); + +There is no inode in the error path, so the configfs_d_iput() is lost +and makes sd and fragment memory leaked. + +To fix this, when we failed in configfs_create(), manually call +configfs_put(sd) to keep the refcount correct. + +Fixes: 7063fbf22611 ("[PATCH] configfs: User-driven configuration filesystem") +Signed-off-by: Chen Zhongjin +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + fs/configfs/dir.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c +index d1f9d2632202..ec6519e1ca3b 100644 +--- a/fs/configfs/dir.c ++++ b/fs/configfs/dir.c +@@ -316,6 +316,7 @@ static int configfs_create_dir(struct config_item *item, struct dentry *dentry, + return 0; + + out_remove: ++ configfs_put(dentry->d_fsdata); + configfs_remove_dirent(dentry); + return PTR_ERR(inode); + } +@@ -382,6 +383,7 @@ int configfs_create_link(struct configfs_dirent *target, struct dentry *parent, + return 0; + + out_remove: ++ configfs_put(dentry->d_fsdata); + configfs_remove_dirent(dentry); + return PTR_ERR(inode); + } +-- +2.35.1 + diff --git a/queue-6.0/coresight-trbe-remove-cpuhp-instance-node-before-rem.patch b/queue-6.0/coresight-trbe-remove-cpuhp-instance-node-before-rem.patch new file mode 100644 index 00000000000..c34716ecf48 --- /dev/null +++ b/queue-6.0/coresight-trbe-remove-cpuhp-instance-node-before-rem.patch @@ -0,0 +1,61 @@ +From acbb4a7472e542133da5116cc743c2e30a490165 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Nov 2022 17:03:55 +0800 +Subject: coresight: trbe: remove cpuhp instance node before remove cpuhp state + +From: Yang Shen + +[ Upstream commit 20ee8c223f792947378196307d8e707c9cdc2d61 ] + +cpuhp_state_add_instance() and cpuhp_state_remove_instance() should +be used in pairs. Or there will lead to the warn on +cpuhp_remove_multi_state() since the cpuhp_step list is not empty. + +The following is the error log with 'rmmod coresight-trbe': +Error: Removing state 215 which has instances left. +Call trace: + __cpuhp_remove_state_cpuslocked+0x144/0x160 + __cpuhp_remove_state+0xac/0x100 + arm_trbe_device_remove+0x2c/0x60 [coresight_trbe] + platform_remove+0x34/0x70 + device_remove+0x54/0x90 + device_release_driver_internal+0x1e4/0x250 + driver_detach+0x5c/0xb0 + bus_remove_driver+0x64/0xc0 + driver_unregister+0x3c/0x70 + platform_driver_unregister+0x20/0x30 + arm_trbe_exit+0x1c/0x658 [coresight_trbe] + __arm64_sys_delete_module+0x1ac/0x24c + invoke_syscall+0x50/0x120 + el0_svc_common.constprop.0+0x58/0x1a0 + do_el0_svc+0x38/0xd0 + el0_svc+0x2c/0xc0 + el0t_64_sync_handler+0x1ac/0x1b0 + el0t_64_sync+0x19c/0x1a0 + ---[ end trace 0000000000000000 ]--- + +Fixes: 3fbf7f011f24 ("coresight: sink: Add TRBE driver") +Reviewed-by: Anshuman Khandual +Signed-off-by: Yang Shen +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20221122090355.23533-1-shenyang39@huawei.com +Signed-off-by: Sasha Levin +--- + drivers/hwtracing/coresight/coresight-trbe.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c +index 2b386bb848f8..1fc4fd79a1c6 100644 +--- a/drivers/hwtracing/coresight/coresight-trbe.c ++++ b/drivers/hwtracing/coresight/coresight-trbe.c +@@ -1434,6 +1434,7 @@ static int arm_trbe_probe_cpuhp(struct trbe_drvdata *drvdata) + + static void arm_trbe_remove_cpuhp(struct trbe_drvdata *drvdata) + { ++ cpuhp_state_remove_instance(drvdata->trbe_online, &drvdata->hotplug_node); + cpuhp_remove_multi_state(drvdata->trbe_online); + } + +-- +2.35.1 + diff --git a/queue-6.0/counter-stm32-lptimer-cnt-fix-the-check-on-arr-and-c.patch b/queue-6.0/counter-stm32-lptimer-cnt-fix-the-check-on-arr-and-c.patch new file mode 100644 index 00000000000..3d45bc9c6ce --- /dev/null +++ b/queue-6.0/counter-stm32-lptimer-cnt-fix-the-check-on-arr-and-c.patch @@ -0,0 +1,42 @@ +From 5e73e365ba0ae594275c3e8073228b63951b4701 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Nov 2022 14:36:09 +0100 +Subject: counter: stm32-lptimer-cnt: fix the check on arr and cmp registers + update + +From: Fabrice Gasnier + +[ Upstream commit fd5ac974fc25feed084c2d1599d0dddb4e0556bc ] + +The ARR (auto reload register) and CMP (compare) registers are +successively written. The status bits to check the update of these +registers are polled together with regmap_read_poll_timeout(). +The condition to end the loop may become true, even if one of the register +isn't correctly updated. +So ensure both status bits are set before clearing them. + +Fixes: d8958824cf07 ("iio: counter: Add support for STM32 LPTimer") +Signed-off-by: Fabrice Gasnier +Link: https://lore.kernel.org/r/20221123133609.465614-1-fabrice.gasnier@foss.st.com/ +Signed-off-by: William Breathitt Gray +Signed-off-by: Sasha Levin +--- + drivers/counter/stm32-lptimer-cnt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c +index 68031d93ce89..aee3b1a8aaa7 100644 +--- a/drivers/counter/stm32-lptimer-cnt.c ++++ b/drivers/counter/stm32-lptimer-cnt.c +@@ -69,7 +69,7 @@ static int stm32_lptim_set_enable_state(struct stm32_lptim_cnt *priv, + + /* ensure CMP & ARR registers are properly written */ + ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val, +- (val & STM32_LPTIM_CMPOK_ARROK), ++ (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK, + 100, 1000); + if (ret) + return ret; +-- +2.35.1 + diff --git a/queue-6.0/cpu-hotplug-do-not-bail-out-in-dying-starting-sectio.patch b/queue-6.0/cpu-hotplug-do-not-bail-out-in-dying-starting-sectio.patch new file mode 100644 index 00000000000..bdbad2f9a08 --- /dev/null +++ b/queue-6.0/cpu-hotplug-do-not-bail-out-in-dying-starting-sectio.patch @@ -0,0 +1,141 @@ +From d6cd2a9a84452fcbf6d48d182de25fc2fdf4f6fc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Sep 2022 11:12:59 +0100 +Subject: cpu/hotplug: Do not bail-out in DYING/STARTING sections + +From: Vincent Donnefort + +[ Upstream commit 6f855b39e4602b6b42a8e5cbcfefb8a1b8b5f0be ] + +The DYING/STARTING callbacks are not expected to fail. However, as reported +by Derek, buggy drivers such as tboot are still free to return errors +within those sections, which halts the hot(un)plug and leaves the CPU in an +unrecoverable state. + +As there is no rollback possible, only log the failures and proceed with +the following steps. + +This restores the hotplug behaviour prior to commit 453e41085183 +("cpu/hotplug: Add cpuhp_invoke_callback_range()") + +Fixes: 453e41085183 ("cpu/hotplug: Add cpuhp_invoke_callback_range()") +Reported-by: Derek Dolney +Signed-off-by: Vincent Donnefort +Signed-off-by: Thomas Gleixner +Tested-by: Derek Dolney +Reviewed-by: Valentin Schneider +Link: https://bugzilla.kernel.org/show_bug.cgi?id=215867 +Link: https://lore.kernel.org/r/20220927101259.1149636-1-vdonnefort@google.com +Signed-off-by: Sasha Levin +--- + kernel/cpu.c | 56 +++++++++++++++++++++++++++++++++++++--------------- + 1 file changed, 40 insertions(+), 16 deletions(-) + +diff --git a/kernel/cpu.c b/kernel/cpu.c +index 979de993f853..98a7a7b1471b 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -663,21 +663,51 @@ static bool cpuhp_next_state(bool bringup, + return true; + } + +-static int cpuhp_invoke_callback_range(bool bringup, +- unsigned int cpu, +- struct cpuhp_cpu_state *st, +- enum cpuhp_state target) ++static int __cpuhp_invoke_callback_range(bool bringup, ++ unsigned int cpu, ++ struct cpuhp_cpu_state *st, ++ enum cpuhp_state target, ++ bool nofail) + { + enum cpuhp_state state; +- int err = 0; ++ int ret = 0; + + while (cpuhp_next_state(bringup, &state, st, target)) { ++ int err; ++ + err = cpuhp_invoke_callback(cpu, state, bringup, NULL, NULL); +- if (err) ++ if (!err) ++ continue; ++ ++ if (nofail) { ++ pr_warn("CPU %u %s state %s (%d) failed (%d)\n", ++ cpu, bringup ? "UP" : "DOWN", ++ cpuhp_get_step(st->state)->name, ++ st->state, err); ++ ret = -1; ++ } else { ++ ret = err; + break; ++ } + } + +- return err; ++ return ret; ++} ++ ++static inline int cpuhp_invoke_callback_range(bool bringup, ++ unsigned int cpu, ++ struct cpuhp_cpu_state *st, ++ enum cpuhp_state target) ++{ ++ return __cpuhp_invoke_callback_range(bringup, cpu, st, target, false); ++} ++ ++static inline void cpuhp_invoke_callback_range_nofail(bool bringup, ++ unsigned int cpu, ++ struct cpuhp_cpu_state *st, ++ enum cpuhp_state target) ++{ ++ __cpuhp_invoke_callback_range(bringup, cpu, st, target, true); + } + + static inline bool can_rollback_cpu(struct cpuhp_cpu_state *st) +@@ -999,7 +1029,6 @@ static int take_cpu_down(void *_param) + struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state); + enum cpuhp_state target = max((int)st->target, CPUHP_AP_OFFLINE); + int err, cpu = smp_processor_id(); +- int ret; + + /* Ensure this CPU doesn't handle any more interrupts. */ + err = __cpu_disable(); +@@ -1012,13 +1041,10 @@ static int take_cpu_down(void *_param) + */ + WARN_ON(st->state != (CPUHP_TEARDOWN_CPU - 1)); + +- /* Invoke the former CPU_DYING callbacks */ +- ret = cpuhp_invoke_callback_range(false, cpu, st, target); +- + /* +- * DYING must not fail! ++ * Invoke the former CPU_DYING callbacks. DYING must not fail! + */ +- WARN_ON_ONCE(ret); ++ cpuhp_invoke_callback_range_nofail(false, cpu, st, target); + + /* Give up timekeeping duties */ + tick_handover_do_timer(); +@@ -1296,16 +1322,14 @@ void notify_cpu_starting(unsigned int cpu) + { + struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); + enum cpuhp_state target = min((int)st->target, CPUHP_AP_ONLINE); +- int ret; + + rcu_cpu_starting(cpu); /* Enables RCU usage on this CPU. */ + cpumask_set_cpu(cpu, &cpus_booted_once_mask); +- ret = cpuhp_invoke_callback_range(true, cpu, st, target); + + /* + * STARTING must not fail! + */ +- WARN_ON_ONCE(ret); ++ cpuhp_invoke_callback_range_nofail(true, cpu, st, target); + } + + /* +-- +2.35.1 + diff --git a/queue-6.0/cpu-hotplug-make-target_store-a-nop-when-target-stat.patch b/queue-6.0/cpu-hotplug-make-target_store-a-nop-when-target-stat.patch new file mode 100644 index 00000000000..022e5f0f811 --- /dev/null +++ b/queue-6.0/cpu-hotplug-make-target_store-a-nop-when-target-stat.patch @@ -0,0 +1,60 @@ +From 774909e4e0c642f44142c90f07ec52f562e13b0f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 11:23:28 -0500 +Subject: cpu/hotplug: Make target_store() a nop when target == state + +From: Phil Auld + +[ Upstream commit 64ea6e44f85b9b75925ebe1ba0e6e8430cc4e06f ] + +Writing the current state back in hotplug/target calls cpu_down() +which will set cpu dying even when it isn't and then nothing will +ever clear it. A stress test that reads values and writes them back +for all cpu device files in sysfs will trigger the BUG() in +select_fallback_rq once all cpus are marked as dying. + +kernel/cpu.c::target_store() + ... + if (st->state < target) + ret = cpu_up(dev->id, target); + else + ret = cpu_down(dev->id, target); + +cpu_down() -> cpu_set_state() + bool bringup = st->state < target; + ... + if (cpu_dying(cpu) != !bringup) + set_cpu_dying(cpu, !bringup); + +Fix this by letting state==target fall through in the target_store() +conditional. Also make sure st->target == target in that case. + +Fixes: 757c989b9994 ("cpu/hotplug: Make target state writeable") +Signed-off-by: Phil Auld +Signed-off-by: Thomas Gleixner +Reviewed-by: Valentin Schneider +Link: https://lore.kernel.org/r/20221117162329.3164999-2-pauld@redhat.com +Signed-off-by: Sasha Levin +--- + kernel/cpu.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/kernel/cpu.c b/kernel/cpu.c +index bbad5e375d3b..979de993f853 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -2326,8 +2326,10 @@ static ssize_t target_store(struct device *dev, struct device_attribute *attr, + + if (st->state < target) + ret = cpu_up(dev->id, target); +- else ++ else if (st->state > target) + ret = cpu_down(dev->id, target); ++ else if (WARN_ON(st->target != target)) ++ st->target = target; + out: + unlock_device_hotplug(); + return ret ? ret : count; +-- +2.35.1 + diff --git a/queue-6.0/cpufreq-amd_freq_sensitivity-add-missing-pci_dev_put.patch b/queue-6.0/cpufreq-amd_freq_sensitivity-add-missing-pci_dev_put.patch new file mode 100644 index 00000000000..97cb1d7ea1c --- /dev/null +++ b/queue-6.0/cpufreq-amd_freq_sensitivity-add-missing-pci_dev_put.patch @@ -0,0 +1,37 @@ +From 362cbac486f5bdac6e4d5f2e0df114ccbaa301a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Nov 2022 19:33:39 +0800 +Subject: cpufreq: amd_freq_sensitivity: Add missing pci_dev_put() + +From: Xiongfeng Wang + +[ Upstream commit 91fda1f88c0968f1491ab150bb01690525af150a ] + +pci_get_device() will increase the reference count for the returned +pci_dev. We need to use pci_dev_put() to decrease the reference count +after using pci_get_device(). Let's add it. + +Fixes: 59a3b3a8db16 ("cpufreq: AMD: Ignore the check for ProcFeedback in ST/CZ") +Signed-off-by: Xiongfeng Wang +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/amd_freq_sensitivity.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/cpufreq/amd_freq_sensitivity.c b/drivers/cpufreq/amd_freq_sensitivity.c +index 6448e03bcf48..59b19b9975e8 100644 +--- a/drivers/cpufreq/amd_freq_sensitivity.c ++++ b/drivers/cpufreq/amd_freq_sensitivity.c +@@ -125,6 +125,8 @@ static int __init amd_freq_sensitivity_init(void) + if (!pcidev) { + if (!boot_cpu_has(X86_FEATURE_PROC_FEEDBACK)) + return -ENODEV; ++ } else { ++ pci_dev_put(pcidev); + } + + if (rdmsrl_safe(MSR_AMD64_FREQ_SENSITIVITY_ACTUAL, &val)) +-- +2.35.1 + diff --git a/queue-6.0/cpufreq-qcom-hw-fix-memory-leak-in-qcom_cpufreq_hw_r.patch b/queue-6.0/cpufreq-qcom-hw-fix-memory-leak-in-qcom_cpufreq_hw_r.patch new file mode 100644 index 00000000000..7cf62a489da --- /dev/null +++ b/queue-6.0/cpufreq-qcom-hw-fix-memory-leak-in-qcom_cpufreq_hw_r.patch @@ -0,0 +1,36 @@ +From 80e438c86bfce5d131ff0058385aa00e22aed866 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Nov 2022 15:23:02 +0800 +Subject: cpufreq: qcom-hw: Fix memory leak in qcom_cpufreq_hw_read_lut() + +From: Chen Hui + +[ Upstream commit 9901c21bcaf2f01fe5078f750d624f4ddfa8f81b ] + +If "cpu_dev" fails to get opp table in qcom_cpufreq_hw_read_lut(), +the program will return, resulting in "table" resource is not released. + +Fixes: 51c843cf77bb ("cpufreq: qcom: Update the bandwidth levels on frequency change") +Signed-off-by: Chen Hui +Reviewed-by: Sibi Sankar +Signed-off-by: Viresh Kumar +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/qcom-cpufreq-hw.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c +index bb32659820ce..9221a416230a 100644 +--- a/drivers/cpufreq/qcom-cpufreq-hw.c ++++ b/drivers/cpufreq/qcom-cpufreq-hw.c +@@ -190,6 +190,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev, + } + } else if (ret != -ENODEV) { + dev_err(cpu_dev, "Invalid opp table in device tree\n"); ++ kfree(table); + return ret; + } else { + policy->fast_switch_possible = true; +-- +2.35.1 + diff --git a/queue-6.0/cpufreq-qcom-hw-fix-the-frequency-returned-by-cpufre.patch b/queue-6.0/cpufreq-qcom-hw-fix-the-frequency-returned-by-cpufre.patch new file mode 100644 index 00000000000..6cb30392df3 --- /dev/null +++ b/queue-6.0/cpufreq-qcom-hw-fix-the-frequency-returned-by-cpufre.patch @@ -0,0 +1,94 @@ +From 9405be54bbcd17dc4a75cd971a7652321443d8ab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 11:01:45 +0530 +Subject: cpufreq: qcom-hw: Fix the frequency returned by cpufreq_driver->get() + +From: Manivannan Sadhasivam + +[ Upstream commit c72cf0cb1d77f6b1b58c334dcc3d09fa13111c4c ] + +The cpufreq_driver->get() callback is supposed to return the current +frequency of the CPU and not the one requested by the CPUFreq core. +Fix it by returning the frequency that gets supplied to the CPU after +the DCVS operation of EPSS/OSM. + +Fixes: 2849dd8bc72b ("cpufreq: qcom-hw: Add support for QCOM cpufreq HW driver") +Reported-by: Sudeep Holla +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Viresh Kumar +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/qcom-cpufreq-hw.c | 42 +++++++++++++++++++++---------- + 1 file changed, 29 insertions(+), 13 deletions(-) + +diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c +index 9221a416230a..823b069203e1 100644 +--- a/drivers/cpufreq/qcom-cpufreq-hw.c ++++ b/drivers/cpufreq/qcom-cpufreq-hw.c +@@ -122,7 +122,35 @@ static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy, + return 0; + } + ++static unsigned long qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data) ++{ ++ unsigned int lval; ++ ++ if (data->soc_data->reg_current_vote) ++ lval = readl_relaxed(data->base + data->soc_data->reg_current_vote) & 0x3ff; ++ else ++ lval = readl_relaxed(data->base + data->soc_data->reg_domain_state) & 0xff; ++ ++ return lval * xo_rate; ++} ++ ++/* Get the current frequency of the CPU (after throttling) */ + static unsigned int qcom_cpufreq_hw_get(unsigned int cpu) ++{ ++ struct qcom_cpufreq_data *data; ++ struct cpufreq_policy *policy; ++ ++ policy = cpufreq_cpu_get_raw(cpu); ++ if (!policy) ++ return 0; ++ ++ data = policy->driver_data; ++ ++ return qcom_lmh_get_throttle_freq(data) / HZ_PER_KHZ; ++} ++ ++/* Get the frequency requested by the cpufreq core for the CPU */ ++static unsigned int qcom_cpufreq_get_freq(unsigned int cpu) + { + struct qcom_cpufreq_data *data; + const struct qcom_cpufreq_soc_data *soc_data; +@@ -284,18 +312,6 @@ static void qcom_get_related_cpus(int index, struct cpumask *m) + } + } + +-static unsigned long qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data) +-{ +- unsigned int lval; +- +- if (data->soc_data->reg_current_vote) +- lval = readl_relaxed(data->base + data->soc_data->reg_current_vote) & 0x3ff; +- else +- lval = readl_relaxed(data->base + data->soc_data->reg_domain_state) & 0xff; +- +- return lval * xo_rate; +-} +- + static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data) + { + struct cpufreq_policy *policy = data->policy; +@@ -337,7 +353,7 @@ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data) + * If h/w throttled frequency is higher than what cpufreq has requested + * for, then stop polling and switch back to interrupt mechanism. + */ +- if (throttled_freq >= qcom_cpufreq_hw_get(cpu)) ++ if (throttled_freq >= qcom_cpufreq_get_freq(cpu)) + enable_irq(data->throttle_irq); + else + mod_delayed_work(system_highpri_wq, &data->throttle_work, +-- +2.35.1 + diff --git a/queue-6.0/cpuidle-dt-return-the-correct-numbers-of-parsed-idle.patch b/queue-6.0/cpuidle-dt-return-the-correct-numbers-of-parsed-idle.patch new file mode 100644 index 00000000000..ff28c082b45 --- /dev/null +++ b/queue-6.0/cpuidle-dt-return-the-correct-numbers-of-parsed-idle.patch @@ -0,0 +1,44 @@ +From a764dcaf802073dce6c193ab5f56bb87c53225ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Oct 2022 17:10:12 +0200 +Subject: cpuidle: dt: Return the correct numbers of parsed idle states + +From: Ulf Hansson + +[ Upstream commit ee3c2c8ad6ba6785f14a60e4081d7c82e88162a2 ] + +While we correctly skips to initialize an idle state from a disabled idle +state node in DT, the returned value from dt_init_idle_driver() don't get +adjusted accordingly. Instead the number of found idle state nodes are +returned, while the callers are expecting the number of successfully +initialized idle states from DT. + +This leads to cpuidle drivers unnecessarily continues to initialize their +idle state specific data. Moreover, in the case when all idle states have +been disabled in DT, we would end up registering a cpuidle driver, rather +than relying on the default arch specific idle call. + +Fixes: 9f14da345599 ("drivers: cpuidle: implement DT based idle states infrastructure") +Signed-off-by: Ulf Hansson +Reviewed-by: Sudeep Holla +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/cpuidle/dt_idle_states.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c +index 252f2a9686a6..448bc796b0b4 100644 +--- a/drivers/cpuidle/dt_idle_states.c ++++ b/drivers/cpuidle/dt_idle_states.c +@@ -223,6 +223,6 @@ int dt_init_idle_driver(struct cpuidle_driver *drv, + * also be 0 on platforms with missing DT idle states or legacy DT + * configuration predating the DT idle states bindings. + */ +- return i; ++ return state_idx - start_idx; + } + EXPORT_SYMBOL_GPL(dt_init_idle_driver); +-- +2.35.1 + diff --git a/queue-6.0/crypto-amlogic-remove-kcalloc-without-check.patch b/queue-6.0/crypto-amlogic-remove-kcalloc-without-check.patch new file mode 100644 index 00000000000..1a39f073ea0 --- /dev/null +++ b/queue-6.0/crypto-amlogic-remove-kcalloc-without-check.patch @@ -0,0 +1,53 @@ +From b28a715c1992edb9d36279628dce66c392daa06c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Nov 2022 22:56:19 +0100 +Subject: crypto: amlogic - Remove kcalloc without check + +From: Christophe JAILLET + +[ Upstream commit 3d780c8a9850ad60dee47a8d971ba7888f3d1bd3 ] + +There is no real point in allocating dedicated memory for the irqs array. +MAXFLOW is only 2, so it is easier to allocated the needed space +directly within the 'meson_dev' structure. + +This saves some memory allocation and avoids an indirection when using the +irqs array. + +Fixes: 48fe583fe541 ("crypto: amlogic - Add crypto accelerator...") +Signed-off-by: Christophe JAILLET +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/amlogic/amlogic-gxl-core.c | 1 - + drivers/crypto/amlogic/amlogic-gxl.h | 2 +- + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c +index 6e7ae896717c..937187027ad5 100644 +--- a/drivers/crypto/amlogic/amlogic-gxl-core.c ++++ b/drivers/crypto/amlogic/amlogic-gxl-core.c +@@ -237,7 +237,6 @@ static int meson_crypto_probe(struct platform_device *pdev) + return err; + } + +- mc->irqs = devm_kcalloc(mc->dev, MAXFLOW, sizeof(int), GFP_KERNEL); + for (i = 0; i < MAXFLOW; i++) { + mc->irqs[i] = platform_get_irq(pdev, i); + if (mc->irqs[i] < 0) +diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h +index dc0f142324a3..8c0746a1d6d4 100644 +--- a/drivers/crypto/amlogic/amlogic-gxl.h ++++ b/drivers/crypto/amlogic/amlogic-gxl.h +@@ -95,7 +95,7 @@ struct meson_dev { + struct device *dev; + struct meson_flow *chanlist; + atomic_t flow; +- int *irqs; ++ int irqs[MAXFLOW]; + #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG + struct dentry *dbgfs_dir; + #endif +-- +2.35.1 + diff --git a/queue-6.0/crypto-ccree-make-cc_debugfs_global_fini-available-f.patch b/queue-6.0/crypto-ccree-make-cc_debugfs_global_fini-available-f.patch new file mode 100644 index 00000000000..f8d63f06b70 --- /dev/null +++ b/queue-6.0/crypto-ccree-make-cc_debugfs_global_fini-available-f.patch @@ -0,0 +1,46 @@ +From 0c51c0a978d317aec6406f0cb3bb87c76377cc12 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Nov 2022 18:22:36 +0100 +Subject: crypto: ccree - Make cc_debugfs_global_fini() available for module + init function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit 8e96729fc26c8967db45a3fb7a60387619f77a22 ] + +ccree_init() calls cc_debugfs_global_fini(), the former is an init +function and the latter an exit function though. + +A modular build emits: + + WARNING: modpost: drivers/crypto/ccree/ccree.o: section mismatch in reference: init_module (section: .init.text) -> cc_debugfs_global_fini (section: .exit.text) + +(with CONFIG_DEBUG_SECTION_MISMATCH=y). + +Fixes: 4f1c596df706 ("crypto: ccree - Remove debugfs when platform_driver_register failed") +Signed-off-by: Uwe Kleine-König +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/ccree/cc_debugfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/crypto/ccree/cc_debugfs.c b/drivers/crypto/ccree/cc_debugfs.c +index 7083767602fc..8f008f024f8f 100644 +--- a/drivers/crypto/ccree/cc_debugfs.c ++++ b/drivers/crypto/ccree/cc_debugfs.c +@@ -55,7 +55,7 @@ void __init cc_debugfs_global_init(void) + cc_debugfs_dir = debugfs_create_dir("ccree", NULL); + } + +-void __exit cc_debugfs_global_fini(void) ++void cc_debugfs_global_fini(void) + { + debugfs_remove(cc_debugfs_dir); + } +-- +2.35.1 + diff --git a/queue-6.0/crypto-ccree-remove-debugfs-when-platform_driver_reg.patch b/queue-6.0/crypto-ccree-remove-debugfs-when-platform_driver_reg.patch new file mode 100644 index 00000000000..f257c163793 --- /dev/null +++ b/queue-6.0/crypto-ccree-remove-debugfs-when-platform_driver_reg.patch @@ -0,0 +1,49 @@ +From e4fbf2cc8967f7799eaf2c2b4c279604a818f0ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Nov 2022 16:29:12 +0800 +Subject: crypto: ccree - Remove debugfs when platform_driver_register failed + +From: Gaosheng Cui + +[ Upstream commit 4f1c596df706c9aca662b6c214fad84047ae2a97 ] + +When platform_driver_register failed, we need to remove debugfs, +which will caused a resource leak, fix it. + +Failed logs as follows: +[ 32.606488] debugfs: Directory 'ccree' with parent '/' already present! + +Fixes: 4c3f97276e15 ("crypto: ccree - introduce CryptoCell driver") +Signed-off-by: Gaosheng Cui +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/ccree/cc_driver.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/ccree/cc_driver.c b/drivers/crypto/ccree/cc_driver.c +index cadead18b59e..d489c6f80892 100644 +--- a/drivers/crypto/ccree/cc_driver.c ++++ b/drivers/crypto/ccree/cc_driver.c +@@ -651,9 +651,17 @@ static struct platform_driver ccree_driver = { + + static int __init ccree_init(void) + { ++ int rc; ++ + cc_debugfs_global_init(); + +- return platform_driver_register(&ccree_driver); ++ rc = platform_driver_register(&ccree_driver); ++ if (rc) { ++ cc_debugfs_global_fini(); ++ return rc; ++ } ++ ++ return 0; + } + module_init(ccree_init); + +-- +2.35.1 + diff --git a/queue-6.0/crypto-cryptd-use-request-context-instead-of-stack-f.patch b/queue-6.0/crypto-cryptd-use-request-context-instead-of-stack-f.patch new file mode 100644 index 00000000000..2a63d643057 --- /dev/null +++ b/queue-6.0/crypto-cryptd-use-request-context-instead-of-stack-f.patch @@ -0,0 +1,128 @@ +From 15f82129170ab6184fe8fa9be4b4748bff24aa94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Nov 2022 17:59:17 +0800 +Subject: crypto: cryptd - Use request context instead of stack for sub-request + +From: Herbert Xu + +[ Upstream commit 3a58c231172537f7b0e19d93ed33decd04f80eab ] + +cryptd is buggy as it tries to use sync_skcipher without going +through the proper sync_skcipher interface. In fact it doesn't +even need sync_skcipher since it's already a proper skcipher and +can easily access the request context instead of using something +off the stack. + +Fixes: 36b3875a97b8 ("crypto: cryptd - Remove VLA usage of skcipher") +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/cryptd.c | 36 +++++++++++++++++++----------------- + 1 file changed, 19 insertions(+), 17 deletions(-) + +diff --git a/crypto/cryptd.c b/crypto/cryptd.c +index 668095eca0fa..ca3a40fc7da9 100644 +--- a/crypto/cryptd.c ++++ b/crypto/cryptd.c +@@ -68,11 +68,12 @@ struct aead_instance_ctx { + + struct cryptd_skcipher_ctx { + refcount_t refcnt; +- struct crypto_sync_skcipher *child; ++ struct crypto_skcipher *child; + }; + + struct cryptd_skcipher_request_ctx { + crypto_completion_t complete; ++ struct skcipher_request req; + }; + + struct cryptd_hash_ctx { +@@ -227,13 +228,13 @@ static int cryptd_skcipher_setkey(struct crypto_skcipher *parent, + const u8 *key, unsigned int keylen) + { + struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(parent); +- struct crypto_sync_skcipher *child = ctx->child; ++ struct crypto_skcipher *child = ctx->child; + +- crypto_sync_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); +- crypto_sync_skcipher_set_flags(child, +- crypto_skcipher_get_flags(parent) & +- CRYPTO_TFM_REQ_MASK); +- return crypto_sync_skcipher_setkey(child, key, keylen); ++ crypto_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); ++ crypto_skcipher_set_flags(child, ++ crypto_skcipher_get_flags(parent) & ++ CRYPTO_TFM_REQ_MASK); ++ return crypto_skcipher_setkey(child, key, keylen); + } + + static void cryptd_skcipher_complete(struct skcipher_request *req, int err) +@@ -258,13 +259,13 @@ static void cryptd_skcipher_encrypt(struct crypto_async_request *base, + struct cryptd_skcipher_request_ctx *rctx = skcipher_request_ctx(req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm); +- struct crypto_sync_skcipher *child = ctx->child; +- SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, child); ++ struct skcipher_request *subreq = &rctx->req; ++ struct crypto_skcipher *child = ctx->child; + + if (unlikely(err == -EINPROGRESS)) + goto out; + +- skcipher_request_set_sync_tfm(subreq, child); ++ skcipher_request_set_tfm(subreq, child); + skcipher_request_set_callback(subreq, CRYPTO_TFM_REQ_MAY_SLEEP, + NULL, NULL); + skcipher_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, +@@ -286,13 +287,13 @@ static void cryptd_skcipher_decrypt(struct crypto_async_request *base, + struct cryptd_skcipher_request_ctx *rctx = skcipher_request_ctx(req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm); +- struct crypto_sync_skcipher *child = ctx->child; +- SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, child); ++ struct skcipher_request *subreq = &rctx->req; ++ struct crypto_skcipher *child = ctx->child; + + if (unlikely(err == -EINPROGRESS)) + goto out; + +- skcipher_request_set_sync_tfm(subreq, child); ++ skcipher_request_set_tfm(subreq, child); + skcipher_request_set_callback(subreq, CRYPTO_TFM_REQ_MAY_SLEEP, + NULL, NULL); + skcipher_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, +@@ -343,9 +344,10 @@ static int cryptd_skcipher_init_tfm(struct crypto_skcipher *tfm) + if (IS_ERR(cipher)) + return PTR_ERR(cipher); + +- ctx->child = (struct crypto_sync_skcipher *)cipher; ++ ctx->child = cipher; + crypto_skcipher_set_reqsize( +- tfm, sizeof(struct cryptd_skcipher_request_ctx)); ++ tfm, sizeof(struct cryptd_skcipher_request_ctx) + ++ crypto_skcipher_reqsize(cipher)); + return 0; + } + +@@ -353,7 +355,7 @@ static void cryptd_skcipher_exit_tfm(struct crypto_skcipher *tfm) + { + struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm); + +- crypto_free_sync_skcipher(ctx->child); ++ crypto_free_skcipher(ctx->child); + } + + static void cryptd_skcipher_free(struct skcipher_instance *inst) +@@ -931,7 +933,7 @@ struct crypto_skcipher *cryptd_skcipher_child(struct cryptd_skcipher *tfm) + { + struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(&tfm->base); + +- return &ctx->child->base; ++ return ctx->child; + } + EXPORT_SYMBOL_GPL(cryptd_skcipher_child); + +-- +2.35.1 + diff --git a/queue-6.0/crypto-hisilicon-hpre-fix-resource-leak-in-remove-pr.patch b/queue-6.0/crypto-hisilicon-hpre-fix-resource-leak-in-remove-pr.patch new file mode 100644 index 00000000000..4a479001237 --- /dev/null +++ b/queue-6.0/crypto-hisilicon-hpre-fix-resource-leak-in-remove-pr.patch @@ -0,0 +1,49 @@ +From 4a7e3716b9556df683cf3b3abdeab48f1e6c6ebc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 24 Sep 2022 15:38:31 +0800 +Subject: crypto: hisilicon/hpre - fix resource leak in remove process + +From: Zhiqi Song + +[ Upstream commit 45e6319bd5f2154d8b8c9f1eaa4ac030ba0d330c ] + +In hpre_remove(), when the disable operation of qm sriov failed, +the following logic should continue to be executed to release the +remaining resources that have been allocated, instead of returning +directly, otherwise there will be resource leakage. + +Signed-off-by: Zhiqi Song +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/hisilicon/hpre/hpre_main.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c +index fd55c6ff13ba..7a50ca664ada 100644 +--- a/drivers/crypto/hisilicon/hpre/hpre_main.c ++++ b/drivers/crypto/hisilicon/hpre/hpre_main.c +@@ -1287,18 +1287,12 @@ static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id) + static void hpre_remove(struct pci_dev *pdev) + { + struct hisi_qm *qm = pci_get_drvdata(pdev); +- int ret; + + hisi_qm_pm_uninit(qm); + hisi_qm_wait_task_finish(qm, &hpre_devices); + hisi_qm_alg_unregister(qm, &hpre_devices); +- if (qm->fun_type == QM_HW_PF && qm->vfs_num) { +- ret = hisi_qm_sriov_disable(pdev, true); +- if (ret) { +- pci_err(pdev, "Disable SRIOV fail!\n"); +- return; +- } +- } ++ if (qm->fun_type == QM_HW_PF && qm->vfs_num) ++ hisi_qm_sriov_disable(pdev, true); + + hpre_debugfs_exit(qm); + hisi_qm_stop(qm, QM_NORMAL); +-- +2.35.1 + diff --git a/queue-6.0/crypto-hisilicon-qm-add-missing-pci_dev_put-in-q_num.patch b/queue-6.0/crypto-hisilicon-qm-add-missing-pci_dev_put-in-q_num.patch new file mode 100644 index 00000000000..24d3d52f8e8 --- /dev/null +++ b/queue-6.0/crypto-hisilicon-qm-add-missing-pci_dev_put-in-q_num.patch @@ -0,0 +1,55 @@ +From f80cbfdea33418e49f36ac91a6e06138d712b69a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Nov 2022 18:00:36 +0800 +Subject: crypto: hisilicon/qm - add missing pci_dev_put() in q_num_set() + +From: Xiongfeng Wang + +[ Upstream commit cc7710d0d4ebc6998f04035cde4f32c5ddbe9d7f ] + +pci_get_device() will increase the reference count for the returned +pci_dev. We need to use pci_dev_put() to decrease the reference count +before q_num_set() returns. + +Fixes: c8b4b477079d ("crypto: hisilicon - add HiSilicon HPRE accelerator") +Signed-off-by: Xiongfeng Wang +Reviewed-by: Weili Qian +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + include/linux/hisi_acc_qm.h | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/include/linux/hisi_acc_qm.h b/include/linux/hisi_acc_qm.h +index 851c962ba473..ce0c3ed67a5f 100644 +--- a/include/linux/hisi_acc_qm.h ++++ b/include/linux/hisi_acc_qm.h +@@ -400,14 +400,14 @@ struct hisi_qp { + static inline int q_num_set(const char *val, const struct kernel_param *kp, + unsigned int device) + { +- struct pci_dev *pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI, +- device, NULL); ++ struct pci_dev *pdev; + u32 n, q_num; + int ret; + + if (!val) + return -EINVAL; + ++ pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI, device, NULL); + if (!pdev) { + q_num = min_t(u32, QM_QNUM_V1, QM_QNUM_V2); + pr_info("No device found currently, suppose queue number is %u\n", +@@ -417,6 +417,8 @@ static inline int q_num_set(const char *val, const struct kernel_param *kp, + q_num = QM_QNUM_V1; + else + q_num = QM_QNUM_V2; ++ ++ pci_dev_put(pdev); + } + + ret = kstrtou32(val, 10, &n); +-- +2.35.1 + diff --git a/queue-6.0/crypto-hisilicon-qm-fix-missing-destroy-qp_idr.patch b/queue-6.0/crypto-hisilicon-qm-fix-missing-destroy-qp_idr.patch new file mode 100644 index 00000000000..0178e3bfd8f --- /dev/null +++ b/queue-6.0/crypto-hisilicon-qm-fix-missing-destroy-qp_idr.patch @@ -0,0 +1,49 @@ +From 8152e90a8b25f2b803490ec1e549d417a19803a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 13 Aug 2022 18:34:52 +0800 +Subject: crypto: hisilicon/qm - fix missing destroy qp_idr + +From: Weili Qian + +[ Upstream commit 116be08f6e4e385733d42360a33c3d883d2dd702 ] + +In the function hisi_qm_memory_init(), if resource alloc fails after +idr_init, the initialized qp_idr needs to be destroyed. + +Signed-off-by: Weili Qian +Signed-off-by: Yang Shen +Signed-off-by: Herbert Xu +Stable-dep-of: ee1537fe3dd8 ("crypto: hisilicon/qm - re-enable communicate interrupt before notifying PF") +Signed-off-by: Sasha Levin +--- + drivers/crypto/hisilicon/qm.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index 9fa2efe60153..bdb7d5ba23b8 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -6143,8 +6143,8 @@ static int hisi_qm_memory_init(struct hisi_qm *qm) + GFP_ATOMIC); + dev_dbg(dev, "allocate qm dma buf size=%zx)\n", qm->qdma.size); + if (!qm->qdma.va) { +- ret = -ENOMEM; +- goto err_alloc_qdma; ++ ret = -ENOMEM; ++ goto err_destroy_idr; + } + + QM_INIT_BUF(qm, eqe, QM_EQ_DEPTH); +@@ -6160,7 +6160,8 @@ static int hisi_qm_memory_init(struct hisi_qm *qm) + + err_alloc_qp_array: + dma_free_coherent(dev, qm->qdma.size, qm->qdma.va, qm->qdma.dma); +-err_alloc_qdma: ++err_destroy_idr: ++ idr_destroy(&qm->qp_idr); + kfree(qm->factor); + + return ret; +-- +2.35.1 + diff --git a/queue-6.0/crypto-hisilicon-qm-get-hardware-features-from-hardw.patch b/queue-6.0/crypto-hisilicon-qm-get-hardware-features-from-hardw.patch new file mode 100644 index 00000000000..fb574e41873 --- /dev/null +++ b/queue-6.0/crypto-hisilicon-qm-get-hardware-features-from-hardw.patch @@ -0,0 +1,648 @@ +From 5ebb594eca74c3d20b771432f35fc251a2366e7e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Sep 2022 17:46:55 +0800 +Subject: crypto: hisilicon/qm - get hardware features from hardware registers + +From: Weili Qian + +[ Upstream commit 82f00b24f532557fb0e15a6a2747859e4b70c4bd ] + +Before hardware V3, hardwares do not provide the feature registers, +driver resolves hardware differences based on the hardware version. +As a result, the driver does not support the new hardware. + +Hardware V3 and later versions support to obtain hardware features, +such as power-gating management and doorbell isolation, through +the hardware registers. To be compatible with later hardware versions, +the features of the current device is obtained by reading the +hardware registers instead of the hardware version. + +Signed-off-by: Weili Qian +Signed-off-by: Herbert Xu +Stable-dep-of: ee1537fe3dd8 ("crypto: hisilicon/qm - re-enable communicate interrupt before notifying PF") +Signed-off-by: Sasha Levin +--- + drivers/crypto/hisilicon/hpre/hpre_main.c | 4 +- + drivers/crypto/hisilicon/qm.c | 196 +++++++++++++++------- + drivers/crypto/hisilicon/sec2/sec_main.c | 4 +- + drivers/crypto/hisilicon/zip/zip_main.c | 4 +- + include/linux/hisi_acc_qm.h | 31 +++- + 5 files changed, 170 insertions(+), 69 deletions(-) + +diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c +index 9d529df0eab9..fd55c6ff13ba 100644 +--- a/drivers/crypto/hisilicon/hpre/hpre_main.c ++++ b/drivers/crypto/hisilicon/hpre/hpre_main.c +@@ -457,7 +457,7 @@ static void hpre_open_sva_prefetch(struct hisi_qm *qm) + u32 val; + int ret; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) + return; + + /* Enable prefetch */ +@@ -478,7 +478,7 @@ static void hpre_close_sva_prefetch(struct hisi_qm *qm) + u32 val; + int ret; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) + return; + + val = readl_relaxed(qm->io_base + HPRE_PREFETCH_CFG); +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index bdb7d5ba23b8..2cfb072a218f 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -86,9 +86,7 @@ + #define QM_DB_CMD_SHIFT_V1 16 + #define QM_DB_INDEX_SHIFT_V1 32 + #define QM_DB_PRIORITY_SHIFT_V1 48 +-#define QM_QUE_ISO_CFG_V 0x0030 + #define QM_PAGE_SIZE 0x0034 +-#define QM_QUE_ISO_EN 0x100154 + #define QM_CAPBILITY 0x100158 + #define QM_QP_NUN_MASK GENMASK(10, 0) + #define QM_QP_DB_INTERVAL 0x10000 +@@ -205,6 +203,8 @@ + #define MAX_WAIT_COUNTS 1000 + #define QM_CACHE_WB_START 0x204 + #define QM_CACHE_WB_DONE 0x208 ++#define QM_FUNC_CAPS_REG 0x3100 ++#define QM_CAPBILITY_VERSION GENMASK(7, 0) + + #define PCI_BAR_2 2 + #define PCI_BAR_4 4 +@@ -329,6 +329,22 @@ enum qm_mb_cmd { + QM_VF_GET_QOS, + }; + ++static const struct hisi_qm_cap_info qm_cap_info_comm[] = { ++ {QM_SUPPORT_DB_ISOLATION, 0x30, 0, BIT(0), 0x0, 0x0, 0x0}, ++ {QM_SUPPORT_FUNC_QOS, 0x3100, 0, BIT(8), 0x0, 0x0, 0x1}, ++ {QM_SUPPORT_STOP_QP, 0x3100, 0, BIT(9), 0x0, 0x0, 0x1}, ++ {QM_SUPPORT_MB_COMMAND, 0x3100, 0, BIT(11), 0x0, 0x0, 0x1}, ++ {QM_SUPPORT_SVA_PREFETCH, 0x3100, 0, BIT(14), 0x0, 0x0, 0x1}, ++}; ++ ++static const struct hisi_qm_cap_info qm_cap_info_pf[] = { ++ {QM_SUPPORT_RPM, 0x3100, 0, BIT(13), 0x0, 0x0, 0x1}, ++}; ++ ++static const struct hisi_qm_cap_info qm_cap_info_vf[] = { ++ {QM_SUPPORT_RPM, 0x3100, 0, BIT(12), 0x0, 0x0, 0x0}, ++}; ++ + struct qm_cqe { + __le32 rsvd0; + __le16 cmd_id; +@@ -426,10 +442,7 @@ struct hisi_qm_hw_ops { + void (*hw_error_init)(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe); + void (*hw_error_uninit)(struct hisi_qm *qm); + enum acc_err_result (*hw_error_handle)(struct hisi_qm *qm); +- int (*stop_qp)(struct hisi_qp *qp); + int (*set_msi)(struct hisi_qm *qm, bool set); +- int (*ping_all_vfs)(struct hisi_qm *qm, u64 cmd); +- int (*ping_pf)(struct hisi_qm *qm, u64 cmd); + }; + + struct qm_dfx_item { +@@ -828,6 +841,36 @@ static int qm_dev_mem_reset(struct hisi_qm *qm) + POLL_TIMEOUT); + } + ++/** ++ * hisi_qm_get_hw_info() - Get device information. ++ * @qm: The qm which want to get information. ++ * @info_table: Array for storing device information. ++ * @index: Index in info_table. ++ * @is_read: Whether read from reg, 0: not support read from reg. ++ * ++ * This function returns device information the caller needs. ++ */ ++u32 hisi_qm_get_hw_info(struct hisi_qm *qm, ++ const struct hisi_qm_cap_info *info_table, ++ u32 index, bool is_read) ++{ ++ u32 val; ++ ++ switch (qm->ver) { ++ case QM_HW_V1: ++ return info_table[index].v1_val; ++ case QM_HW_V2: ++ return info_table[index].v2_val; ++ default: ++ if (!is_read) ++ return info_table[index].v3_val; ++ ++ val = readl(qm->io_base + info_table[index].offset); ++ return (val >> info_table[index].shift) & info_table[index].mask; ++ } ++} ++EXPORT_SYMBOL_GPL(hisi_qm_get_hw_info); ++ + static u32 qm_get_irq_num_v1(struct hisi_qm *qm) + { + return QM_IRQ_NUM_V1; +@@ -854,7 +897,7 @@ static int qm_pm_get_sync(struct hisi_qm *qm) + struct device *dev = &qm->pdev->dev; + int ret; + +- if (qm->fun_type == QM_HW_VF || qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_RPM, &qm->caps)) + return 0; + + ret = pm_runtime_resume_and_get(dev); +@@ -870,7 +913,7 @@ static void qm_pm_put_sync(struct hisi_qm *qm) + { + struct device *dev = &qm->pdev->dev; + +- if (qm->fun_type == QM_HW_VF || qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_RPM, &qm->caps)) + return; + + pm_runtime_mark_last_busy(dev); +@@ -1151,7 +1194,7 @@ static void qm_init_prefetch(struct hisi_qm *qm) + struct device *dev = &qm->pdev->dev; + u32 page_type = 0x0; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) + return; + + switch (PAGE_SIZE) { +@@ -1270,7 +1313,7 @@ static void qm_vft_data_cfg(struct hisi_qm *qm, enum vft_type type, u32 base, + } + break; + case SHAPER_VFT: +- if (qm->ver >= QM_HW_V3) { ++ if (factor) { + tmp = factor->cir_b | + (factor->cir_u << QM_SHAPER_FACTOR_CIR_U_SHIFT) | + (factor->cir_s << QM_SHAPER_FACTOR_CIR_S_SHIFT) | +@@ -1288,10 +1331,13 @@ static void qm_vft_data_cfg(struct hisi_qm *qm, enum vft_type type, u32 base, + static int qm_set_vft_common(struct hisi_qm *qm, enum vft_type type, + u32 fun_num, u32 base, u32 number) + { +- struct qm_shaper_factor *factor = &qm->factor[fun_num]; ++ struct qm_shaper_factor *factor = NULL; + unsigned int val; + int ret; + ++ if (type == SHAPER_VFT && test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) ++ factor = &qm->factor[fun_num]; ++ + ret = readl_relaxed_poll_timeout(qm->io_base + QM_VFT_CFG_RDY, val, + val & BIT(0), POLL_PERIOD, + POLL_TIMEOUT); +@@ -1349,7 +1395,7 @@ static int qm_set_sqc_cqc_vft(struct hisi_qm *qm, u32 fun_num, u32 base, + } + + /* init default shaper qos val */ +- if (qm->ver >= QM_HW_V3) { ++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) { + ret = qm_shaper_init_vft(qm, fun_num); + if (ret) + goto back_sqc_cqc; +@@ -2495,7 +2541,7 @@ static int qm_wait_vf_prepare_finish(struct hisi_qm *qm) + u64 val; + u32 i; + +- if (!qm->vfs_num || qm->ver < QM_HW_V3) ++ if (!qm->vfs_num || !test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) + return 0; + + while (true) { +@@ -2780,10 +2826,7 @@ static const struct hisi_qm_hw_ops qm_hw_ops_v3 = { + .hw_error_init = qm_hw_error_init_v3, + .hw_error_uninit = qm_hw_error_uninit_v3, + .hw_error_handle = qm_hw_error_handle_v2, +- .stop_qp = qm_stop_qp, + .set_msi = qm_set_msi_v3, +- .ping_all_vfs = qm_ping_all_vfs, +- .ping_pf = qm_ping_pf, + }; + + static void *qm_get_avail_sqe(struct hisi_qp *qp) +@@ -3080,8 +3123,8 @@ static int qm_drain_qp(struct hisi_qp *qp) + return 0; + + /* Kunpeng930 supports drain qp by device */ +- if (qm->ops->stop_qp) { +- ret = qm->ops->stop_qp(qp); ++ if (test_bit(QM_SUPPORT_STOP_QP, &qm->caps)) { ++ ret = qm_stop_qp(qp); + if (ret) + dev_err(dev, "Failed to stop qp(%u)!\n", qp->qp_id); + return ret; +@@ -3312,7 +3355,7 @@ static int hisi_qm_uacce_mmap(struct uacce_queue *q, + if (qm->ver == QM_HW_V1) { + if (sz > PAGE_SIZE * QM_DOORBELL_PAGE_NR) + return -EINVAL; +- } else if (qm->ver == QM_HW_V2 || !qm->use_db_isolation) { ++ } else if (!test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) { + if (sz > PAGE_SIZE * (QM_DOORBELL_PAGE_NR + + QM_DOORBELL_SQ_CQ_BASE_V2 / PAGE_SIZE)) + return -EINVAL; +@@ -3466,7 +3509,7 @@ static int qm_alloc_uacce(struct hisi_qm *qm) + + if (qm->ver == QM_HW_V1) + mmio_page_nr = QM_DOORBELL_PAGE_NR; +- else if (qm->ver == QM_HW_V2 || !qm->use_db_isolation) ++ else if (!test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) + mmio_page_nr = QM_DOORBELL_PAGE_NR + + QM_DOORBELL_SQ_CQ_BASE_V2 / PAGE_SIZE; + else +@@ -3628,7 +3671,7 @@ static void hisi_qm_pre_init(struct hisi_qm *qm) + init_rwsem(&qm->qps_lock); + qm->qp_in_used = 0; + qm->misc_ctl = false; +- if (qm->fun_type == QM_HW_PF && qm->ver > QM_HW_V2) { ++ 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"); + } +@@ -3638,7 +3681,7 @@ static void qm_cmd_uninit(struct hisi_qm *qm) + { + u32 val; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) + return; + + val = readl(qm->io_base + QM_IFC_INT_MASK); +@@ -3650,7 +3693,7 @@ static void qm_cmd_init(struct hisi_qm *qm) + { + u32 val; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) + return; + + /* Clear communication interrupt source */ +@@ -3666,7 +3709,7 @@ static void qm_put_pci_res(struct hisi_qm *qm) + { + struct pci_dev *pdev = qm->pdev; + +- if (qm->use_db_isolation) ++ if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) + iounmap(qm->db_io_base); + + iounmap(qm->io_base); +@@ -3716,7 +3759,9 @@ static void hisi_qm_memory_uninit(struct hisi_qm *qm) + } + + idr_destroy(&qm->qp_idr); +- kfree(qm->factor); ++ ++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) ++ kfree(qm->factor); + } + + /** +@@ -4499,12 +4544,10 @@ static int qm_vf_read_qos(struct hisi_qm *qm) + qm->mb_qos = 0; + + /* vf ping pf to get function qos */ +- if (qm->ops->ping_pf) { +- ret = qm->ops->ping_pf(qm, QM_VF_GET_QOS); +- if (ret) { +- pci_err(qm->pdev, "failed to send cmd to PF to get qos!\n"); +- return ret; +- } ++ ret = qm_ping_pf(qm, QM_VF_GET_QOS); ++ if (ret) { ++ pci_err(qm->pdev, "failed to send cmd to PF to get qos!\n"); ++ return ret; + } + + while (true) { +@@ -4676,14 +4719,14 @@ static const struct file_operations qm_algqos_fops = { + * hisi_qm_set_algqos_init() - Initialize function qos debugfs files. + * @qm: The qm for which we want to add debugfs files. + * +- * Create function qos debugfs files. ++ * Create function qos debugfs files, VF ping PF to get function qos. + */ + static void hisi_qm_set_algqos_init(struct hisi_qm *qm) + { + if (qm->fun_type == QM_HW_PF) + debugfs_create_file("alg_qos", 0644, qm->debug.debug_root, + qm, &qm_algqos_fops); +- else ++ else if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) + debugfs_create_file("alg_qos", 0444, qm->debug.debug_root, + qm, &qm_algqos_fops); + } +@@ -4731,7 +4774,7 @@ void hisi_qm_debug_init(struct hisi_qm *qm) + &qm_atomic64_ops); + } + +- if (qm->ver >= QM_HW_V3) ++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) + hisi_qm_set_algqos_init(qm); + } + EXPORT_SYMBOL_GPL(hisi_qm_debug_init); +@@ -4848,7 +4891,9 @@ int hisi_qm_sriov_disable(struct pci_dev *pdev, bool is_frozen) + + pci_disable_sriov(pdev); + /* clear vf function shaper configure array */ +- memset(qm->factor + 1, 0, sizeof(struct qm_shaper_factor) * total_vfs); ++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) ++ memset(qm->factor + 1, 0, sizeof(struct qm_shaper_factor) * total_vfs); ++ + ret = qm_clear_vft_config(qm); + if (ret) + return ret; +@@ -5072,8 +5117,8 @@ static int qm_try_stop_vfs(struct hisi_qm *qm, u64 cmd, + return 0; + + /* Kunpeng930 supports to notify VFs to stop before PF reset */ +- if (qm->ops->ping_all_vfs) { +- ret = qm->ops->ping_all_vfs(qm, cmd); ++ if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) { ++ ret = qm_ping_all_vfs(qm, cmd); + if (ret) + pci_err(pdev, "failed to send cmd to all VFs before PF reset!\n"); + } else { +@@ -5264,8 +5309,8 @@ static int qm_try_start_vfs(struct hisi_qm *qm, enum qm_mb_cmd cmd) + } + + /* Kunpeng930 supports to notify VFs to start after PF reset. */ +- if (qm->ops->ping_all_vfs) { +- ret = qm->ops->ping_all_vfs(qm, cmd); ++ if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) { ++ ret = qm_ping_all_vfs(qm, cmd); + if (ret) + pci_warn(pdev, "failed to send cmd to all VFs after PF reset!\n"); + } else { +@@ -5713,7 +5758,7 @@ static void qm_pf_reset_vf_prepare(struct hisi_qm *qm, + hisi_qm_set_hw_reset(qm, QM_RESET_STOP_RX_OFFSET); + out: + pci_save_state(pdev); +- ret = qm->ops->ping_pf(qm, cmd); ++ ret = qm_ping_pf(qm, cmd); + if (ret) + dev_warn(&pdev->dev, "PF responds timeout in reset prepare!\n"); + } +@@ -5731,7 +5776,7 @@ static void qm_pf_reset_vf_done(struct hisi_qm *qm) + cmd = QM_VF_START_FAIL; + } + +- ret = qm->ops->ping_pf(qm, cmd); ++ ret = qm_ping_pf(qm, cmd); + if (ret) + dev_warn(&pdev->dev, "PF responds timeout in reset done!\n"); + +@@ -5936,7 +5981,7 @@ static int qm_get_qp_num(struct hisi_qm *qm) + qm->ctrl_qp_num = readl(qm->io_base + QM_CAPBILITY) & + QM_QP_NUN_MASK; + +- if (qm->use_db_isolation) ++ if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) + qm->max_qp_num = (readl(qm->io_base + QM_CAPBILITY) >> + QM_QP_MAX_NUM_SHIFT) & QM_QP_NUN_MASK; + else +@@ -5952,6 +5997,39 @@ static int qm_get_qp_num(struct hisi_qm *qm) + return 0; + } + ++static void qm_get_hw_caps(struct hisi_qm *qm) ++{ ++ const struct hisi_qm_cap_info *cap_info = qm->fun_type == QM_HW_PF ? ++ qm_cap_info_pf : qm_cap_info_vf; ++ u32 size = qm->fun_type == QM_HW_PF ? ARRAY_SIZE(qm_cap_info_pf) : ++ ARRAY_SIZE(qm_cap_info_vf); ++ u32 val, i; ++ ++ /* Doorbell isolate register is a independent register. */ ++ val = hisi_qm_get_hw_info(qm, qm_cap_info_comm, QM_SUPPORT_DB_ISOLATION, true); ++ if (val) ++ set_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps); ++ ++ if (qm->ver >= QM_HW_V3) { ++ val = readl(qm->io_base + QM_FUNC_CAPS_REG); ++ qm->cap_ver = val & QM_CAPBILITY_VERSION; ++ } ++ ++ /* Get PF/VF common capbility */ ++ for (i = 1; i < ARRAY_SIZE(qm_cap_info_comm); i++) { ++ val = hisi_qm_get_hw_info(qm, qm_cap_info_comm, i, qm->cap_ver); ++ if (val) ++ set_bit(qm_cap_info_comm[i].type, &qm->caps); ++ } ++ ++ /* Get PF/VF different capbility */ ++ for (i = 0; i < size; i++) { ++ val = hisi_qm_get_hw_info(qm, cap_info, i, qm->cap_ver); ++ if (val) ++ set_bit(cap_info[i].type, &qm->caps); ++ } ++} ++ + static int qm_get_pci_res(struct hisi_qm *qm) + { + struct pci_dev *pdev = qm->pdev; +@@ -5971,16 +6049,8 @@ static int qm_get_pci_res(struct hisi_qm *qm) + goto err_request_mem_regions; + } + +- if (qm->ver > QM_HW_V2) { +- if (qm->fun_type == QM_HW_PF) +- qm->use_db_isolation = readl(qm->io_base + +- QM_QUE_ISO_EN) & BIT(0); +- else +- qm->use_db_isolation = readl(qm->io_base + +- QM_QUE_ISO_CFG_V) & BIT(0); +- } +- +- if (qm->use_db_isolation) { ++ qm_get_hw_caps(qm); ++ if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) { + qm->db_interval = QM_QP_DB_INTERVAL; + qm->db_phys_base = pci_resource_start(pdev, PCI_BAR_4); + qm->db_io_base = ioremap(qm->db_phys_base, +@@ -6004,7 +6074,7 @@ static int qm_get_pci_res(struct hisi_qm *qm) + return 0; + + err_db_ioremap: +- if (qm->use_db_isolation) ++ if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) + iounmap(qm->db_io_base); + err_ioremap: + iounmap(qm->io_base); +@@ -6121,12 +6191,15 @@ static int hisi_qm_memory_init(struct hisi_qm *qm) + int ret, total_func, i; + size_t off = 0; + +- total_func = pci_sriov_get_totalvfs(qm->pdev) + 1; +- qm->factor = kcalloc(total_func, sizeof(struct qm_shaper_factor), GFP_KERNEL); +- if (!qm->factor) +- return -ENOMEM; +- for (i = 0; i < total_func; i++) +- qm->factor[i].func_qos = QM_QOS_MAX_VAL; ++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) { ++ total_func = pci_sriov_get_totalvfs(qm->pdev) + 1; ++ qm->factor = kcalloc(total_func, sizeof(struct qm_shaper_factor), GFP_KERNEL); ++ if (!qm->factor) ++ return -ENOMEM; ++ ++ for (i = 0; i < total_func; i++) ++ qm->factor[i].func_qos = QM_QOS_MAX_VAL; ++ } + + #define QM_INIT_BUF(qm, type, num) do { \ + (qm)->type = ((qm)->qdma.va + (off)); \ +@@ -6162,7 +6235,8 @@ static int hisi_qm_memory_init(struct hisi_qm *qm) + dma_free_coherent(dev, qm->qdma.size, qm->qdma.va, qm->qdma.dma); + err_destroy_idr: + idr_destroy(&qm->qp_idr); +- kfree(qm->factor); ++ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) ++ kfree(qm->factor); + + return ret; + } +@@ -6305,7 +6379,7 @@ void hisi_qm_pm_init(struct hisi_qm *qm) + { + struct device *dev = &qm->pdev->dev; + +- if (qm->fun_type == QM_HW_VF || qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_RPM, &qm->caps)) + return; + + pm_runtime_set_autosuspend_delay(dev, QM_AUTOSUSPEND_DELAY); +@@ -6324,7 +6398,7 @@ void hisi_qm_pm_uninit(struct hisi_qm *qm) + { + struct device *dev = &qm->pdev->dev; + +- if (qm->fun_type == QM_HW_VF || qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_RPM, &qm->caps)) + return; + + pm_runtime_get_noresume(dev); +diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c +index 2c0be91c0b09..1ec3b06345fd 100644 +--- a/drivers/crypto/hisilicon/sec2/sec_main.c ++++ b/drivers/crypto/hisilicon/sec2/sec_main.c +@@ -415,7 +415,7 @@ static void sec_open_sva_prefetch(struct hisi_qm *qm) + u32 val; + int ret; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) + return; + + /* Enable prefetch */ +@@ -435,7 +435,7 @@ static void sec_close_sva_prefetch(struct hisi_qm *qm) + u32 val; + int ret; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) + return; + + val = readl_relaxed(qm->io_base + SEC_PREFETCH_CFG); +diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c +index c3303d99acac..65ed2ae8e131 100644 +--- a/drivers/crypto/hisilicon/zip/zip_main.c ++++ b/drivers/crypto/hisilicon/zip/zip_main.c +@@ -348,7 +348,7 @@ static void hisi_zip_open_sva_prefetch(struct hisi_qm *qm) + u32 val; + int ret; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) + return; + + /* Enable prefetch */ +@@ -368,7 +368,7 @@ static void hisi_zip_close_sva_prefetch(struct hisi_qm *qm) + u32 val; + int ret; + +- if (qm->ver < QM_HW_V3) ++ if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps)) + return; + + val = readl_relaxed(qm->io_base + HZIP_PREFETCH_CFG); +diff --git a/include/linux/hisi_acc_qm.h b/include/linux/hisi_acc_qm.h +index 116e8bd68c99..851c962ba473 100644 +--- a/include/linux/hisi_acc_qm.h ++++ b/include/linux/hisi_acc_qm.h +@@ -168,6 +168,15 @@ enum qm_vf_state { + QM_NOT_READY, + }; + ++enum qm_cap_bits { ++ QM_SUPPORT_DB_ISOLATION = 0x0, ++ QM_SUPPORT_FUNC_QOS, ++ QM_SUPPORT_STOP_QP, ++ QM_SUPPORT_MB_COMMAND, ++ QM_SUPPORT_SVA_PREFETCH, ++ QM_SUPPORT_RPM, ++}; ++ + struct dfx_diff_registers { + u32 *regs; + u32 reg_offset; +@@ -258,6 +267,18 @@ struct hisi_qm_err_ini { + void (*err_info_init)(struct hisi_qm *qm); + }; + ++struct hisi_qm_cap_info { ++ u32 type; ++ /* Register offset */ ++ u32 offset; ++ /* Bit offset in register */ ++ u32 shift; ++ u32 mask; ++ u32 v1_val; ++ u32 v2_val; ++ u32 v3_val; ++}; ++ + struct hisi_qm_list { + struct mutex lock; + struct list_head list; +@@ -278,6 +299,9 @@ struct hisi_qm { + struct pci_dev *pdev; + void __iomem *io_base; + void __iomem *db_io_base; ++ ++ /* Capbility version, 0: not supports */ ++ u32 cap_ver; + u32 sqe_size; + u32 qp_base; + u32 qp_num; +@@ -304,6 +328,8 @@ struct hisi_qm { + struct hisi_qm_err_info err_info; + struct hisi_qm_err_status err_status; + unsigned long misc_ctl; /* driver removing and reset sched */ ++ /* Device capability bit */ ++ unsigned long caps; + + struct rw_semaphore qps_lock; + struct idr qp_idr; +@@ -326,8 +352,6 @@ struct hisi_qm { + bool use_sva; + bool is_frozen; + +- /* doorbell isolation enable */ +- bool use_db_isolation; + resource_size_t phys_base; + resource_size_t db_phys_base; + struct uacce_device *uacce; +@@ -501,6 +525,9 @@ void hisi_qm_pm_init(struct hisi_qm *qm); + int hisi_qm_get_dfx_access(struct hisi_qm *qm); + void hisi_qm_put_dfx_access(struct hisi_qm *qm); + void hisi_qm_regs_dump(struct seq_file *s, struct debugfs_regset32 *regset); ++u32 hisi_qm_get_hw_info(struct hisi_qm *qm, ++ const struct hisi_qm_cap_info *info_table, ++ u32 index, bool is_read); + + /* Used by VFIO ACC live migration driver */ + struct pci_driver *hisi_sec_get_pf_driver(void); +-- +2.35.1 + diff --git a/queue-6.0/crypto-hisilicon-qm-increase-the-memory-of-local-var.patch b/queue-6.0/crypto-hisilicon-qm-increase-the-memory-of-local-var.patch new file mode 100644 index 00000000000..01dd2375df2 --- /dev/null +++ b/queue-6.0/crypto-hisilicon-qm-increase-the-memory-of-local-var.patch @@ -0,0 +1,45 @@ +From bd5eb3ecb30702a086a6ae4482768a7c6c015160 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Oct 2022 01:17:44 +0000 +Subject: crypto: hisilicon/qm - increase the memory of local variables + +From: Kai Ye + +[ Upstream commit 3efe90af4c0c46c58dba1b306de142827153d9c0 ] + +Increase the buffer to prevent stack overflow by fuzz test. The maximum +length of the qos configuration buffer is 256 bytes. Currently, the value +of the 'val buffer' is only 32 bytes. The sscanf does not check the dest +memory length. So the 'val buffer' may stack overflow. + +Signed-off-by: Kai Ye +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/hisilicon/qm.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index 180589c73663..959f4846aa23 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -252,7 +252,6 @@ + #define QM_QOS_MIN_CIR_B 100 + #define QM_QOS_MAX_CIR_U 6 + #define QM_QOS_MAX_CIR_S 11 +-#define QM_QOS_VAL_MAX_LEN 32 + #define QM_DFX_BASE 0x0100000 + #define QM_DFX_STATE1 0x0104000 + #define QM_DFX_STATE2 0x01040C8 +@@ -4626,7 +4625,7 @@ static ssize_t qm_get_qos_value(struct hisi_qm *qm, const char *buf, + unsigned int *fun_index) + { + char tbuf_bdf[QM_DBG_READ_LEN] = {0}; +- char val_buf[QM_QOS_VAL_MAX_LEN] = {0}; ++ char val_buf[QM_DBG_READ_LEN] = {0}; + u32 tmp1, device, function; + int ret, bus; + +-- +2.35.1 + diff --git a/queue-6.0/crypto-hisilicon-qm-re-enable-communicate-interrupt-.patch b/queue-6.0/crypto-hisilicon-qm-re-enable-communicate-interrupt-.patch new file mode 100644 index 00000000000..74901504cb4 --- /dev/null +++ b/queue-6.0/crypto-hisilicon-qm-re-enable-communicate-interrupt-.patch @@ -0,0 +1,47 @@ +From e090d7bd37b283db6f9f689604eabb9d216391db Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 24 Sep 2022 19:04:31 +0800 +Subject: crypto: hisilicon/qm - re-enable communicate interrupt before + notifying PF + +From: Weili Qian + +[ Upstream commit ee1537fe3dd89860d0336563891f6cac707d0cb5 ] + +After the device is reset, the VF needs to re-enable communication +interrupt before the VF sends restart complete message to the PF. +If the interrupt is re-enabled after the VF notifies the PF, the PF +may fail to send messages to the VF after receiving VF's restart +complete message. + +Fixes: 760fe22cf5e9 ("crypto: hisilicon/qm - update reset flow") +Signed-off-by: Weili Qian +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/hisilicon/qm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index 2cfb072a218f..180589c73663 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -5776,6 +5776,7 @@ static void qm_pf_reset_vf_done(struct hisi_qm *qm) + cmd = QM_VF_START_FAIL; + } + ++ qm_cmd_init(qm); + ret = qm_ping_pf(qm, cmd); + if (ret) + dev_warn(&pdev->dev, "PF responds timeout in reset done!\n"); +@@ -5837,7 +5838,6 @@ static void qm_pf_reset_vf_process(struct hisi_qm *qm, + goto err_get_status; + + qm_pf_reset_vf_done(qm); +- qm_cmd_init(qm); + + dev_info(dev, "device reset done.\n"); + +-- +2.35.1 + diff --git a/queue-6.0/crypto-img-hash-fix-variable-dereferenced-before-che.patch b/queue-6.0/crypto-img-hash-fix-variable-dereferenced-before-che.patch new file mode 100644 index 00000000000..963010913be --- /dev/null +++ b/queue-6.0/crypto-img-hash-fix-variable-dereferenced-before-che.patch @@ -0,0 +1,52 @@ +From 65887ea95b7ac572adc71094aec861489994cfde Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Dec 2022 14:25:26 +0800 +Subject: crypto: img-hash - Fix variable dereferenced before check 'hdev->req' + +From: Gaosheng Cui + +[ Upstream commit 04ba54e5af8f8f0137b08cb51a0b3a2e1ea46c94 ] + +Smatch report warning as follows: + +drivers/crypto/img-hash.c:366 img_hash_dma_task() warn: variable +dereferenced before check 'hdev->req' + +Variable dereferenced should be done after check 'hdev->req', +fix it. + +Fixes: d358f1abbf71 ("crypto: img-hash - Add Imagination Technologies hw hash accelerator") +Fixes: 10badea259fa ("crypto: img-hash - Fix null pointer exception") +Signed-off-by: Gaosheng Cui +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/img-hash.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/crypto/img-hash.c b/drivers/crypto/img-hash.c +index d8e82d69745d..9629e98bd68b 100644 +--- a/drivers/crypto/img-hash.c ++++ b/drivers/crypto/img-hash.c +@@ -358,12 +358,16 @@ static int img_hash_dma_init(struct img_hash_dev *hdev) + static void img_hash_dma_task(unsigned long d) + { + struct img_hash_dev *hdev = (struct img_hash_dev *)d; +- struct img_hash_request_ctx *ctx = ahash_request_ctx(hdev->req); ++ struct img_hash_request_ctx *ctx; + u8 *addr; + size_t nbytes, bleft, wsend, len, tbc; + struct scatterlist tsg; + +- if (!hdev->req || !ctx->sg) ++ if (!hdev->req) ++ return; ++ ++ ctx = ahash_request_ctx(hdev->req); ++ if (!ctx->sg) + return; + + addr = sg_virt(ctx->sg); +-- +2.35.1 + diff --git a/queue-6.0/crypto-nitrox-avoid-double-free-on-error-path-in-nit.patch b/queue-6.0/crypto-nitrox-avoid-double-free-on-error-path-in-nit.patch new file mode 100644 index 00000000000..c4002ae6f85 --- /dev/null +++ b/queue-6.0/crypto-nitrox-avoid-double-free-on-error-path-in-nit.patch @@ -0,0 +1,43 @@ +From 5480b9edfac370a2fb73d67fe6639f2fc99e18b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 28 Sep 2022 13:25:05 +0300 +Subject: crypto: nitrox - avoid double free on error path in + nitrox_sriov_init() + +From: Natalia Petrova + +[ Upstream commit 094528b6a5a755b1195a01e10b13597d67d1a0e6 ] + +If alloc_workqueue() fails in nitrox_mbox_init() it deallocates +ndev->iov.vfdev and returns error code, but then nitrox_sriov_init() +calls nitrox_sriov_cleanup() where ndev->iov.vfdev is deallocated +again. + +Fix this by nulling ndev->iov.vfdev after the first deallocation. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 9e5de3e06e54 ("crypto: cavium/nitrox - Add mailbox...") +Signed-off-by: Natalia Petrova +Signed-off-by: Alexey Khoroshilov +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/cavium/nitrox/nitrox_mbx.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/crypto/cavium/nitrox/nitrox_mbx.c b/drivers/crypto/cavium/nitrox/nitrox_mbx.c +index 9e7308e39b30..d4e06999af9b 100644 +--- a/drivers/crypto/cavium/nitrox/nitrox_mbx.c ++++ b/drivers/crypto/cavium/nitrox/nitrox_mbx.c +@@ -195,6 +195,7 @@ int nitrox_mbox_init(struct nitrox_device *ndev) + ndev->iov.pf2vf_wq = alloc_workqueue("nitrox_pf2vf", 0, 0); + if (!ndev->iov.pf2vf_wq) { + kfree(ndev->iov.vfdev); ++ ndev->iov.vfdev = NULL; + return -ENOMEM; + } + /* enable pf2vf mailbox interrupts */ +-- +2.35.1 + diff --git a/queue-6.0/crypto-omap-sham-use-pm_runtime_resume_and_get-in-om.patch b/queue-6.0/crypto-omap-sham-use-pm_runtime_resume_and_get-in-om.patch new file mode 100644 index 00000000000..2fd4c0f33b3 --- /dev/null +++ b/queue-6.0/crypto-omap-sham-use-pm_runtime_resume_and_get-in-om.patch @@ -0,0 +1,41 @@ +From 58a6b758a866bfe2b52f8765837bcb45c055182e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Nov 2022 14:49:40 +0800 +Subject: crypto: omap-sham - Use pm_runtime_resume_and_get() in + omap_sham_probe() + +From: Shang XiaoJing + +[ Upstream commit 7bcceb4c9896b1b672b636ae70fe75110d6bf1ad ] + +omap_sham_probe() calls pm_runtime_get_sync() and calls +pm_runtime_put_sync() latter to put usage_counter. However, +pm_runtime_get_sync() will increment usage_counter even it failed. Fix +it by replacing it with pm_runtime_resume_and_get() to keep usage +counter balanced. + +Fixes: b359f034c8bf ("crypto: omap-sham - Convert to use pm_runtime API") +Signed-off-by: Shang XiaoJing +Acked-by: Mark Greer +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/omap-sham.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c +index 655a7f5a406a..cbeda59c6b19 100644 +--- a/drivers/crypto/omap-sham.c ++++ b/drivers/crypto/omap-sham.c +@@ -2114,7 +2114,7 @@ static int omap_sham_probe(struct platform_device *pdev) + + pm_runtime_enable(dev); + +- err = pm_runtime_get_sync(dev); ++ err = pm_runtime_resume_and_get(dev); + if (err < 0) { + dev_err(dev, "failed to get sync: %d\n", err); + goto err_pm; +-- +2.35.1 + diff --git a/queue-6.0/crypto-qat-fix-error-return-code-in-adf_probe.patch b/queue-6.0/crypto-qat-fix-error-return-code-in-adf_probe.patch new file mode 100644 index 00000000000..0fe73bffc5d --- /dev/null +++ b/queue-6.0/crypto-qat-fix-error-return-code-in-adf_probe.patch @@ -0,0 +1,35 @@ +From 03fd1a02be5a379d8dd4d087be6657c77d4cb5f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Nov 2022 19:27:34 +0800 +Subject: crypto: qat - fix error return code in adf_probe + +From: Wang Yufen + +[ Upstream commit 31f81401e23fb88cc030cd586abd28740e6c8136 ] + +Fix to return a negative error code -EINVAL instead of 0. + +Fixes: 0cec19c761e5 ("crypto: qat - add support for compression for 4xxx") +Signed-off-by: Wang Yufen +Acked-by: Giovanni Cabiddu +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/qat/qat_4xxx/adf_drv.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/crypto/qat/qat_4xxx/adf_drv.c b/drivers/crypto/qat/qat_4xxx/adf_drv.c +index 2f212561acc4..670a58b25cb1 100644 +--- a/drivers/crypto/qat/qat_4xxx/adf_drv.c ++++ b/drivers/crypto/qat/qat_4xxx/adf_drv.c +@@ -261,6 +261,7 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + hw_data->accel_capabilities_mask = hw_data->get_accel_cap(accel_dev); + if (!hw_data->accel_capabilities_mask) { + dev_err(&pdev->dev, "Failed to get capabilities mask.\n"); ++ ret = -EINVAL; + goto out_err; + } + +-- +2.35.1 + diff --git a/queue-6.0/crypto-rockchip-add-fallback-for-ahash.patch b/queue-6.0/crypto-rockchip-add-fallback-for-ahash.patch new file mode 100644 index 00000000000..bac996ac4c7 --- /dev/null +++ b/queue-6.0/crypto-rockchip-add-fallback-for-ahash.patch @@ -0,0 +1,86 @@ +From 38e900d649e86de9ec416b69870d793646e1dbe8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Sep 2022 07:54:45 +0000 +Subject: crypto: rockchip - add fallback for ahash + +From: Corentin Labbe + +[ Upstream commit 816600485cb597b3ff7d6806a95a78512839f775 ] + +Adds a fallback for all case hardware cannot handle. + +Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API") +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 38 +++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +index 49017d1fb510..16009bb0bf16 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -16,6 +16,40 @@ + * so we put the fixed hash out when met zero message. + */ + ++static bool rk_ahash_need_fallback(struct ahash_request *req) ++{ ++ struct scatterlist *sg; ++ ++ sg = req->src; ++ while (sg) { ++ if (!IS_ALIGNED(sg->offset, sizeof(u32))) { ++ return true; ++ } ++ if (sg->length % 4) { ++ return true; ++ } ++ sg = sg_next(sg); ++ } ++ return false; ++} ++ ++static int rk_ahash_digest_fb(struct ahash_request *areq) ++{ ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct rk_ahash_ctx *tfmctx = crypto_ahash_ctx(tfm); ++ ++ ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm); ++ rctx->fallback_req.base.flags = areq->base.flags & ++ CRYPTO_TFM_REQ_MAY_SLEEP; ++ ++ rctx->fallback_req.nbytes = areq->nbytes; ++ rctx->fallback_req.src = areq->src; ++ rctx->fallback_req.result = areq->result; ++ ++ return crypto_ahash_digest(&rctx->fallback_req); ++} ++ + static int zero_message_process(struct ahash_request *req) + { + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); +@@ -167,6 +201,9 @@ static int rk_ahash_digest(struct ahash_request *req) + struct rk_ahash_ctx *tctx = crypto_tfm_ctx(req->base.tfm); + struct rk_crypto_info *dev = tctx->dev; + ++ if (rk_ahash_need_fallback(req)) ++ return rk_ahash_digest_fb(req); ++ + if (!req->nbytes) + return zero_message_process(req); + else +@@ -309,6 +346,7 @@ static void rk_cra_hash_exit(struct crypto_tfm *tfm) + struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm); + + free_page((unsigned long)tctx->dev->addr_vir); ++ crypto_free_ahash(tctx->fallback_tfm); + } + + struct rk_crypto_tmp rk_ahash_sha1 = { +-- +2.35.1 + diff --git a/queue-6.0/crypto-rockchip-add-fallback-for-cipher.patch b/queue-6.0/crypto-rockchip-add-fallback-for-cipher.patch new file mode 100644 index 00000000000..32a1f0eba2d --- /dev/null +++ b/queue-6.0/crypto-rockchip-add-fallback-for-cipher.patch @@ -0,0 +1,259 @@ +From b9718f5784f7f2ba332089ce7cda4804c1d5c8eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Sep 2022 07:54:44 +0000 +Subject: crypto: rockchip - add fallback for cipher + +From: Corentin Labbe + +[ Upstream commit 68ef8af09a1a912a5ed2cfaa4cca7606f52cef90 ] + +The hardware does not handle 0 size length request, let's add a +fallback. +Furthermore fallback will be used for all unaligned case the hardware +cannot handle. + +Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API") +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/Kconfig | 4 + + drivers/crypto/rockchip/rk3288_crypto.h | 2 + + .../crypto/rockchip/rk3288_crypto_skcipher.c | 97 ++++++++++++++++--- + 3 files changed, 90 insertions(+), 13 deletions(-) + +diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig +index 3e6aa319920b..3080bd3d8cbb 100644 +--- a/drivers/crypto/Kconfig ++++ b/drivers/crypto/Kconfig +@@ -669,6 +669,10 @@ config CRYPTO_DEV_IMGTEC_HASH + config CRYPTO_DEV_ROCKCHIP + tristate "Rockchip's Cryptographic Engine driver" + depends on OF && ARCH_ROCKCHIP ++ depends on PM ++ select CRYPTO_ECB ++ select CRYPTO_CBC ++ select CRYPTO_DES + select CRYPTO_AES + select CRYPTO_LIB_DES + select CRYPTO_MD5 +diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h +index 3e60e3dca1b5..dfff0e2a83e4 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -246,10 +246,12 @@ struct rk_cipher_ctx { + struct rk_crypto_info *dev; + unsigned int keylen; + u8 iv[AES_BLOCK_SIZE]; ++ struct crypto_skcipher *fallback_tfm; + }; + + struct rk_cipher_rctx { + u32 mode; ++ struct skcipher_request fallback_req; // keep at the end + }; + + enum alg_type { +diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +index bbd0bf52bf07..eac5bba66e25 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -13,6 +13,63 @@ + + #define RK_CRYPTO_DEC BIT(0) + ++static int rk_cipher_need_fallback(struct skcipher_request *req) ++{ ++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); ++ unsigned int bs = crypto_skcipher_blocksize(tfm); ++ struct scatterlist *sgs, *sgd; ++ unsigned int stodo, dtodo, len; ++ ++ if (!req->cryptlen) ++ return true; ++ ++ len = req->cryptlen; ++ sgs = req->src; ++ sgd = req->dst; ++ while (sgs && sgd) { ++ if (!IS_ALIGNED(sgs->offset, sizeof(u32))) { ++ return true; ++ } ++ if (!IS_ALIGNED(sgd->offset, sizeof(u32))) { ++ return true; ++ } ++ stodo = min(len, sgs->length); ++ if (stodo % bs) { ++ return true; ++ } ++ dtodo = min(len, sgd->length); ++ if (dtodo % bs) { ++ return true; ++ } ++ if (stodo != dtodo) { ++ return true; ++ } ++ len -= stodo; ++ sgs = sg_next(sgs); ++ sgd = sg_next(sgd); ++ } ++ return false; ++} ++ ++static int rk_cipher_fallback(struct skcipher_request *areq) ++{ ++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq); ++ struct rk_cipher_ctx *op = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq); ++ int err; ++ ++ skcipher_request_set_tfm(&rctx->fallback_req, op->fallback_tfm); ++ skcipher_request_set_callback(&rctx->fallback_req, areq->base.flags, ++ areq->base.complete, areq->base.data); ++ skcipher_request_set_crypt(&rctx->fallback_req, areq->src, areq->dst, ++ areq->cryptlen, areq->iv); ++ if (rctx->mode & RK_CRYPTO_DEC) ++ err = crypto_skcipher_decrypt(&rctx->fallback_req); ++ else ++ err = crypto_skcipher_encrypt(&rctx->fallback_req); ++ return err; ++} ++ + static void rk_crypto_complete(struct crypto_async_request *base, int err) + { + if (base->complete) +@@ -22,10 +79,10 @@ static void rk_crypto_complete(struct crypto_async_request *base, int err) + static int rk_handle_req(struct rk_crypto_info *dev, + struct skcipher_request *req) + { +- if (!IS_ALIGNED(req->cryptlen, dev->align_size)) +- return -EINVAL; +- else +- return dev->enqueue(dev, &req->base); ++ if (rk_cipher_need_fallback(req)) ++ return rk_cipher_fallback(req); ++ ++ return dev->enqueue(dev, &req->base); + } + + static int rk_aes_setkey(struct crypto_skcipher *cipher, +@@ -39,7 +96,8 @@ static int rk_aes_setkey(struct crypto_skcipher *cipher, + return -EINVAL; + ctx->keylen = keylen; + memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, key, keylen); +- return 0; ++ ++ return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); + } + + static int rk_des_setkey(struct crypto_skcipher *cipher, +@@ -54,7 +112,8 @@ static int rk_des_setkey(struct crypto_skcipher *cipher, + + ctx->keylen = keylen; + memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen); +- return 0; ++ ++ return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); + } + + static int rk_tdes_setkey(struct crypto_skcipher *cipher, +@@ -69,7 +128,7 @@ static int rk_tdes_setkey(struct crypto_skcipher *cipher, + + ctx->keylen = keylen; + memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen); +- return 0; ++ return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); + } + + static int rk_aes_ecb_encrypt(struct skcipher_request *req) +@@ -394,6 +453,7 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm) + { + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + struct skcipher_alg *alg = crypto_skcipher_alg(tfm); ++ const char *name = crypto_tfm_alg_name(&tfm->base); + struct rk_crypto_tmp *algt; + + algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); +@@ -407,6 +467,16 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm) + if (!ctx->dev->addr_vir) + return -ENOMEM; + ++ ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK); ++ if (IS_ERR(ctx->fallback_tfm)) { ++ dev_err(ctx->dev->dev, "ERROR: Cannot allocate fallback for %s %ld\n", ++ name, PTR_ERR(ctx->fallback_tfm)); ++ return PTR_ERR(ctx->fallback_tfm); ++ } ++ ++ tfm->reqsize = sizeof(struct rk_cipher_rctx) + ++ crypto_skcipher_reqsize(ctx->fallback_tfm); ++ + return 0; + } + +@@ -415,6 +485,7 @@ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm) + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + + free_page((unsigned long)ctx->dev->addr_vir); ++ crypto_free_skcipher(ctx->fallback_tfm); + } + + struct rk_crypto_tmp rk_ecb_aes_alg = { +@@ -423,7 +494,7 @@ struct rk_crypto_tmp rk_ecb_aes_alg = { + .base.cra_name = "ecb(aes)", + .base.cra_driver_name = "ecb-aes-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = AES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x0f, +@@ -445,7 +516,7 @@ struct rk_crypto_tmp rk_cbc_aes_alg = { + .base.cra_name = "cbc(aes)", + .base.cra_driver_name = "cbc-aes-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = AES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x0f, +@@ -468,7 +539,7 @@ struct rk_crypto_tmp rk_ecb_des_alg = { + .base.cra_name = "ecb(des)", + .base.cra_driver_name = "ecb-des-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = DES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x07, +@@ -490,7 +561,7 @@ struct rk_crypto_tmp rk_cbc_des_alg = { + .base.cra_name = "cbc(des)", + .base.cra_driver_name = "cbc-des-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = DES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x07, +@@ -513,7 +584,7 @@ struct rk_crypto_tmp rk_ecb_des3_ede_alg = { + .base.cra_name = "ecb(des3_ede)", + .base.cra_driver_name = "ecb-des3-ede-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = DES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x07, +@@ -535,7 +606,7 @@ struct rk_crypto_tmp rk_cbc_des3_ede_alg = { + .base.cra_name = "cbc(des3_ede)", + .base.cra_driver_name = "cbc-des3-ede-rk", + .base.cra_priority = 300, +- .base.cra_flags = CRYPTO_ALG_ASYNC, ++ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = DES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct rk_cipher_ctx), + .base.cra_alignmask = 0x07, +-- +2.35.1 + diff --git a/queue-6.0/crypto-rockchip-better-handle-cipher-key.patch b/queue-6.0/crypto-rockchip-better-handle-cipher-key.patch new file mode 100644 index 00000000000..58805b1b525 --- /dev/null +++ b/queue-6.0/crypto-rockchip-better-handle-cipher-key.patch @@ -0,0 +1,94 @@ +From 18b08e5da621cc436ed1e49060a885aa41add368 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Sep 2022 07:54:46 +0000 +Subject: crypto: rockchip - better handle cipher key + +From: Corentin Labbe + +[ Upstream commit d6b23ccef82816050c2fd458c9dabfa0e0af09b9 ] + +The key should not be set in hardware too much in advance, this will +fail it 2 TFM with different keys generate alternative requests. +The key should be stored and used just before doing cipher operations. + +Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API") +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/rockchip/rk3288_crypto.h | 1 + + drivers/crypto/rockchip/rk3288_crypto_skcipher.c | 10 +++++++--- + 2 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h +index dfff0e2a83e4..665cc0bb2264 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -245,6 +245,7 @@ struct rk_ahash_rctx { + struct rk_cipher_ctx { + struct rk_crypto_info *dev; + unsigned int keylen; ++ u8 key[AES_MAX_KEY_SIZE]; + u8 iv[AES_BLOCK_SIZE]; + struct crypto_skcipher *fallback_tfm; + }; +diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +index eac5bba66e25..1ef94f8db2c5 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -95,7 +95,7 @@ static int rk_aes_setkey(struct crypto_skcipher *cipher, + keylen != AES_KEYSIZE_256) + return -EINVAL; + ctx->keylen = keylen; +- memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, key, keylen); ++ memcpy(ctx->key, key, keylen); + + return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); + } +@@ -111,7 +111,7 @@ static int rk_des_setkey(struct crypto_skcipher *cipher, + return err; + + ctx->keylen = keylen; +- memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen); ++ memcpy(ctx->key, key, keylen); + + return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); + } +@@ -127,7 +127,8 @@ static int rk_tdes_setkey(struct crypto_skcipher *cipher, + return err; + + ctx->keylen = keylen; +- memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen); ++ memcpy(ctx->key, key, keylen); ++ + return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen); + } + +@@ -283,6 +284,7 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev) + RK_CRYPTO_TDES_BYTESWAP_IV; + CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode); + memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize); ++ memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen); + conf_reg = RK_CRYPTO_DESSEL; + } else { + rctx->mode |= RK_CRYPTO_AES_FIFO_MODE | +@@ -295,6 +297,7 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev) + rctx->mode |= RK_CRYPTO_AES_256BIT_key; + CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode); + memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize); ++ memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen); + } + conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO | + RK_CRYPTO_BYTESWAP_BRFIFO; +@@ -484,6 +487,7 @@ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm) + { + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + ++ memzero_explicit(ctx->key, ctx->keylen); + free_page((unsigned long)ctx->dev->addr_vir); + crypto_free_skcipher(ctx->fallback_tfm); + } +-- +2.35.1 + diff --git a/queue-6.0/crypto-rockchip-do-not-do-custom-power-management.patch b/queue-6.0/crypto-rockchip-do-not-do-custom-power-management.patch new file mode 100644 index 00000000000..7cfc75b3f74 --- /dev/null +++ b/queue-6.0/crypto-rockchip-do-not-do-custom-power-management.patch @@ -0,0 +1,111 @@ +From 1ee3286890c3cc08acfe031db7864897ac478860 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Sep 2022 07:54:41 +0000 +Subject: crypto: rockchip - do not do custom power management + +From: Corentin Labbe + +[ Upstream commit c50ef1411c8cbad0c7db100c477126076b6e3348 ] + +The clock enable/disable at tfm init/exit is fragile, +if 2 tfm are init in the same time and one is removed just after, +it will leave the hardware uncloked even if a user remains. + +Instead simply enable clocks at probe time. +We will do PM later. + +Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API") +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/rockchip/rk3288_crypto.c | 4 ++-- + drivers/crypto/rockchip/rk3288_crypto.h | 2 -- + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 3 +-- + drivers/crypto/rockchip/rk3288_crypto_skcipher.c | 5 +++-- + 4 files changed, 6 insertions(+), 8 deletions(-) + +diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c +index 35d73061d156..5f8444b9633a 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -395,8 +395,7 @@ static int rk_crypto_probe(struct platform_device *pdev) + rk_crypto_done_task_cb, (unsigned long)crypto_info); + crypto_init_queue(&crypto_info->queue, 50); + +- crypto_info->enable_clk = rk_crypto_enable_clk; +- crypto_info->disable_clk = rk_crypto_disable_clk; ++ rk_crypto_enable_clk(crypto_info); + crypto_info->load_data = rk_load_data; + crypto_info->unload_data = rk_unload_data; + crypto_info->enqueue = rk_crypto_enqueue; +@@ -423,6 +422,7 @@ static int rk_crypto_remove(struct platform_device *pdev) + struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev); + + rk_crypto_unregister(); ++ rk_crypto_disable_clk(crypto_tmp); + tasklet_kill(&crypto_tmp->done_task); + tasklet_kill(&crypto_tmp->queue_task); + return 0; +diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h +index 97278c2574ff..2fa7131e4060 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -220,8 +220,6 @@ struct rk_crypto_info { + int (*start)(struct rk_crypto_info *dev); + int (*update)(struct rk_crypto_info *dev); + void (*complete)(struct crypto_async_request *base, int err); +- int (*enable_clk)(struct rk_crypto_info *dev); +- void (*disable_clk)(struct rk_crypto_info *dev); + int (*load_data)(struct rk_crypto_info *dev, + struct scatterlist *sg_src, + struct scatterlist *sg_dst); +diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +index ed03058497bc..49017d1fb510 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -301,7 +301,7 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm) + sizeof(struct rk_ahash_rctx) + + crypto_ahash_reqsize(tctx->fallback_tfm)); + +- return tctx->dev->enable_clk(tctx->dev); ++ return 0; + } + + static void rk_cra_hash_exit(struct crypto_tfm *tfm) +@@ -309,7 +309,6 @@ static void rk_cra_hash_exit(struct crypto_tfm *tfm) + struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm); + + free_page((unsigned long)tctx->dev->addr_vir); +- return tctx->dev->disable_clk(tctx->dev); + } + + struct rk_crypto_tmp rk_ahash_sha1 = { +diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +index 5bbf0d2722e1..8c44a19eab75 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -388,8 +388,10 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm) + ctx->dev->update = rk_ablk_rx; + ctx->dev->complete = rk_crypto_complete; + ctx->dev->addr_vir = (char *)__get_free_page(GFP_KERNEL); ++ if (!ctx->dev->addr_vir) ++ return -ENOMEM; + +- return ctx->dev->addr_vir ? ctx->dev->enable_clk(ctx->dev) : -ENOMEM; ++ return 0; + } + + static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm) +@@ -397,7 +399,6 @@ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm) + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + + free_page((unsigned long)ctx->dev->addr_vir); +- ctx->dev->disable_clk(ctx->dev); + } + + struct rk_crypto_tmp rk_ecb_aes_alg = { +-- +2.35.1 + diff --git a/queue-6.0/crypto-rockchip-do-not-store-mode-globally.patch b/queue-6.0/crypto-rockchip-do-not-store-mode-globally.patch new file mode 100644 index 00000000000..8f8734b6e91 --- /dev/null +++ b/queue-6.0/crypto-rockchip-do-not-store-mode-globally.patch @@ -0,0 +1,275 @@ +From c56e92134449c4c8dac79c7c072365e3d60544f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Sep 2022 07:54:43 +0000 +Subject: crypto: rockchip - do not store mode globally + +From: Corentin Labbe + +[ Upstream commit 87e356c4966444866186f68f05832fdcc0f351a3 ] + +Storing the mode globally does not work if 2 requests are handled in the +same time. +We should store it in a request context. + +Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API") +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/rockchip/rk3288_crypto.h | 5 +- + .../crypto/rockchip/rk3288_crypto_skcipher.c | 58 ++++++++++++------- + 2 files changed, 41 insertions(+), 22 deletions(-) + +diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h +index 2fa7131e4060..3e60e3dca1b5 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -245,10 +245,13 @@ struct rk_ahash_rctx { + struct rk_cipher_ctx { + struct rk_crypto_info *dev; + unsigned int keylen; +- u32 mode; + u8 iv[AES_BLOCK_SIZE]; + }; + ++struct rk_cipher_rctx { ++ u32 mode; ++}; ++ + enum alg_type { + ALG_TYPE_HASH, + ALG_TYPE_CIPHER, +diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +index 8c44a19eab75..bbd0bf52bf07 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -76,9 +76,10 @@ static int rk_aes_ecb_encrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_AES_ECB_MODE; ++ rctx->mode = RK_CRYPTO_AES_ECB_MODE; + return rk_handle_req(dev, req); + } + +@@ -86,9 +87,10 @@ static int rk_aes_ecb_decrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC; ++ rctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } + +@@ -96,9 +98,10 @@ static int rk_aes_cbc_encrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_AES_CBC_MODE; ++ rctx->mode = RK_CRYPTO_AES_CBC_MODE; + return rk_handle_req(dev, req); + } + +@@ -106,9 +109,10 @@ static int rk_aes_cbc_decrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC; ++ rctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } + +@@ -116,9 +120,10 @@ static int rk_des_ecb_encrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = 0; ++ rctx->mode = 0; + return rk_handle_req(dev, req); + } + +@@ -126,9 +131,10 @@ static int rk_des_ecb_decrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_DEC; ++ rctx->mode = RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } + +@@ -136,9 +142,10 @@ static int rk_des_cbc_encrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC; ++ rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC; + return rk_handle_req(dev, req); + } + +@@ -146,9 +153,10 @@ static int rk_des_cbc_decrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC; ++ rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } + +@@ -156,9 +164,10 @@ static int rk_des3_ede_ecb_encrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_SELECT; ++ rctx->mode = RK_CRYPTO_TDES_SELECT; + return rk_handle_req(dev, req); + } + +@@ -166,9 +175,10 @@ static int rk_des3_ede_ecb_decrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC; ++ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } + +@@ -176,9 +186,10 @@ static int rk_des3_ede_cbc_encrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC; ++ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC; + return rk_handle_req(dev, req); + } + +@@ -186,9 +197,10 @@ static int rk_des3_ede_cbc_decrypt(struct skcipher_request *req) + { + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_crypto_info *dev = ctx->dev; + +- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC | ++ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC | + RK_CRYPTO_DEC; + return rk_handle_req(dev, req); + } +@@ -199,6 +211,7 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev) + skcipher_request_cast(dev->async_req); + struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); + struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher); + u32 ivsize, block, conf_reg = 0; + +@@ -206,22 +219,22 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev) + ivsize = crypto_skcipher_ivsize(cipher); + + if (block == DES_BLOCK_SIZE) { +- ctx->mode |= RK_CRYPTO_TDES_FIFO_MODE | ++ rctx->mode |= RK_CRYPTO_TDES_FIFO_MODE | + RK_CRYPTO_TDES_BYTESWAP_KEY | + RK_CRYPTO_TDES_BYTESWAP_IV; +- CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, ctx->mode); ++ CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode); + memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize); + conf_reg = RK_CRYPTO_DESSEL; + } else { +- ctx->mode |= RK_CRYPTO_AES_FIFO_MODE | ++ rctx->mode |= RK_CRYPTO_AES_FIFO_MODE | + RK_CRYPTO_AES_KEY_CHANGE | + RK_CRYPTO_AES_BYTESWAP_KEY | + RK_CRYPTO_AES_BYTESWAP_IV; + if (ctx->keylen == AES_KEYSIZE_192) +- ctx->mode |= RK_CRYPTO_AES_192BIT_key; ++ rctx->mode |= RK_CRYPTO_AES_192BIT_key; + else if (ctx->keylen == AES_KEYSIZE_256) +- ctx->mode |= RK_CRYPTO_AES_256BIT_key; +- CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, ctx->mode); ++ rctx->mode |= RK_CRYPTO_AES_256BIT_key; ++ CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode); + memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize); + } + conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO | +@@ -246,6 +259,7 @@ static int rk_set_data_start(struct rk_crypto_info *dev) + struct skcipher_request *req = + skcipher_request_cast(dev->async_req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + u32 ivsize = crypto_skcipher_ivsize(tfm); + u8 *src_last_blk = page_address(sg_page(dev->sg_src)) + +@@ -254,7 +268,7 @@ static int rk_set_data_start(struct rk_crypto_info *dev) + /* Store the iv that need to be updated in chain mode. + * And update the IV buffer to contain the next IV for decryption mode. + */ +- if (ctx->mode & RK_CRYPTO_DEC) { ++ if (rctx->mode & RK_CRYPTO_DEC) { + memcpy(ctx->iv, src_last_blk, ivsize); + sg_pcopy_to_buffer(dev->first, dev->src_nents, req->iv, + ivsize, dev->total - ivsize); +@@ -294,11 +308,12 @@ static void rk_iv_copyback(struct rk_crypto_info *dev) + struct skcipher_request *req = + skcipher_request_cast(dev->async_req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + u32 ivsize = crypto_skcipher_ivsize(tfm); + + /* Update the IV buffer to contain the next IV for encryption mode. */ +- if (!(ctx->mode & RK_CRYPTO_DEC)) { ++ if (!(rctx->mode & RK_CRYPTO_DEC)) { + if (dev->aligned) { + memcpy(req->iv, sg_virt(dev->sg_dst) + + dev->sg_dst->length - ivsize, ivsize); +@@ -314,11 +329,12 @@ static void rk_update_iv(struct rk_crypto_info *dev) + struct skcipher_request *req = + skcipher_request_cast(dev->async_req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + u32 ivsize = crypto_skcipher_ivsize(tfm); + u8 *new_iv = NULL; + +- if (ctx->mode & RK_CRYPTO_DEC) { ++ if (rctx->mode & RK_CRYPTO_DEC) { + new_iv = ctx->iv; + } else { + new_iv = page_address(sg_page(dev->sg_dst)) + +-- +2.35.1 + diff --git a/queue-6.0/crypto-rockchip-remove-non-aligned-handling.patch b/queue-6.0/crypto-rockchip-remove-non-aligned-handling.patch new file mode 100644 index 00000000000..9ee4e3eae73 --- /dev/null +++ b/queue-6.0/crypto-rockchip-remove-non-aligned-handling.patch @@ -0,0 +1,280 @@ +From d35120c86007bd2d03f0ade37bb53161bc8ce15f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Sep 2022 07:54:47 +0000 +Subject: crypto: rockchip - remove non-aligned handling + +From: Corentin Labbe + +[ Upstream commit bb3c7b73363c9a149b12b74c44ae94b73a8fddf8 ] + +Now driver have fallback for un-aligned cases, remove all code handling +those cases. + +Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API") +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/rockchip/rk3288_crypto.c | 69 +++++-------------- + drivers/crypto/rockchip/rk3288_crypto.h | 4 -- + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 22 ++---- + .../crypto/rockchip/rk3288_crypto_skcipher.c | 39 +++-------- + 4 files changed, 31 insertions(+), 103 deletions(-) + +diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c +index 5f8444b9633a..31453257ab11 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -88,63 +88,26 @@ static int rk_load_data(struct rk_crypto_info *dev, + { + unsigned int count; + +- dev->aligned = dev->aligned ? +- check_alignment(sg_src, sg_dst, dev->align_size) : +- dev->aligned; +- if (dev->aligned) { +- count = min(dev->left_bytes, sg_src->length); +- dev->left_bytes -= count; +- +- if (!dma_map_sg(dev->dev, sg_src, 1, DMA_TO_DEVICE)) { +- dev_err(dev->dev, "[%s:%d] dma_map_sg(src) error\n", ++ count = min(dev->left_bytes, sg_src->length); ++ dev->left_bytes -= count; ++ ++ if (!dma_map_sg(dev->dev, sg_src, 1, DMA_TO_DEVICE)) { ++ dev_err(dev->dev, "[%s:%d] dma_map_sg(src) error\n", + __func__, __LINE__); +- return -EINVAL; +- } +- dev->addr_in = sg_dma_address(sg_src); ++ return -EINVAL; ++ } ++ dev->addr_in = sg_dma_address(sg_src); + +- if (sg_dst) { +- if (!dma_map_sg(dev->dev, sg_dst, 1, DMA_FROM_DEVICE)) { +- dev_err(dev->dev, ++ if (sg_dst) { ++ if (!dma_map_sg(dev->dev, sg_dst, 1, DMA_FROM_DEVICE)) { ++ dev_err(dev->dev, + "[%s:%d] dma_map_sg(dst) error\n", + __func__, __LINE__); +- dma_unmap_sg(dev->dev, sg_src, 1, +- DMA_TO_DEVICE); +- return -EINVAL; +- } +- dev->addr_out = sg_dma_address(sg_dst); +- } +- } else { +- count = (dev->left_bytes > PAGE_SIZE) ? +- PAGE_SIZE : dev->left_bytes; +- +- if (!sg_pcopy_to_buffer(dev->first, dev->src_nents, +- dev->addr_vir, count, +- dev->total - dev->left_bytes)) { +- dev_err(dev->dev, "[%s:%d] pcopy err\n", +- __func__, __LINE__); ++ dma_unmap_sg(dev->dev, sg_src, 1, ++ DMA_TO_DEVICE); + return -EINVAL; + } +- dev->left_bytes -= count; +- sg_init_one(&dev->sg_tmp, dev->addr_vir, count); +- if (!dma_map_sg(dev->dev, &dev->sg_tmp, 1, DMA_TO_DEVICE)) { +- dev_err(dev->dev, "[%s:%d] dma_map_sg(sg_tmp) error\n", +- __func__, __LINE__); +- return -ENOMEM; +- } +- dev->addr_in = sg_dma_address(&dev->sg_tmp); +- +- if (sg_dst) { +- if (!dma_map_sg(dev->dev, &dev->sg_tmp, 1, +- DMA_FROM_DEVICE)) { +- dev_err(dev->dev, +- "[%s:%d] dma_map_sg(sg_tmp) error\n", +- __func__, __LINE__); +- dma_unmap_sg(dev->dev, &dev->sg_tmp, 1, +- DMA_TO_DEVICE); +- return -ENOMEM; +- } +- dev->addr_out = sg_dma_address(&dev->sg_tmp); +- } ++ dev->addr_out = sg_dma_address(sg_dst); + } + dev->count = count; + return 0; +@@ -154,11 +117,11 @@ static void rk_unload_data(struct rk_crypto_info *dev) + { + struct scatterlist *sg_in, *sg_out; + +- sg_in = dev->aligned ? dev->sg_src : &dev->sg_tmp; ++ sg_in = dev->sg_src; + dma_unmap_sg(dev->dev, sg_in, 1, DMA_TO_DEVICE); + + if (dev->sg_dst) { +- sg_out = dev->aligned ? dev->sg_dst : &dev->sg_tmp; ++ sg_out = dev->sg_dst; + dma_unmap_sg(dev->dev, sg_out, 1, DMA_FROM_DEVICE); + } + } +diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h +index 665cc0bb2264..df4db59fa13e 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -204,12 +204,8 @@ struct rk_crypto_info { + /* the public variable */ + struct scatterlist *sg_src; + struct scatterlist *sg_dst; +- struct scatterlist sg_tmp; + struct scatterlist *first; + unsigned int left_bytes; +- void *addr_vir; +- int aligned; +- int align_size; + size_t src_nents; + size_t dst_nents; + unsigned int total; +diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +index 16009bb0bf16..c762e462eb57 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -236,8 +236,6 @@ static int rk_ahash_start(struct rk_crypto_info *dev) + + dev->total = req->nbytes; + dev->left_bytes = req->nbytes; +- dev->aligned = 0; +- dev->align_size = 4; + dev->sg_dst = NULL; + dev->sg_src = req->src; + dev->first = req->src; +@@ -272,15 +270,13 @@ static int rk_ahash_crypto_rx(struct rk_crypto_info *dev) + + dev->unload_data(dev); + if (dev->left_bytes) { +- if (dev->aligned) { +- if (sg_is_last(dev->sg_src)) { +- dev_warn(dev->dev, "[%s:%d], Lack of data\n", +- __func__, __LINE__); +- err = -ENOMEM; +- goto out_rx; +- } +- dev->sg_src = sg_next(dev->sg_src); ++ if (sg_is_last(dev->sg_src)) { ++ dev_warn(dev->dev, "[%s:%d], Lack of data\n", ++ __func__, __LINE__); ++ err = -ENOMEM; ++ goto out_rx; + } ++ dev->sg_src = sg_next(dev->sg_src); + err = rk_ahash_set_data_start(dev); + } else { + /* +@@ -318,11 +314,6 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm) + algt = container_of(alg, struct rk_crypto_tmp, alg.hash); + + tctx->dev = algt->dev; +- tctx->dev->addr_vir = (void *)__get_free_page(GFP_KERNEL); +- if (!tctx->dev->addr_vir) { +- dev_err(tctx->dev->dev, "failed to kmalloc for addr_vir\n"); +- return -ENOMEM; +- } + tctx->dev->start = rk_ahash_start; + tctx->dev->update = rk_ahash_crypto_rx; + tctx->dev->complete = rk_ahash_crypto_complete; +@@ -345,7 +336,6 @@ static void rk_cra_hash_exit(struct crypto_tfm *tfm) + { + struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm); + +- free_page((unsigned long)tctx->dev->addr_vir); + crypto_free_ahash(tctx->fallback_tfm); + } + +diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +index 1ef94f8db2c5..d067b7f09165 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -356,7 +356,6 @@ static int rk_ablk_start(struct rk_crypto_info *dev) + dev->src_nents = sg_nents(req->src); + dev->sg_dst = req->dst; + dev->dst_nents = sg_nents(req->dst); +- dev->aligned = 1; + + spin_lock_irqsave(&dev->lock, flags); + rk_ablk_hw_init(dev); +@@ -376,13 +375,9 @@ static void rk_iv_copyback(struct rk_crypto_info *dev) + + /* Update the IV buffer to contain the next IV for encryption mode. */ + if (!(rctx->mode & RK_CRYPTO_DEC)) { +- if (dev->aligned) { +- memcpy(req->iv, sg_virt(dev->sg_dst) + +- dev->sg_dst->length - ivsize, ivsize); +- } else { +- memcpy(req->iv, dev->addr_vir + +- dev->count - ivsize, ivsize); +- } ++ memcpy(req->iv, ++ sg_virt(dev->sg_dst) + dev->sg_dst->length - ivsize, ++ ivsize); + } + } + +@@ -420,27 +415,16 @@ static int rk_ablk_rx(struct rk_crypto_info *dev) + skcipher_request_cast(dev->async_req); + + dev->unload_data(dev); +- if (!dev->aligned) { +- if (!sg_pcopy_from_buffer(req->dst, dev->dst_nents, +- dev->addr_vir, dev->count, +- dev->total - dev->left_bytes - +- dev->count)) { +- err = -EINVAL; +- goto out_rx; +- } +- } + if (dev->left_bytes) { + rk_update_iv(dev); +- if (dev->aligned) { +- if (sg_is_last(dev->sg_src)) { +- dev_err(dev->dev, "[%s:%d] Lack of data\n", ++ if (sg_is_last(dev->sg_src)) { ++ dev_err(dev->dev, "[%s:%d] Lack of data\n", + __func__, __LINE__); +- err = -ENOMEM; +- goto out_rx; +- } +- dev->sg_src = sg_next(dev->sg_src); +- dev->sg_dst = sg_next(dev->sg_dst); ++ err = -ENOMEM; ++ goto out_rx; + } ++ dev->sg_src = sg_next(dev->sg_src); ++ dev->sg_dst = sg_next(dev->sg_dst); + err = rk_set_data_start(dev); + } else { + rk_iv_copyback(dev); +@@ -462,13 +446,9 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm) + algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); + + ctx->dev = algt->dev; +- ctx->dev->align_size = crypto_tfm_alg_alignmask(crypto_skcipher_tfm(tfm)) + 1; + ctx->dev->start = rk_ablk_start; + ctx->dev->update = rk_ablk_rx; + ctx->dev->complete = rk_crypto_complete; +- ctx->dev->addr_vir = (char *)__get_free_page(GFP_KERNEL); +- if (!ctx->dev->addr_vir) +- return -ENOMEM; + + ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(ctx->fallback_tfm)) { +@@ -488,7 +468,6 @@ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm) + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); + + memzero_explicit(ctx->key, ctx->keylen); +- free_page((unsigned long)ctx->dev->addr_vir); + crypto_free_skcipher(ctx->fallback_tfm); + } + +-- +2.35.1 + diff --git a/queue-6.0/crypto-rockchip-rework-by-using-crypto_engine.patch b/queue-6.0/crypto-rockchip-rework-by-using-crypto_engine.patch new file mode 100644 index 00000000000..8c0238295af --- /dev/null +++ b/queue-6.0/crypto-rockchip-rework-by-using-crypto_engine.patch @@ -0,0 +1,902 @@ +From 79bc0fbc0d8bd96bf9bf2558ef2dfd9d5e273ca0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Sep 2022 07:54:48 +0000 +Subject: crypto: rockchip - rework by using crypto_engine + +From: Corentin Labbe + +[ Upstream commit 57d67c6e8219b2a034c16d6149e30fb40fd39935 ] + +Instead of doing manual queue management, let's use the crypto/engine +for that. +In the same time, rework the requests handling to be easier to +understand (and fix all bugs related to them). + +Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API") +Reviewed-by: John Keeping +Signed-off-by: Corentin Labbe +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/Kconfig | 1 + + drivers/crypto/rockchip/rk3288_crypto.c | 152 +---------- + drivers/crypto/rockchip/rk3288_crypto.h | 39 +-- + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 144 +++++----- + .../crypto/rockchip/rk3288_crypto_skcipher.c | 250 +++++++++--------- + 5 files changed, 221 insertions(+), 365 deletions(-) + +diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig +index 3080bd3d8cbb..79d9e14b70c8 100644 +--- a/drivers/crypto/Kconfig ++++ b/drivers/crypto/Kconfig +@@ -674,6 +674,7 @@ config CRYPTO_DEV_ROCKCHIP + select CRYPTO_CBC + select CRYPTO_DES + select CRYPTO_AES ++ select CRYPTO_ENGINE + select CRYPTO_LIB_DES + select CRYPTO_MD5 + select CRYPTO_SHA1 +diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c +index 31453257ab11..14a0aef18ab1 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto.c ++++ b/drivers/crypto/rockchip/rk3288_crypto.c +@@ -65,149 +65,24 @@ static void rk_crypto_disable_clk(struct rk_crypto_info *dev) + clk_disable_unprepare(dev->sclk); + } + +-static int check_alignment(struct scatterlist *sg_src, +- struct scatterlist *sg_dst, +- int align_mask) +-{ +- int in, out, align; +- +- in = IS_ALIGNED((uint32_t)sg_src->offset, 4) && +- IS_ALIGNED((uint32_t)sg_src->length, align_mask); +- if (!sg_dst) +- return in; +- out = IS_ALIGNED((uint32_t)sg_dst->offset, 4) && +- IS_ALIGNED((uint32_t)sg_dst->length, align_mask); +- align = in && out; +- +- return (align && (sg_src->length == sg_dst->length)); +-} +- +-static int rk_load_data(struct rk_crypto_info *dev, +- struct scatterlist *sg_src, +- struct scatterlist *sg_dst) +-{ +- unsigned int count; +- +- count = min(dev->left_bytes, sg_src->length); +- dev->left_bytes -= count; +- +- if (!dma_map_sg(dev->dev, sg_src, 1, DMA_TO_DEVICE)) { +- dev_err(dev->dev, "[%s:%d] dma_map_sg(src) error\n", +- __func__, __LINE__); +- return -EINVAL; +- } +- dev->addr_in = sg_dma_address(sg_src); +- +- if (sg_dst) { +- if (!dma_map_sg(dev->dev, sg_dst, 1, DMA_FROM_DEVICE)) { +- dev_err(dev->dev, +- "[%s:%d] dma_map_sg(dst) error\n", +- __func__, __LINE__); +- dma_unmap_sg(dev->dev, sg_src, 1, +- DMA_TO_DEVICE); +- return -EINVAL; +- } +- dev->addr_out = sg_dma_address(sg_dst); +- } +- dev->count = count; +- return 0; +-} +- +-static void rk_unload_data(struct rk_crypto_info *dev) +-{ +- struct scatterlist *sg_in, *sg_out; +- +- sg_in = dev->sg_src; +- dma_unmap_sg(dev->dev, sg_in, 1, DMA_TO_DEVICE); +- +- if (dev->sg_dst) { +- sg_out = dev->sg_dst; +- dma_unmap_sg(dev->dev, sg_out, 1, DMA_FROM_DEVICE); +- } +-} +- + static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) + { + struct rk_crypto_info *dev = platform_get_drvdata(dev_id); + u32 interrupt_status; + +- spin_lock(&dev->lock); + interrupt_status = CRYPTO_READ(dev, RK_CRYPTO_INTSTS); + CRYPTO_WRITE(dev, RK_CRYPTO_INTSTS, interrupt_status); + ++ dev->status = 1; + if (interrupt_status & 0x0a) { + dev_warn(dev->dev, "DMA Error\n"); +- dev->err = -EFAULT; ++ dev->status = 0; + } +- tasklet_schedule(&dev->done_task); ++ complete(&dev->complete); + +- spin_unlock(&dev->lock); + return IRQ_HANDLED; + } + +-static int rk_crypto_enqueue(struct rk_crypto_info *dev, +- struct crypto_async_request *async_req) +-{ +- unsigned long flags; +- int ret; +- +- spin_lock_irqsave(&dev->lock, flags); +- ret = crypto_enqueue_request(&dev->queue, async_req); +- if (dev->busy) { +- spin_unlock_irqrestore(&dev->lock, flags); +- return ret; +- } +- dev->busy = true; +- spin_unlock_irqrestore(&dev->lock, flags); +- tasklet_schedule(&dev->queue_task); +- +- return ret; +-} +- +-static void rk_crypto_queue_task_cb(unsigned long data) +-{ +- struct rk_crypto_info *dev = (struct rk_crypto_info *)data; +- struct crypto_async_request *async_req, *backlog; +- unsigned long flags; +- int err = 0; +- +- dev->err = 0; +- spin_lock_irqsave(&dev->lock, flags); +- backlog = crypto_get_backlog(&dev->queue); +- async_req = crypto_dequeue_request(&dev->queue); +- +- if (!async_req) { +- dev->busy = false; +- spin_unlock_irqrestore(&dev->lock, flags); +- return; +- } +- spin_unlock_irqrestore(&dev->lock, flags); +- +- if (backlog) { +- backlog->complete(backlog, -EINPROGRESS); +- backlog = NULL; +- } +- +- dev->async_req = async_req; +- err = dev->start(dev); +- if (err) +- dev->complete(dev->async_req, err); +-} +- +-static void rk_crypto_done_task_cb(unsigned long data) +-{ +- struct rk_crypto_info *dev = (struct rk_crypto_info *)data; +- +- if (dev->err) { +- dev->complete(dev->async_req, dev->err); +- return; +- } +- +- dev->err = dev->update(dev); +- if (dev->err) +- dev->complete(dev->async_req, dev->err); +-} +- + static struct rk_crypto_tmp *rk_cipher_algs[] = { + &rk_ecb_aes_alg, + &rk_cbc_aes_alg, +@@ -300,8 +175,6 @@ static int rk_crypto_probe(struct platform_device *pdev) + if (err) + goto err_crypto; + +- spin_lock_init(&crypto_info->lock); +- + crypto_info->reg = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(crypto_info->reg)) { + err = PTR_ERR(crypto_info->reg); +@@ -352,17 +225,11 @@ static int rk_crypto_probe(struct platform_device *pdev) + crypto_info->dev = &pdev->dev; + platform_set_drvdata(pdev, crypto_info); + +- tasklet_init(&crypto_info->queue_task, +- rk_crypto_queue_task_cb, (unsigned long)crypto_info); +- tasklet_init(&crypto_info->done_task, +- rk_crypto_done_task_cb, (unsigned long)crypto_info); +- crypto_init_queue(&crypto_info->queue, 50); ++ crypto_info->engine = crypto_engine_alloc_init(&pdev->dev, true); ++ crypto_engine_start(crypto_info->engine); ++ init_completion(&crypto_info->complete); + + rk_crypto_enable_clk(crypto_info); +- crypto_info->load_data = rk_load_data; +- crypto_info->unload_data = rk_unload_data; +- crypto_info->enqueue = rk_crypto_enqueue; +- crypto_info->busy = false; + + err = rk_crypto_register(crypto_info); + if (err) { +@@ -374,9 +241,9 @@ static int rk_crypto_probe(struct platform_device *pdev) + return 0; + + err_register_alg: +- tasklet_kill(&crypto_info->queue_task); +- tasklet_kill(&crypto_info->done_task); ++ crypto_engine_exit(crypto_info->engine); + err_crypto: ++ dev_err(dev, "Crypto Accelerator not successfully registered\n"); + return err; + } + +@@ -386,8 +253,7 @@ static int rk_crypto_remove(struct platform_device *pdev) + + rk_crypto_unregister(); + rk_crypto_disable_clk(crypto_tmp); +- tasklet_kill(&crypto_tmp->done_task); +- tasklet_kill(&crypto_tmp->queue_task); ++ crypto_engine_exit(crypto_tmp->engine); + return 0; + } + +diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h +index df4db59fa13e..045e811b4af8 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto.h ++++ b/drivers/crypto/rockchip/rk3288_crypto.h +@@ -5,9 +5,11 @@ + #include + #include + #include ++#include + #include + #include + #include ++#include + #include + #include + +@@ -193,39 +195,15 @@ struct rk_crypto_info { + struct reset_control *rst; + void __iomem *reg; + int irq; +- struct crypto_queue queue; +- struct tasklet_struct queue_task; +- struct tasklet_struct done_task; +- struct crypto_async_request *async_req; +- int err; +- /* device lock */ +- spinlock_t lock; +- +- /* the public variable */ +- struct scatterlist *sg_src; +- struct scatterlist *sg_dst; +- struct scatterlist *first; +- unsigned int left_bytes; +- size_t src_nents; +- size_t dst_nents; +- unsigned int total; +- unsigned int count; +- dma_addr_t addr_in; +- dma_addr_t addr_out; +- bool busy; +- int (*start)(struct rk_crypto_info *dev); +- int (*update)(struct rk_crypto_info *dev); +- void (*complete)(struct crypto_async_request *base, int err); +- int (*load_data)(struct rk_crypto_info *dev, +- struct scatterlist *sg_src, +- struct scatterlist *sg_dst); +- void (*unload_data)(struct rk_crypto_info *dev); +- int (*enqueue)(struct rk_crypto_info *dev, +- struct crypto_async_request *async_req); ++ ++ struct crypto_engine *engine; ++ struct completion complete; ++ int status; + }; + + /* the private variable of hash */ + struct rk_ahash_ctx { ++ struct crypto_engine_ctx enginectx; + struct rk_crypto_info *dev; + /* for fallback */ + struct crypto_ahash *fallback_tfm; +@@ -235,10 +213,12 @@ struct rk_ahash_ctx { + struct rk_ahash_rctx { + struct ahash_request fallback_req; + u32 mode; ++ int nrsg; + }; + + /* the private variable of cipher */ + struct rk_cipher_ctx { ++ struct crypto_engine_ctx enginectx; + struct rk_crypto_info *dev; + unsigned int keylen; + u8 key[AES_MAX_KEY_SIZE]; +@@ -247,6 +227,7 @@ struct rk_cipher_ctx { + }; + + struct rk_cipher_rctx { ++ u8 backup_iv[AES_BLOCK_SIZE]; + u32 mode; + struct skcipher_request fallback_req; // keep at the end + }; +diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +index c762e462eb57..edd40e16a3f0 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -9,6 +9,7 @@ + * Some ideas are from marvell/cesa.c and s5p-sss.c driver. + */ + #include ++#include + #include "rk3288_crypto.h" + + /* +@@ -72,16 +73,12 @@ static int zero_message_process(struct ahash_request *req) + return 0; + } + +-static void rk_ahash_crypto_complete(struct crypto_async_request *base, int err) ++static void rk_ahash_reg_init(struct ahash_request *req) + { +- if (base->complete) +- base->complete(base, err); +-} +- +-static void rk_ahash_reg_init(struct rk_crypto_info *dev) +-{ +- struct ahash_request *req = ahash_request_cast(dev->async_req); + struct rk_ahash_rctx *rctx = ahash_request_ctx(req); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); ++ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); ++ struct rk_crypto_info *dev = tctx->dev; + int reg_status; + + reg_status = CRYPTO_READ(dev, RK_CRYPTO_CTRL) | +@@ -108,7 +105,7 @@ static void rk_ahash_reg_init(struct rk_crypto_info *dev) + RK_CRYPTO_BYTESWAP_BRFIFO | + RK_CRYPTO_BYTESWAP_BTFIFO); + +- CRYPTO_WRITE(dev, RK_CRYPTO_HASH_MSG_LEN, dev->total); ++ CRYPTO_WRITE(dev, RK_CRYPTO_HASH_MSG_LEN, req->nbytes); + } + + static int rk_ahash_init(struct ahash_request *req) +@@ -206,44 +203,59 @@ static int rk_ahash_digest(struct ahash_request *req) + + if (!req->nbytes) + return zero_message_process(req); +- else +- return dev->enqueue(dev, &req->base); ++ ++ return crypto_transfer_hash_request_to_engine(dev->engine, req); + } + +-static void crypto_ahash_dma_start(struct rk_crypto_info *dev) ++static void crypto_ahash_dma_start(struct rk_crypto_info *dev, struct scatterlist *sg) + { +- CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAS, dev->addr_in); +- CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAL, (dev->count + 3) / 4); ++ CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAS, sg_dma_address(sg)); ++ CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAL, sg_dma_len(sg) / 4); + CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_HASH_START | + (RK_CRYPTO_HASH_START << 16)); + } + +-static int rk_ahash_set_data_start(struct rk_crypto_info *dev) ++static int rk_hash_prepare(struct crypto_engine *engine, void *breq) ++{ ++ struct ahash_request *areq = container_of(breq, struct ahash_request, base); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); ++ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); ++ int ret; ++ ++ ret = dma_map_sg(tctx->dev->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE); ++ if (ret <= 0) ++ return -EINVAL; ++ ++ rctx->nrsg = ret; ++ ++ return 0; ++} ++ ++static int rk_hash_unprepare(struct crypto_engine *engine, void *breq) + { +- int err; ++ struct ahash_request *areq = container_of(breq, struct ahash_request, base); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); ++ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); + +- err = dev->load_data(dev, dev->sg_src, NULL); +- if (!err) +- crypto_ahash_dma_start(dev); +- return err; ++ dma_unmap_sg(tctx->dev->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE); ++ return 0; + } + +-static int rk_ahash_start(struct rk_crypto_info *dev) ++static int rk_hash_run(struct crypto_engine *engine, void *breq) + { +- struct ahash_request *req = ahash_request_cast(dev->async_req); +- struct crypto_ahash *tfm; +- struct rk_ahash_rctx *rctx; +- +- dev->total = req->nbytes; +- dev->left_bytes = req->nbytes; +- dev->sg_dst = NULL; +- dev->sg_src = req->src; +- dev->first = req->src; +- dev->src_nents = sg_nents(req->src); +- rctx = ahash_request_ctx(req); ++ struct ahash_request *areq = container_of(breq, struct ahash_request, base); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); ++ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); ++ struct scatterlist *sg = areq->src; ++ int err = 0; ++ int i; ++ u32 v; ++ + rctx->mode = 0; + +- tfm = crypto_ahash_reqtfm(req); + switch (crypto_ahash_digestsize(tfm)) { + case SHA1_DIGEST_SIZE: + rctx->mode = RK_CRYPTO_HASH_SHA1; +@@ -255,30 +267,26 @@ static int rk_ahash_start(struct rk_crypto_info *dev) + rctx->mode = RK_CRYPTO_HASH_MD5; + break; + default: +- return -EINVAL; ++ err = -EINVAL; ++ goto theend; + } + +- rk_ahash_reg_init(dev); +- return rk_ahash_set_data_start(dev); +-} ++ rk_ahash_reg_init(areq); + +-static int rk_ahash_crypto_rx(struct rk_crypto_info *dev) +-{ +- int err = 0; +- struct ahash_request *req = ahash_request_cast(dev->async_req); +- struct crypto_ahash *tfm; +- +- dev->unload_data(dev); +- if (dev->left_bytes) { +- if (sg_is_last(dev->sg_src)) { +- dev_warn(dev->dev, "[%s:%d], Lack of data\n", +- __func__, __LINE__); +- err = -ENOMEM; +- goto out_rx; ++ while (sg) { ++ reinit_completion(&tctx->dev->complete); ++ tctx->dev->status = 0; ++ crypto_ahash_dma_start(tctx->dev, sg); ++ wait_for_completion_interruptible_timeout(&tctx->dev->complete, ++ msecs_to_jiffies(2000)); ++ if (!tctx->dev->status) { ++ dev_err(tctx->dev->dev, "DMA timeout\n"); ++ err = -EFAULT; ++ goto theend; + } +- dev->sg_src = sg_next(dev->sg_src); +- err = rk_ahash_set_data_start(dev); +- } else { ++ sg = sg_next(sg); ++ } ++ + /* + * it will take some time to process date after last dma + * transmission. +@@ -289,18 +297,20 @@ static int rk_ahash_crypto_rx(struct rk_crypto_info *dev) + * efficiency, and make it response quickly when dma + * complete. + */ +- while (!CRYPTO_READ(dev, RK_CRYPTO_HASH_STS)) +- udelay(10); +- +- tfm = crypto_ahash_reqtfm(req); +- memcpy_fromio(req->result, dev->reg + RK_CRYPTO_HASH_DOUT_0, +- crypto_ahash_digestsize(tfm)); +- dev->complete(dev->async_req, 0); +- tasklet_schedule(&dev->queue_task); ++ while (!CRYPTO_READ(tctx->dev, RK_CRYPTO_HASH_STS)) ++ udelay(10); ++ ++ for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++) { ++ v = readl(tctx->dev->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4); ++ put_unaligned_le32(v, areq->result + i * 4); + } + +-out_rx: +- return err; ++theend: ++ local_bh_disable(); ++ crypto_finalize_hash_request(engine, breq, err); ++ local_bh_enable(); ++ ++ return 0; + } + + static int rk_cra_hash_init(struct crypto_tfm *tfm) +@@ -314,9 +324,6 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm) + algt = container_of(alg, struct rk_crypto_tmp, alg.hash); + + tctx->dev = algt->dev; +- tctx->dev->start = rk_ahash_start; +- tctx->dev->update = rk_ahash_crypto_rx; +- tctx->dev->complete = rk_ahash_crypto_complete; + + /* for fallback */ + tctx->fallback_tfm = crypto_alloc_ahash(alg_name, 0, +@@ -325,10 +332,15 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm) + dev_err(tctx->dev->dev, "Could not load fallback driver.\n"); + return PTR_ERR(tctx->fallback_tfm); + } ++ + crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), + sizeof(struct rk_ahash_rctx) + + crypto_ahash_reqsize(tctx->fallback_tfm)); + ++ tctx->enginectx.op.do_one_request = rk_hash_run; ++ tctx->enginectx.op.prepare_request = rk_hash_prepare; ++ tctx->enginectx.op.unprepare_request = rk_hash_unprepare; ++ + return 0; + } + +diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +index d067b7f09165..67a7e05d5ae3 100644 +--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c +@@ -9,6 +9,7 @@ + * Some ideas are from marvell-cesa.c and s5p-sss.c driver. + */ + #include ++#include + #include "rk3288_crypto.h" + + #define RK_CRYPTO_DEC BIT(0) +@@ -70,19 +71,15 @@ static int rk_cipher_fallback(struct skcipher_request *areq) + return err; + } + +-static void rk_crypto_complete(struct crypto_async_request *base, int err) +-{ +- if (base->complete) +- base->complete(base, err); +-} +- + static int rk_handle_req(struct rk_crypto_info *dev, + struct skcipher_request *req) + { ++ struct crypto_engine *engine = dev->engine; ++ + if (rk_cipher_need_fallback(req)) + return rk_cipher_fallback(req); + +- return dev->enqueue(dev, &req->base); ++ return crypto_transfer_skcipher_request_to_engine(engine, req); + } + + static int rk_aes_setkey(struct crypto_skcipher *cipher, +@@ -265,25 +262,21 @@ static int rk_des3_ede_cbc_decrypt(struct skcipher_request *req) + return rk_handle_req(dev, req); + } + +-static void rk_ablk_hw_init(struct rk_crypto_info *dev) ++static void rk_ablk_hw_init(struct rk_crypto_info *dev, struct skcipher_request *req) + { +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); + struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req); + struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher); + struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher); +- u32 ivsize, block, conf_reg = 0; ++ u32 block, conf_reg = 0; + + block = crypto_tfm_alg_blocksize(tfm); +- ivsize = crypto_skcipher_ivsize(cipher); + + if (block == DES_BLOCK_SIZE) { + rctx->mode |= RK_CRYPTO_TDES_FIFO_MODE | + RK_CRYPTO_TDES_BYTESWAP_KEY | + RK_CRYPTO_TDES_BYTESWAP_IV; + CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode); +- memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize); + memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen); + conf_reg = RK_CRYPTO_DESSEL; + } else { +@@ -296,7 +289,6 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev) + else if (ctx->keylen == AES_KEYSIZE_256) + rctx->mode |= RK_CRYPTO_AES_256BIT_key; + CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode); +- memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize); + memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen); + } + conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO | +@@ -306,133 +298,138 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev) + RK_CRYPTO_BCDMA_ERR_ENA | RK_CRYPTO_BCDMA_DONE_ENA); + } + +-static void crypto_dma_start(struct rk_crypto_info *dev) ++static void crypto_dma_start(struct rk_crypto_info *dev, ++ struct scatterlist *sgs, ++ struct scatterlist *sgd, unsigned int todo) + { +- CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAS, dev->addr_in); +- CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAL, dev->count / 4); +- CRYPTO_WRITE(dev, RK_CRYPTO_BTDMAS, dev->addr_out); ++ CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAS, sg_dma_address(sgs)); ++ CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAL, todo); ++ CRYPTO_WRITE(dev, RK_CRYPTO_BTDMAS, sg_dma_address(sgd)); + CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_BLOCK_START | + _SBF(RK_CRYPTO_BLOCK_START, 16)); + } + +-static int rk_set_data_start(struct rk_crypto_info *dev) ++static int rk_cipher_run(struct crypto_engine *engine, void *async_req) + { +- int err; +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); ++ struct skcipher_request *areq = container_of(async_req, struct skcipher_request, base); ++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq); + struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); +- u32 ivsize = crypto_skcipher_ivsize(tfm); +- u8 *src_last_blk = page_address(sg_page(dev->sg_src)) + +- dev->sg_src->offset + dev->sg_src->length - ivsize; +- +- /* Store the iv that need to be updated in chain mode. +- * And update the IV buffer to contain the next IV for decryption mode. +- */ +- if (rctx->mode & RK_CRYPTO_DEC) { +- memcpy(ctx->iv, src_last_blk, ivsize); +- sg_pcopy_to_buffer(dev->first, dev->src_nents, req->iv, +- ivsize, dev->total - ivsize); +- } +- +- err = dev->load_data(dev, dev->sg_src, dev->sg_dst); +- if (!err) +- crypto_dma_start(dev); +- return err; +-} +- +-static int rk_ablk_start(struct rk_crypto_info *dev) +-{ +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); +- unsigned long flags; ++ struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq); ++ struct scatterlist *sgs, *sgd; + int err = 0; ++ int ivsize = crypto_skcipher_ivsize(tfm); ++ int offset; ++ u8 iv[AES_BLOCK_SIZE]; ++ u8 biv[AES_BLOCK_SIZE]; ++ u8 *ivtouse = areq->iv; ++ unsigned int len = areq->cryptlen; ++ unsigned int todo; ++ ++ ivsize = crypto_skcipher_ivsize(tfm); ++ if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) { ++ if (rctx->mode & RK_CRYPTO_DEC) { ++ offset = areq->cryptlen - ivsize; ++ scatterwalk_map_and_copy(rctx->backup_iv, areq->src, ++ offset, ivsize, 0); ++ } ++ } + +- dev->left_bytes = req->cryptlen; +- dev->total = req->cryptlen; +- dev->sg_src = req->src; +- dev->first = req->src; +- dev->src_nents = sg_nents(req->src); +- dev->sg_dst = req->dst; +- dev->dst_nents = sg_nents(req->dst); +- +- spin_lock_irqsave(&dev->lock, flags); +- rk_ablk_hw_init(dev); +- err = rk_set_data_start(dev); +- spin_unlock_irqrestore(&dev->lock, flags); +- return err; +-} +- +-static void rk_iv_copyback(struct rk_crypto_info *dev) +-{ +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); +- u32 ivsize = crypto_skcipher_ivsize(tfm); ++ sgs = areq->src; ++ sgd = areq->dst; + +- /* Update the IV buffer to contain the next IV for encryption mode. */ +- if (!(rctx->mode & RK_CRYPTO_DEC)) { +- memcpy(req->iv, +- sg_virt(dev->sg_dst) + dev->sg_dst->length - ivsize, +- ivsize); ++ while (sgs && sgd && len) { ++ if (!sgs->length) { ++ sgs = sg_next(sgs); ++ sgd = sg_next(sgd); ++ continue; ++ } ++ if (rctx->mode & RK_CRYPTO_DEC) { ++ /* we backup last block of source to be used as IV at next step */ ++ offset = sgs->length - ivsize; ++ scatterwalk_map_and_copy(biv, sgs, offset, ivsize, 0); ++ } ++ if (sgs == sgd) { ++ err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL); ++ if (err <= 0) { ++ err = -EINVAL; ++ goto theend_iv; ++ } ++ } else { ++ err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE); ++ if (err <= 0) { ++ err = -EINVAL; ++ goto theend_iv; ++ } ++ err = dma_map_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE); ++ if (err <= 0) { ++ err = -EINVAL; ++ goto theend_sgs; ++ } ++ } ++ err = 0; ++ rk_ablk_hw_init(ctx->dev, areq); ++ if (ivsize) { ++ if (ivsize == DES_BLOCK_SIZE) ++ memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_IV_0, ivtouse, ivsize); ++ else ++ memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_IV_0, ivtouse, ivsize); ++ } ++ reinit_completion(&ctx->dev->complete); ++ ctx->dev->status = 0; ++ ++ todo = min(sg_dma_len(sgs), len); ++ len -= todo; ++ crypto_dma_start(ctx->dev, sgs, sgd, todo / 4); ++ wait_for_completion_interruptible_timeout(&ctx->dev->complete, ++ msecs_to_jiffies(2000)); ++ if (!ctx->dev->status) { ++ dev_err(ctx->dev->dev, "DMA timeout\n"); ++ err = -EFAULT; ++ goto theend; ++ } ++ if (sgs == sgd) { ++ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL); ++ } else { ++ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE); ++ dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE); ++ } ++ if (rctx->mode & RK_CRYPTO_DEC) { ++ memcpy(iv, biv, ivsize); ++ ivtouse = iv; ++ } else { ++ offset = sgd->length - ivsize; ++ scatterwalk_map_and_copy(iv, sgd, offset, ivsize, 0); ++ ivtouse = iv; ++ } ++ sgs = sg_next(sgs); ++ sgd = sg_next(sgd); + } +-} +- +-static void rk_update_iv(struct rk_crypto_info *dev) +-{ +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); +- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); +- struct rk_cipher_rctx *rctx = skcipher_request_ctx(req); +- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm); +- u32 ivsize = crypto_skcipher_ivsize(tfm); +- u8 *new_iv = NULL; + +- if (rctx->mode & RK_CRYPTO_DEC) { +- new_iv = ctx->iv; +- } else { +- new_iv = page_address(sg_page(dev->sg_dst)) + +- dev->sg_dst->offset + dev->sg_dst->length - ivsize; ++ if (areq->iv && ivsize > 0) { ++ offset = areq->cryptlen - ivsize; ++ if (rctx->mode & RK_CRYPTO_DEC) { ++ memcpy(areq->iv, rctx->backup_iv, ivsize); ++ memzero_explicit(rctx->backup_iv, ivsize); ++ } else { ++ scatterwalk_map_and_copy(areq->iv, areq->dst, offset, ++ ivsize, 0); ++ } + } + +- if (ivsize == DES_BLOCK_SIZE) +- memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, new_iv, ivsize); +- else if (ivsize == AES_BLOCK_SIZE) +- memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, new_iv, ivsize); +-} ++theend: ++ local_bh_disable(); ++ crypto_finalize_skcipher_request(engine, areq, err); ++ local_bh_enable(); ++ return 0; + +-/* return: +- * true some err was occurred +- * fault no err, continue +- */ +-static int rk_ablk_rx(struct rk_crypto_info *dev) +-{ +- int err = 0; +- struct skcipher_request *req = +- skcipher_request_cast(dev->async_req); +- +- dev->unload_data(dev); +- if (dev->left_bytes) { +- rk_update_iv(dev); +- if (sg_is_last(dev->sg_src)) { +- dev_err(dev->dev, "[%s:%d] Lack of data\n", +- __func__, __LINE__); +- err = -ENOMEM; +- goto out_rx; +- } +- dev->sg_src = sg_next(dev->sg_src); +- dev->sg_dst = sg_next(dev->sg_dst); +- err = rk_set_data_start(dev); ++theend_sgs: ++ if (sgs == sgd) { ++ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL); + } else { +- rk_iv_copyback(dev); +- /* here show the calculation is over without any err */ +- dev->complete(dev->async_req, 0); +- tasklet_schedule(&dev->queue_task); ++ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE); ++ dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE); + } +-out_rx: ++theend_iv: + return err; + } + +@@ -446,9 +443,6 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm) + algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher); + + ctx->dev = algt->dev; +- ctx->dev->start = rk_ablk_start; +- ctx->dev->update = rk_ablk_rx; +- ctx->dev->complete = rk_crypto_complete; + + ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(ctx->fallback_tfm)) { +@@ -460,6 +454,8 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm) + tfm->reqsize = sizeof(struct rk_cipher_rctx) + + crypto_skcipher_reqsize(ctx->fallback_tfm); + ++ ctx->enginectx.op.do_one_request = rk_cipher_run; ++ + return 0; + } + +-- +2.35.1 + diff --git a/queue-6.0/crypto-sun8i-ss-use-dma_addr-instead-u32.patch b/queue-6.0/crypto-sun8i-ss-use-dma_addr-instead-u32.patch new file mode 100644 index 00000000000..6e9ab610e6e --- /dev/null +++ b/queue-6.0/crypto-sun8i-ss-use-dma_addr-instead-u32.patch @@ -0,0 +1,36 @@ +From 74b5a923ad4d3db125242353594131e9af4d0567 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Sep 2022 08:55:55 +0000 +Subject: crypto: sun8i-ss - use dma_addr instead u32 + +From: Corentin Labbe + +[ Upstream commit 839b8ae2fc10f205317bcc32c9de18456756e1f5 ] + +The DMA address need to be stored in a dma_addr_t + +Fixes: 359e893e8af4 ("crypto: sun8i-ss - rework handling of IV") +Reported-by: Dan Carpenter +Signed-off-by: Corentin Labbe +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c +index 910d6751644c..902f6be057ec 100644 +--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c ++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c +@@ -124,7 +124,7 @@ static int sun8i_ss_setup_ivs(struct skcipher_request *areq) + unsigned int ivsize = crypto_skcipher_ivsize(tfm); + struct sun8i_ss_flow *sf = &ss->flows[rctx->flow]; + int i = 0; +- u32 a; ++ dma_addr_t a; + int err; + + rctx->ivlen = ivsize; +-- +2.35.1 + diff --git a/queue-6.0/crypto-tcrypt-fix-multibuffer-skcipher-speed-test-me.patch b/queue-6.0/crypto-tcrypt-fix-multibuffer-skcipher-speed-test-me.patch new file mode 100644 index 00000000000..d252bf7927e --- /dev/null +++ b/queue-6.0/crypto-tcrypt-fix-multibuffer-skcipher-speed-test-me.patch @@ -0,0 +1,45 @@ +From d2d2ad7693eb9950e3b59abc2efbe88085fe3620 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Nov 2022 17:24:11 +0800 +Subject: crypto: tcrypt - Fix multibuffer skcipher speed test mem leak + +From: Zhang Yiqun + +[ Upstream commit 1aa33fc8d4032227253ceb736f47c52b859d9683 ] + +In the past, the data for mb-skcipher test has been allocated +twice, that means the first allcated memory area is without +free, which may cause a potential memory leakage. So this +patch is to remove one allocation to fix this error. + +Fixes: e161c5930c15 ("crypto: tcrypt - add multibuf skcipher...") +Signed-off-by: Zhang Yiqun +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/tcrypt.c | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c +index 574640210c80..bc57b182f304 100644 +--- a/crypto/tcrypt.c ++++ b/crypto/tcrypt.c +@@ -1101,15 +1101,6 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs, + goto out_free_tfm; + } + +- +- for (i = 0; i < num_mb; ++i) +- if (testmgr_alloc_buf(data[i].xbuf)) { +- while (i--) +- testmgr_free_buf(data[i].xbuf); +- goto out_free_tfm; +- } +- +- + for (i = 0; i < num_mb; ++i) { + data[i].req = skcipher_request_alloc(tfm, GFP_KERNEL); + if (!data[i].req) { +-- +2.35.1 + diff --git a/queue-6.0/crypto-tcrypt-fix-return-value-for-multiple-subtests.patch b/queue-6.0/crypto-tcrypt-fix-return-value-for-multiple-subtests.patch new file mode 100644 index 00000000000..4a66cb4291c --- /dev/null +++ b/queue-6.0/crypto-tcrypt-fix-return-value-for-multiple-subtests.patch @@ -0,0 +1,548 @@ +From 2609a60f996dab6d2945b6fe9348f2f743a04567 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Sep 2022 16:40:14 -0500 +Subject: crypto: tcrypt - fix return value for multiple subtests + +From: Robert Elliott + +[ Upstream commit 65c92cbb3f2365627a10cf97560d51e88fb4e588 ] + +When a test mode invokes multiple tests (e.g., mode 0 invokes modes +1 through 199, and mode 3 tests three block cipher modes with des), +don't keep accumulating the return values with ret += tcrypt_test(), +which results in a bogus value if more than one report a nonzero +value (e.g., two reporting -2 (-ENOENT) end up reporting -4 (-EINTR)). +Instead, keep track of the minimum return value reported by any +subtest. + +Fixes: 4e033a6bc70f ("crypto: tcrypt - Do not exit on success in fips mode") +Signed-off-by: Robert Elliott +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/tcrypt.c | 256 ++++++++++++++++++++++++------------------------ + 1 file changed, 128 insertions(+), 128 deletions(-) + +diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c +index 59eb8ec36664..574640210c80 100644 +--- a/crypto/tcrypt.c ++++ b/crypto/tcrypt.c +@@ -1494,387 +1494,387 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb) + } + + for (i = 1; i < 200; i++) +- ret += do_test(NULL, 0, 0, i, num_mb); ++ ret = min(ret, do_test(NULL, 0, 0, i, num_mb)); + break; + + case 1: +- ret += tcrypt_test("md5"); ++ ret = min(ret, tcrypt_test("md5")); + break; + + case 2: +- ret += tcrypt_test("sha1"); ++ ret = min(ret, tcrypt_test("sha1")); + break; + + case 3: +- ret += tcrypt_test("ecb(des)"); +- ret += tcrypt_test("cbc(des)"); +- ret += tcrypt_test("ctr(des)"); ++ ret = min(ret, tcrypt_test("ecb(des)")); ++ ret = min(ret, tcrypt_test("cbc(des)")); ++ ret = min(ret, tcrypt_test("ctr(des)")); + break; + + case 4: +- ret += tcrypt_test("ecb(des3_ede)"); +- ret += tcrypt_test("cbc(des3_ede)"); +- ret += tcrypt_test("ctr(des3_ede)"); ++ ret = min(ret, tcrypt_test("ecb(des3_ede)")); ++ ret = min(ret, tcrypt_test("cbc(des3_ede)")); ++ ret = min(ret, tcrypt_test("ctr(des3_ede)")); + break; + + case 5: +- ret += tcrypt_test("md4"); ++ ret = min(ret, tcrypt_test("md4")); + break; + + case 6: +- ret += tcrypt_test("sha256"); ++ ret = min(ret, tcrypt_test("sha256")); + break; + + case 7: +- ret += tcrypt_test("ecb(blowfish)"); +- ret += tcrypt_test("cbc(blowfish)"); +- ret += tcrypt_test("ctr(blowfish)"); ++ ret = min(ret, tcrypt_test("ecb(blowfish)")); ++ ret = min(ret, tcrypt_test("cbc(blowfish)")); ++ ret = min(ret, tcrypt_test("ctr(blowfish)")); + break; + + case 8: +- ret += tcrypt_test("ecb(twofish)"); +- ret += tcrypt_test("cbc(twofish)"); +- ret += tcrypt_test("ctr(twofish)"); +- ret += tcrypt_test("lrw(twofish)"); +- ret += tcrypt_test("xts(twofish)"); ++ ret = min(ret, tcrypt_test("ecb(twofish)")); ++ ret = min(ret, tcrypt_test("cbc(twofish)")); ++ ret = min(ret, tcrypt_test("ctr(twofish)")); ++ ret = min(ret, tcrypt_test("lrw(twofish)")); ++ ret = min(ret, tcrypt_test("xts(twofish)")); + break; + + case 9: +- ret += tcrypt_test("ecb(serpent)"); +- ret += tcrypt_test("cbc(serpent)"); +- ret += tcrypt_test("ctr(serpent)"); +- ret += tcrypt_test("lrw(serpent)"); +- ret += tcrypt_test("xts(serpent)"); ++ ret = min(ret, tcrypt_test("ecb(serpent)")); ++ ret = min(ret, tcrypt_test("cbc(serpent)")); ++ ret = min(ret, tcrypt_test("ctr(serpent)")); ++ ret = min(ret, tcrypt_test("lrw(serpent)")); ++ ret = min(ret, tcrypt_test("xts(serpent)")); + break; + + case 10: +- ret += tcrypt_test("ecb(aes)"); +- ret += tcrypt_test("cbc(aes)"); +- ret += tcrypt_test("lrw(aes)"); +- ret += tcrypt_test("xts(aes)"); +- ret += tcrypt_test("ctr(aes)"); +- ret += tcrypt_test("rfc3686(ctr(aes))"); +- ret += tcrypt_test("ofb(aes)"); +- ret += tcrypt_test("cfb(aes)"); +- ret += tcrypt_test("xctr(aes)"); ++ ret = min(ret, tcrypt_test("ecb(aes)")); ++ ret = min(ret, tcrypt_test("cbc(aes)")); ++ ret = min(ret, tcrypt_test("lrw(aes)")); ++ ret = min(ret, tcrypt_test("xts(aes)")); ++ ret = min(ret, tcrypt_test("ctr(aes)")); ++ ret = min(ret, tcrypt_test("rfc3686(ctr(aes))")); ++ ret = min(ret, tcrypt_test("ofb(aes)")); ++ ret = min(ret, tcrypt_test("cfb(aes)")); ++ ret = min(ret, tcrypt_test("xctr(aes)")); + break; + + case 11: +- ret += tcrypt_test("sha384"); ++ ret = min(ret, tcrypt_test("sha384")); + break; + + case 12: +- ret += tcrypt_test("sha512"); ++ ret = min(ret, tcrypt_test("sha512")); + break; + + case 13: +- ret += tcrypt_test("deflate"); ++ ret = min(ret, tcrypt_test("deflate")); + break; + + case 14: +- ret += tcrypt_test("ecb(cast5)"); +- ret += tcrypt_test("cbc(cast5)"); +- ret += tcrypt_test("ctr(cast5)"); ++ ret = min(ret, tcrypt_test("ecb(cast5)")); ++ ret = min(ret, tcrypt_test("cbc(cast5)")); ++ ret = min(ret, tcrypt_test("ctr(cast5)")); + break; + + case 15: +- ret += tcrypt_test("ecb(cast6)"); +- ret += tcrypt_test("cbc(cast6)"); +- ret += tcrypt_test("ctr(cast6)"); +- ret += tcrypt_test("lrw(cast6)"); +- ret += tcrypt_test("xts(cast6)"); ++ ret = min(ret, tcrypt_test("ecb(cast6)")); ++ ret = min(ret, tcrypt_test("cbc(cast6)")); ++ ret = min(ret, tcrypt_test("ctr(cast6)")); ++ ret = min(ret, tcrypt_test("lrw(cast6)")); ++ ret = min(ret, tcrypt_test("xts(cast6)")); + break; + + case 16: +- ret += tcrypt_test("ecb(arc4)"); ++ ret = min(ret, tcrypt_test("ecb(arc4)")); + break; + + case 17: +- ret += tcrypt_test("michael_mic"); ++ ret = min(ret, tcrypt_test("michael_mic")); + break; + + case 18: +- ret += tcrypt_test("crc32c"); ++ ret = min(ret, tcrypt_test("crc32c")); + break; + + case 19: +- ret += tcrypt_test("ecb(tea)"); ++ ret = min(ret, tcrypt_test("ecb(tea)")); + break; + + case 20: +- ret += tcrypt_test("ecb(xtea)"); ++ ret = min(ret, tcrypt_test("ecb(xtea)")); + break; + + case 21: +- ret += tcrypt_test("ecb(khazad)"); ++ ret = min(ret, tcrypt_test("ecb(khazad)")); + break; + + case 22: +- ret += tcrypt_test("wp512"); ++ ret = min(ret, tcrypt_test("wp512")); + break; + + case 23: +- ret += tcrypt_test("wp384"); ++ ret = min(ret, tcrypt_test("wp384")); + break; + + case 24: +- ret += tcrypt_test("wp256"); ++ ret = min(ret, tcrypt_test("wp256")); + break; + + case 26: +- ret += tcrypt_test("ecb(anubis)"); +- ret += tcrypt_test("cbc(anubis)"); ++ ret = min(ret, tcrypt_test("ecb(anubis)")); ++ ret = min(ret, tcrypt_test("cbc(anubis)")); + break; + + case 30: +- ret += tcrypt_test("ecb(xeta)"); ++ ret = min(ret, tcrypt_test("ecb(xeta)")); + break; + + case 31: +- ret += tcrypt_test("pcbc(fcrypt)"); ++ ret = min(ret, tcrypt_test("pcbc(fcrypt)")); + break; + + case 32: +- ret += tcrypt_test("ecb(camellia)"); +- ret += tcrypt_test("cbc(camellia)"); +- ret += tcrypt_test("ctr(camellia)"); +- ret += tcrypt_test("lrw(camellia)"); +- ret += tcrypt_test("xts(camellia)"); ++ ret = min(ret, tcrypt_test("ecb(camellia)")); ++ ret = min(ret, tcrypt_test("cbc(camellia)")); ++ ret = min(ret, tcrypt_test("ctr(camellia)")); ++ ret = min(ret, tcrypt_test("lrw(camellia)")); ++ ret = min(ret, tcrypt_test("xts(camellia)")); + break; + + case 33: +- ret += tcrypt_test("sha224"); ++ ret = min(ret, tcrypt_test("sha224")); + break; + + case 35: +- ret += tcrypt_test("gcm(aes)"); ++ ret = min(ret, tcrypt_test("gcm(aes)")); + break; + + case 36: +- ret += tcrypt_test("lzo"); ++ ret = min(ret, tcrypt_test("lzo")); + break; + + case 37: +- ret += tcrypt_test("ccm(aes)"); ++ ret = min(ret, tcrypt_test("ccm(aes)")); + break; + + case 38: +- ret += tcrypt_test("cts(cbc(aes))"); ++ ret = min(ret, tcrypt_test("cts(cbc(aes))")); + break; + + case 39: +- ret += tcrypt_test("xxhash64"); ++ ret = min(ret, tcrypt_test("xxhash64")); + break; + + case 40: +- ret += tcrypt_test("rmd160"); ++ ret = min(ret, tcrypt_test("rmd160")); + break; + + case 42: +- ret += tcrypt_test("blake2b-512"); ++ ret = min(ret, tcrypt_test("blake2b-512")); + break; + + case 43: +- ret += tcrypt_test("ecb(seed)"); ++ ret = min(ret, tcrypt_test("ecb(seed)")); + break; + + case 45: +- ret += tcrypt_test("rfc4309(ccm(aes))"); ++ ret = min(ret, tcrypt_test("rfc4309(ccm(aes))")); + break; + + case 46: +- ret += tcrypt_test("ghash"); ++ ret = min(ret, tcrypt_test("ghash")); + break; + + case 47: +- ret += tcrypt_test("crct10dif"); ++ ret = min(ret, tcrypt_test("crct10dif")); + break; + + case 48: +- ret += tcrypt_test("sha3-224"); ++ ret = min(ret, tcrypt_test("sha3-224")); + break; + + case 49: +- ret += tcrypt_test("sha3-256"); ++ ret = min(ret, tcrypt_test("sha3-256")); + break; + + case 50: +- ret += tcrypt_test("sha3-384"); ++ ret = min(ret, tcrypt_test("sha3-384")); + break; + + case 51: +- ret += tcrypt_test("sha3-512"); ++ ret = min(ret, tcrypt_test("sha3-512")); + break; + + case 52: +- ret += tcrypt_test("sm3"); ++ ret = min(ret, tcrypt_test("sm3")); + break; + + case 53: +- ret += tcrypt_test("streebog256"); ++ ret = min(ret, tcrypt_test("streebog256")); + break; + + case 54: +- ret += tcrypt_test("streebog512"); ++ ret = min(ret, tcrypt_test("streebog512")); + break; + + case 55: +- ret += tcrypt_test("gcm(sm4)"); ++ ret = min(ret, tcrypt_test("gcm(sm4)")); + break; + + case 56: +- ret += tcrypt_test("ccm(sm4)"); ++ ret = min(ret, tcrypt_test("ccm(sm4)")); + break; + + case 57: +- ret += tcrypt_test("polyval"); ++ ret = min(ret, tcrypt_test("polyval")); + break; + + case 58: +- ret += tcrypt_test("gcm(aria)"); ++ ret = min(ret, tcrypt_test("gcm(aria)")); + break; + + case 100: +- ret += tcrypt_test("hmac(md5)"); ++ ret = min(ret, tcrypt_test("hmac(md5)")); + break; + + case 101: +- ret += tcrypt_test("hmac(sha1)"); ++ ret = min(ret, tcrypt_test("hmac(sha1)")); + break; + + case 102: +- ret += tcrypt_test("hmac(sha256)"); ++ ret = min(ret, tcrypt_test("hmac(sha256)")); + break; + + case 103: +- ret += tcrypt_test("hmac(sha384)"); ++ ret = min(ret, tcrypt_test("hmac(sha384)")); + break; + + case 104: +- ret += tcrypt_test("hmac(sha512)"); ++ ret = min(ret, tcrypt_test("hmac(sha512)")); + break; + + case 105: +- ret += tcrypt_test("hmac(sha224)"); ++ ret = min(ret, tcrypt_test("hmac(sha224)")); + break; + + case 106: +- ret += tcrypt_test("xcbc(aes)"); ++ ret = min(ret, tcrypt_test("xcbc(aes)")); + break; + + case 108: +- ret += tcrypt_test("hmac(rmd160)"); ++ ret = min(ret, tcrypt_test("hmac(rmd160)")); + break; + + case 109: +- ret += tcrypt_test("vmac64(aes)"); ++ ret = min(ret, tcrypt_test("vmac64(aes)")); + break; + + case 111: +- ret += tcrypt_test("hmac(sha3-224)"); ++ ret = min(ret, tcrypt_test("hmac(sha3-224)")); + break; + + case 112: +- ret += tcrypt_test("hmac(sha3-256)"); ++ ret = min(ret, tcrypt_test("hmac(sha3-256)")); + break; + + case 113: +- ret += tcrypt_test("hmac(sha3-384)"); ++ ret = min(ret, tcrypt_test("hmac(sha3-384)")); + break; + + case 114: +- ret += tcrypt_test("hmac(sha3-512)"); ++ ret = min(ret, tcrypt_test("hmac(sha3-512)")); + break; + + case 115: +- ret += tcrypt_test("hmac(streebog256)"); ++ ret = min(ret, tcrypt_test("hmac(streebog256)")); + break; + + case 116: +- ret += tcrypt_test("hmac(streebog512)"); ++ ret = min(ret, tcrypt_test("hmac(streebog512)")); + break; + + case 150: +- ret += tcrypt_test("ansi_cprng"); ++ ret = min(ret, tcrypt_test("ansi_cprng")); + break; + + case 151: +- ret += tcrypt_test("rfc4106(gcm(aes))"); ++ ret = min(ret, tcrypt_test("rfc4106(gcm(aes))")); + break; + + case 152: +- ret += tcrypt_test("rfc4543(gcm(aes))"); ++ ret = min(ret, tcrypt_test("rfc4543(gcm(aes))")); + break; + + case 153: +- ret += tcrypt_test("cmac(aes)"); ++ ret = min(ret, tcrypt_test("cmac(aes)")); + break; + + case 154: +- ret += tcrypt_test("cmac(des3_ede)"); ++ ret = min(ret, tcrypt_test("cmac(des3_ede)")); + break; + + case 155: +- ret += tcrypt_test("authenc(hmac(sha1),cbc(aes))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha1),cbc(aes))")); + break; + + case 156: +- ret += tcrypt_test("authenc(hmac(md5),ecb(cipher_null))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(md5),ecb(cipher_null))")); + break; + + case 157: +- ret += tcrypt_test("authenc(hmac(sha1),ecb(cipher_null))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha1),ecb(cipher_null))")); + break; + + case 158: +- ret += tcrypt_test("cbcmac(sm4)"); ++ ret = min(ret, tcrypt_test("cbcmac(sm4)")); + break; + + case 159: +- ret += tcrypt_test("cmac(sm4)"); ++ ret = min(ret, tcrypt_test("cmac(sm4)")); + break; + + case 181: +- ret += tcrypt_test("authenc(hmac(sha1),cbc(des))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha1),cbc(des))")); + break; + case 182: +- ret += tcrypt_test("authenc(hmac(sha1),cbc(des3_ede))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha1),cbc(des3_ede))")); + break; + case 183: +- ret += tcrypt_test("authenc(hmac(sha224),cbc(des))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha224),cbc(des))")); + break; + case 184: +- ret += tcrypt_test("authenc(hmac(sha224),cbc(des3_ede))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha224),cbc(des3_ede))")); + break; + case 185: +- ret += tcrypt_test("authenc(hmac(sha256),cbc(des))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha256),cbc(des))")); + break; + case 186: +- ret += tcrypt_test("authenc(hmac(sha256),cbc(des3_ede))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha256),cbc(des3_ede))")); + break; + case 187: +- ret += tcrypt_test("authenc(hmac(sha384),cbc(des))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha384),cbc(des))")); + break; + case 188: +- ret += tcrypt_test("authenc(hmac(sha384),cbc(des3_ede))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha384),cbc(des3_ede))")); + break; + case 189: +- ret += tcrypt_test("authenc(hmac(sha512),cbc(des))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha512),cbc(des))")); + break; + case 190: +- ret += tcrypt_test("authenc(hmac(sha512),cbc(des3_ede))"); ++ ret = min(ret, tcrypt_test("authenc(hmac(sha512),cbc(des3_ede))")); + break; + case 191: +- ret += tcrypt_test("ecb(sm4)"); +- ret += tcrypt_test("cbc(sm4)"); +- ret += tcrypt_test("cfb(sm4)"); +- ret += tcrypt_test("ctr(sm4)"); ++ ret = min(ret, tcrypt_test("ecb(sm4)")); ++ ret = min(ret, tcrypt_test("cbc(sm4)")); ++ ret = min(ret, tcrypt_test("cfb(sm4)")); ++ ret = min(ret, tcrypt_test("ctr(sm4)")); + break; + case 192: +- ret += tcrypt_test("ecb(aria)"); +- ret += tcrypt_test("cbc(aria)"); +- ret += tcrypt_test("cfb(aria)"); +- ret += tcrypt_test("ctr(aria)"); ++ ret = min(ret, tcrypt_test("ecb(aria)")); ++ ret = min(ret, tcrypt_test("cbc(aria)")); ++ ret = min(ret, tcrypt_test("cfb(aria)")); ++ ret = min(ret, tcrypt_test("ctr(aria)")); + break; + case 200: + test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0, +-- +2.35.1 + diff --git a/queue-6.0/cxl-fix-possible-null-ptr-deref-in-cxl_guest_init_af.patch b/queue-6.0/cxl-fix-possible-null-ptr-deref-in-cxl_guest_init_af.patch new file mode 100644 index 00000000000..72e0be74ac8 --- /dev/null +++ b/queue-6.0/cxl-fix-possible-null-ptr-deref-in-cxl_guest_init_af.patch @@ -0,0 +1,99 @@ +From 5a1649b4906bb83940c74eccf2f1e28581480453 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Nov 2022 22:54:39 +0800 +Subject: cxl: fix possible null-ptr-deref in cxl_guest_init_afu|adapter() + +From: Yang Yingliang + +[ Upstream commit 61c80d1c3833e196256fb060382db94f24d3d9a7 ] + +If device_register() fails in cxl_register_afu|adapter(), the device +is not added, device_unregister() can not be called in the error path, +otherwise it will cause a null-ptr-deref because of removing not added +device. + +As comment of device_register() says, it should use put_device() to give +up the reference in the error path. So split device_unregister() into +device_del() and put_device(), then goes to put dev when register fails. + +Fixes: 14baf4d9c739 ("cxl: Add guest-specific code") +Signed-off-by: Yang Yingliang +Acked-by: Andrew Donnellan +Acked-by: Frederic Barrat +Link: https://lore.kernel.org/r/20221111145440.2426970-1-yangyingliang@huawei.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/misc/cxl/guest.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c +index 375f692ae9d6..fb95a2d5cef4 100644 +--- a/drivers/misc/cxl/guest.c ++++ b/drivers/misc/cxl/guest.c +@@ -965,10 +965,10 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n + * if it returns an error! + */ + if ((rc = cxl_register_afu(afu))) +- goto err_put1; ++ goto err_put_dev; + + if ((rc = cxl_sysfs_afu_add(afu))) +- goto err_put1; ++ goto err_del_dev; + + /* + * pHyp doesn't expose the programming models supported by the +@@ -984,7 +984,7 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n + afu->modes_supported = CXL_MODE_DIRECTED; + + if ((rc = cxl_afu_select_best_mode(afu))) +- goto err_put2; ++ goto err_remove_sysfs; + + adapter->afu[afu->slice] = afu; + +@@ -1004,10 +1004,12 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n + + return 0; + +-err_put2: ++err_remove_sysfs: + cxl_sysfs_afu_remove(afu); +-err_put1: +- device_unregister(&afu->dev); ++err_del_dev: ++ device_del(&afu->dev); ++err_put_dev: ++ put_device(&afu->dev); + free = false; + guest_release_serr_irq(afu); + err2: +@@ -1141,18 +1143,20 @@ struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_devic + * even if it returns an error! + */ + if ((rc = cxl_register_adapter(adapter))) +- goto err_put1; ++ goto err_put_dev; + + if ((rc = cxl_sysfs_adapter_add(adapter))) +- goto err_put1; ++ goto err_del_dev; + + /* release the context lock as the adapter is configured */ + cxl_adapter_context_unlock(adapter); + + return adapter; + +-err_put1: +- device_unregister(&adapter->dev); ++err_del_dev: ++ device_del(&adapter->dev); ++err_put_dev: ++ put_device(&adapter->dev); + free = false; + cxl_guest_remove_chardev(adapter); + err1: +-- +2.35.1 + diff --git a/queue-6.0/cxl-fix-possible-null-ptr-deref-in-cxl_pci_init_afu-.patch b/queue-6.0/cxl-fix-possible-null-ptr-deref-in-cxl_pci_init_afu-.patch new file mode 100644 index 00000000000..6f9c8204f20 --- /dev/null +++ b/queue-6.0/cxl-fix-possible-null-ptr-deref-in-cxl_pci_init_afu-.patch @@ -0,0 +1,94 @@ +From b479fade14b317d8255e72ea92e13361286ff2c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Nov 2022 22:54:40 +0800 +Subject: cxl: fix possible null-ptr-deref in cxl_pci_init_afu|adapter() + +From: Yang Yingliang + +[ Upstream commit 02cd3032b154fa02fdf90e7467abaeed889330b2 ] + +If device_register() fails in cxl_pci_afu|adapter(), the device +is not added, device_unregister() can not be called in the error +path, otherwise it will cause a null-ptr-deref because of removing +not added device. + +As comment of device_register() says, it should use put_device() to give +up the reference in the error path. So split device_unregister() into +device_del() and put_device(), then goes to put dev when register fails. + +Fixes: f204e0b8cedd ("cxl: Driver code for powernv PCIe based cards for userspace access") +Signed-off-by: Yang Yingliang +Acked-by: Frederic Barrat +Acked-by: Andrew Donnellan +Link: https://lore.kernel.org/r/20221111145440.2426970-2-yangyingliang@huawei.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/misc/cxl/pci.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c +index 3de0aea62ade..6d495d641c95 100644 +--- a/drivers/misc/cxl/pci.c ++++ b/drivers/misc/cxl/pci.c +@@ -1164,10 +1164,10 @@ static int pci_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev) + * if it returns an error! + */ + if ((rc = cxl_register_afu(afu))) +- goto err_put1; ++ goto err_put_dev; + + if ((rc = cxl_sysfs_afu_add(afu))) +- goto err_put1; ++ goto err_del_dev; + + adapter->afu[afu->slice] = afu; + +@@ -1176,10 +1176,12 @@ static int pci_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev) + + return 0; + +-err_put1: ++err_del_dev: ++ device_del(&afu->dev); ++err_put_dev: + pci_deconfigure_afu(afu); + cxl_debugfs_afu_remove(afu); +- device_unregister(&afu->dev); ++ put_device(&afu->dev); + return rc; + + err_free_native: +@@ -1667,23 +1669,25 @@ static struct cxl *cxl_pci_init_adapter(struct pci_dev *dev) + * even if it returns an error! + */ + if ((rc = cxl_register_adapter(adapter))) +- goto err_put1; ++ goto err_put_dev; + + if ((rc = cxl_sysfs_adapter_add(adapter))) +- goto err_put1; ++ goto err_del_dev; + + /* Release the context lock as adapter is configured */ + cxl_adapter_context_unlock(adapter); + + return adapter; + +-err_put1: ++err_del_dev: ++ device_del(&adapter->dev); ++err_put_dev: + /* This should mirror cxl_remove_adapter, except without the + * sysfs parts + */ + cxl_debugfs_adapter_remove(adapter); + cxl_deconfigure_adapter(adapter); +- device_unregister(&adapter->dev); ++ put_device(&adapter->dev); + return ERR_PTR(rc); + + err_release: +-- +2.35.1 + diff --git a/queue-6.0/cxl-fix-refcount-leak-in-cxl_calc_capp_routing.patch b/queue-6.0/cxl-fix-refcount-leak-in-cxl_calc_capp_routing.patch new file mode 100644 index 00000000000..b168b19dfe2 --- /dev/null +++ b/queue-6.0/cxl-fix-refcount-leak-in-cxl_calc_capp_routing.patch @@ -0,0 +1,41 @@ +From 6725f3f21233f446c7fec723ba95dd744cf130fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 5 Jun 2022 10:00:38 +0400 +Subject: cxl: Fix refcount leak in cxl_calc_capp_routing + +From: Miaoqian Lin + +[ Upstream commit 1d09697ff22908ae487fc8c4fbde1811732be523 ] + +of_get_next_parent() returns a node pointer with refcount incremented, +we should use of_node_put() on it when not need anymore. +This function only calls of_node_put() in normal path, +missing it in the error path. +Add missing of_node_put() to avoid refcount leak. + +Fixes: f24be42aab37 ("cxl: Add psl9 specific code") +Signed-off-by: Miaoqian Lin +Acked-by: Andrew Donnellan +Acked-by: Frederic Barrat +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20220605060038.62217-1-linmq006@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/misc/cxl/pci.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c +index 6d495d641c95..0ff944860dda 100644 +--- a/drivers/misc/cxl/pci.c ++++ b/drivers/misc/cxl/pci.c +@@ -387,6 +387,7 @@ int cxl_calc_capp_routing(struct pci_dev *dev, u64 *chipid, + rc = get_phb_index(np, phb_index); + if (rc) { + pr_err("cxl: invalid phb index\n"); ++ of_node_put(np); + return rc; + } + +-- +2.35.1 + diff --git a/queue-6.0/debugfs-fix-error-when-writing-negative-value-to-ato.patch b/queue-6.0/debugfs-fix-error-when-writing-negative-value-to-ato.patch new file mode 100644 index 00000000000..94fe6319184 --- /dev/null +++ b/queue-6.0/debugfs-fix-error-when-writing-negative-value-to-ato.patch @@ -0,0 +1,198 @@ +From 307f5c9761f654af8849ef8c6a7fc7e0a4a47bc4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Sep 2022 02:24:18 +0900 +Subject: debugfs: fix error when writing negative value to atomic_t debugfs + file + +From: Akinobu Mita + +[ Upstream commit d472cf797c4e268613dbce5ec9b95d0bcae19ecb ] + +The simple attribute files do not accept a negative value since the commit +488dac0c9237 ("libfs: fix error cast of negative value in +simple_attr_write()"), so we have to use a 64-bit value to write a +negative value for a debugfs file created by debugfs_create_atomic_t(). + +This restores the previous behaviour by introducing +DEFINE_DEBUGFS_ATTRIBUTE_SIGNED for a signed value. + +Link: https://lkml.kernel.org/r/20220919172418.45257-4-akinobu.mita@gmail.com +Fixes: 488dac0c9237 ("libfs: fix error cast of negative value in simple_attr_write()") +Signed-off-by: Akinobu Mita +Reported-by: Zhao Gongyi +Reviewed-by: David Hildenbrand +Reviewed-by: Greg Kroah-Hartman +Cc: Alexander Viro +Cc: Jonathan Corbet +Cc: Oscar Salvador +Cc: Rafael J. Wysocki +Cc: Shuah Khan +Cc: Wei Yongjun +Cc: Yicong Yang +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + .../fault-injection/fault-injection.rst | 10 +++---- + fs/debugfs/file.c | 28 +++++++++++++++---- + include/linux/debugfs.h | 19 +++++++++++-- + 3 files changed, 43 insertions(+), 14 deletions(-) + +diff --git a/Documentation/fault-injection/fault-injection.rst b/Documentation/fault-injection/fault-injection.rst +index 17779a2772e5..5f6454b9dbd4 100644 +--- a/Documentation/fault-injection/fault-injection.rst ++++ b/Documentation/fault-injection/fault-injection.rst +@@ -83,9 +83,7 @@ configuration of fault-injection capabilities. + - /sys/kernel/debug/fail*/times: + + specifies how many times failures may happen at most. A value of -1 +- means "no limit". Note, though, that this file only accepts unsigned +- values. So, if you want to specify -1, you better use 'printf' instead +- of 'echo', e.g.: $ printf %#x -1 > times ++ means "no limit". + + - /sys/kernel/debug/fail*/space: + +@@ -284,7 +282,7 @@ Application Examples + echo Y > /sys/kernel/debug/$FAILTYPE/task-filter + echo 10 > /sys/kernel/debug/$FAILTYPE/probability + echo 100 > /sys/kernel/debug/$FAILTYPE/interval +- printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times ++ echo -1 > /sys/kernel/debug/$FAILTYPE/times + echo 0 > /sys/kernel/debug/$FAILTYPE/space + echo 2 > /sys/kernel/debug/$FAILTYPE/verbose + echo Y > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait +@@ -338,7 +336,7 @@ Application Examples + echo N > /sys/kernel/debug/$FAILTYPE/task-filter + echo 10 > /sys/kernel/debug/$FAILTYPE/probability + echo 100 > /sys/kernel/debug/$FAILTYPE/interval +- printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times ++ echo -1 > /sys/kernel/debug/$FAILTYPE/times + echo 0 > /sys/kernel/debug/$FAILTYPE/space + echo 2 > /sys/kernel/debug/$FAILTYPE/verbose + echo Y > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait +@@ -369,7 +367,7 @@ Application Examples + echo N > /sys/kernel/debug/$FAILTYPE/task-filter + echo 100 > /sys/kernel/debug/$FAILTYPE/probability + echo 0 > /sys/kernel/debug/$FAILTYPE/interval +- printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times ++ echo -1 > /sys/kernel/debug/$FAILTYPE/times + echo 0 > /sys/kernel/debug/$FAILTYPE/space + echo 1 > /sys/kernel/debug/$FAILTYPE/verbose + +diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c +index 950c63fa4d0b..38930d9b0bb7 100644 +--- a/fs/debugfs/file.c ++++ b/fs/debugfs/file.c +@@ -378,8 +378,8 @@ ssize_t debugfs_attr_read(struct file *file, char __user *buf, + } + EXPORT_SYMBOL_GPL(debugfs_attr_read); + +-ssize_t debugfs_attr_write(struct file *file, const char __user *buf, +- size_t len, loff_t *ppos) ++static ssize_t debugfs_attr_write_xsigned(struct file *file, const char __user *buf, ++ size_t len, loff_t *ppos, bool is_signed) + { + struct dentry *dentry = F_DENTRY(file); + ssize_t ret; +@@ -387,12 +387,28 @@ ssize_t debugfs_attr_write(struct file *file, const char __user *buf, + ret = debugfs_file_get(dentry); + if (unlikely(ret)) + return ret; +- ret = simple_attr_write(file, buf, len, ppos); ++ if (is_signed) ++ ret = simple_attr_write_signed(file, buf, len, ppos); ++ else ++ ret = simple_attr_write(file, buf, len, ppos); + debugfs_file_put(dentry); + return ret; + } ++ ++ssize_t debugfs_attr_write(struct file *file, const char __user *buf, ++ size_t len, loff_t *ppos) ++{ ++ return debugfs_attr_write_xsigned(file, buf, len, ppos, false); ++} + EXPORT_SYMBOL_GPL(debugfs_attr_write); + ++ssize_t debugfs_attr_write_signed(struct file *file, const char __user *buf, ++ size_t len, loff_t *ppos) ++{ ++ return debugfs_attr_write_xsigned(file, buf, len, ppos, true); ++} ++EXPORT_SYMBOL_GPL(debugfs_attr_write_signed); ++ + static struct dentry *debugfs_create_mode_unsafe(const char *name, umode_t mode, + struct dentry *parent, void *value, + const struct file_operations *fops, +@@ -738,11 +754,11 @@ static int debugfs_atomic_t_get(void *data, u64 *val) + *val = atomic_read((atomic_t *)data); + return 0; + } +-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get, ++DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t, debugfs_atomic_t_get, + debugfs_atomic_t_set, "%lld\n"); +-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_ro, debugfs_atomic_t_get, NULL, ++DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t_ro, debugfs_atomic_t_get, NULL, + "%lld\n"); +-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set, ++DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t_wo, NULL, debugfs_atomic_t_set, + "%lld\n"); + + /** +diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h +index f60674692d36..ea2d919fd9c7 100644 +--- a/include/linux/debugfs.h ++++ b/include/linux/debugfs.h +@@ -45,7 +45,7 @@ struct debugfs_u32_array { + + extern struct dentry *arch_debugfs_dir; + +-#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \ ++#define DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, __is_signed) \ + static int __fops ## _open(struct inode *inode, struct file *file) \ + { \ + __simple_attr_check_format(__fmt, 0ull); \ +@@ -56,10 +56,16 @@ static const struct file_operations __fops = { \ + .open = __fops ## _open, \ + .release = simple_attr_release, \ + .read = debugfs_attr_read, \ +- .write = debugfs_attr_write, \ ++ .write = (__is_signed) ? debugfs_attr_write_signed : debugfs_attr_write, \ + .llseek = no_llseek, \ + } + ++#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \ ++ DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, false) ++ ++#define DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(__fops, __get, __set, __fmt) \ ++ DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, true) ++ + typedef struct vfsmount *(*debugfs_automount_t)(struct dentry *, void *); + + #if defined(CONFIG_DEBUG_FS) +@@ -102,6 +108,8 @@ ssize_t debugfs_attr_read(struct file *file, char __user *buf, + size_t len, loff_t *ppos); + ssize_t debugfs_attr_write(struct file *file, const char __user *buf, + size_t len, loff_t *ppos); ++ssize_t debugfs_attr_write_signed(struct file *file, const char __user *buf, ++ size_t len, loff_t *ppos); + + struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, + struct dentry *new_dir, const char *new_name); +@@ -254,6 +262,13 @@ static inline ssize_t debugfs_attr_write(struct file *file, + return -ENODEV; + } + ++static inline ssize_t debugfs_attr_write_signed(struct file *file, ++ const char __user *buf, ++ size_t len, loff_t *ppos) ++{ ++ return -ENODEV; ++} ++ + static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, + struct dentry *new_dir, char *new_name) + { +-- +2.35.1 + diff --git a/queue-6.0/devlink-hold-region-lock-when-flushing-snapshots.patch b/queue-6.0/devlink-hold-region-lock-when-flushing-snapshots.patch new file mode 100644 index 00000000000..2de6e9719d9 --- /dev/null +++ b/queue-6.0/devlink-hold-region-lock-when-flushing-snapshots.patch @@ -0,0 +1,53 @@ +From 7900cb775b18791f4a8f72eb85270f94920684ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Dec 2022 18:01:00 -0800 +Subject: devlink: hold region lock when flushing snapshots + +From: Jakub Kicinski + +[ Upstream commit b4cafb3d2c740f8d1b1234b43ac4a60e5291c960 ] + +Netdevsim triggers a splat on reload, when it destroys regions +with snapshots pending: + + WARNING: CPU: 1 PID: 787 at net/core/devlink.c:6291 devlink_region_snapshot_del+0x12e/0x140 + CPU: 1 PID: 787 Comm: devlink Not tainted 6.1.0-07460-g7ae9888d6e1c #580 + RIP: 0010:devlink_region_snapshot_del+0x12e/0x140 + Call Trace: + + devl_region_destroy+0x70/0x140 + nsim_dev_reload_down+0x2f/0x60 [netdevsim] + devlink_reload+0x1f7/0x360 + devlink_nl_cmd_reload+0x6ce/0x860 + genl_family_rcv_msg_doit.isra.0+0x145/0x1c0 + +This is the locking assert in devlink_region_snapshot_del(), +we're supposed to be holding the region->snapshot_lock here. + +Fixes: 2dec18ad826f ("net: devlink: remove region snapshots list dependency on devlink->lock") +Signed-off-by: Jakub Kicinski +Reviewed-by: Jiri Pirko +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/core/devlink.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/core/devlink.c b/net/core/devlink.c +index cfa6a099457a..b3a869ccc8ed 100644 +--- a/net/core/devlink.c ++++ b/net/core/devlink.c +@@ -11358,8 +11358,10 @@ void devl_region_destroy(struct devlink_region *region) + devl_assert_locked(devlink); + + /* Free all snapshots of region */ ++ mutex_lock(®ion->snapshot_lock); + list_for_each_entry_safe(snapshot, ts, ®ion->snapshot_list, list) + devlink_region_snapshot_del(region, snapshot); ++ mutex_unlock(®ion->snapshot_lock); + + list_del(®ion->list); + mutex_destroy(®ion->snapshot_lock); +-- +2.35.1 + diff --git a/queue-6.0/devlink-protect-devlink-dump-by-the-instance-lock.patch b/queue-6.0/devlink-protect-devlink-dump-by-the-instance-lock.patch new file mode 100644 index 00000000000..b1a449d8a00 --- /dev/null +++ b/queue-6.0/devlink-protect-devlink-dump-by-the-instance-lock.patch @@ -0,0 +1,48 @@ +From f2847aa712f0534fb0dd6b944bb3cf1097500f33 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Dec 2022 20:41:22 -0800 +Subject: devlink: protect devlink dump by the instance lock + +From: Jakub Kicinski + +[ Upstream commit 214964a13ab56a9757d146b79b468a7ca190fbfb ] + +Take the instance lock around devlink_nl_fill() when dumping, +doit takes it already. + +We are only dumping basic info so in the worst case we were risking +data races around the reload statistics. Until the big devlink mutex +was removed all relevant code was protected by it, so the missing +instance lock was not exposed. + +Fixes: d3efc2a6a6d8 ("net: devlink: remove devlink_mutex") +Reviewed-by: Jiri Pirko +Reviewed-by: Jacob Keller +Link: https://lore.kernel.org/r/20221216044122.1863550-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/devlink.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/net/core/devlink.c b/net/core/devlink.c +index b3a869ccc8ed..5f894bd20c31 100644 +--- a/net/core/devlink.c ++++ b/net/core/devlink.c +@@ -1498,10 +1498,13 @@ static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg, + continue; + } + ++ devl_lock(devlink); + err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, NLM_F_MULTI); ++ devl_unlock(devlink); + devlink_put(devlink); ++ + if (err) + goto out; + idx++; +-- +2.35.1 + diff --git a/queue-6.0/dm-cleanup-close_table_device.patch b/queue-6.0/dm-cleanup-close_table_device.patch new file mode 100644 index 00000000000..2c78377636c --- /dev/null +++ b/queue-6.0/dm-cleanup-close_table_device.patch @@ -0,0 +1,62 @@ +From c2e030d1f11b79659e1f2f8b3766888fd85642b2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Nov 2022 22:10:48 +0800 +Subject: dm: cleanup close_table_device + +From: Christoph Hellwig + +[ Upstream commit 7b5865831c1003122f737df5e16adaa583f1a595 ] + +Take the list unlink and free into close_table_device so that no half +torn down table_devices exist. Also remove the check for a NULL bdev +as that can't happen - open_table_device never adds a table_device to +the list that does not have a valid block_device. + +Signed-off-by: Christoph Hellwig +Signed-off-by: Yu Kuai +Reviewed-by: Mike Snitzer +Link: https://lore.kernel.org/r/20221115141054.1051801-5-yukuai1@huaweicloud.com +Signed-off-by: Jens Axboe +Stable-dep-of: 1a581b721699 ("dm: track per-add_disk holder relations in DM") +Signed-off-by: Sasha Levin +--- + drivers/md/dm.c | 12 +++--------- + 1 file changed, 3 insertions(+), 9 deletions(-) + +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index 1903afa4618a..620abcef2df5 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -774,14 +774,11 @@ static struct table_device *open_table_device(struct mapped_device *md, + */ + static void close_table_device(struct table_device *td, struct mapped_device *md) + { +- if (!td->dm_dev.bdev) +- return; +- + bd_unlink_disk_holder(td->dm_dev.bdev, dm_disk(md)); + blkdev_put(td->dm_dev.bdev, td->dm_dev.mode | FMODE_EXCL); + put_dax(td->dm_dev.dax_dev); +- td->dm_dev.bdev = NULL; +- td->dm_dev.dax_dev = NULL; ++ list_del(&td->list); ++ kfree(td); + } + + static struct table_device *find_table_device(struct list_head *l, dev_t dev, +@@ -823,11 +820,8 @@ void dm_put_table_device(struct mapped_device *md, struct dm_dev *d) + struct table_device *td = container_of(d, struct table_device, dm_dev); + + mutex_lock(&md->table_devices_lock); +- if (refcount_dec_and_test(&td->count)) { ++ if (refcount_dec_and_test(&td->count)) + close_table_device(td, md); +- list_del(&td->list); +- kfree(td); +- } + mutex_unlock(&md->table_devices_lock); + } + +-- +2.35.1 + diff --git a/queue-6.0/dm-cleanup-open_table_device.patch b/queue-6.0/dm-cleanup-open_table_device.patch new file mode 100644 index 00000000000..6b07b595e4a --- /dev/null +++ b/queue-6.0/dm-cleanup-open_table_device.patch @@ -0,0 +1,119 @@ +From 59f455a845a2554f4412de46c93889723f8b34ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Nov 2022 22:10:47 +0800 +Subject: dm: cleanup open_table_device + +From: Christoph Hellwig + +[ Upstream commit b9a785d2dc6567b2fd9fc60057a6a945a276927a ] + +Move all the logic for allocation the table_device and linking it into +the list into the open_table_device. This keeps the code tidy and +ensures that the table_devices only exist in fully initialized state. + +Signed-off-by: Christoph Hellwig +Signed-off-by: Yu Kuai +Reviewed-by: Mike Snitzer +Link: https://lore.kernel.org/r/20221115141054.1051801-4-yukuai1@huaweicloud.com +Signed-off-by: Jens Axboe +Stable-dep-of: 1a581b721699 ("dm: track per-add_disk holder relations in DM") +Signed-off-by: Sasha Levin +--- + drivers/md/dm.c | 56 ++++++++++++++++++++++++------------------------- + 1 file changed, 27 insertions(+), 29 deletions(-) + +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index b4a2cb5333fc..1903afa4618a 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -732,28 +732,41 @@ static char *_dm_claim_ptr = "I belong to device-mapper"; + /* + * Open a table device so we can use it as a map destination. + */ +-static int open_table_device(struct table_device *td, dev_t dev, +- struct mapped_device *md) ++static struct table_device *open_table_device(struct mapped_device *md, ++ dev_t dev, fmode_t mode) + { ++ struct table_device *td; + struct block_device *bdev; + u64 part_off; + int r; + +- BUG_ON(td->dm_dev.bdev); ++ td = kmalloc_node(sizeof(*td), GFP_KERNEL, md->numa_node_id); ++ if (!td) ++ return ERR_PTR(-ENOMEM); ++ refcount_set(&td->count, 1); + +- bdev = blkdev_get_by_dev(dev, td->dm_dev.mode | FMODE_EXCL, _dm_claim_ptr); +- if (IS_ERR(bdev)) +- return PTR_ERR(bdev); ++ bdev = blkdev_get_by_dev(dev, mode | FMODE_EXCL, _dm_claim_ptr); ++ if (IS_ERR(bdev)) { ++ r = PTR_ERR(bdev); ++ goto out_free_td; ++ } + + r = bd_link_disk_holder(bdev, dm_disk(md)); +- if (r) { +- blkdev_put(bdev, td->dm_dev.mode | FMODE_EXCL); +- return r; +- } ++ if (r) ++ goto out_blkdev_put; + ++ td->dm_dev.mode = mode; + td->dm_dev.bdev = bdev; + td->dm_dev.dax_dev = fs_dax_get_by_bdev(bdev, &part_off, NULL, NULL); +- return 0; ++ format_dev_t(td->dm_dev.name, dev); ++ list_add(&td->list, &md->table_devices); ++ return td; ++ ++out_blkdev_put: ++ blkdev_put(bdev, mode | FMODE_EXCL); ++out_free_td: ++ kfree(td); ++ return ERR_PTR(r); + } + + /* +@@ -786,31 +799,16 @@ static struct table_device *find_table_device(struct list_head *l, dev_t dev, + int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode, + struct dm_dev **result) + { +- int r; + struct table_device *td; + + mutex_lock(&md->table_devices_lock); + td = find_table_device(&md->table_devices, dev, mode); + if (!td) { +- td = kmalloc_node(sizeof(*td), GFP_KERNEL, md->numa_node_id); +- if (!td) { +- mutex_unlock(&md->table_devices_lock); +- return -ENOMEM; +- } +- +- td->dm_dev.mode = mode; +- td->dm_dev.bdev = NULL; +- +- if ((r = open_table_device(td, dev, md))) { ++ td = open_table_device(md, dev, mode); ++ if (IS_ERR(td)) { + mutex_unlock(&md->table_devices_lock); +- kfree(td); +- return r; ++ return PTR_ERR(td); + } +- +- format_dev_t(td->dm_dev.name, dev); +- +- refcount_set(&td->count, 1); +- list_add(&td->list, &md->table_devices); + } else { + refcount_inc(&td->count); + } +-- +2.35.1 + diff --git a/queue-6.0/dm-make-sure-create-and-remove-dm-device-won-t-race-.patch b/queue-6.0/dm-make-sure-create-and-remove-dm-device-won-t-race-.patch new file mode 100644 index 00000000000..bce7b63ac94 --- /dev/null +++ b/queue-6.0/dm-make-sure-create-and-remove-dm-device-won-t-race-.patch @@ -0,0 +1,74 @@ +From 5ac9f51dd35fc9f760091bba7d3e9f510622be15 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Nov 2022 22:10:49 +0800 +Subject: dm: make sure create and remove dm device won't race with open and + close table + +From: Yu Kuai + +[ Upstream commit d563792c8933a810d28ce0f2831f0726c2b15a31 ] + +open_table_device() and close_table_device() is protected by +table_devices_lock, hence use it to protect add_disk() and +del_gendisk(). + +Prepare to track per-add_disk holder relations in dm. + +Signed-off-by: Yu Kuai +Reviewed-by: Mike Snitzer +Reviewed-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20221115141054.1051801-6-yukuai1@huaweicloud.com +Signed-off-by: Jens Axboe +Stable-dep-of: 1a581b721699 ("dm: track per-add_disk holder relations in DM") +Signed-off-by: Sasha Levin +--- + drivers/md/dm.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index 620abcef2df5..e7fc2a69633c 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -1965,7 +1965,14 @@ static void cleanup_mapped_device(struct mapped_device *md) + spin_unlock(&_minor_lock); + if (dm_get_md_type(md) != DM_TYPE_NONE) { + dm_sysfs_exit(md); ++ ++ /* ++ * Hold lock to make sure del_gendisk() won't concurrent ++ * with open/close_table_device(). ++ */ ++ mutex_lock(&md->table_devices_lock); + del_gendisk(md->disk); ++ mutex_unlock(&md->table_devices_lock); + } + dm_queue_destroy_crypto_profile(md->queue); + put_disk(md->disk); +@@ -2325,15 +2332,24 @@ int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t) + if (r) + return r; + ++ /* ++ * Hold lock to make sure add_disk() and del_gendisk() won't concurrent ++ * with open_table_device() and close_table_device(). ++ */ ++ mutex_lock(&md->table_devices_lock); + r = add_disk(md->disk); ++ mutex_unlock(&md->table_devices_lock); + if (r) + return r; + + r = dm_sysfs_init(md); + if (r) { ++ mutex_lock(&md->table_devices_lock); + del_gendisk(md->disk); ++ mutex_unlock(&md->table_devices_lock); + return r; + } ++ + md->type = type; + return 0; + } +-- +2.35.1 + diff --git a/queue-6.0/dm-track-per-add_disk-holder-relations-in-dm.patch b/queue-6.0/dm-track-per-add_disk-holder-relations-in-dm.patch new file mode 100644 index 00000000000..d7a76ec9592 --- /dev/null +++ b/queue-6.0/dm-track-per-add_disk-holder-relations-in-dm.patch @@ -0,0 +1,126 @@ +From a55bcb965cbb8704e1aa6c6ddd7ebca9373a966a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Nov 2022 22:10:50 +0800 +Subject: dm: track per-add_disk holder relations in DM + +From: Christoph Hellwig + +[ Upstream commit 1a581b72169968f4154b5793828f3bc28b258b35 ] + +dm is a bit special in that it opens the underlying devices. Commit +89f871af1b26 ("dm: delay registering the gendisk") tried to accommodate +that by allowing to add the holder to the list before add_gendisk and +then just add them to sysfs once add_disk is called. But that leads to +really odd lifetime problems and error handling problems as we can't +know the state of the kobjects and don't unwind properly. To fix this +switch to just registering all existing table_devices with the holder +code right after add_disk, and remove them before calling del_gendisk. + +Fixes: 89f871af1b26 ("dm: delay registering the gendisk") +Reported-by: Yu Kuai +Signed-off-by: Christoph Hellwig +Signed-off-by: Yu Kuai +Reviewed-by: Mike Snitzer +Link: https://lore.kernel.org/r/20221115141054.1051801-7-yukuai1@huaweicloud.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/md/dm.c | 49 +++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 39 insertions(+), 10 deletions(-) + +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index e7fc2a69633c..bbde744f7dba 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -751,9 +751,16 @@ static struct table_device *open_table_device(struct mapped_device *md, + goto out_free_td; + } + +- r = bd_link_disk_holder(bdev, dm_disk(md)); +- if (r) +- goto out_blkdev_put; ++ /* ++ * We can be called before the dm disk is added. In that case we can't ++ * register the holder relation here. It will be done once add_disk was ++ * called. ++ */ ++ if (md->disk->slave_dir) { ++ r = bd_link_disk_holder(bdev, md->disk); ++ if (r) ++ goto out_blkdev_put; ++ } + + td->dm_dev.mode = mode; + td->dm_dev.bdev = bdev; +@@ -774,7 +781,8 @@ static struct table_device *open_table_device(struct mapped_device *md, + */ + static void close_table_device(struct table_device *td, struct mapped_device *md) + { +- bd_unlink_disk_holder(td->dm_dev.bdev, dm_disk(md)); ++ if (md->disk->slave_dir) ++ bd_unlink_disk_holder(td->dm_dev.bdev, md->disk); + blkdev_put(td->dm_dev.bdev, td->dm_dev.mode | FMODE_EXCL); + put_dax(td->dm_dev.dax_dev); + list_del(&td->list); +@@ -1964,7 +1972,13 @@ static void cleanup_mapped_device(struct mapped_device *md) + md->disk->private_data = NULL; + spin_unlock(&_minor_lock); + if (dm_get_md_type(md) != DM_TYPE_NONE) { ++ struct table_device *td; ++ + dm_sysfs_exit(md); ++ list_for_each_entry(td, &md->table_devices, list) { ++ bd_unlink_disk_holder(td->dm_dev.bdev, ++ md->disk); ++ } + + /* + * Hold lock to make sure del_gendisk() won't concurrent +@@ -2304,6 +2318,7 @@ int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t) + { + enum dm_queue_mode type = dm_table_get_type(t); + struct queue_limits limits; ++ struct table_device *td; + int r; + + switch (type) { +@@ -2342,16 +2357,30 @@ int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t) + if (r) + return r; + +- r = dm_sysfs_init(md); +- if (r) { +- mutex_lock(&md->table_devices_lock); +- del_gendisk(md->disk); +- mutex_unlock(&md->table_devices_lock); +- return r; ++ /* ++ * Register the holder relationship for devices added before the disk ++ * was live. ++ */ ++ list_for_each_entry(td, &md->table_devices, list) { ++ r = bd_link_disk_holder(td->dm_dev.bdev, md->disk); ++ if (r) ++ goto out_undo_holders; + } + ++ r = dm_sysfs_init(md); ++ if (r) ++ goto out_undo_holders; ++ + md->type = type; + return 0; ++ ++out_undo_holders: ++ list_for_each_entry_continue_reverse(td, &md->table_devices, list) ++ bd_unlink_disk_holder(td->dm_dev.bdev, md->disk); ++ mutex_lock(&md->table_devices_lock); ++ del_gendisk(md->disk); ++ mutex_unlock(&md->table_devices_lock); ++ return r; + } + + struct mapped_device *dm_get_md(dev_t dev) +-- +2.35.1 + diff --git a/queue-6.0/dmaengine-apple-admac-allocate-cache-sram-to-channel.patch b/queue-6.0/dmaengine-apple-admac-allocate-cache-sram-to-channel.patch new file mode 100644 index 00000000000..98e6acbc2a0 --- /dev/null +++ b/queue-6.0/dmaengine-apple-admac-allocate-cache-sram-to-channel.patch @@ -0,0 +1,217 @@ +From aec679a754a7b4ddee426694d18178fa8cb5f574 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Oct 2022 15:23:24 +0200 +Subject: dmaengine: apple-admac: Allocate cache SRAM to channels +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Martin PoviÅ¡er + +[ Upstream commit 568aa6dd641f63166bb60d769e256789b3ac42d4 ] + +There's a previously unknown part of the controller interface: We have +to assign SRAM carveouts to channels to store their in-flight samples +in. So, obtain the size of the SRAM from a read-only register and divide +it into 2K blocks for allocation to channels. The FIFO depths we +configure will always fit into 2K. + +(This fixes audio artifacts during simultaneous playback/capture on +multiple channels -- which looking back is fully accounted for by having +had the caches in the DMA controller overlap in memory.) + +Fixes: b127315d9a78 ("dmaengine: apple-admac: Add Apple ADMAC driver") +Signed-off-by: Martin PoviÅ¡er +Link: https://lore.kernel.org/r/20221019132324.8585-2-povik+lin@cutebit.org +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/dma/apple-admac.c | 102 +++++++++++++++++++++++++++++++++++++- + 1 file changed, 101 insertions(+), 1 deletion(-) + +diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c +index d69ed9c93648..e3334762be85 100644 +--- a/drivers/dma/apple-admac.c ++++ b/drivers/dma/apple-admac.c +@@ -20,6 +20,12 @@ + #define NCHANNELS_MAX 64 + #define IRQ_NOUTPUTS 4 + ++/* ++ * For allocation purposes we split the cache ++ * memory into blocks of fixed size (given in bytes). ++ */ ++#define SRAM_BLOCK 2048 ++ + #define RING_WRITE_SLOT GENMASK(1, 0) + #define RING_READ_SLOT GENMASK(5, 4) + #define RING_FULL BIT(9) +@@ -35,6 +41,9 @@ + #define REG_TX_STOP 0x0004 + #define REG_RX_START 0x0008 + #define REG_RX_STOP 0x000c ++#define REG_IMPRINT 0x0090 ++#define REG_TX_SRAM_SIZE 0x0094 ++#define REG_RX_SRAM_SIZE 0x0098 + + #define REG_CHAN_CTL(ch) (0x8000 + (ch) * 0x200) + #define REG_CHAN_CTL_RST_RINGS BIT(0) +@@ -52,7 +61,9 @@ + #define BUS_WIDTH_FRAME_2_WORDS 0x10 + #define BUS_WIDTH_FRAME_4_WORDS 0x20 + +-#define CHAN_BUFSIZE 0x8000 ++#define REG_CHAN_SRAM_CARVEOUT(ch) (0x8050 + (ch) * 0x200) ++#define CHAN_SRAM_CARVEOUT_SIZE GENMASK(31, 16) ++#define CHAN_SRAM_CARVEOUT_BASE GENMASK(15, 0) + + #define REG_CHAN_FIFOCTL(ch) (0x8054 + (ch) * 0x200) + #define CHAN_FIFOCTL_LIMIT GENMASK(31, 16) +@@ -75,6 +86,8 @@ struct admac_chan { + struct dma_chan chan; + struct tasklet_struct tasklet; + ++ u32 carveout; ++ + spinlock_t lock; + struct admac_tx *current_tx; + int nperiod_acks; +@@ -91,11 +104,23 @@ struct admac_chan { + struct list_head to_free; + }; + ++struct admac_sram { ++ u32 size; ++ /* ++ * SRAM_CARVEOUT has 16-bit fields, so the SRAM cannot be larger than ++ * 64K and a 32-bit bitfield over 2K blocks covers it. ++ */ ++ u32 allocated; ++}; ++ + struct admac_data { + struct dma_device dma; + struct device *dev; + __iomem void *base; + ++ struct mutex cache_alloc_lock; ++ struct admac_sram txcache, rxcache; ++ + int irq; + int irq_index; + int nchannels; +@@ -116,6 +141,60 @@ struct admac_tx { + struct list_head node; + }; + ++static int admac_alloc_sram_carveout(struct admac_data *ad, ++ enum dma_transfer_direction dir, ++ u32 *out) ++{ ++ struct admac_sram *sram; ++ int i, ret = 0, nblocks; ++ ++ if (dir == DMA_MEM_TO_DEV) ++ sram = &ad->txcache; ++ else ++ sram = &ad->rxcache; ++ ++ mutex_lock(&ad->cache_alloc_lock); ++ ++ nblocks = sram->size / SRAM_BLOCK; ++ for (i = 0; i < nblocks; i++) ++ if (!(sram->allocated & BIT(i))) ++ break; ++ ++ if (i < nblocks) { ++ *out = FIELD_PREP(CHAN_SRAM_CARVEOUT_BASE, i * SRAM_BLOCK) | ++ FIELD_PREP(CHAN_SRAM_CARVEOUT_SIZE, SRAM_BLOCK); ++ sram->allocated |= BIT(i); ++ } else { ++ ret = -EBUSY; ++ } ++ ++ mutex_unlock(&ad->cache_alloc_lock); ++ ++ return ret; ++} ++ ++static void admac_free_sram_carveout(struct admac_data *ad, ++ enum dma_transfer_direction dir, ++ u32 carveout) ++{ ++ struct admac_sram *sram; ++ u32 base = FIELD_GET(CHAN_SRAM_CARVEOUT_BASE, carveout); ++ int i; ++ ++ if (dir == DMA_MEM_TO_DEV) ++ sram = &ad->txcache; ++ else ++ sram = &ad->rxcache; ++ ++ if (WARN_ON(base >= sram->size)) ++ return; ++ ++ mutex_lock(&ad->cache_alloc_lock); ++ i = base / SRAM_BLOCK; ++ sram->allocated &= ~BIT(i); ++ mutex_unlock(&ad->cache_alloc_lock); ++} ++ + static void admac_modify(struct admac_data *ad, int reg, u32 mask, u32 val) + { + void __iomem *addr = ad->base + reg; +@@ -464,15 +543,28 @@ static void admac_synchronize(struct dma_chan *chan) + static int admac_alloc_chan_resources(struct dma_chan *chan) + { + struct admac_chan *adchan = to_admac_chan(chan); ++ struct admac_data *ad = adchan->host; ++ int ret; + + dma_cookie_init(&adchan->chan); ++ ret = admac_alloc_sram_carveout(ad, admac_chan_direction(adchan->no), ++ &adchan->carveout); ++ if (ret < 0) ++ return ret; ++ ++ writel_relaxed(adchan->carveout, ++ ad->base + REG_CHAN_SRAM_CARVEOUT(adchan->no)); + return 0; + } + + static void admac_free_chan_resources(struct dma_chan *chan) + { ++ struct admac_chan *adchan = to_admac_chan(chan); ++ + admac_terminate_all(chan); + admac_synchronize(chan); ++ admac_free_sram_carveout(adchan->host, admac_chan_direction(adchan->no), ++ adchan->carveout); + } + + static struct dma_chan *admac_dma_of_xlate(struct of_phandle_args *dma_spec, +@@ -710,6 +802,7 @@ static int admac_probe(struct platform_device *pdev) + platform_set_drvdata(pdev, ad); + ad->dev = &pdev->dev; + ad->nchannels = nchannels; ++ mutex_init(&ad->cache_alloc_lock); + + /* + * The controller has 4 IRQ outputs. Try them all until +@@ -788,6 +881,13 @@ static int admac_probe(struct platform_device *pdev) + goto free_irq; + } + ++ ad->txcache.size = readl_relaxed(ad->base + REG_TX_SRAM_SIZE); ++ ad->rxcache.size = readl_relaxed(ad->base + REG_RX_SRAM_SIZE); ++ ++ dev_info(&pdev->dev, "Audio DMA Controller\n"); ++ dev_info(&pdev->dev, "imprint %x TX cache %u RX cache %u\n", ++ readl_relaxed(ad->base + REG_IMPRINT), ad->txcache.size, ad->rxcache.size); ++ + return 0; + + free_irq: +-- +2.35.1 + diff --git a/queue-6.0/dmaengine-apple-admac-do-not-use-devres-for-irqs.patch b/queue-6.0/dmaengine-apple-admac-do-not-use-devres-for-irqs.patch new file mode 100644 index 00000000000..d9d11dba41f --- /dev/null +++ b/queue-6.0/dmaengine-apple-admac-do-not-use-devres-for-irqs.patch @@ -0,0 +1,95 @@ +From c1cd60030af21908582ae4eadcf1bc18175480bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 18 Sep 2022 11:58:44 +0200 +Subject: dmaengine: apple-admac: Do not use devres for IRQs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Martin PoviÅ¡er + +[ Upstream commit 072431595a57bc6605c29724afce5f9ef8114915 ] + +This is in advance of adding support for triggering the reset signal to +the peripheral, since registering the IRQ handler will have to be +sequenced with it. + +Signed-off-by: Martin PoviÅ¡er +Link: https://lore.kernel.org/r/20220918095845.68860-4-povik+lin@cutebit.org +Signed-off-by: Vinod Koul +Stable-dep-of: 568aa6dd641f ("dmaengine: apple-admac: Allocate cache SRAM to channels") +Signed-off-by: Sasha Levin +--- + drivers/dma/apple-admac.c | 27 ++++++++++++++++++--------- + 1 file changed, 18 insertions(+), 9 deletions(-) + +diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c +index 6780761a1640..d69ed9c93648 100644 +--- a/drivers/dma/apple-admac.c ++++ b/drivers/dma/apple-admac.c +@@ -96,6 +96,7 @@ struct admac_data { + struct device *dev; + __iomem void *base; + ++ int irq; + int irq_index; + int nchannels; + struct admac_chan channels[]; +@@ -724,12 +725,7 @@ static int admac_probe(struct platform_device *pdev) + + if (irq < 0) + return dev_err_probe(&pdev->dev, irq, "no usable interrupt\n"); +- +- err = devm_request_irq(&pdev->dev, irq, admac_interrupt, +- 0, dev_name(&pdev->dev), ad); +- if (err) +- return dev_err_probe(&pdev->dev, err, +- "unable to register interrupt\n"); ++ ad->irq = irq; + + ad->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(ad->base)) +@@ -774,17 +770,29 @@ static int admac_probe(struct platform_device *pdev) + tasklet_setup(&adchan->tasklet, admac_chan_tasklet); + } + +- err = dma_async_device_register(&ad->dma); ++ err = request_irq(irq, admac_interrupt, 0, dev_name(&pdev->dev), ad); + if (err) +- return dev_err_probe(&pdev->dev, err, "failed to register DMA device\n"); ++ return dev_err_probe(&pdev->dev, err, ++ "unable to register interrupt\n"); ++ ++ err = dma_async_device_register(&ad->dma); ++ if (err) { ++ dev_err_probe(&pdev->dev, err, "failed to register DMA device\n"); ++ goto free_irq; ++ } + + err = of_dma_controller_register(pdev->dev.of_node, admac_dma_of_xlate, ad); + if (err) { + dma_async_device_unregister(&ad->dma); +- return dev_err_probe(&pdev->dev, err, "failed to register with OF\n"); ++ dev_err_probe(&pdev->dev, err, "failed to register with OF\n"); ++ goto free_irq; + } + + return 0; ++ ++free_irq: ++ free_irq(ad->irq, ad); ++ return err; + } + + static int admac_remove(struct platform_device *pdev) +@@ -793,6 +801,7 @@ static int admac_remove(struct platform_device *pdev) + + of_dma_controller_free(pdev->dev.of_node); + dma_async_device_unregister(&ad->dma); ++ free_irq(ad->irq, ad); + + return 0; + } +-- +2.35.1 + diff --git a/queue-6.0/dmaengine-idxd-fix-crc_val-field-for-completion-reco.patch b/queue-6.0/dmaengine-idxd-fix-crc_val-field-for-completion-reco.patch new file mode 100644 index 00000000000..10f6ded1a78 --- /dev/null +++ b/queue-6.0/dmaengine-idxd-fix-crc_val-field-for-completion-reco.patch @@ -0,0 +1,38 @@ +From a0d89ea710fbe5d93029062f11aa1ddd12952e1c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 10 Nov 2022 17:27:15 -0800 +Subject: dmaengine: idxd: Fix crc_val field for completion record + +From: Fenghua Yu + +[ Upstream commit dc901d98b1fe6e52ab81cd3e0879379168e06daa ] + +The crc_val in the completion record should be 64 bits and not 32 bits. + +Fixes: 4ac823e9cd85 ("dmaengine: idxd: fix delta_rec and crc size field for completion record") +Reported-by: Nirav N Shah +Signed-off-by: Fenghua Yu +Reviewed-by: Dave Jiang +Link: https://lore.kernel.org/r/20221111012715.2031481-1-fenghua.yu@intel.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + include/uapi/linux/idxd.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/uapi/linux/idxd.h b/include/uapi/linux/idxd.h +index 2b9e7feba3f3..1d553bedbdb5 100644 +--- a/include/uapi/linux/idxd.h ++++ b/include/uapi/linux/idxd.h +@@ -295,7 +295,7 @@ struct dsa_completion_record { + }; + + uint32_t delta_rec_size; +- uint32_t crc_val; ++ uint64_t crc_val; + + /* DIF check & strip */ + struct { +-- +2.35.1 + diff --git a/queue-6.0/drbd-destroy-workqueue-when-drbd-device-was-freed.patch b/queue-6.0/drbd-destroy-workqueue-when-drbd-device-was-freed.patch new file mode 100644 index 00000000000..d99e717965d --- /dev/null +++ b/queue-6.0/drbd-destroy-workqueue-when-drbd-device-was-freed.patch @@ -0,0 +1,56 @@ +From 6f91a1e5a16c0e65e6d4db870f1de1b993f49d20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Nov 2022 09:58:17 +0800 +Subject: drbd: destroy workqueue when drbd device was freed + +From: Wang ShaoBo + +[ Upstream commit 8692814b77ca4228a99da8a005de0acf40af6132 ] + +A submitter workqueue is dynamically allocated by init_submitter() +called by drbd_create_device(), we should destroy it when this +device is not needed or destroyed. + +Fixes: 113fef9e20e0 ("drbd: prepare to queue write requests on a submit worker") +Signed-off-by: Wang ShaoBo +Link: https://lore.kernel.org/r/20221124015817.2729789-3-bobo.shaobowang@huawei.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/drbd/drbd_main.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c +index 78cae4e75af1..677240232684 100644 +--- a/drivers/block/drbd/drbd_main.c ++++ b/drivers/block/drbd/drbd_main.c +@@ -2217,6 +2217,8 @@ void drbd_destroy_device(struct kref *kref) + kref_put(&peer_device->connection->kref, drbd_destroy_connection); + kfree(peer_device); + } ++ if (device->submit.wq) ++ destroy_workqueue(device->submit.wq); + kfree(device); + kref_put(&resource->kref, drbd_destroy_resource); + } +@@ -2771,7 +2773,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig + + err = add_disk(disk); + if (err) +- goto out_idr_remove_from_resource; ++ goto out_destroy_workqueue; + + /* inherit the connection state */ + device->state.conn = first_connection(resource)->cstate; +@@ -2785,6 +2787,8 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig + drbd_debugfs_device_add(device); + return NO_ERROR; + ++out_destroy_workqueue: ++ destroy_workqueue(device->submit.wq); + out_idr_remove_from_resource: + for_each_connection_safe(connection, n, resource) { + peer_device = idr_remove(&connection->peer_devices, vnr); +-- +2.35.1 + diff --git a/queue-6.0/drbd-remove-call-to-memset-before-free-device-resour.patch b/queue-6.0/drbd-remove-call-to-memset-before-free-device-resour.patch new file mode 100644 index 00000000000..d3c8e84841d --- /dev/null +++ b/queue-6.0/drbd-remove-call-to-memset-before-free-device-resour.patch @@ -0,0 +1,53 @@ +From f7e1557aff2606ba6996540eed3d59d340791446 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Nov 2022 09:58:16 +0800 +Subject: drbd: remove call to memset before free device/resource/connection + +From: Wang ShaoBo + +[ Upstream commit 6e7b854e4c1b02dba00760dfa79d8dbf6cce561e ] + +This revert c2258ffc56f2 ("drbd: poison free'd device, resource and +connection structs"), add memset is odd here for debugging, there are +some methods to accurately show what happened, such as kdump. + +Signed-off-by: Wang ShaoBo +Link: https://lore.kernel.org/r/20221124015817.2729789-2-bobo.shaobowang@huawei.com +Signed-off-by: Jens Axboe +Stable-dep-of: 8692814b77ca ("drbd: destroy workqueue when drbd device was freed") +Signed-off-by: Sasha Levin +--- + drivers/block/drbd/drbd_main.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c +index 8532b839a343..78cae4e75af1 100644 +--- a/drivers/block/drbd/drbd_main.c ++++ b/drivers/block/drbd/drbd_main.c +@@ -2217,7 +2217,6 @@ void drbd_destroy_device(struct kref *kref) + kref_put(&peer_device->connection->kref, drbd_destroy_connection); + kfree(peer_device); + } +- memset(device, 0xfd, sizeof(*device)); + kfree(device); + kref_put(&resource->kref, drbd_destroy_resource); + } +@@ -2309,7 +2308,6 @@ void drbd_destroy_resource(struct kref *kref) + idr_destroy(&resource->devices); + free_cpumask_var(resource->cpu_mask); + kfree(resource->name); +- memset(resource, 0xf2, sizeof(*resource)); + kfree(resource); + } + +@@ -2650,7 +2648,6 @@ void drbd_destroy_connection(struct kref *kref) + drbd_free_socket(&connection->data); + kfree(connection->int_dig_in); + kfree(connection->int_dig_vv); +- memset(connection, 0xfc, sizeof(*connection)); + kfree(connection); + kref_put(&resource->kref, drbd_destroy_resource); + } +-- +2.35.1 + diff --git a/queue-6.0/drbd-use-blk_queue_max_discard_sectors-helper.patch b/queue-6.0/drbd-use-blk_queue_max_discard_sectors-helper.patch new file mode 100644 index 00000000000..cb834598af7 --- /dev/null +++ b/queue-6.0/drbd-use-blk_queue_max_discard_sectors-helper.patch @@ -0,0 +1,72 @@ +From 1b27f409e4c7fa73544e4003be11717f7e1796a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Nov 2022 14:34:51 +0100 +Subject: drbd: use blk_queue_max_discard_sectors helper +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Christoph Böhmwalder + +[ Upstream commit 258bea6388ac93f34561fd91064232d14e174bff ] + +We currently only set q->limits.max_discard_sectors, but that is not +enough. Another field, max_hw_discard_sectors, was introduced in +commit 0034af036554 ("block: make /sys/block//queue/discard_max_bytes +writeable"). + +The difference is that max_discard_sectors can be changed from user +space via sysfs, while max_hw_discard_sectors is the "hardware" upper +limit. + +So use this helper, which sets both. + +This is also a fixup for commit 998e9cbcd615 ("drbd: cleanup +decide_on_discard_support"): if discards are not supported, that does +not necessarily mean we also want to disable write_zeroes. + +Fixes: 998e9cbcd615 ("drbd: cleanup decide_on_discard_support") +Reviewed-by: Joel Colledge +Signed-off-by: Christoph Böhmwalder +Link: https://lore.kernel.org/r/20221109133453.51652-2-christoph.boehmwalder@linbit.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/drbd/drbd_nl.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c +index 013d355a2033..921c303a7b5c 100644 +--- a/drivers/block/drbd/drbd_nl.c ++++ b/drivers/block/drbd/drbd_nl.c +@@ -1210,6 +1210,7 @@ static void decide_on_discard_support(struct drbd_device *device, + struct drbd_connection *connection = + first_peer_device(device)->connection; + struct request_queue *q = device->rq_queue; ++ unsigned int max_discard_sectors; + + if (bdev && !bdev_max_discard_sectors(bdev->backing_bdev)) + goto not_supported; +@@ -1230,15 +1231,14 @@ static void decide_on_discard_support(struct drbd_device *device, + * topology on all peers. + */ + blk_queue_discard_granularity(q, 512); +- q->limits.max_discard_sectors = drbd_max_discard_sectors(connection); +- q->limits.max_write_zeroes_sectors = +- drbd_max_discard_sectors(connection); ++ max_discard_sectors = drbd_max_discard_sectors(connection); ++ blk_queue_max_discard_sectors(q, max_discard_sectors); ++ blk_queue_max_write_zeroes_sectors(q, max_discard_sectors); + return; + + not_supported: + blk_queue_discard_granularity(q, 0); +- q->limits.max_discard_sectors = 0; +- q->limits.max_write_zeroes_sectors = 0; ++ blk_queue_max_discard_sectors(q, 0); + } + + static void fixup_write_zeroes(struct drbd_device *device, struct request_queue *q) +-- +2.35.1 + diff --git a/queue-6.0/drivers-dio-fix-possible-memory-leak-in-dio_init.patch b/queue-6.0/drivers-dio-fix-possible-memory-leak-in-dio_init.patch new file mode 100644 index 00000000000..a5f37c28f30 --- /dev/null +++ b/queue-6.0/drivers-dio-fix-possible-memory-leak-in-dio_init.patch @@ -0,0 +1,60 @@ +From f59bcde245f515f9217e2411cfb6ea34df29bb9c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Nov 2022 14:40:36 +0800 +Subject: drivers: dio: fix possible memory leak in dio_init() + +From: Yang Yingliang + +[ Upstream commit e63e99397b2613d50a5f4f02ed07307e67a190f1 ] + +If device_register() returns error, the 'dev' and name needs be +freed. Add a release function, and then call put_device() in the +error path, so the name is freed in kobject_cleanup() and to the +'dev' is freed in release function. + +Fixes: 2e4c77bea3d8 ("m68k: dio - Kill warn_unused_result warnings") +Fixes: 1fa5ae857bb1 ("driver core: get rid of struct device's bus_id string array") +Signed-off-by: Yang Yingliang +Link: https://lore.kernel.org/r/20221109064036.1835346-1-yangyingliang@huawei.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/dio/dio.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c +index 0e5a5662d5a4..0a051d656880 100644 +--- a/drivers/dio/dio.c ++++ b/drivers/dio/dio.c +@@ -109,6 +109,12 @@ static char dio_no_name[] = { 0 }; + + #endif /* CONFIG_DIO_CONSTANTS */ + ++static void dio_dev_release(struct device *dev) ++{ ++ struct dio_dev *ddev = container_of(dev, typeof(struct dio_dev), dev); ++ kfree(ddev); ++} ++ + int __init dio_find(int deviceid) + { + /* Called to find a DIO device before the full bus scan has run. +@@ -225,6 +231,7 @@ static int __init dio_init(void) + dev->bus = &dio_bus; + dev->dev.parent = &dio_bus.dev; + dev->dev.bus = &dio_bus_type; ++ dev->dev.release = dio_dev_release; + dev->scode = scode; + dev->resource.start = pa; + dev->resource.end = pa + DIO_SIZE(scode, va); +@@ -252,6 +259,7 @@ static int __init dio_init(void) + if (error) { + pr_err("DIO: Error registering device %s\n", + dev->name); ++ put_device(&dev->dev); + continue; + } + error = dio_create_sysfs_dev_files(dev); +-- +2.35.1 + diff --git a/queue-6.0/drivers-mcb-fix-resource-leak-in-mcb_probe.patch b/queue-6.0/drivers-mcb-fix-resource-leak-in-mcb_probe.patch new file mode 100644 index 00000000000..6c636e38d66 --- /dev/null +++ b/queue-6.0/drivers-mcb-fix-resource-leak-in-mcb_probe.patch @@ -0,0 +1,41 @@ +From 6a601794de8c6219ee412bcf0e4215ce8edad988 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Dec 2022 01:38:49 -0800 +Subject: drivers: mcb: fix resource leak in mcb_probe() + +From: Zhengchao Shao + +[ Upstream commit d7237462561fcd224fa687c56ccb68629f50fc0d ] + +When probe hook function failed in mcb_probe(), it doesn't put the device. +Compiled test only. + +Fixes: 7bc364097a89 ("mcb: Acquire reference to device in probe") +Signed-off-by: Zhengchao Shao +Signed-off-by: Johannes Thumshirn +Link: https://lore.kernel.org/r/9f87de36bfb85158b506cb78c6fc9db3f6a3bad1.1669624063.git.johannes.thumshirn@wdc.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/mcb/mcb-core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/mcb/mcb-core.c b/drivers/mcb/mcb-core.c +index 338fc889b357..b8ad4f16b4ac 100644 +--- a/drivers/mcb/mcb-core.c ++++ b/drivers/mcb/mcb-core.c +@@ -71,8 +71,10 @@ static int mcb_probe(struct device *dev) + + get_device(dev); + ret = mdrv->probe(mdev, found_id); +- if (ret) ++ if (ret) { + module_put(carrier_mod); ++ put_device(dev); ++ } + + return ret; + } +-- +2.35.1 + diff --git a/queue-6.0/drivers-md-md-bitmap-check-the-return-value-of-md_bi.patch b/queue-6.0/drivers-md-md-bitmap-check-the-return-value-of-md_bi.patch new file mode 100644 index 00000000000..1d6605fe1ad --- /dev/null +++ b/queue-6.0/drivers-md-md-bitmap-check-the-return-value-of-md_bi.patch @@ -0,0 +1,65 @@ +From a70e617c7d80934bfa02894daad6b267cef0e723 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Sep 2022 16:33:05 -0700 +Subject: drivers/md/md-bitmap: check the return value of + md_bitmap_get_counter() + +From: Li Zhong + +[ Upstream commit 3bd548e5b819b8c0f2c9085de775c5c7bff9052f ] + +Check the return value of md_bitmap_get_counter() in case it returns +NULL pointer, which will result in a null pointer dereference. + +v2: update the check to include other dereference + +Signed-off-by: Li Zhong +Signed-off-by: Song Liu +Signed-off-by: Sasha Levin +--- + drivers/md/md-bitmap.c | 27 +++++++++++++++------------ + 1 file changed, 15 insertions(+), 12 deletions(-) + +diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c +index bf6dffadbe6f..63ece30114e5 100644 +--- a/drivers/md/md-bitmap.c ++++ b/drivers/md/md-bitmap.c +@@ -2195,20 +2195,23 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks, + + if (set) { + bmc_new = md_bitmap_get_counter(&bitmap->counts, block, &new_blocks, 1); +- if (*bmc_new == 0) { +- /* need to set on-disk bits too. */ +- sector_t end = block + new_blocks; +- sector_t start = block >> chunkshift; +- start <<= chunkshift; +- while (start < end) { +- md_bitmap_file_set_bit(bitmap, block); +- start += 1 << chunkshift; ++ if (bmc_new) { ++ if (*bmc_new == 0) { ++ /* need to set on-disk bits too. */ ++ sector_t end = block + new_blocks; ++ sector_t start = block >> chunkshift; ++ ++ start <<= chunkshift; ++ while (start < end) { ++ md_bitmap_file_set_bit(bitmap, block); ++ start += 1 << chunkshift; ++ } ++ *bmc_new = 2; ++ md_bitmap_count_page(&bitmap->counts, block, 1); ++ md_bitmap_set_pending(&bitmap->counts, block); + } +- *bmc_new = 2; +- md_bitmap_count_page(&bitmap->counts, block, 1); +- md_bitmap_set_pending(&bitmap->counts, block); ++ *bmc_new |= NEEDED_MASK; + } +- *bmc_new |= NEEDED_MASK; + if (new_blocks < old_blocks) + old_blocks = new_blocks; + } +-- +2.35.1 + diff --git a/queue-6.0/drivers-net-qlcnic-fix-potential-memory-leak-in-qlcn.patch b/queue-6.0/drivers-net-qlcnic-fix-potential-memory-leak-in-qlcn.patch new file mode 100644 index 00000000000..59d00503b78 --- /dev/null +++ b/queue-6.0/drivers-net-qlcnic-fix-potential-memory-leak-in-qlcn.patch @@ -0,0 +1,38 @@ +From bce5a8ae9fa8f01d07d9f83fbba4e7cc9a97220a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Dec 2022 08:54:10 +0000 +Subject: drivers: net: qlcnic: Fix potential memory leak in + qlcnic_sriov_init() + +From: Yuan Can + +[ Upstream commit 01de1123322e4fe1bbd0fcdf0982511b55519c03 ] + +If vp alloc failed in qlcnic_sriov_init(), all previously allocated vp +needs to be freed. + +Fixes: f197a7aa6288 ("qlcnic: VF-PF communication channel implementation") +Signed-off-by: Yuan Can +Reviewed-by: Leon Romanovsky +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +index 9282321c2e7f..f9dd50152b1e 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +@@ -221,6 +221,8 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs) + return 0; + + qlcnic_destroy_async_wq: ++ while (i--) ++ kfree(sriov->vf_info[i].vp); + destroy_workqueue(bc->bc_async_wq); + + qlcnic_destroy_trans_wq: +-- +2.35.1 + diff --git a/queue-6.0/drivers-perf-hisi-fix-some-event-id-for-hisi-pcie-pm.patch b/queue-6.0/drivers-perf-hisi-fix-some-event-id-for-hisi-pcie-pm.patch new file mode 100644 index 00000000000..08c66ab0c4c --- /dev/null +++ b/queue-6.0/drivers-perf-hisi-fix-some-event-id-for-hisi-pcie-pm.patch @@ -0,0 +1,43 @@ +From 05da6c1973288c0fb4677f9a2206680c2d60f7ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 16:41:33 +0800 +Subject: drivers/perf: hisi: Fix some event id for hisi-pcie-pmu + +From: Yicong Yang + +[ Upstream commit 6b4bb4f38dbfe85247f006f06135ba46450d5bf0 ] + +Some event id of hisi-pcie-pmu is incorrect, fix them. + +Fixes: 8404b0fbc7fb ("drivers/perf: hisi: Add driver for HiSilicon PCIe PMU") +Reviewed-by: Jonathan Cameron +Signed-off-by: Yicong Yang +Link: https://lore.kernel.org/r/20221117084136.53572-2-yangyicong@huawei.com +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + drivers/perf/hisilicon/hisi_pcie_pmu.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c +index 21771708597d..071e63d9a9ac 100644 +--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c ++++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c +@@ -693,10 +693,10 @@ static struct attribute *hisi_pcie_pmu_events_attr[] = { + HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_cnt, 0x10210), + HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_latency, 0x0011), + HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_cnt, 0x10011), +- HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_flux, 0x1005), +- HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_time, 0x11005), +- HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_flux, 0x2004), +- HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_time, 0x12004), ++ HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_flux, 0x0804), ++ HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_time, 0x10804), ++ HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_flux, 0x0405), ++ HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_time, 0x10405), + NULL + }; + +-- +2.35.1 + diff --git a/queue-6.0/drivers-perf-marvell_cn10k-fix-hotplug-callback-leak.patch b/queue-6.0/drivers-perf-marvell_cn10k-fix-hotplug-callback-leak.patch new file mode 100644 index 00000000000..9b774501d4e --- /dev/null +++ b/queue-6.0/drivers-perf-marvell_cn10k-fix-hotplug-callback-leak.patch @@ -0,0 +1,46 @@ +From 8d243054440a00880bebdeea311c08a0fe10dead Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Nov 2022 07:02:07 +0000 +Subject: drivers: perf: marvell_cn10k: Fix hotplug callback leak in + tad_pmu_init() + +From: Yuan Can + +[ Upstream commit 973ae93d80d9d262f695eb485a1902b74c4b9098 ] + +tad_pmu_init() won't remove the callback added by cpuhp_setup_state_multi() +when platform_driver_register() failed. Remove the callback by +cpuhp_remove_multi_state() in fail path. + +Similar to the handling of arm_ccn_init() in commit 26242b330093 ("bus: +arm-ccn: Prevent hotplug callback leak") + +Fixes: 036a7584bede ("drivers: perf: Add LLC-TAD perf counter support") +Signed-off-by: Yuan Can +Link: https://lore.kernel.org/r/20221115070207.32634-3-yuancan@huawei.com +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + drivers/perf/marvell_cn10k_tad_pmu.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c b/drivers/perf/marvell_cn10k_tad_pmu.c +index 69c3050a4348..a1166afb3702 100644 +--- a/drivers/perf/marvell_cn10k_tad_pmu.c ++++ b/drivers/perf/marvell_cn10k_tad_pmu.c +@@ -408,7 +408,11 @@ static int __init tad_pmu_init(void) + if (ret < 0) + return ret; + tad_pmu_cpuhp_state = ret; +- return platform_driver_register(&tad_pmu_driver); ++ ret = platform_driver_register(&tad_pmu_driver); ++ if (ret) ++ cpuhp_remove_multi_state(tad_pmu_cpuhp_state); ++ ++ return ret; + } + + static void __exit tad_pmu_exit(void) +-- +2.35.1 + diff --git a/queue-6.0/drivers-soc-ti-knav_qmss_queue-mark-knav_acc_firmwar.patch b/queue-6.0/drivers-soc-ti-knav_qmss_queue-mark-knav_acc_firmwar.patch new file mode 100644 index 00000000000..8e2743cbbc2 --- /dev/null +++ b/queue-6.0/drivers-soc-ti-knav_qmss_queue-mark-knav_acc_firmwar.patch @@ -0,0 +1,42 @@ +From 08343d9feccd543970c9d38637c718447cd1eac9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Oct 2022 23:32:12 +0800 +Subject: drivers: soc: ti: knav_qmss_queue: Mark knav_acc_firmwares as static + +From: Chen Jiahao + +[ Upstream commit adf85adc2a7199b41e7a4da083bd17274a3d6969 ] + +There is a sparse warning shown below: + +drivers/soc/ti/knav_qmss_queue.c:70:12: warning: symbol +'knav_acc_firmwares' was not declared. Should it be static? + +Since 'knav_acc_firmwares' is only called within knav_qmss_queue.c, +mark it as static to fix the warning. + +Fixes: 96ee19becc3b ("soc: ti: add firmware file name as part of the driver") +Signed-off-by: Chen Jiahao +Signed-off-by: Nishanth Menon +Link: https://lore.kernel.org/r/20221019153212.72350-1-chenjiahao16@huawei.com +Signed-off-by: Sasha Levin +--- + drivers/soc/ti/knav_qmss_queue.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c +index 92af7d1b6f5b..16a6d530a0d4 100644 +--- a/drivers/soc/ti/knav_qmss_queue.c ++++ b/drivers/soc/ti/knav_qmss_queue.c +@@ -67,7 +67,7 @@ static DEFINE_MUTEX(knav_dev_lock); + * Newest followed by older ones. Search is done from start of the array + * until a firmware file is found. + */ +-const char *knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"}; ++static const char * const knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"}; + + static bool device_ready; + bool knav_qmss_device_ready(void) +-- +2.35.1 + diff --git a/queue-6.0/drivers-staging-r8188eu-fix-sleep-in-atomic-context-.patch b/queue-6.0/drivers-staging-r8188eu-fix-sleep-in-atomic-context-.patch new file mode 100644 index 00000000000..ea9b9978eb4 --- /dev/null +++ b/queue-6.0/drivers-staging-r8188eu-fix-sleep-in-atomic-context-.patch @@ -0,0 +1,54 @@ +From f2c2f0484f0a1d3634f54860fac91bd8f6986f25 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Oct 2022 16:34:24 +0800 +Subject: drivers: staging: r8188eu: Fix sleep-in-atomic-context bug in + rtw_join_timeout_handler + +From: Duoming Zhou + +[ Upstream commit ce8cc75c7419ad54cb99437543a54c97c7446db5 ] + +The rtw_join_timeout_handler() is a timer handler that +runs in atomic context, but it could call msleep(). +As a result, the sleep-in-atomic-context bug will happen. +The process is shown below: + + (atomic context) +rtw_join_timeout_handler + _rtw_join_timeout_handler + rtw_do_join + rtw_select_and_join_from_scanned_queue + rtw_indicate_disconnect + rtw_lps_ctrl_wk_cmd + lps_ctrl_wk_hdl + LPS_Leave + LPS_RF_ON_check + msleep //sleep in atomic context + +Fix by removing msleep() and replacing with mdelay(). + +Fixes: 15865124feed ("staging: r8188eu: introduce new core dir for RTL8188eu driver") +Signed-off-by: Duoming Zhou +Link: https://lore.kernel.org/r/20221018083424.79741-1-duoming@zju.edu.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/staging/r8188eu/core/rtw_pwrctrl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/staging/r8188eu/core/rtw_pwrctrl.c b/drivers/staging/r8188eu/core/rtw_pwrctrl.c +index 10550bd2c16d..abfd14bfd5fb 100644 +--- a/drivers/staging/r8188eu/core/rtw_pwrctrl.c ++++ b/drivers/staging/r8188eu/core/rtw_pwrctrl.c +@@ -273,7 +273,7 @@ static s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms) + err = -1; + break; + } +- msleep(1); ++ mdelay(1); + } + + return err; +-- +2.35.1 + diff --git a/queue-6.0/drm-amd-display-disable-drr-actions-during-state-com.patch b/queue-6.0/drm-amd-display-disable-drr-actions-during-state-com.patch new file mode 100644 index 00000000000..af479716d4d --- /dev/null +++ b/queue-6.0/drm-amd-display-disable-drr-actions-during-state-com.patch @@ -0,0 +1,42 @@ +From e6b03c46bc97964b0b574872b2f6f745134a69ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Oct 2022 19:06:10 -0400 +Subject: drm/amd/display: Disable DRR actions during state commit + +From: Wesley Chalmers + +[ Upstream commit de020e5fa9ebc6fc32e82ae6ccb0282451ed937c ] + +[WHY] +Committing a state while performing DRR actions can cause underflow. + +[HOW] +Disabled features performing DRR actions during state commit. +Need to follow-up on why DRR actions affect state commit. + +Reviewed-by: Jun Lei +Acked-by: Alan Liu +Signed-off-by: Wesley Chalmers +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +index fb59fed8f425..9d369155901a 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +@@ -973,8 +973,5 @@ void dcn30_prepare_bandwidth(struct dc *dc, + dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz); + + dcn20_prepare_bandwidth(dc, context); +- +- dc_dmub_srv_p_state_delegate(dc, +- context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching, context); + } + +-- +2.35.1 + diff --git a/queue-6.0/drm-amd-display-fix-array-index-out-of-bound-error-i.patch b/queue-6.0/drm-amd-display-fix-array-index-out-of-bound-error-i.patch new file mode 100644 index 00000000000..5502b5d42fb --- /dev/null +++ b/queue-6.0/drm-amd-display-fix-array-index-out-of-bound-error-i.patch @@ -0,0 +1,68 @@ +From 00771e1ce0fd6b10c7d9e7bf53d55d8dcaa83b13 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Nov 2022 15:35:53 -0400 +Subject: drm/amd/display: fix array index out of bound error in bios parser + +From: Aurabindo Pillai + +[ Upstream commit 4fc1ba4aa589ca267468ad23fedef37562227d32 ] + +[Why&How] +Firmware headers dictate that gpio_pin array only has a size of 8. The +count returned from vbios however is greater than 8. + +Fix this by not using array indexing but incrementing the pointer since +gpio_pin definition in atomfirmware.h is hardcoded to size 8 + +Reviewed-by: Martin Leung +Acked-by: Tom Chung +Signed-off-by: Aurabindo Pillai +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../gpu/drm/amd/display/dc/bios/bios_parser2.c | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +index de3a1f3fd4f1..c98cd7c5b9f7 100644 +--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c ++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +@@ -487,6 +487,7 @@ static enum bp_result get_gpio_i2c_info( + uint32_t count = 0; + unsigned int table_index = 0; + bool find_valid = false; ++ struct atom_gpio_pin_assignment *pin; + + if (!info) + return BP_RESULT_BADINPUT; +@@ -514,20 +515,17 @@ static enum bp_result get_gpio_i2c_info( + - sizeof(struct atom_common_table_header)) + / sizeof(struct atom_gpio_pin_assignment); + ++ pin = (struct atom_gpio_pin_assignment *) header->gpio_pin; ++ + for (table_index = 0; table_index < count; table_index++) { +- if (((record->i2c_id & I2C_HW_CAP) == ( +- header->gpio_pin[table_index].gpio_id & +- I2C_HW_CAP)) && +- ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) == +- (header->gpio_pin[table_index].gpio_id & +- I2C_HW_ENGINE_ID_MASK)) && +- ((record->i2c_id & I2C_HW_LANE_MUX) == +- (header->gpio_pin[table_index].gpio_id & +- I2C_HW_LANE_MUX))) { ++ if (((record->i2c_id & I2C_HW_CAP) == (pin->gpio_id & I2C_HW_CAP)) && ++ ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) == (pin->gpio_id & I2C_HW_ENGINE_ID_MASK)) && ++ ((record->i2c_id & I2C_HW_LANE_MUX) == (pin->gpio_id & I2C_HW_LANE_MUX))) { + /* still valid */ + find_valid = true; + break; + } ++ pin = (struct atom_gpio_pin_assignment *)((uint8_t *)pin + sizeof(struct atom_gpio_pin_assignment)); + } + + /* If we don't find the entry that we are looking for then +-- +2.35.1 + diff --git a/queue-6.0/drm-amd-display-fix-dtbclk-disable-requests-and-src_.patch b/queue-6.0/drm-amd-display-fix-dtbclk-disable-requests-and-src_.patch new file mode 100644 index 00000000000..46dbb7c4b1e --- /dev/null +++ b/queue-6.0/drm-amd-display-fix-dtbclk-disable-requests-and-src_.patch @@ -0,0 +1,63 @@ +From 56aacff0b50b8d8595f967d37a6c7c264f8cc6b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 19 Nov 2022 11:42:41 -0500 +Subject: drm/amd/display: Fix DTBCLK disable requests and SRC_SEL programming + +From: Alvin Lee + +[ Upstream commit f6015da7f2410109bd2ccd2e2828f26185aeb81d ] + +[Description] +- When transitioning FRL / DP2 is not required, we will always request + DTBCLK = 0Mhz, but PMFW returns the min freq +- This causes us to make DTBCLK requests every time we call optimize + after transitioning from FRL to non-FRL +- If DTBCLK is not required, request the min instead (then we only need + to make 1 extra request at boot time) +- Also when programming PIPE_DTO_SRC_SEL, don't programming for DP + first, just programming once for the required selection (programming + DP on an HDMI connection then switching back causes corruption) + +Reviewed-by: Dillon Varone +Acked-by: Jasdeep Dhillon +Signed-off-by: Alvin Lee +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c | 2 +- + drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c | 6 +----- + 2 files changed, 2 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c +index e7f1d5f8166f..59a29c32f66a 100644 +--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c ++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c +@@ -436,7 +436,7 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base, + } + + if (!new_clocks->dtbclk_en) { +- new_clocks->ref_dtbclk_khz = 0; ++ new_clocks->ref_dtbclk_khz = clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz * 1000; + } + + /* clock limits are received with MHz precision, divide by 1000 to prevent setting clocks at every call */ +diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c +index 6dd8dadd68a5..6f160f65c8fa 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c +@@ -225,11 +225,7 @@ void dccg32_set_dtbclk_dto( + } else { + REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst], + DTBCLK_DTO_ENABLE[params->otg_inst], 0, +- PIPE_DTO_SRC_SEL[params->otg_inst], 1); +- if (params->is_hdmi) +- REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst], +- PIPE_DTO_SRC_SEL[params->otg_inst], 0); +- ++ PIPE_DTO_SRC_SEL[params->otg_inst], params->is_hdmi ? 0 : 1); + REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0); + REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0); + } +-- +2.35.1 + diff --git a/queue-6.0/drm-amd-display-prevent-memory-leak.patch b/queue-6.0/drm-amd-display-prevent-memory-leak.patch new file mode 100644 index 00000000000..ce4c3d39e6a --- /dev/null +++ b/queue-6.0/drm-amd-display-prevent-memory-leak.patch @@ -0,0 +1,73 @@ +From 9267767fb37332f39c59be6e1602ecd57e37c59a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 17:54:05 +0800 +Subject: drm/amd/display: prevent memory leak + +From: gehao + +[ Upstream commit d232afb1f3417ae8194ccf19ad3a8360e70e104e ] + +In dce6(0,1,4)_create_resource_pool and dce80_create_resource_pool +the allocated memory should be released if construct pool fails. + +Reviewed-by: Rodrigo Siqueira +Signed-off-by: gehao +Signed-off-by: Rodrigo Siqueira +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c | 3 +++ + drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c | 2 ++ + 2 files changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c +index fc6aa098bda0..8db9f7514466 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c +@@ -1128,6 +1128,7 @@ struct resource_pool *dce60_create_resource_pool( + if (dce60_construct(num_virtual_links, dc, pool)) + return &pool->base; + ++ kfree(pool); + BREAK_TO_DEBUGGER(); + return NULL; + } +@@ -1325,6 +1326,7 @@ struct resource_pool *dce61_create_resource_pool( + if (dce61_construct(num_virtual_links, dc, pool)) + return &pool->base; + ++ kfree(pool); + BREAK_TO_DEBUGGER(); + return NULL; + } +@@ -1518,6 +1520,7 @@ struct resource_pool *dce64_create_resource_pool( + if (dce64_construct(num_virtual_links, dc, pool)) + return &pool->base; + ++ kfree(pool); + BREAK_TO_DEBUGGER(); + return NULL; + } +diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +index b28025960050..5825e6f412bd 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +@@ -1137,6 +1137,7 @@ struct resource_pool *dce80_create_resource_pool( + if (dce80_construct(num_virtual_links, dc, pool)) + return &pool->base; + ++ kfree(pool); + BREAK_TO_DEBUGGER(); + return NULL; + } +@@ -1336,6 +1337,7 @@ struct resource_pool *dce81_create_resource_pool( + if (dce81_construct(num_virtual_links, dc, pool)) + return &pool->base; + ++ kfree(pool); + BREAK_TO_DEBUGGER(); + return NULL; + } +-- +2.35.1 + diff --git a/queue-6.0/drm-amd-display-use-the-largest-vready_offset-in-pip.patch b/queue-6.0/drm-amd-display-use-the-largest-vready_offset-in-pip.patch new file mode 100644 index 00000000000..bec092088e5 --- /dev/null +++ b/queue-6.0/drm-amd-display-use-the-largest-vready_offset-in-pip.patch @@ -0,0 +1,141 @@ +From a64bc9daaa44a67b59734b935815b6dd03a8eaf2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Nov 2022 17:43:13 -0500 +Subject: drm/amd/display: Use the largest vready_offset in pipe group + +From: Wesley Chalmers + +[ Upstream commit 5842abd985b792a3b13a89b6dae4869b56656c92 ] + +[WHY] +Corruption can occur in LB if vready_offset is not large enough. +DML calculates vready_offset for each pipe, but we currently select the +top pipe's vready_offset, which is not necessarily enough for all pipes +in the group. + +[HOW] +Wherever program_global_sync is currently called, iterate through the +entire pipe group and find the highest vready_offset. + +Reviewed-by: Dillon Varone +Acked-by: Jasdeep Dhillon +Signed-off-by: Wesley Chalmers +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 30 +++++++++++++++++-- + .../drm/amd/display/dc/dcn20/dcn20_hwseq.c | 29 ++++++++++++++++-- + 2 files changed, 55 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +index bc9b92838ea9..d7757e7900ba 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +@@ -867,6 +867,32 @@ static void false_optc_underflow_wa( + tg->funcs->clear_optc_underflow(tg); + } + ++static int calculate_vready_offset_for_group(struct pipe_ctx *pipe) ++{ ++ struct pipe_ctx *other_pipe; ++ int vready_offset = pipe->pipe_dlg_param.vready_offset; ++ ++ /* Always use the largest vready_offset of all connected pipes */ ++ for (other_pipe = pipe->bottom_pipe; other_pipe != NULL; other_pipe = other_pipe->bottom_pipe) { ++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset) ++ vready_offset = other_pipe->pipe_dlg_param.vready_offset; ++ } ++ for (other_pipe = pipe->top_pipe; other_pipe != NULL; other_pipe = other_pipe->top_pipe) { ++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset) ++ vready_offset = other_pipe->pipe_dlg_param.vready_offset; ++ } ++ for (other_pipe = pipe->next_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->next_odm_pipe) { ++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset) ++ vready_offset = other_pipe->pipe_dlg_param.vready_offset; ++ } ++ for (other_pipe = pipe->prev_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->prev_odm_pipe) { ++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset) ++ vready_offset = other_pipe->pipe_dlg_param.vready_offset; ++ } ++ ++ return vready_offset; ++} ++ + enum dc_status dcn10_enable_stream_timing( + struct pipe_ctx *pipe_ctx, + struct dc_state *context, +@@ -902,7 +928,7 @@ enum dc_status dcn10_enable_stream_timing( + pipe_ctx->stream_res.tg->funcs->program_timing( + pipe_ctx->stream_res.tg, + &stream->timing, +- pipe_ctx->pipe_dlg_param.vready_offset, ++ calculate_vready_offset_for_group(pipe_ctx), + pipe_ctx->pipe_dlg_param.vstartup_start, + pipe_ctx->pipe_dlg_param.vupdate_offset, + pipe_ctx->pipe_dlg_param.vupdate_width, +@@ -2869,7 +2895,7 @@ void dcn10_program_pipe( + + pipe_ctx->stream_res.tg->funcs->program_global_sync( + pipe_ctx->stream_res.tg, +- pipe_ctx->pipe_dlg_param.vready_offset, ++ calculate_vready_offset_for_group(pipe_ctx), + pipe_ctx->pipe_dlg_param.vstartup_start, + pipe_ctx->pipe_dlg_param.vupdate_offset, + pipe_ctx->pipe_dlg_param.vupdate_width); +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +index 146189323dbe..cd799ce6e48b 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +@@ -1608,6 +1608,31 @@ static void dcn20_update_dchubp_dpp( + hubp->funcs->phantom_hubp_post_enable(hubp); + } + ++static int calculate_vready_offset_for_group(struct pipe_ctx *pipe) ++{ ++ struct pipe_ctx *other_pipe; ++ int vready_offset = pipe->pipe_dlg_param.vready_offset; ++ ++ /* Always use the largest vready_offset of all connected pipes */ ++ for (other_pipe = pipe->bottom_pipe; other_pipe != NULL; other_pipe = other_pipe->bottom_pipe) { ++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset) ++ vready_offset = other_pipe->pipe_dlg_param.vready_offset; ++ } ++ for (other_pipe = pipe->top_pipe; other_pipe != NULL; other_pipe = other_pipe->top_pipe) { ++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset) ++ vready_offset = other_pipe->pipe_dlg_param.vready_offset; ++ } ++ for (other_pipe = pipe->next_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->next_odm_pipe) { ++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset) ++ vready_offset = other_pipe->pipe_dlg_param.vready_offset; ++ } ++ for (other_pipe = pipe->prev_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->prev_odm_pipe) { ++ if (other_pipe->pipe_dlg_param.vready_offset > vready_offset) ++ vready_offset = other_pipe->pipe_dlg_param.vready_offset; ++ } ++ ++ return vready_offset; ++} + + static void dcn20_program_pipe( + struct dc *dc, +@@ -1626,7 +1651,7 @@ static void dcn20_program_pipe( + && !pipe_ctx->prev_odm_pipe) { + pipe_ctx->stream_res.tg->funcs->program_global_sync( + pipe_ctx->stream_res.tg, +- pipe_ctx->pipe_dlg_param.vready_offset, ++ calculate_vready_offset_for_group(pipe_ctx), + pipe_ctx->pipe_dlg_param.vstartup_start, + pipe_ctx->pipe_dlg_param.vupdate_offset, + pipe_ctx->pipe_dlg_param.vupdate_width); +@@ -2038,7 +2063,7 @@ bool dcn20_update_bandwidth( + + pipe_ctx->stream_res.tg->funcs->program_global_sync( + pipe_ctx->stream_res.tg, +- pipe_ctx->pipe_dlg_param.vready_offset, ++ calculate_vready_offset_for_group(pipe_ctx), + pipe_ctx->pipe_dlg_param.vstartup_start, + pipe_ctx->pipe_dlg_param.vupdate_offset, + pipe_ctx->pipe_dlg_param.vupdate_width); +-- +2.35.1 + diff --git a/queue-6.0/drm-amd-display-wait-for-vblank-during-pipe-programm.patch b/queue-6.0/drm-amd-display-wait-for-vblank-during-pipe-programm.patch new file mode 100644 index 00000000000..ab4e5c08c00 --- /dev/null +++ b/queue-6.0/drm-amd-display-wait-for-vblank-during-pipe-programm.patch @@ -0,0 +1,48 @@ +From 3ffee9028d10a5d17e7be56c5bb7f81cd00faf08 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Oct 2022 11:46:54 -0400 +Subject: drm/amd/display: wait for vblank during pipe programming + +From: Haiyi Zhou + +[ Upstream commit 203ccaf586446b578909de1b763278033fb74b51 ] + +[WHY] +Skipping vblank during global sync update request can result in +underflow on certain displays. + +[HOW] +Roll back to the previous behavior where DC waits for vblank during pipe +programming. + +Fixes: 5d3e14421410 ("drm/amd/display: do not wait for vblank during pipe programming") +Tested-by: Mark Broadworth +Reviewed-by: Martin Leung +Acked-by: Rodrigo Siqueira +Signed-off-by: Haiyi Zhou +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +index 0f30df523fdf..146189323dbe 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +@@ -1632,10 +1632,8 @@ static void dcn20_program_pipe( + pipe_ctx->pipe_dlg_param.vupdate_width); + + if (pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) { +- pipe_ctx->stream_res.tg->funcs->wait_for_state( +- pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK); +- pipe_ctx->stream_res.tg->funcs->wait_for_state( +- pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE); ++ pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK); ++ pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE); + } + + pipe_ctx->stream_res.tg->funcs->set_vtg_params( +-- +2.35.1 + diff --git a/queue-6.0/drm-amd-display-workaround-to-increase-phantom-pipe-.patch b/queue-6.0/drm-amd-display-workaround-to-increase-phantom-pipe-.patch new file mode 100644 index 00000000000..0a217727c8d --- /dev/null +++ b/queue-6.0/drm-amd-display-workaround-to-increase-phantom-pipe-.patch @@ -0,0 +1,61 @@ +From 1964447fb162463d085feb3a4ccb2c46375294df Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Nov 2022 00:16:56 -0400 +Subject: drm/amd/display: Workaround to increase phantom pipe vactive in + pipesplit + +From: George Shen + +[ Upstream commit 5b8f9deaf3b6badfc0da968e6e07ceabd19700b6 ] + +[Why] +Certain high resolution displays exhibit DCC line corruption with SubVP +enabled. This is likely due to insufficient DCC meta data buffered +immediately after the mclk switch. + +[How] +Add workaround to increase phantom pipe vactive height by +meta_row_height number of lines, thus increasing the amount of meta data +buffered immediately after mclk switch finishes. + +Reviewed-by: Alvin Lee +Acked-by: Tom Chung +Signed-off-by: George Shen +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +index 07c56e231b04..d05df4f7139f 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +@@ -485,9 +485,11 @@ void dcn32_set_phantom_stream_timing(struct dc *dc, + unsigned int i, pipe_idx; + struct pipe_ctx *pipe; + uint32_t phantom_vactive, phantom_bp, pstate_width_fw_delay_lines; ++ unsigned int num_dpp; + unsigned int vlevel = context->bw_ctx.dml.vba.VoltageLevel; + unsigned int dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb]; + unsigned int socclk = context->bw_ctx.dml.vba.SOCCLKPerState[vlevel]; ++ struct vba_vars_st *vba = &context->bw_ctx.dml.vba; + + dc_assert_fp_enabled(); + +@@ -523,6 +525,11 @@ void dcn32_set_phantom_stream_timing(struct dc *dc, + phantom_vactive = get_subviewport_lines_needed_in_mall(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx) + + pstate_width_fw_delay_lines + dc->caps.subvp_swath_height_margin_lines; + ++ // W/A for DCC corruption with certain high resolution timings. ++ // Determing if pipesplit is used. If so, add meta_row_height to the phantom vactive. ++ num_dpp = vba->NoOfDPP[vba->VoltageLevel][vba->maxMpcComb][vba->pipe_plane[pipe_idx]]; ++ phantom_vactive += num_dpp > 1 ? vba->meta_row_height[vba->pipe_plane[pipe_idx]] : 0; ++ + // For backporch of phantom pipe, use vstartup of the main pipe + phantom_bp = get_vstartup(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); + +-- +2.35.1 + diff --git a/queue-6.0/drm-amd-pm-smu11-baco-is-supported-when-it-s-in-baco.patch b/queue-6.0/drm-amd-pm-smu11-baco-is-supported-when-it-s-in-baco.patch new file mode 100644 index 00000000000..33387eca35d --- /dev/null +++ b/queue-6.0/drm-amd-pm-smu11-baco-is-supported-when-it-s-in-baco.patch @@ -0,0 +1,43 @@ +From f170dcdd8d658050e8ab4e0705c59643113ccd6f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Nov 2022 17:33:24 +0800 +Subject: drm/amd/pm/smu11: BACO is supported when it's in BACO state + +From: Guchun Chen + +[ Upstream commit 6dca7efe6e522bf213c7dab691fa580d82f48f74 ] + +Return true early if ASIC is in BACO state already, no need +to talk to SMU. It can fix the issue that driver was not +calling BACO exit at all in runtime pm resume, and a timing +issue leading to a PCI AER error happened eventually. + +Fixes: 8795e182b02d ("PCI/portdrv: Don't disable AER reporting in get_port_device_capability()") +Suggested-by: Lijo Lazar +Signed-off-by: Guchun Chen +Reviewed-by: Lijo Lazar +Reviewed-by: Evan Quan +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +index 70b560737687..ad5f6a15a1d7 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +@@ -1588,6 +1588,10 @@ bool smu_v11_0_baco_is_support(struct smu_context *smu) + if (amdgpu_sriov_vf(smu->adev) || !smu_baco->platform_support) + return false; + ++ /* return true if ASIC is in BACO state already */ ++ if (smu_v11_0_baco_get_state(smu) == SMU_BACO_STATE_ENTER) ++ return true; ++ + /* Arcturus does not support this bit mask */ + if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_BACO_BIT) && + !smu_cmn_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT)) +-- +2.35.1 + diff --git a/queue-6.0/drm-amdgpu-fix-pci-device-refcount-leak-in-amdgpu_at.patch b/queue-6.0/drm-amdgpu-fix-pci-device-refcount-leak-in-amdgpu_at.patch new file mode 100644 index 00000000000..a583eab5c7a --- /dev/null +++ b/queue-6.0/drm-amdgpu-fix-pci-device-refcount-leak-in-amdgpu_at.patch @@ -0,0 +1,40 @@ +From facdee3c596627308659e5741cba661f7ad39e5e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Nov 2022 19:30:43 +0800 +Subject: drm/amdgpu: Fix PCI device refcount leak in amdgpu_atrm_get_bios() + +From: Xiongfeng Wang + +[ Upstream commit ca54639c7752edf1304d92ff4d0c049d4efc9ba0 ] + +As comment of pci_get_class() says, it returns a pci_device with its +refcount increased and decreased the refcount for the input parameter +@from if it is not NULL. + +If we break the loop in amdgpu_atrm_get_bios() with 'pdev' not NULL, we +need to call pci_dev_put() to decrease the refcount. Add the missing +pci_dev_put() to avoid refcount leak. + +Fixes: d38ceaf99ed0 ("drm/amdgpu: add core driver (v4)") +Signed-off-by: Xiongfeng Wang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c +index e363f56c72af..30c28a69e847 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c +@@ -317,6 +317,7 @@ static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev) + + if (!found) + return false; ++ pci_dev_put(pdev); + + adev->bios = kmalloc(size, GFP_KERNEL); + if (!adev->bios) { +-- +2.35.1 + diff --git a/queue-6.0/drm-amdgpu-fix-pci-device-refcount-leak.patch b/queue-6.0/drm-amdgpu-fix-pci-device-refcount-leak.patch new file mode 100644 index 00000000000..82565dde537 --- /dev/null +++ b/queue-6.0/drm-amdgpu-fix-pci-device-refcount-leak.patch @@ -0,0 +1,58 @@ +From 210d7c26340dc40fa3f42fd263029f205672712e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 23:00:03 +0800 +Subject: drm/amdgpu: fix pci device refcount leak + +From: Yang Yingliang + +[ Upstream commit b85e285e3d6352b02947fc1b72303673dfacb0aa ] + +As comment of pci_get_domain_bus_and_slot() says, it returns +a pci device with refcount increment, when finish using it, +the caller must decrement the reference count by calling +pci_dev_put(). + +So before returning from amdgpu_device_resume|suspend_display_audio(), +pci_dev_put() is called to avoid refcount leak. + +Fixes: 3f12acc8d6d4 ("drm/amdgpu: put the audio codec into suspend state before gpu reset V3") +Reviewed-by: Evan Quan +Signed-off-by: Yang Yingliang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index e0c960cc1d2e..f04e698e631c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -5004,6 +5004,8 @@ static void amdgpu_device_resume_display_audio(struct amdgpu_device *adev) + pm_runtime_enable(&(p->dev)); + pm_runtime_resume(&(p->dev)); + } ++ ++ pci_dev_put(p); + } + + static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev) +@@ -5042,6 +5044,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev) + + if (expires < ktime_get_mono_fast_ns()) { + dev_warn(adev->dev, "failed to suspend display audio\n"); ++ pci_dev_put(p); + /* TODO: abort the succeeding gpu reset? */ + return -ETIMEDOUT; + } +@@ -5049,6 +5052,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev) + + pm_runtime_disable(&(p->dev)); + ++ pci_dev_put(p); + return 0; + } + +-- +2.35.1 + diff --git a/queue-6.0/drm-amdgpu-fix-type-of-second-parameter-in-odn_edit_.patch b/queue-6.0/drm-amdgpu-fix-type-of-second-parameter-in-odn_edit_.patch new file mode 100644 index 00000000000..654870cfec0 --- /dev/null +++ b/queue-6.0/drm-amdgpu-fix-type-of-second-parameter-in-odn_edit_.patch @@ -0,0 +1,78 @@ +From 50aede00d5f3b498ce488a0721add0f82ec2527d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Nov 2022 08:25:40 -0700 +Subject: drm/amdgpu: Fix type of second parameter in odn_edit_dpm_table() + callback + +From: Nathan Chancellor + +[ Upstream commit e4d0ef752081e7aa6ffb7ccac11c499c732a2e05 ] + +With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG), +indirect call targets are validated against the expected function +pointer prototype to make sure the call target is valid to help mitigate +ROP attacks. If they are not identical, there is a failure at run time, +which manifests as either a kernel panic or thread getting killed. A +proposed warning in clang aims to catch these at compile time, which +reveals: + + drivers/gpu/drm/amd/amdgpu/../pm/swsmu/amdgpu_smu.c:3008:29: error: incompatible function pointer types initializing 'int (*)(void *, uint32_t, long *, uint32_t)' (aka 'int (*)(void *, unsigned int, long *, unsigned int)') with an expression of type 'int (void *, enum PP_OD_DPM_TABLE_COMMAND, long *, uint32_t)' (aka 'int (void *, enum PP_OD_DPM_TABLE_COMMAND, long *, unsigned int)') [-Werror,-Wincompatible-function-pointer-types-strict] + .odn_edit_dpm_table = smu_od_edit_dpm_table, + ^~~~~~~~~~~~~~~~~~~~~ + 1 error generated. + +There are only two implementations of ->odn_edit_dpm_table() in 'struct +amd_pm_funcs': smu_od_edit_dpm_table() and pp_odn_edit_dpm_table(). One +has a second parameter type of 'enum PP_OD_DPM_TABLE_COMMAND' and the +other uses 'u32'. Ultimately, smu_od_edit_dpm_table() calls +->od_edit_dpm_table() from 'struct pptable_funcs' and +pp_odn_edit_dpm_table() calls ->odn_edit_dpm_table() from 'struct +pp_hwmgr_func', which both have a second parameter type of 'enum +PP_OD_DPM_TABLE_COMMAND'. + +Update the type parameter in both the prototype in 'struct amd_pm_funcs' +and pp_odn_edit_dpm_table() to 'enum PP_OD_DPM_TABLE_COMMAND', which +cleans up the warning. + +Link: https://github.com/ClangBuiltLinux/linux/issues/1750 +Reported-by: Sami Tolvanen +Reviewed-by: Kees Cook +Signed-off-by: Nathan Chancellor +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/include/kgd_pp_interface.h | 3 ++- + drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h +index 7e3231c2191c..ffe19883b2ee 100644 +--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h ++++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h +@@ -354,7 +354,8 @@ struct amd_pm_funcs { + int (*get_power_profile_mode)(void *handle, char *buf); + int (*set_power_profile_mode)(void *handle, long *input, uint32_t size); + int (*set_fine_grain_clk_vol)(void *handle, uint32_t type, long *input, uint32_t size); +- int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size); ++ int (*odn_edit_dpm_table)(void *handle, enum PP_OD_DPM_TABLE_COMMAND type, ++ long *input, uint32_t size); + int (*set_mp1_state)(void *handle, enum pp_mp1_state mp1_state); + int (*smu_i2c_bus_access)(void *handle, bool acquire); + int (*gfx_state_change_set)(void *handle, uint32_t state); +diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +index 1eb4e613b27a..6562978de84a 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +@@ -838,7 +838,8 @@ static int pp_set_fine_grain_clk_vol(void *handle, uint32_t type, long *input, u + return hwmgr->hwmgr_func->set_fine_grain_clk_vol(hwmgr, type, input, size); + } + +-static int pp_odn_edit_dpm_table(void *handle, uint32_t type, long *input, uint32_t size) ++static int pp_odn_edit_dpm_table(void *handle, enum PP_OD_DPM_TABLE_COMMAND type, ++ long *input, uint32_t size) + { + struct pp_hwmgr *hwmgr = handle; + +-- +2.35.1 + diff --git a/queue-6.0/drm-amdgpu-fix-type-of-second-parameter-in-trans_msg.patch b/queue-6.0/drm-amdgpu-fix-type-of-second-parameter-in-trans_msg.patch new file mode 100644 index 00000000000..4313fbf3e11 --- /dev/null +++ b/queue-6.0/drm-amdgpu-fix-type-of-second-parameter-in-trans_msg.patch @@ -0,0 +1,66 @@ +From 0925827973d2389c0b69ee88ba03ed7bc4471b22 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Nov 2022 08:25:39 -0700 +Subject: drm/amdgpu: Fix type of second parameter in trans_msg() callback + +From: Nathan Chancellor + +[ Upstream commit f0d0f1087333714ee683cc134a95afe331d7ddd9 ] + +With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG), +indirect call targets are validated against the expected function +pointer prototype to make sure the call target is valid to help mitigate +ROP attacks. If they are not identical, there is a failure at run time, +which manifests as either a kernel panic or thread getting killed. A +proposed warning in clang aims to catch these at compile time, which +reveals: + + drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c:412:15: error: incompatible function pointer types initializing 'void (*)(struct amdgpu_device *, u32, u32, u32, u32)' (aka 'void (*)(struct amdgpu_device *, unsigned int, unsigned int, unsigned int, unsigned int)') with an expression of type 'void (struct amdgpu_device *, enum idh_request, u32, u32, u32)' (aka 'void (struct amdgpu_device *, enum idh_request, unsigned int, unsigned int, unsigned int)') [-Werror,-Wincompatible-function-pointer-types-strict] + .trans_msg = xgpu_ai_mailbox_trans_msg, + ^~~~~~~~~~~~~~~~~~~~~~~~~ + 1 error generated. + + drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c:435:15: error: incompatible function pointer types initializing 'void (*)(struct amdgpu_device *, u32, u32, u32, u32)' (aka 'void (*)(struct amdgpu_device *, unsigned int, unsigned int, unsigned int, unsigned int)') with an expression of type 'void (struct amdgpu_device *, enum idh_request, u32, u32, u32)' (aka 'void (struct amdgpu_device *, enum idh_request, unsigned int, unsigned int, unsigned int)') [-Werror,-Wincompatible-function-pointer-types-strict] + .trans_msg = xgpu_nv_mailbox_trans_msg, + ^~~~~~~~~~~~~~~~~~~~~~~~~ + 1 error generated. + +The type of the second parameter in the prototype should be 'enum +idh_request' instead of 'u32'. Update it to clear up the warnings. + +Link: https://github.com/ClangBuiltLinux/linux/issues/1750 +Reported-by: Sami Tolvanen +Reviewed-by: Kees Cook +Signed-off-by: Nathan Chancellor +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +index 617d072275eb..77210fd64a2b 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +@@ -75,6 +75,8 @@ struct amdgpu_vf_error_buffer { + uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE]; + }; + ++enum idh_request; ++ + /** + * struct amdgpu_virt_ops - amdgpu device virt operations + */ +@@ -84,7 +86,8 @@ struct amdgpu_virt_ops { + int (*req_init_data)(struct amdgpu_device *adev); + int (*reset_gpu)(struct amdgpu_device *adev); + int (*wait_reset)(struct amdgpu_device *adev); +- void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3); ++ void (*trans_msg)(struct amdgpu_device *adev, enum idh_request req, ++ u32 data1, u32 data2, u32 data3); + }; + + /* +-- +2.35.1 + diff --git a/queue-6.0/drm-amdgpu-powerplay-psm-fix-memory-leak-in-power-st.patch b/queue-6.0/drm-amdgpu-powerplay-psm-fix-memory-leak-in-power-st.patch new file mode 100644 index 00000000000..c400846e709 --- /dev/null +++ b/queue-6.0/drm-amdgpu-powerplay-psm-fix-memory-leak-in-power-st.patch @@ -0,0 +1,41 @@ +From 105a948e673886da078c10119df136f18bcda803 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Oct 2022 21:53:57 -0300 +Subject: drm/amdgpu/powerplay/psm: Fix memory leak in power state init + +From: Rafael Mendonca + +[ Upstream commit 8f8033d5663b18e6efb33feb61f2287a04605ab5 ] + +Commit 902bc65de0b3 ("drm/amdgpu/powerplay/psm: return an error in power +state init") made the power state init function return early in case of +failure to get an entry from the powerplay table, but it missed to clean up +the allocated memory for the current power state before returning. + +Fixes: 902bc65de0b3 ("drm/amdgpu/powerplay/psm: return an error in power state init") +Reviewed-by: Evan Quan +Signed-off-by: Rafael Mendonca +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c +index 67d7da0b6fed..1d829402cd2e 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c +@@ -75,8 +75,10 @@ int psm_init_power_state_table(struct pp_hwmgr *hwmgr) + for (i = 0; i < table_entries; i++) { + result = hwmgr->hwmgr_func->get_pp_table_entry(hwmgr, i, state); + if (result) { ++ kfree(hwmgr->current_ps); + kfree(hwmgr->request_ps); + kfree(hwmgr->ps); ++ hwmgr->current_ps = NULL; + hwmgr->request_ps = NULL; + hwmgr->ps = NULL; + return -EINVAL; +-- +2.35.1 + diff --git a/queue-6.0/drm-amdkfd-fix-memory-leakage.patch b/queue-6.0/drm-amdkfd-fix-memory-leakage.patch new file mode 100644 index 00000000000..53395886479 --- /dev/null +++ b/queue-6.0/drm-amdkfd-fix-memory-leakage.patch @@ -0,0 +1,38 @@ +From 0e4976d87526bf050fa0e02ccadfe6b3177430e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Nov 2022 23:02:54 -0500 +Subject: drm/amdkfd: Fix memory leakage + +From: Konstantin Meskhidze + +[ Upstream commit 75818afff631e1ea785a82c3e8bb82eb0dee539c ] + +This patch fixes potential memory leakage and seg fault +in _gpuvm_import_dmabuf() function + +Fixes: d4ec4bdc0bd5 ("drm/amdkfd: Allow access for mmapping KFD BOs") +Signed-off-by: Konstantin Meskhidze +Signed-off-by: Felix Kuehling +Reviewed-by: Felix Kuehling +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +index 5e184952ec98..6659630303a3 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +@@ -2253,7 +2253,7 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev, + + ret = drm_vma_node_allow(&obj->vma_node, drm_priv); + if (ret) { +- kfree(mem); ++ kfree(*mem); + return ret; + } + +-- +2.35.1 + diff --git a/queue-6.0/drm-atomic-helper-don-t-allocate-new-plane-state-in-.patch b/queue-6.0/drm-atomic-helper-don-t-allocate-new-plane-state-in-.patch new file mode 100644 index 00000000000..5b9e2b7ab79 --- /dev/null +++ b/queue-6.0/drm-atomic-helper-don-t-allocate-new-plane-state-in-.patch @@ -0,0 +1,78 @@ +From 66f00960b3a4a823fcefcea790b915c34e4558c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Oct 2022 14:43:37 +0200 +Subject: drm/atomic-helper: Don't allocate new plane state in CRTC check + +From: Thomas Zimmermann + +[ Upstream commit dbbf933d365da1a76a540211bee3d57bde520194 ] + +In drm_atomic_helper_check_crtc_state(), do not add a new plane state +to the global state if it does not exist already. Adding a new plane +state will result in overhead for the plane during the atomic-commit +step. + +For the test in drm_atomic_helper_check_crtc_state() to succeed, it +is important that the CRTC has an enabled primary plane after the +commit. Simply testing the CRTC state's plane_mask for a primary plane +is sufficient. + +Note that the helper still only tests for an attached primary plane. +Drivers have to ensure that the plane contains valid pixel information. + +v5: + * fix commit description (Javier) +v3: + * test for a primary plane in plane_mask (Ville) +v2: + * remove unnecessary test for plane->crtc (Ville) + * inline drm_atomic_get_next_plane_state() (Ville) + * acquire plane lock before accessing plane->state (Ville) + +Signed-off-by: Thomas Zimmermann +Reviewed-by: Javier Martinez Canillas +Fixes: d6b9af1097fe ("drm/atomic-helper: Add helper drm_atomic_helper_check_crtc_state()") +Cc: Thomas Zimmermann +Cc: Jocelyn Falempe +Cc: Maarten Lankhorst +Cc: Maxime Ripard +Cc: David Airlie +Cc: Daniel Vetter +Cc: dri-devel@lists.freedesktop.org +Link: https://patchwork.freedesktop.org/patch/msgid/20221007124338.24152-2-tzimmermann@suse.de +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_atomic_helper.c | 10 +--------- + 1 file changed, 1 insertion(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c +index 8bf41aa24068..6526d6ade04b 100644 +--- a/drivers/gpu/drm/drm_atomic_helper.c ++++ b/drivers/gpu/drm/drm_atomic_helper.c +@@ -899,7 +899,6 @@ int drm_atomic_helper_check_crtc_state(struct drm_crtc_state *crtc_state, + bool can_disable_primary_planes) + { + struct drm_device *dev = crtc_state->crtc->dev; +- struct drm_atomic_state *state = crtc_state->state; + + if (!crtc_state->enable) + return 0; +@@ -910,14 +909,7 @@ int drm_atomic_helper_check_crtc_state(struct drm_crtc_state *crtc_state, + struct drm_plane *plane; + + drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) { +- struct drm_plane_state *plane_state; +- +- if (plane->type != DRM_PLANE_TYPE_PRIMARY) +- continue; +- plane_state = drm_atomic_get_plane_state(state, plane); +- if (IS_ERR(plane_state)) +- return PTR_ERR(plane_state); +- if (plane_state->fb && plane_state->crtc) { ++ if (plane->type == DRM_PLANE_TYPE_PRIMARY) { + has_primary_plane = true; + break; + } +-- +2.35.1 + diff --git a/queue-6.0/drm-bridge-adv7533-remove-dynamic-lane-switching-fro.patch b/queue-6.0/drm-bridge-adv7533-remove-dynamic-lane-switching-fro.patch new file mode 100644 index 00000000000..bf6855ae19a --- /dev/null +++ b/queue-6.0/drm-bridge-adv7533-remove-dynamic-lane-switching-fro.patch @@ -0,0 +1,228 @@ +From 5c1bf19bf3049d5422146df968e60a016baffe1c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Oct 2022 14:10:49 -0700 +Subject: drm/bridge: adv7533: remove dynamic lane switching from adv7533 + bridge + +From: Abhinav Kumar + +[ Upstream commit 9a0cdcd6649b76f0b7ceec0e55b0a718321e34d3 ] + +adv7533 bridge tries to dynamically switch lanes based on the +mode by detaching and attaching the mipi dsi device. + +This approach is incorrect because this method of dynamic switch of +detaching and attaching the mipi dsi device also results in removing +and adding the component which is not necessary. + +This approach is also prone to deadlocks. So for example, on the +db410c whenever this path is executed with lockdep enabled, +this results in a deadlock due to below ordering of locks. + +-> #1 (crtc_ww_class_acquire){+.+.}-{0:0}: + lock_acquire+0x6c/0x90 + drm_modeset_acquire_init+0xf4/0x150 + drmm_mode_config_init+0x220/0x770 + msm_drm_bind+0x13c/0x654 + try_to_bring_up_aggregate_device+0x164/0x1d0 + __component_add+0xa8/0x174 + component_add+0x18/0x2c + dsi_dev_attach+0x24/0x30 + dsi_host_attach+0x98/0x14c + devm_mipi_dsi_attach+0x38/0xb0 + adv7533_attach_dsi+0x8c/0x110 + adv7511_probe+0x5a0/0x930 + i2c_device_probe+0x30c/0x350 + really_probe.part.0+0x9c/0x2b0 + __driver_probe_device+0x98/0x144 + driver_probe_device+0xac/0x14c + __device_attach_driver+0xbc/0x124 + bus_for_each_drv+0x78/0xd0 + __device_attach+0xa8/0x1c0 + device_initial_probe+0x18/0x24 + bus_probe_device+0xa0/0xac + deferred_probe_work_func+0x90/0xd0 + process_one_work+0x28c/0x6b0 + worker_thread+0x240/0x444 + kthread+0x110/0x114 + ret_from_fork+0x10/0x20 + +-> #0 (component_mutex){+.+.}-{3:3}: + __lock_acquire+0x1280/0x20ac + lock_acquire.part.0+0xe0/0x230 + lock_acquire+0x6c/0x90 + __mutex_lock+0x84/0x400 + mutex_lock_nested+0x3c/0x70 + component_del+0x34/0x170 + dsi_dev_detach+0x24/0x30 + dsi_host_detach+0x20/0x64 + mipi_dsi_detach+0x2c/0x40 + adv7533_mode_set+0x64/0x90 + adv7511_bridge_mode_set+0x210/0x214 + drm_bridge_chain_mode_set+0x5c/0x84 + crtc_set_mode+0x18c/0x1dc + drm_atomic_helper_commit_modeset_disables+0x40/0x50 + msm_atomic_commit_tail+0x1d0/0x6e0 + commit_tail+0xa4/0x180 + drm_atomic_helper_commit+0x178/0x3b0 + drm_atomic_commit+0xa4/0xe0 + drm_client_modeset_commit_atomic+0x228/0x284 + drm_client_modeset_commit_locked+0x64/0x1d0 + drm_client_modeset_commit+0x34/0x60 + drm_fb_helper_lastclose+0x74/0xcc + drm_lastclose+0x3c/0x80 + drm_release+0xfc/0x114 + __fput+0x70/0x224 + ____fput+0x14/0x20 + task_work_run+0x88/0x1a0 + do_exit+0x350/0xa50 + do_group_exit+0x38/0xa4 + __wake_up_parent+0x0/0x34 + invoke_syscall+0x48/0x114 + el0_svc_common.constprop.0+0x60/0x11c + do_el0_svc+0x30/0xc0 + el0_svc+0x58/0x100 + el0t_64_sync_handler+0x1b0/0x1bc + el0t_64_sync+0x18c/0x190 + +Due to above reasons, remove the dynamic lane switching +code from adv7533 bridge chip and filter out the modes +which would need different number of lanes as compared +to the initialization time using the mode_valid callback. + +This can be potentially re-introduced by using the pre_enable() +callback but this needs to be evaluated first whether such an +approach will work so this will be done with a separate change. + +changes since RFC: + - Fix commit text and add TODO comment + +changes in v2: + - Fix checkpatch formatting errors + +Fixes: 62b2f026cd8e ("drm/bridge: adv7533: Change number of DSI lanes dynamically") +Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/16 +Suggested-by: Dmitry Baryshkov +Signed-off-by: Abhinav Kumar +Reviewed-by: Robert Foss +Link: https://lore.kernel.org/r/1661797363-7564-1-git-send-email-quic_abhinavk@quicinc.com +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/1665522649-3423-1-git-send-email-quic_abhinavk@quicinc.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/adv7511/adv7511.h | 3 ++- + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 18 ++++++++++---- + drivers/gpu/drm/bridge/adv7511/adv7533.c | 25 ++++++++++---------- + 3 files changed, 29 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h +index 94de73cbeb2d..17445800248d 100644 +--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h ++++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h +@@ -402,7 +402,8 @@ static inline int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) + + void adv7533_dsi_power_on(struct adv7511 *adv); + void adv7533_dsi_power_off(struct adv7511 *adv); +-void adv7533_mode_set(struct adv7511 *adv, const struct drm_display_mode *mode); ++enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, ++ const struct drm_display_mode *mode); + int adv7533_patch_registers(struct adv7511 *adv); + int adv7533_patch_cec_registers(struct adv7511 *adv); + int adv7533_attach_dsi(struct adv7511 *adv); +diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +index 6031bdd92342..0f0950c11196 100644 +--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c ++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +@@ -697,7 +697,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector) + } + + static enum drm_mode_status adv7511_mode_valid(struct adv7511 *adv7511, +- struct drm_display_mode *mode) ++ const struct drm_display_mode *mode) + { + if (mode->clock > 165000) + return MODE_CLOCK_HIGH; +@@ -791,9 +791,6 @@ static void adv7511_mode_set(struct adv7511 *adv7511, + regmap_update_bits(adv7511->regmap, 0x17, + 0x60, (vsync_polarity << 6) | (hsync_polarity << 5)); + +- if (adv7511->type == ADV7533 || adv7511->type == ADV7535) +- adv7533_mode_set(adv7511, adj_mode); +- + drm_mode_copy(&adv7511->curr_mode, adj_mode); + + /* +@@ -913,6 +910,18 @@ static void adv7511_bridge_mode_set(struct drm_bridge *bridge, + adv7511_mode_set(adv, mode, adj_mode); + } + ++static enum drm_mode_status adv7511_bridge_mode_valid(struct drm_bridge *bridge, ++ const struct drm_display_info *info, ++ const struct drm_display_mode *mode) ++{ ++ struct adv7511 *adv = bridge_to_adv7511(bridge); ++ ++ if (adv->type == ADV7533 || adv->type == ADV7535) ++ return adv7533_mode_valid(adv, mode); ++ else ++ return adv7511_mode_valid(adv, mode); ++} ++ + static int adv7511_bridge_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) + { +@@ -960,6 +969,7 @@ static const struct drm_bridge_funcs adv7511_bridge_funcs = { + .enable = adv7511_bridge_enable, + .disable = adv7511_bridge_disable, + .mode_set = adv7511_bridge_mode_set, ++ .mode_valid = adv7511_bridge_mode_valid, + .attach = adv7511_bridge_attach, + .detect = adv7511_bridge_detect, + .get_edid = adv7511_bridge_get_edid, +diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c +index ef6270806d1d..258c79d4dab0 100644 +--- a/drivers/gpu/drm/bridge/adv7511/adv7533.c ++++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c +@@ -100,26 +100,27 @@ void adv7533_dsi_power_off(struct adv7511 *adv) + regmap_write(adv->regmap_cec, 0x27, 0x0b); + } + +-void adv7533_mode_set(struct adv7511 *adv, const struct drm_display_mode *mode) ++enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, ++ const struct drm_display_mode *mode) + { ++ int lanes; + struct mipi_dsi_device *dsi = adv->dsi; +- int lanes, ret; +- +- if (adv->num_dsi_lanes != 4) +- return; + + if (mode->clock > 80000) + lanes = 4; + else + lanes = 3; + +- if (lanes != dsi->lanes) { +- mipi_dsi_detach(dsi); +- dsi->lanes = lanes; +- ret = mipi_dsi_attach(dsi); +- if (ret) +- dev_err(&dsi->dev, "failed to change host lanes\n"); +- } ++ /* ++ * TODO: add support for dynamic switching of lanes ++ * by using the bridge pre_enable() op . Till then filter ++ * out the modes which shall need different number of lanes ++ * than what was configured in the device tree. ++ */ ++ if (lanes != dsi->lanes) ++ return MODE_BAD; ++ ++ return MODE_OK; + } + + int adv7533_patch_registers(struct adv7511 *adv) +-- +2.35.1 + diff --git a/queue-6.0/drm-bridge-it6505-initialize-aux-channel-in-it6505_i.patch b/queue-6.0/drm-bridge-it6505-initialize-aux-channel-in-it6505_i.patch new file mode 100644 index 00000000000..1bdfd254890 --- /dev/null +++ b/queue-6.0/drm-bridge-it6505-initialize-aux-channel-in-it6505_i.patch @@ -0,0 +1,54 @@ +From 727c5ca60f298c8f632513df65530282d3a1c591 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Oct 2022 19:04:08 +0800 +Subject: drm/bridge: it6505: Initialize AUX channel in it6505_i2c_probe + +From: Pin-yen Lin + +[ Upstream commit e577d4b13064c337b83fe7edecb3f34e87144821 ] + +During device boot, the HPD interrupt could be triggered before the DRM +subsystem registers it6505 as a DRM bridge. In such cases, the driver +tries to access AUX channel and causes NULL pointer dereference. +Initializing the AUX channel earlier to prevent such error. + +Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver") +Signed-off-by: Pin-yen Lin +Reviewed-by: Robert Foss +Signed-off-by: Robert Foss +Link: https://patchwork.freedesktop.org/patch/msgid/20221013110411.1674359-2-treapking@chromium.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/ite-it6505.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c +index a09d1a39ab0a..711f403afe7c 100644 +--- a/drivers/gpu/drm/bridge/ite-it6505.c ++++ b/drivers/gpu/drm/bridge/ite-it6505.c +@@ -2854,10 +2854,7 @@ static int it6505_bridge_attach(struct drm_bridge *bridge, + } + + /* Register aux channel */ +- it6505->aux.name = "DP-AUX"; +- it6505->aux.dev = dev; + it6505->aux.drm_dev = bridge->dev; +- it6505->aux.transfer = it6505_aux_transfer; + + ret = drm_dp_aux_register(&it6505->aux); + +@@ -3310,6 +3307,11 @@ static int it6505_i2c_probe(struct i2c_client *client, + DRM_DEV_DEBUG_DRIVER(dev, "it6505 device name: %s", dev_name(dev)); + debugfs_init(it6505); + ++ it6505->aux.name = "DP-AUX"; ++ it6505->aux.dev = dev; ++ it6505->aux.transfer = it6505_aux_transfer; ++ drm_dp_aux_init(&it6505->aux); ++ + it6505->bridge.funcs = &it6505_bridge_funcs; + it6505->bridge.type = DRM_MODE_CONNECTOR_DisplayPort; + it6505->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | +-- +2.35.1 + diff --git a/queue-6.0/drm-edid-add-a-quirk-for-two-lg-monitors-to-get-them.patch b/queue-6.0/drm-edid-add-a-quirk-for-two-lg-monitors-to-get-them.patch new file mode 100644 index 00000000000..30b3202ea16 --- /dev/null +++ b/queue-6.0/drm-edid-add-a-quirk-for-two-lg-monitors-to-get-them.patch @@ -0,0 +1,88 @@ +From b1df0fa6739e2c13bc519d6ca152c518c6da5c60 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Oct 2022 16:37:34 -0400 +Subject: drm/edid: add a quirk for two LG monitors to get them to work on + 10bpc + +From: Hamza Mahfooz + +[ Upstream commit aa193f7eff8ff753577351140b8af13b76cdc7c2 ] + +The LG 27GP950 and LG 27GN950 have visible display corruption when +trying to use 10bpc modes. So, to fix this, cap their maximum DSC +target bitrate to 15bpp. + +Suggested-by: Roman Li +Reviewed-by: Harry Wentland +Signed-off-by: Hamza Mahfooz +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_edid.c | 12 ++++++++++++ + include/drm/drm_connector.h | 6 ++++++ + 2 files changed, 18 insertions(+) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index eaa819381281..fefcfac999d9 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -87,6 +87,8 @@ static int oui(u8 first, u8 second, u8 third) + #define EDID_QUIRK_FORCE_10BPC (1 << 11) + /* Non desktop display (i.e. HMD) */ + #define EDID_QUIRK_NON_DESKTOP (1 << 12) ++/* Cap the DSC target bitrate to 15bpp */ ++#define EDID_QUIRK_CAP_DSC_15BPP (1 << 13) + + #define MICROSOFT_IEEE_OUI 0xca125c + +@@ -147,6 +149,12 @@ static const struct edid_quirk { + EDID_QUIRK('F', 'C', 'M', 13600, EDID_QUIRK_PREFER_LARGE_75 | + EDID_QUIRK_DETAILED_IN_CM), + ++ /* LG 27GP950 */ ++ EDID_QUIRK('G', 'S', 'M', 0x5bbf, EDID_QUIRK_CAP_DSC_15BPP), ++ ++ /* LG 27GN950 */ ++ EDID_QUIRK('G', 'S', 'M', 0x5b9a, EDID_QUIRK_CAP_DSC_15BPP), ++ + /* LGD panel of HP zBook 17 G2, eDP 10 bpc, but reports unknown bpc */ + EDID_QUIRK('L', 'G', 'D', 764, EDID_QUIRK_FORCE_10BPC), + +@@ -6116,6 +6124,7 @@ static void drm_reset_display_info(struct drm_connector *connector) + + info->mso_stream_count = 0; + info->mso_pixel_overlap = 0; ++ info->max_dsc_bpp = 0; + } + + static u32 update_display_info(struct drm_connector *connector, +@@ -6202,6 +6211,9 @@ static u32 update_display_info(struct drm_connector *connector, + info->non_desktop = true; + } + ++ if (quirks & EDID_QUIRK_CAP_DSC_15BPP) ++ info->max_dsc_bpp = 15; ++ + return quirks; + } + +diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h +index 7df7876b2ad5..d9879fc9ceb1 100644 +--- a/include/drm/drm_connector.h ++++ b/include/drm/drm_connector.h +@@ -635,6 +635,12 @@ struct drm_display_info { + * @mso_pixel_overlap: eDP MSO segment pixel overlap, 0-8 pixels. + */ + u8 mso_pixel_overlap; ++ ++ /** ++ * @max_dsc_bpp: Maximum DSC target bitrate, if it is set to 0 the ++ * monitor's default value is used instead. ++ */ ++ u32 max_dsc_bpp; + }; + + int drm_display_info_set_bus_formats(struct drm_display_info *info, +-- +2.35.1 + diff --git a/queue-6.0/drm-etnaviv-add-missing-quirks-for-gc300.patch b/queue-6.0/drm-etnaviv-add-missing-quirks-for-gc300.patch new file mode 100644 index 00000000000..6b6d49edcf1 --- /dev/null +++ b/queue-6.0/drm-etnaviv-add-missing-quirks-for-gc300.patch @@ -0,0 +1,53 @@ +From a07f8098bbd25c431de8b94cc489486fa4660dbd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 10 Sep 2022 13:29:38 -0700 +Subject: drm/etnaviv: add missing quirks for GC300 + +From: Doug Brown + +[ Upstream commit cc7d3fb446a91f24978a6aa59cbb578f92e22242 ] + +The GC300's features register doesn't specify that a 2D pipe is +available, and like the GC600, its idle register reports zero bits where +modules aren't present. + +Signed-off-by: Doug Brown +Reviewed-by: Christian Gmeiner +Signed-off-by: Lucas Stach +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +index 37018bc55810..f667e7906d1f 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +@@ -416,6 +416,12 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu) + if (gpu->identity.model == chipModel_GC700) + gpu->identity.features &= ~chipFeatures_FAST_CLEAR; + ++ /* These models/revisions don't have the 2D pipe bit */ ++ if ((gpu->identity.model == chipModel_GC500 && ++ gpu->identity.revision <= 2) || ++ gpu->identity.model == chipModel_GC300) ++ gpu->identity.features |= chipFeatures_PIPE_2D; ++ + if ((gpu->identity.model == chipModel_GC500 && + gpu->identity.revision < 2) || + (gpu->identity.model == chipModel_GC300 && +@@ -449,8 +455,9 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu) + gpu_read(gpu, VIVS_HI_CHIP_MINOR_FEATURE_5); + } + +- /* GC600 idle register reports zero bits where modules aren't present */ +- if (gpu->identity.model == chipModel_GC600) ++ /* GC600/300 idle register reports zero bits where modules aren't present */ ++ if (gpu->identity.model == chipModel_GC600 || ++ gpu->identity.model == chipModel_GC300) + gpu->idle_mask = VIVS_HI_IDLE_STATE_TX | + VIVS_HI_IDLE_STATE_RA | + VIVS_HI_IDLE_STATE_SE | +-- +2.35.1 + diff --git a/queue-6.0/drm-fourcc-fix-vsub-hsub-for-q410-and-q401.patch b/queue-6.0/drm-fourcc-fix-vsub-hsub-for-q410-and-q401.patch new file mode 100644 index 00000000000..4d4cddd967a --- /dev/null +++ b/queue-6.0/drm-fourcc-fix-vsub-hsub-for-q410-and-q401.patch @@ -0,0 +1,48 @@ +From 2c1a2c776289f4ee779509432a6fea8ddf680633 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Sep 2022 15:43:06 +0100 +Subject: drm/fourcc: Fix vsub/hsub for Q410 and Q401 + +From: Brian Starkey + +[ Upstream commit b230555f3257f197dd98641ef6ebaf778b52dd51 ] + +These formats are not subsampled, but that means hsub and vsub should be +1, not 0. + +Fixes: 94b292b27734 ("drm: drm_fourcc: add NV15, Q410, Q401 YUV formats") +Reported-by: George Kennedy +Reported-by: butt3rflyh4ck +Signed-off-by: Brian Starkey +Reviewed-by: Liviu Dudau +Signed-off-by: Liviu Dudau +Link: https://patchwork.freedesktop.org/patch/msgid/20220913144306.17279-1-brian.starkey@arm.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_fourcc.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c +index 07741b678798..6768b7d18b6f 100644 +--- a/drivers/gpu/drm/drm_fourcc.c ++++ b/drivers/gpu/drm/drm_fourcc.c +@@ -263,12 +263,12 @@ const struct drm_format_info *__drm_format_info(u32 format) + .vsub = 2, .is_yuv = true }, + { .format = DRM_FORMAT_Q410, .depth = 0, + .num_planes = 3, .char_per_block = { 2, 2, 2 }, +- .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0, +- .vsub = 0, .is_yuv = true }, ++ .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1, ++ .vsub = 1, .is_yuv = true }, + { .format = DRM_FORMAT_Q401, .depth = 0, + .num_planes = 3, .char_per_block = { 2, 2, 2 }, +- .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0, +- .vsub = 0, .is_yuv = true }, ++ .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1, ++ .vsub = 1, .is_yuv = true }, + { .format = DRM_FORMAT_P030, .depth = 0, .num_planes = 2, + .char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 }, + .hsub = 2, .vsub = 2, .is_yuv = true}, +-- +2.35.1 + diff --git a/queue-6.0/drm-fsl-dcu-fix-return-type-of-fsl_dcu_drm_connector.patch b/queue-6.0/drm-fsl-dcu-fix-return-type-of-fsl_dcu_drm_connector.patch new file mode 100644 index 00000000000..06875d1fe6c --- /dev/null +++ b/queue-6.0/drm-fsl-dcu-fix-return-type-of-fsl_dcu_drm_connector.patch @@ -0,0 +1,57 @@ +From 59b5b5ddaceacad95a10dafa12873e806fa9c356 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Nov 2022 08:42:15 -0700 +Subject: drm/fsl-dcu: Fix return type of fsl_dcu_drm_connector_mode_valid() + +From: Nathan Chancellor + +[ Upstream commit 96d845a67b7e406cfed7880a724c8ca6121e022e ] + +With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG), +indirect call targets are validated against the expected function +pointer prototype to make sure the call target is valid to help mitigate +ROP attacks. If they are not identical, there is a failure at run time, +which manifests as either a kernel panic or thread getting killed. A +proposed warning in clang aims to catch these at compile time, which +reveals: + + drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c:74:16: error: incompatible function pointer types initializing 'enum drm_mode_status (*)(struct drm_connector *, struct drm_display_mode *)' with an expression of type 'int (struct drm_connector *, struct drm_display_mode *)' [-Werror,-Wincompatible-function-pointer-types-strict] + .mode_valid = fsl_dcu_drm_connector_mode_valid, + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 1 error generated. + +->mode_valid() in 'struct drm_connector_helper_funcs' expects a return +type of 'enum drm_mode_status', not 'int'. Adjust the return type of +fsl_dcu_drm_connector_mode_valid() to match the prototype's to resolve +the warning and CFI failure. + +Link: https://github.com/ClangBuiltLinux/linux/issues/1750 +Reported-by: Sami Tolvanen +Signed-off-by: Nathan Chancellor +Reviewed-by: Kees Cook +Signed-off-by: Kees Cook +Link: https://lore.kernel.org/r/20221102154215.78059-1-nathan@kernel.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c +index 4d4a715b429d..2c2b92324a2e 100644 +--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c ++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c +@@ -60,8 +60,9 @@ static int fsl_dcu_drm_connector_get_modes(struct drm_connector *connector) + return drm_panel_get_modes(fsl_connector->panel, connector); + } + +-static int fsl_dcu_drm_connector_mode_valid(struct drm_connector *connector, +- struct drm_display_mode *mode) ++static enum drm_mode_status ++fsl_dcu_drm_connector_mode_valid(struct drm_connector *connector, ++ struct drm_display_mode *mode) + { + if (mode->hdisplay & 0xf) + return MODE_ERROR; +-- +2.35.1 + diff --git a/queue-6.0/drm-i915-bios-fix-a-memory-leak-in-generate_lfp_data.patch b/queue-6.0/drm-i915-bios-fix-a-memory-leak-in-generate_lfp_data.patch new file mode 100644 index 00000000000..2fd1fedf34f --- /dev/null +++ b/queue-6.0/drm-i915-bios-fix-a-memory-leak-in-generate_lfp_data.patch @@ -0,0 +1,43 @@ +From 32c827f9f330fc48c5341c0bde22c381ec6407a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Nov 2022 14:34:28 +0800 +Subject: drm/i915/bios: fix a memory leak in generate_lfp_data_ptrs + +From: Xia Fukun + +[ Upstream commit 1382901f75a5a7dc8eac05059fd0c7816def4eae ] + +When (size != 0 || ptrs->lvds_ entries != 3), the program tries to +free() the ptrs. However, the ptrs is not created by calling kzmalloc(), +but is obtained by pointer offset operation. +This may lead to memory leaks or undefined behavior. + +Fix this by replacing the arguments of kfree() with ptrs_block. + +Fixes: a87d0a847607 ("drm/i915/bios: Generate LFP data table pointers if the VBT lacks them") +Signed-off-by: Xia Fukun +Signed-off-by: Jani Nikula +Link: https://patchwork.freedesktop.org/patch/msgid/20221125063428.69486-1-xiafukun@huawei.com +(cherry picked from commit 7674cd0b7d28b952151c3df26bbfa7e07eb2b4ec) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/display/intel_bios.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c +index 459571e2cc57..2bfcfbfa52a4 100644 +--- a/drivers/gpu/drm/i915/display/intel_bios.c ++++ b/drivers/gpu/drm/i915/display/intel_bios.c +@@ -414,7 +414,7 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915, + ptrs->lvds_entries++; + + if (size != 0 || ptrs->lvds_entries != 3) { +- kfree(ptrs); ++ kfree(ptrs_block); + return NULL; + } + +-- +2.35.1 + diff --git a/queue-6.0/drm-i915-fix-compute-pre-emption-w-a-to-apply-to-com.patch b/queue-6.0/drm-i915-fix-compute-pre-emption-w-a-to-apply-to-com.patch new file mode 100644 index 00000000000..25a57e3123d --- /dev/null +++ b/queue-6.0/drm-i915-fix-compute-pre-emption-w-a-to-apply-to-com.patch @@ -0,0 +1,94 @@ +From 591f21ff48a1310878377fb6a31be9ccae17a634 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Oct 2022 14:38:11 -0700 +Subject: drm/i915: Fix compute pre-emption w/a to apply to compute engines +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: John Harrison + +[ Upstream commit c3bd49cd9a1043b963331e7fd874b380bed3f2bd ] + +An earlier patch added support for compute engines. However, it missed +enabling the anti-pre-emption w/a for the new engine class. So move +the 'compute capable' flag earlier and use it for the pre-emption w/a +test. + +Fixes: c674c5b9342e ("drm/i915/xehp: CCS should use RCS setup functions") +Cc: Tvrtko Ursulin +Cc: Daniele Ceraolo Spurio +Cc: Aravind Iddamsetty +Cc: Matt Roper +Cc: Tvrtko Ursulin +Cc: Daniel Vetter +Cc: Maarten Lankhorst +Cc: Lucas De Marchi +Cc: John Harrison +Cc: Jason Ekstrand +Cc: "Michał Winiarski" +Cc: Matthew Brost +Cc: Chris Wilson +Cc: Tejas Upadhyay +Cc: Umesh Nerlige Ramappa +Cc: "Thomas Hellström" +Cc: Stuart Summers +Cc: Matthew Auld +Cc: Jani Nikula +Cc: Ramalingam C +Cc: Akeem G Abodunrin +Signed-off-by: John Harrison +Reviewed-by: Matt Roper +Link: https://patchwork.freedesktop.org/patch/msgid/20221006213813.1563435-3-John.C.Harrison@Intel.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/gt/intel_engine_cs.c | 24 +++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c +index 699308a1323d..3dd0af057e6b 100644 +--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c ++++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c +@@ -486,6 +486,17 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id, + engine->logical_mask = BIT(logical_instance); + __sprint_engine_name(engine); + ++ if ((engine->class == COMPUTE_CLASS && !RCS_MASK(engine->gt) && ++ __ffs(CCS_MASK(engine->gt)) == engine->instance) || ++ engine->class == RENDER_CLASS) ++ engine->flags |= I915_ENGINE_FIRST_RENDER_COMPUTE; ++ ++ /* features common between engines sharing EUs */ ++ if (engine->class == RENDER_CLASS || engine->class == COMPUTE_CLASS) { ++ engine->flags |= I915_ENGINE_HAS_RCS_REG_STATE; ++ engine->flags |= I915_ENGINE_HAS_EU_PRIORITY; ++ } ++ + engine->props.heartbeat_interval_ms = + CONFIG_DRM_I915_HEARTBEAT_INTERVAL; + engine->props.max_busywait_duration_ns = +@@ -498,20 +509,9 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id, + CONFIG_DRM_I915_TIMESLICE_DURATION; + + /* Override to uninterruptible for OpenCL workloads. */ +- if (GRAPHICS_VER(i915) == 12 && engine->class == RENDER_CLASS) ++ if (GRAPHICS_VER(i915) == 12 && (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE)) + engine->props.preempt_timeout_ms = 0; + +- if ((engine->class == COMPUTE_CLASS && !RCS_MASK(engine->gt) && +- __ffs(CCS_MASK(engine->gt)) == engine->instance) || +- engine->class == RENDER_CLASS) +- engine->flags |= I915_ENGINE_FIRST_RENDER_COMPUTE; +- +- /* features common between engines sharing EUs */ +- if (engine->class == RENDER_CLASS || engine->class == COMPUTE_CLASS) { +- engine->flags |= I915_ENGINE_HAS_RCS_REG_STATE; +- engine->flags |= I915_ENGINE_HAS_EU_PRIORITY; +- } +- + /* Cap properties according to any system limits */ + #define CLAMP_PROP(field) \ + do { \ +-- +2.35.1 + diff --git a/queue-6.0/drm-i915-guc-add-a-helper-for-log-buffer-size.patch b/queue-6.0/drm-i915-guc-add-a-helper-for-log-buffer-size.patch new file mode 100644 index 00000000000..dcc77ff4d3d --- /dev/null +++ b/queue-6.0/drm-i915-guc-add-a-helper-for-log-buffer-size.patch @@ -0,0 +1,96 @@ +From 4ddaa438b22dd9f0406dd15bd55801b084bd75e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Jul 2022 19:20:22 -0700 +Subject: drm/i915/guc: Add a helper for log buffer size + +From: Alan Previn + +[ Upstream commit 5ce27d6210018e972197ff7e5da6309f919fd61b ] + +Add a helper to get GuC log buffer size. + +Signed-off-by: Alan Previn +Signed-off-by: John Harrison +Reviewed-by: Matthew Brost +Reviewed-by: Alan Previn +Link: https://patchwork.freedesktop.org/patch/msgid/20220728022028.2190627-2-John.C.Harrison@Intel.com +Stable-dep-of: befb231d5de2 ("drm/i915/guc: Fix GuC error capture sizing estimation and reporting") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 49 ++++++++++++---------- + 1 file changed, 27 insertions(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +index 25b2d7ce6640..492bbf419d4d 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +@@ -15,6 +15,32 @@ + + static void guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log); + ++static u32 intel_guc_log_size(struct intel_guc_log *log) ++{ ++ /* ++ * GuC Log buffer Layout: ++ * ++ * NB: Ordering must follow "enum guc_log_buffer_type". ++ * ++ * +===============================+ 00B ++ * | Debug state header | ++ * +-------------------------------+ 32B ++ * | Crash dump state header | ++ * +-------------------------------+ 64B ++ * | Capture state header | ++ * +-------------------------------+ 96B ++ * | | ++ * +===============================+ PAGE_SIZE (4KB) ++ * | Debug logs | ++ * +===============================+ + DEBUG_SIZE ++ * | Crash Dump logs | ++ * +===============================+ + CRASH_SIZE ++ * | Capture logs | ++ * +===============================+ + CAPTURE_SIZE ++ */ ++ return PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE + CAPTURE_BUFFER_SIZE; ++} ++ + /** + * DOC: GuC firmware log + * +@@ -461,32 +487,11 @@ int intel_guc_log_create(struct intel_guc_log *log) + + GEM_BUG_ON(log->vma); + +- /* +- * GuC Log buffer Layout +- * (this ordering must follow "enum guc_log_buffer_type" definition) +- * +- * +===============================+ 00B +- * | Debug state header | +- * +-------------------------------+ 32B +- * | Crash dump state header | +- * +-------------------------------+ 64B +- * | Capture state header | +- * +-------------------------------+ 96B +- * | | +- * +===============================+ PAGE_SIZE (4KB) +- * | Debug logs | +- * +===============================+ + DEBUG_SIZE +- * | Crash Dump logs | +- * +===============================+ + CRASH_SIZE +- * | Capture logs | +- * +===============================+ + CAPTURE_SIZE +- */ + if (intel_guc_capture_output_min_size_est(guc) > CAPTURE_BUFFER_SIZE) + DRM_WARN("GuC log buffer for state_capture maybe too small. %d < %d\n", + CAPTURE_BUFFER_SIZE, intel_guc_capture_output_min_size_est(guc)); + +- guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE + +- CAPTURE_BUFFER_SIZE; ++ guc_log_size = intel_guc_log_size(log); + + vma = intel_guc_allocate_vma(guc, guc_log_size); + if (IS_ERR(vma)) { +-- +2.35.1 + diff --git a/queue-6.0/drm-i915-guc-add-error-capture-init-warnings-when-ne.patch b/queue-6.0/drm-i915-guc-add-error-capture-init-warnings-when-ne.patch new file mode 100644 index 00000000000..982d641c0e2 --- /dev/null +++ b/queue-6.0/drm-i915-guc-add-error-capture-init-warnings-when-ne.patch @@ -0,0 +1,170 @@ +From d89b61f09df5fa2ff29952a11334739d6850cf1a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Oct 2022 00:29:29 -0700 +Subject: drm/i915/guc: Add error-capture init warnings when needed + +From: Alan Previn + +[ Upstream commit a894077890ad118de88c97c03f67a611ca60882a ] + +If GuC is being used and we initialized GuC-error-capture, +we need to be warning if we don't provide an error-capture +register list in the firmware ADS, for valid GT engines. +A warning makes sense as this would impact debugability +without realizing why a reglist wasn't retrieved and reported +by GuC. + +However, depending on the platform, we might have certain +engines that have a register list for engine instance error state +but not for engine class. Thus, add a check only to warn if the +register list was non existent vs an empty list (use the +empty lists to skip the warning). + +NOTE: if a future platform were to introduce new registers +in place of what was an empty list on existing / legacy hardware +engines no warning is provided as the empty list is meant +to be used intentionally. As an example, if a future hardware +were to add blitter engine-class-registers (new) on top +of the legacy blitter engine-instance-register (HEAD, TAIL, etc.), +no warning is generated. + +Signed-off-by: Alan Previn +Reviewed-by: John Harrison +Signed-off-by: John Harrison +Link: https://patchwork.freedesktop.org/patch/msgid/20221019072930.17755-2-alan.previn.teres.alexis@intel.com +Stable-dep-of: befb231d5de2 ("drm/i915/guc: Fix GuC error capture sizing estimation and reporting") +Signed-off-by: Sasha Levin +--- + .../gpu/drm/i915/gt/uc/intel_guc_capture.c | 78 ++++++++++++++++--- + 1 file changed, 69 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +index d2ac53d4f3b6..c398bdd5403a 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +@@ -419,6 +419,44 @@ guc_capture_get_device_reglist(struct intel_guc *guc) + return default_lists; + } + ++static const char * ++__stringify_type(u32 type) ++{ ++ switch (type) { ++ case GUC_CAPTURE_LIST_TYPE_GLOBAL: ++ return "Global"; ++ case GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS: ++ return "Class"; ++ case GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE: ++ return "Instance"; ++ default: ++ break; ++ } ++ ++ return "unknown"; ++} ++ ++static const char * ++__stringify_engclass(u32 class) ++{ ++ switch (class) { ++ case GUC_RENDER_CLASS: ++ return "Render"; ++ case GUC_VIDEO_CLASS: ++ return "Video"; ++ case GUC_VIDEOENHANCE_CLASS: ++ return "VideoEnhance"; ++ case GUC_BLITTER_CLASS: ++ return "Blitter"; ++ case GUC_COMPUTE_CLASS: ++ return "Compute"; ++ default: ++ break; ++ } ++ ++ return "unknown"; ++} ++ + static int + guc_capture_list_init(struct intel_guc *guc, u32 owner, u32 type, u32 classid, + struct guc_mmio_reg *ptr, u16 num_entries) +@@ -482,23 +520,38 @@ guc_cap_list_num_regs(struct intel_guc_state_capture *gc, u32 owner, u32 type, u + return num_regs; + } + +-int +-intel_guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid, +- size_t *size) ++static int ++guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid, ++ size_t *size, bool is_purpose_est) + { + struct intel_guc_state_capture *gc = guc->capture; ++ struct drm_i915_private *i915 = guc_to_gt(guc)->i915; + struct __guc_capture_ads_cache *cache = &gc->ads_cache[owner][type][classid]; + int num_regs; + +- if (!gc->reglists) ++ if (!gc->reglists) { ++ drm_warn(&i915->drm, "GuC-capture: No reglist on this device\n"); + return -ENODEV; ++ } + + if (cache->is_valid) { + *size = cache->size; + return cache->status; + } + ++ if (!is_purpose_est && owner == GUC_CAPTURE_LIST_INDEX_PF && ++ !guc_capture_get_one_list(gc->reglists, owner, type, classid)) { ++ if (type == GUC_CAPTURE_LIST_TYPE_GLOBAL) ++ drm_warn(&i915->drm, "Missing GuC-Err-Cap reglist Global!\n"); ++ else ++ drm_warn(&i915->drm, "Missing GuC-Err-Cap reglist %s(%u):%s(%u)!\n", ++ __stringify_type(type), type, ++ __stringify_engclass(classid), classid); ++ return -ENODATA; ++ } ++ + num_regs = guc_cap_list_num_regs(gc, owner, type, classid); ++ /* intentional empty lists can exist depending on hw config */ + if (!num_regs) + return -ENODATA; + +@@ -508,6 +561,13 @@ intel_guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 cl + return 0; + } + ++int ++intel_guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid, ++ size_t *size) ++{ ++ return guc_capture_getlistsize(guc, owner, type, classid, size, false); ++} ++ + static void guc_capture_create_prealloc_nodes(struct intel_guc *guc); + + int +@@ -627,15 +687,15 @@ guc_capture_output_min_size_est(struct intel_guc *guc) + worst_min_size += sizeof(struct guc_state_capture_group_header_t) + + (3 * sizeof(struct guc_state_capture_header_t)); + +- if (!intel_guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_GLOBAL, 0, &tmp)) ++ if (!guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_GLOBAL, 0, &tmp, true)) + num_regs += tmp; + +- if (!intel_guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS, +- engine->class, &tmp)) { ++ if (!guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS, ++ engine->class, &tmp, true)) { + num_regs += tmp; + } +- if (!intel_guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE, +- engine->class, &tmp)) { ++ if (!guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE, ++ engine->class, &tmp, true)) { + num_regs += tmp; + } + } +-- +2.35.1 + diff --git a/queue-6.0/drm-i915-guc-fix-capture-size-warning-and-bump-the-s.patch b/queue-6.0/drm-i915-guc-fix-capture-size-warning-and-bump-the-s.patch new file mode 100644 index 00000000000..d3ea4429dda --- /dev/null +++ b/queue-6.0/drm-i915-guc-fix-capture-size-warning-and-bump-the-s.patch @@ -0,0 +1,170 @@ +From f8ae27e5ca3db6539e278528a2ac832fbd4d0678 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Jul 2022 19:20:23 -0700 +Subject: drm/i915/guc: Fix capture size warning and bump the size + +From: John Harrison + +[ Upstream commit 56c7f0e2026328e56106b54cb0e2fe3a7e70ce4f ] + +There was a size check to warn if the GuC error state capture buffer +allocation would be too small to fit a reasonable amount of capture +data for the current platform. Unfortunately, the test was done too +early in the boot sequence and was actually testing 'if(-ENODEV > +size)'. + +Move the check to be later. The check is only used to print a warning +message, so it doesn't really matter how early or late it is done. +Note that it is not possible to dynamically size the buffer because +the allocation needs to be done before the engine information is +available (at least, it would be in the intended two-phase GuC init +process). + +Now that the check works, it is reporting size too small for newer +platforms. The check includes a 3x oversample multiplier to allow for +multiple error captures to be bufferd by GuC before i915 has a chance +to read them out. This is less important than simply being big enough +to fit the first capture. + +So a) bump the default size to be large enough for one capture minimum +and b) make the warning only if one capture won't fit, instead use a +notice for the 3x size. + +Note that the size estimate is a worst case scenario. Actual captures +will likely be smaller. + +Lastly, use drm_warn istead of DRM_WARN as the former provides more +infmration and the latter is deprecated. + +Signed-off-by: John Harrison +Reviewed-by: Alan Previn +Link: https://patchwork.freedesktop.org/patch/msgid/20220728022028.2190627-3-John.C.Harrison@Intel.com +Stable-dep-of: befb231d5de2 ("drm/i915/guc: Fix GuC error capture sizing estimation and reporting") +Signed-off-by: Sasha Levin +--- + .../gpu/drm/i915/gt/uc/intel_guc_capture.c | 40 ++++++++++++++----- + .../gpu/drm/i915/gt/uc/intel_guc_capture.h | 1 - + drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 4 -- + drivers/gpu/drm/i915/gt/uc/intel_guc_log.h | 4 +- + 4 files changed, 31 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +index 75257bd20ff0..b54b7883320b 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +@@ -600,10 +600,8 @@ intel_guc_capture_getnullheader(struct intel_guc *guc, + return 0; + } + +-#define GUC_CAPTURE_OVERBUFFER_MULTIPLIER 3 +- +-int +-intel_guc_capture_output_min_size_est(struct intel_guc *guc) ++static int ++guc_capture_output_min_size_est(struct intel_guc *guc) + { + struct intel_gt *gt = guc_to_gt(guc); + struct intel_engine_cs *engine; +@@ -623,13 +621,8 @@ intel_guc_capture_output_min_size_est(struct intel_guc *guc) + * For each engine instance, there would be 1 x guc_state_capture_group_t output + * followed by 3 x guc_state_capture_t lists. The latter is how the register + * dumps are split across different register types (where the '3' are global vs class +- * vs instance). Finally, let's multiply the whole thing by 3x (just so we are +- * not limited to just 1 round of data in a worst case full register dump log) +- * +- * NOTE: intel_guc_log that allocates the log buffer would round this size up to +- * a power of two. ++ * vs instance). + */ +- + for_each_engine(engine, gt, id) { + worst_min_size += sizeof(struct guc_state_capture_group_header_t) + + (3 * sizeof(struct guc_state_capture_header_t)); +@@ -649,7 +642,30 @@ intel_guc_capture_output_min_size_est(struct intel_guc *guc) + + worst_min_size += (num_regs * sizeof(struct guc_mmio_reg)); + +- return (worst_min_size * GUC_CAPTURE_OVERBUFFER_MULTIPLIER); ++ return worst_min_size; ++} ++ ++/* ++ * Add on a 3x multiplier to allow for multiple back-to-back captures occurring ++ * before the i915 can read the data out and process it ++ */ ++#define GUC_CAPTURE_OVERBUFFER_MULTIPLIER 3 ++ ++static void check_guc_capture_size(struct intel_guc *guc) ++{ ++ struct drm_i915_private *i915 = guc_to_gt(guc)->i915; ++ int min_size = guc_capture_output_min_size_est(guc); ++ int spare_size = min_size * GUC_CAPTURE_OVERBUFFER_MULTIPLIER; ++ ++ if (min_size < 0) ++ drm_warn(&i915->drm, "Failed to calculate GuC error state capture buffer minimum size: %d!\n", ++ min_size); ++ else if (min_size > CAPTURE_BUFFER_SIZE) ++ drm_warn(&i915->drm, "GuC error state capture buffer is too small: %d < %d\n", ++ CAPTURE_BUFFER_SIZE, min_size); ++ else if (spare_size > CAPTURE_BUFFER_SIZE) ++ drm_notice(&i915->drm, "GuC error state capture buffer maybe too small: %d < %d (min = %d)\n", ++ CAPTURE_BUFFER_SIZE, spare_size, min_size); + } + + /* +@@ -1580,5 +1596,7 @@ int intel_guc_capture_init(struct intel_guc *guc) + INIT_LIST_HEAD(&guc->capture->outlist); + INIT_LIST_HEAD(&guc->capture->cachelist); + ++ check_guc_capture_size(guc); ++ + return 0; + } +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h +index d3d7bd0b6db6..fbd3713c7832 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h +@@ -21,7 +21,6 @@ int intel_guc_capture_print_engine_node(struct drm_i915_error_state_buf *m, + void intel_guc_capture_get_matching_node(struct intel_gt *gt, struct intel_engine_coredump *ee, + struct intel_context *ce); + void intel_guc_capture_process(struct intel_guc *guc); +-int intel_guc_capture_output_min_size_est(struct intel_guc *guc); + int intel_guc_capture_getlist(struct intel_guc *guc, u32 owner, u32 type, u32 classid, + void **outptr); + int intel_guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid, +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +index 492bbf419d4d..991d4a02248d 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +@@ -487,10 +487,6 @@ int intel_guc_log_create(struct intel_guc_log *log) + + GEM_BUG_ON(log->vma); + +- if (intel_guc_capture_output_min_size_est(guc) > CAPTURE_BUFFER_SIZE) +- DRM_WARN("GuC log buffer for state_capture maybe too small. %d < %d\n", +- CAPTURE_BUFFER_SIZE, intel_guc_capture_output_min_size_est(guc)); +- + guc_log_size = intel_guc_log_size(log); + + vma = intel_guc_allocate_vma(guc, guc_log_size); +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h +index 18007e639be9..dc9715411d62 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h +@@ -22,11 +22,11 @@ struct intel_guc; + #elif defined(CONFIG_DRM_I915_DEBUG_GEM) + #define CRASH_BUFFER_SIZE SZ_1M + #define DEBUG_BUFFER_SIZE SZ_2M +-#define CAPTURE_BUFFER_SIZE SZ_1M ++#define CAPTURE_BUFFER_SIZE SZ_4M + #else + #define CRASH_BUFFER_SIZE SZ_8K + #define DEBUG_BUFFER_SIZE SZ_64K +-#define CAPTURE_BUFFER_SIZE SZ_16K ++#define CAPTURE_BUFFER_SIZE SZ_2M + #endif + + /* +-- +2.35.1 + diff --git a/queue-6.0/drm-i915-guc-fix-guc-error-capture-sizing-estimation.patch b/queue-6.0/drm-i915-guc-fix-guc-error-capture-sizing-estimation.patch new file mode 100644 index 00000000000..08a29271466 --- /dev/null +++ b/queue-6.0/drm-i915-guc-fix-guc-error-capture-sizing-estimation.patch @@ -0,0 +1,149 @@ +From 387b800c9dafa9e918ba368ba97d7c11d91e49a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Oct 2022 23:05:06 -0700 +Subject: drm/i915/guc: Fix GuC error capture sizing estimation and reporting + +From: Alan Previn + +[ Upstream commit befb231d5de2773f6c6f6cf918234e2e709110a5 ] + +During GuC error capture initialization, we estimate the amount of size +we need for the error-capture-region of the shared GuC-log-buffer. +This calculation was incorrect so fix that. With the fixed calculation +we can reduce the allocation of error-capture region from 4MB to 1MB +(see note2 below for reasoning). Additionally, switch from drm_notice to +drm_debug for the 3X spare size check since that would be impossible to +hit without redesigning gpu_coredump framework to hold multiple captures. + +NOTE1: Even for 1x the min size estimation case, actually running out +of space is a corner case because it can only occur if all engine +instances get reset all at once and i915 isn't able extract the capture +data fast enough within G2H handler worker. + +NOTE2: With the corrected calculation, a DG2 part required ~77K and a PVC +required ~115K (1X min-est-size that is calculated as one-shot all-engine- +reset scenario). + +Fixes: d7c15d76a554 ("drm/i915/guc: Check sizing of guc_capture output") +Cc: Alan Previn +Cc: Matthew Brost +Cc: Lucas De Marchi +Cc: John Harrison +Cc: Umesh Nerlige Ramappa +Cc: Balasubramani Vivekanandan +Cc: Matt Roper +Cc: Jani Nikula +Cc: Joonas Lahtinen +Cc: Chris Wilson +Signed-off-by: Alan Previn +Reviewed-by: John Harrison +Signed-off-by: John Harrison +Link: https://patchwork.freedesktop.org/patch/msgid/20221026060506.1007830-2-alan.previn.teres.alexis@intel.com +Signed-off-by: Sasha Levin +--- + .../gpu/drm/i915/gt/uc/intel_guc_capture.c | 29 ++++++++++++------- + drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 6 ++-- + 2 files changed, 21 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +index c398bdd5403a..34e72675b7e4 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +@@ -555,8 +555,9 @@ guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid, + if (!num_regs) + return -ENODATA; + +- *size = PAGE_ALIGN((sizeof(struct guc_debug_capture_list)) + +- (num_regs * sizeof(struct guc_mmio_reg))); ++ if (size) ++ *size = PAGE_ALIGN((sizeof(struct guc_debug_capture_list)) + ++ (num_regs * sizeof(struct guc_mmio_reg))); + + return 0; + } +@@ -666,7 +667,7 @@ guc_capture_output_min_size_est(struct intel_guc *guc) + struct intel_gt *gt = guc_to_gt(guc); + struct intel_engine_cs *engine; + enum intel_engine_id id; +- int worst_min_size = 0, num_regs = 0; ++ int worst_min_size = 0; + size_t tmp = 0; + + if (!guc->capture) +@@ -688,20 +689,18 @@ guc_capture_output_min_size_est(struct intel_guc *guc) + (3 * sizeof(struct guc_state_capture_header_t)); + + if (!guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_GLOBAL, 0, &tmp, true)) +- num_regs += tmp; ++ worst_min_size += tmp; + + if (!guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS, + engine->class, &tmp, true)) { +- num_regs += tmp; ++ worst_min_size += tmp; + } + if (!guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE, + engine->class, &tmp, true)) { +- num_regs += tmp; ++ worst_min_size += tmp; + } + } + +- worst_min_size += (num_regs * sizeof(struct guc_mmio_reg)); +- + return worst_min_size; + } + +@@ -718,15 +717,23 @@ static void check_guc_capture_size(struct intel_guc *guc) + int spare_size = min_size * GUC_CAPTURE_OVERBUFFER_MULTIPLIER; + u32 buffer_size = intel_guc_log_section_size_capture(&guc->log); + ++ /* ++ * NOTE: min_size is much smaller than the capture region allocation (DG2: <80K vs 1MB) ++ * Additionally, its based on space needed to fit all engines getting reset at once ++ * within the same G2H handler task slot. This is very unlikely. However, if GuC really ++ * does run out of space for whatever reason, we will see an separate warning message ++ * when processing the G2H event capture-notification, search for: ++ * INTEL_GUC_STATE_CAPTURE_EVENT_STATUS_NOSPACE. ++ */ + if (min_size < 0) + drm_warn(&i915->drm, "Failed to calculate GuC error state capture buffer minimum size: %d!\n", + min_size); + else if (min_size > buffer_size) +- drm_warn(&i915->drm, "GuC error state capture buffer is too small: %d < %d\n", ++ drm_warn(&i915->drm, "GuC error state capture buffer maybe small: %d < %d\n", + buffer_size, min_size); + else if (spare_size > buffer_size) +- drm_notice(&i915->drm, "GuC error state capture buffer maybe too small: %d < %d (min = %d)\n", +- buffer_size, spare_size, min_size); ++ drm_dbg(&i915->drm, "GuC error state capture buffer lacks spare size: %d < %d (min = %d)\n", ++ buffer_size, spare_size, min_size); + } + + /* +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +index 2b878030d3e1..8d755d285247 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +@@ -16,15 +16,15 @@ + #if defined(CONFIG_DRM_I915_DEBUG_GUC) + #define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_2M + #define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE SZ_16M +-#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_4M ++#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_1M + #elif defined(CONFIG_DRM_I915_DEBUG_GEM) + #define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_1M + #define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE SZ_2M +-#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_4M ++#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_1M + #else + #define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_8K + #define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE SZ_64K +-#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_2M ++#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_1M + #endif + + static void guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log); +-- +2.35.1 + diff --git a/queue-6.0/drm-i915-guc-limit-scheduling-properties-to-avoid-ov.patch b/queue-6.0/drm-i915-guc-limit-scheduling-properties-to-avoid-ov.patch new file mode 100644 index 00000000000..1bbc18b492a --- /dev/null +++ b/queue-6.0/drm-i915-guc-limit-scheduling-properties-to-avoid-ov.patch @@ -0,0 +1,296 @@ +From 620a2343cedd106fd75d78bb8ea10cd9d1620260 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Oct 2022 14:38:10 -0700 +Subject: drm/i915/guc: Limit scheduling properties to avoid overflow + +From: John Harrison + +[ Upstream commit 568944af44e7538ed5d1389dabf56e938afdaf4f ] + +GuC converts the pre-emption timeout and timeslice quantum values into +clock ticks internally. That significantly reduces the point of 32bit +overflow. On current platforms, worst case scenario is approximately +110 seconds. Rather than allowing the user to set higher values and +then get confused by early timeouts, add limits when setting these +values. + +v2: Add helper functions for clamping (review feedback from Tvrtko). +v3: Add a bunch of BUG_ON range checks in addition to the checks +already in the clamping functions (Tvrtko) + +Signed-off-by: John Harrison +Reviewed-by: Daniele Ceraolo Spurio +Acked-by: Tvrtko Ursulin +Link: https://patchwork.freedesktop.org/patch/msgid/20221006213813.1563435-2-John.C.Harrison@Intel.com +Stable-dep-of: c3bd49cd9a10 ("drm/i915: Fix compute pre-emption w/a to apply to compute engines") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/gt/intel_engine.h | 6 ++ + drivers/gpu/drm/i915/gt/intel_engine_cs.c | 69 +++++++++++++++++++ + drivers/gpu/drm/i915/gt/sysfs_engines.c | 25 ++++--- + drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h | 21 ++++++ + .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 8 +++ + 5 files changed, 119 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h +index 04e435bce79b..cbc8b857d5f7 100644 +--- a/drivers/gpu/drm/i915/gt/intel_engine.h ++++ b/drivers/gpu/drm/i915/gt/intel_engine.h +@@ -348,4 +348,10 @@ intel_engine_get_hung_context(struct intel_engine_cs *engine) + return engine->hung_ce; + } + ++u64 intel_clamp_heartbeat_interval_ms(struct intel_engine_cs *engine, u64 value); ++u64 intel_clamp_max_busywait_duration_ns(struct intel_engine_cs *engine, u64 value); ++u64 intel_clamp_preempt_timeout_ms(struct intel_engine_cs *engine, u64 value); ++u64 intel_clamp_stop_timeout_ms(struct intel_engine_cs *engine, u64 value); ++u64 intel_clamp_timeslice_duration_ms(struct intel_engine_cs *engine, u64 value); ++ + #endif /* _INTEL_RINGBUFFER_H_ */ +diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c +index 37fa813af766..699308a1323d 100644 +--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c ++++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c +@@ -512,6 +512,26 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id, + engine->flags |= I915_ENGINE_HAS_EU_PRIORITY; + } + ++ /* Cap properties according to any system limits */ ++#define CLAMP_PROP(field) \ ++ do { \ ++ u64 clamp = intel_clamp_##field(engine, engine->props.field); \ ++ if (clamp != engine->props.field) { \ ++ drm_notice(&engine->i915->drm, \ ++ "Warning, clamping %s to %lld to prevent overflow\n", \ ++ #field, clamp); \ ++ engine->props.field = clamp; \ ++ } \ ++ } while (0) ++ ++ CLAMP_PROP(heartbeat_interval_ms); ++ CLAMP_PROP(max_busywait_duration_ns); ++ CLAMP_PROP(preempt_timeout_ms); ++ CLAMP_PROP(stop_timeout_ms); ++ CLAMP_PROP(timeslice_duration_ms); ++ ++#undef CLAMP_PROP ++ + engine->defaults = engine->props; /* never to change again */ + + engine->context_size = intel_engine_context_size(gt, engine->class); +@@ -534,6 +554,55 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id, + return 0; + } + ++u64 intel_clamp_heartbeat_interval_ms(struct intel_engine_cs *engine, u64 value) ++{ ++ value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT)); ++ ++ return value; ++} ++ ++u64 intel_clamp_max_busywait_duration_ns(struct intel_engine_cs *engine, u64 value) ++{ ++ value = min(value, jiffies_to_nsecs(2)); ++ ++ return value; ++} ++ ++u64 intel_clamp_preempt_timeout_ms(struct intel_engine_cs *engine, u64 value) ++{ ++ /* ++ * NB: The GuC API only supports 32bit values. However, the limit is further ++ * reduced due to internal calculations which would otherwise overflow. ++ */ ++ if (intel_guc_submission_is_wanted(&engine->gt->uc.guc)) ++ value = min_t(u64, value, guc_policy_max_preempt_timeout_ms()); ++ ++ value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT)); ++ ++ return value; ++} ++ ++u64 intel_clamp_stop_timeout_ms(struct intel_engine_cs *engine, u64 value) ++{ ++ value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT)); ++ ++ return value; ++} ++ ++u64 intel_clamp_timeslice_duration_ms(struct intel_engine_cs *engine, u64 value) ++{ ++ /* ++ * NB: The GuC API only supports 32bit values. However, the limit is further ++ * reduced due to internal calculations which would otherwise overflow. ++ */ ++ if (intel_guc_submission_is_wanted(&engine->gt->uc.guc)) ++ value = min_t(u64, value, guc_policy_max_exec_quantum_ms()); ++ ++ value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT)); ++ ++ return value; ++} ++ + static void __setup_engine_capabilities(struct intel_engine_cs *engine) + { + struct drm_i915_private *i915 = engine->i915; +diff --git a/drivers/gpu/drm/i915/gt/sysfs_engines.c b/drivers/gpu/drm/i915/gt/sysfs_engines.c +index 967031056202..f2d9858d827c 100644 +--- a/drivers/gpu/drm/i915/gt/sysfs_engines.c ++++ b/drivers/gpu/drm/i915/gt/sysfs_engines.c +@@ -144,7 +144,7 @@ max_spin_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) + { + struct intel_engine_cs *engine = kobj_to_engine(kobj); +- unsigned long long duration; ++ unsigned long long duration, clamped; + int err; + + /* +@@ -168,7 +168,8 @@ max_spin_store(struct kobject *kobj, struct kobj_attribute *attr, + if (err) + return err; + +- if (duration > jiffies_to_nsecs(2)) ++ clamped = intel_clamp_max_busywait_duration_ns(engine, duration); ++ if (duration != clamped) + return -EINVAL; + + WRITE_ONCE(engine->props.max_busywait_duration_ns, duration); +@@ -203,7 +204,7 @@ timeslice_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) + { + struct intel_engine_cs *engine = kobj_to_engine(kobj); +- unsigned long long duration; ++ unsigned long long duration, clamped; + int err; + + /* +@@ -218,7 +219,8 @@ timeslice_store(struct kobject *kobj, struct kobj_attribute *attr, + if (err) + return err; + +- if (duration > jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT)) ++ clamped = intel_clamp_timeslice_duration_ms(engine, duration); ++ if (duration != clamped) + return -EINVAL; + + WRITE_ONCE(engine->props.timeslice_duration_ms, duration); +@@ -256,7 +258,7 @@ stop_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) + { + struct intel_engine_cs *engine = kobj_to_engine(kobj); +- unsigned long long duration; ++ unsigned long long duration, clamped; + int err; + + /* +@@ -272,7 +274,8 @@ stop_store(struct kobject *kobj, struct kobj_attribute *attr, + if (err) + return err; + +- if (duration > jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT)) ++ clamped = intel_clamp_stop_timeout_ms(engine, duration); ++ if (duration != clamped) + return -EINVAL; + + WRITE_ONCE(engine->props.stop_timeout_ms, duration); +@@ -306,7 +309,7 @@ preempt_timeout_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) + { + struct intel_engine_cs *engine = kobj_to_engine(kobj); +- unsigned long long timeout; ++ unsigned long long timeout, clamped; + int err; + + /* +@@ -322,7 +325,8 @@ preempt_timeout_store(struct kobject *kobj, struct kobj_attribute *attr, + if (err) + return err; + +- if (timeout > jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT)) ++ clamped = intel_clamp_preempt_timeout_ms(engine, timeout); ++ if (timeout != clamped) + return -EINVAL; + + WRITE_ONCE(engine->props.preempt_timeout_ms, timeout); +@@ -362,7 +366,7 @@ heartbeat_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) + { + struct intel_engine_cs *engine = kobj_to_engine(kobj); +- unsigned long long delay; ++ unsigned long long delay, clamped; + int err; + + /* +@@ -379,7 +383,8 @@ heartbeat_store(struct kobject *kobj, struct kobj_attribute *attr, + if (err) + return err; + +- if (delay >= jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT)) ++ clamped = intel_clamp_heartbeat_interval_ms(engine, delay); ++ if (delay != clamped) + return -EINVAL; + + err = intel_engine_set_heartbeat(engine, delay); +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h +index 323b055e5db9..502e7cb5a302 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h +@@ -305,6 +305,27 @@ struct guc_update_context_policy { + + #define GLOBAL_POLICY_DEFAULT_DPC_PROMOTE_TIME_US 500000 + ++/* ++ * GuC converts the timeout to clock ticks internally. Different platforms have ++ * different GuC clocks. Thus, the maximum value before overflow is platform ++ * dependent. Current worst case scenario is about 110s. So, the spec says to ++ * limit to 100s to be safe. ++ */ ++#define GUC_POLICY_MAX_EXEC_QUANTUM_US (100 * 1000 * 1000UL) ++#define GUC_POLICY_MAX_PREEMPT_TIMEOUT_US (100 * 1000 * 1000UL) ++ ++static inline u32 guc_policy_max_exec_quantum_ms(void) ++{ ++ BUILD_BUG_ON(GUC_POLICY_MAX_EXEC_QUANTUM_US >= UINT_MAX); ++ return GUC_POLICY_MAX_EXEC_QUANTUM_US / 1000; ++} ++ ++static inline u32 guc_policy_max_preempt_timeout_ms(void) ++{ ++ BUILD_BUG_ON(GUC_POLICY_MAX_PREEMPT_TIMEOUT_US >= UINT_MAX); ++ return GUC_POLICY_MAX_PREEMPT_TIMEOUT_US / 1000; ++} ++ + struct guc_policies { + u32 submission_queue_depth[GUC_MAX_ENGINE_CLASSES]; + /* In micro seconds. How much time to allow before DPC processing is +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +index fe179146d51b..cd0c5043863b 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +@@ -2430,6 +2430,10 @@ static int guc_context_policy_init_v70(struct intel_context *ce, bool loop) + int ret; + + /* NB: For both of these, zero means disabled. */ ++ GEM_BUG_ON(overflows_type(engine->props.timeslice_duration_ms * 1000, ++ execution_quantum)); ++ GEM_BUG_ON(overflows_type(engine->props.preempt_timeout_ms * 1000, ++ preemption_timeout)); + execution_quantum = engine->props.timeslice_duration_ms * 1000; + preemption_timeout = engine->props.preempt_timeout_ms * 1000; + +@@ -2486,6 +2490,10 @@ static void guc_context_policy_init_v69(struct intel_engine_cs *engine, + desc->policy_flags |= CONTEXT_POLICY_FLAG_PREEMPT_TO_IDLE_V69; + + /* NB: For both of these, zero means disabled. */ ++ GEM_BUG_ON(overflows_type(engine->props.timeslice_duration_ms * 1000, ++ desc->execution_quantum)); ++ GEM_BUG_ON(overflows_type(engine->props.preempt_timeout_ms * 1000, ++ desc->preemption_timeout)); + desc->execution_quantum = engine->props.timeslice_duration_ms * 1000; + desc->preemption_timeout = engine->props.preempt_timeout_ms * 1000; + } +-- +2.35.1 + diff --git a/queue-6.0/drm-i915-guc-make-default_lists-const-data.patch b/queue-6.0/drm-i915-guc-make-default_lists-const-data.patch new file mode 100644 index 00000000000..2a025446ffa --- /dev/null +++ b/queue-6.0/drm-i915-guc-make-default_lists-const-data.patch @@ -0,0 +1,41 @@ +From 5a9761e2e008e66ff35825f3a62d46656935d948 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Nov 2022 16:16:16 +0200 +Subject: drm/i915/guc: make default_lists const data + +From: Jani Nikula + +[ Upstream commit dfa5e6ef3ccefff9fa8a70d9f5fa6ef6244aa312 ] + +The default_lists array should be in rodata. + +Fixes: dce2bd542337 ("drm/i915/guc: Add Gen9 registers for GuC error state capture.") +Cc: Alan Previn +Cc: Umesh Nerlige Ramappa +Cc: Lucas De Marchi +Signed-off-by: Jani Nikula +Reviewed-by: Lucas De Marchi +Link: https://patchwork.freedesktop.org/patch/msgid/20221122141616.3469214-1-jani.nikula@intel.com +(cherry picked from commit 8b7f7a9b10b704ba7d73199ff0f01354e0bad7a5) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +index 34e72675b7e4..4c51888fd78b 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +@@ -165,7 +165,7 @@ static const struct __guc_mmio_reg_descr empty_regs_list[] = { + } + + /* List of lists */ +-static struct __guc_mmio_reg_descr_group default_lists[] = { ++static const struct __guc_mmio_reg_descr_group default_lists[] = { + MAKE_REGLIST(default_global_regs, PF, GLOBAL, 0), + MAKE_REGLIST(default_rc_class_regs, PF, ENGINE_CLASS, GUC_RENDER_CLASS), + MAKE_REGLIST(xe_lpd_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_RENDER_CLASS), +-- +2.35.1 + diff --git a/queue-6.0/drm-i915-guc-make-guc-log-sizes-runtime-configurable.patch b/queue-6.0/drm-i915-guc-make-guc-log-sizes-runtime-configurable.patch new file mode 100644 index 00000000000..1b9e20387d9 --- /dev/null +++ b/queue-6.0/drm-i915-guc-make-guc-log-sizes-runtime-configurable.patch @@ -0,0 +1,508 @@ +From c6388f92e6bb1c36c41ab3f5c1e774ef0e868592 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Jul 2022 19:20:27 -0700 +Subject: drm/i915/guc: Make GuC log sizes runtime configurable + +From: John Harrison + +[ Upstream commit 8ad0152afb1bb3878bba282308f037d73a87ace5 ] + +The GuC log buffer sizes had to be configured statically at compile +time. This can be quite troublesome when needing to get larger logs +out of a released driver. So re-organise the code to allow a boot time +module parameter override. + +Signed-off-by: John Harrison +Reviewed-by: Alan Previn +Link: https://patchwork.freedesktop.org/patch/msgid/20220728022028.2190627-7-John.C.Harrison@Intel.com +Stable-dep-of: befb231d5de2 ("drm/i915/guc: Fix GuC error capture sizing estimation and reporting") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/gt/uc/intel_guc.c | 53 ++---- + .../gpu/drm/i915/gt/uc/intel_guc_capture.c | 14 +- + drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 176 +++++++++++++++++- + drivers/gpu/drm/i915/gt/uc/intel_guc_log.h | 42 +++-- + drivers/gpu/drm/i915/i915_params.c | 12 ++ + drivers/gpu/drm/i915/i915_params.h | 3 + + 6 files changed, 226 insertions(+), 74 deletions(-) + +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c +index 2706a8c65090..7fbcfeda9195 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c +@@ -224,53 +224,22 @@ static u32 guc_ctl_feature_flags(struct intel_guc *guc) + + static u32 guc_ctl_log_params_flags(struct intel_guc *guc) + { +- u32 offset = intel_guc_ggtt_offset(guc, guc->log.vma) >> PAGE_SHIFT; +- u32 flags; +- +- #if (((CRASH_BUFFER_SIZE) % SZ_1M) == 0) +- #define LOG_UNIT SZ_1M +- #define LOG_FLAG GUC_LOG_LOG_ALLOC_UNITS +- #else +- #define LOG_UNIT SZ_4K +- #define LOG_FLAG 0 +- #endif +- +- #if (((CAPTURE_BUFFER_SIZE) % SZ_1M) == 0) +- #define CAPTURE_UNIT SZ_1M +- #define CAPTURE_FLAG GUC_LOG_CAPTURE_ALLOC_UNITS +- #else +- #define CAPTURE_UNIT SZ_4K +- #define CAPTURE_FLAG 0 +- #endif +- +- BUILD_BUG_ON(!CRASH_BUFFER_SIZE); +- BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, LOG_UNIT)); +- BUILD_BUG_ON(!DEBUG_BUFFER_SIZE); +- BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, LOG_UNIT)); +- BUILD_BUG_ON(!CAPTURE_BUFFER_SIZE); +- BUILD_BUG_ON(!IS_ALIGNED(CAPTURE_BUFFER_SIZE, CAPTURE_UNIT)); +- +- BUILD_BUG_ON((CRASH_BUFFER_SIZE / LOG_UNIT - 1) > +- (GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT)); +- BUILD_BUG_ON((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) > +- (GUC_LOG_DEBUG_MASK >> GUC_LOG_DEBUG_SHIFT)); +- BUILD_BUG_ON((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) > +- (GUC_LOG_CAPTURE_MASK >> GUC_LOG_CAPTURE_SHIFT)); ++ struct intel_guc_log *log = &guc->log; ++ u32 offset, flags; ++ ++ GEM_BUG_ON(!log->sizes_initialised); ++ ++ offset = intel_guc_ggtt_offset(guc, log->vma) >> PAGE_SHIFT; + + flags = GUC_LOG_VALID | + GUC_LOG_NOTIFY_ON_HALF_FULL | +- CAPTURE_FLAG | +- LOG_FLAG | +- ((CRASH_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_CRASH_SHIFT) | +- ((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_DEBUG_SHIFT) | +- ((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) << GUC_LOG_CAPTURE_SHIFT) | ++ log->sizes[GUC_LOG_SECTIONS_DEBUG].flag | ++ log->sizes[GUC_LOG_SECTIONS_CAPTURE].flag | ++ (log->sizes[GUC_LOG_SECTIONS_CRASH].count << GUC_LOG_CRASH_SHIFT) | ++ (log->sizes[GUC_LOG_SECTIONS_DEBUG].count << GUC_LOG_DEBUG_SHIFT) | ++ (log->sizes[GUC_LOG_SECTIONS_CAPTURE].count << GUC_LOG_CAPTURE_SHIFT) | + (offset << GUC_LOG_BUF_ADDR_SHIFT); + +- #undef LOG_UNIT +- #undef LOG_FLAG +- #undef CAPTURE_UNIT +- #undef CAPTURE_FLAG +- + return flags; + } + +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +index b54b7883320b..d2ac53d4f3b6 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +@@ -656,16 +656,17 @@ static void check_guc_capture_size(struct intel_guc *guc) + struct drm_i915_private *i915 = guc_to_gt(guc)->i915; + int min_size = guc_capture_output_min_size_est(guc); + int spare_size = min_size * GUC_CAPTURE_OVERBUFFER_MULTIPLIER; ++ u32 buffer_size = intel_guc_log_section_size_capture(&guc->log); + + if (min_size < 0) + drm_warn(&i915->drm, "Failed to calculate GuC error state capture buffer minimum size: %d!\n", + min_size); +- else if (min_size > CAPTURE_BUFFER_SIZE) ++ else if (min_size > buffer_size) + drm_warn(&i915->drm, "GuC error state capture buffer is too small: %d < %d\n", +- CAPTURE_BUFFER_SIZE, min_size); +- else if (spare_size > CAPTURE_BUFFER_SIZE) ++ buffer_size, min_size); ++ else if (spare_size > buffer_size) + drm_notice(&i915->drm, "GuC error state capture buffer maybe too small: %d < %d (min = %d)\n", +- CAPTURE_BUFFER_SIZE, spare_size, min_size); ++ buffer_size, spare_size, min_size); + } + + /* +@@ -1294,7 +1295,8 @@ static void __guc_capture_process_output(struct intel_guc *guc) + + log_buf_state = guc->log.buf_addr + + (sizeof(struct guc_log_buffer_state) * GUC_CAPTURE_LOG_BUFFER); +- src_data = guc->log.buf_addr + intel_guc_get_log_buffer_offset(GUC_CAPTURE_LOG_BUFFER); ++ src_data = guc->log.buf_addr + ++ intel_guc_get_log_buffer_offset(&guc->log, GUC_CAPTURE_LOG_BUFFER); + + /* + * Make a copy of the state structure, inside GuC log buffer +@@ -1302,7 +1304,7 @@ static void __guc_capture_process_output(struct intel_guc *guc) + * from it multiple times. + */ + memcpy(&log_buf_state_local, log_buf_state, sizeof(struct guc_log_buffer_state)); +- buffer_size = intel_guc_get_log_buffer_size(GUC_CAPTURE_LOG_BUFFER); ++ buffer_size = intel_guc_get_log_buffer_size(&guc->log, GUC_CAPTURE_LOG_BUFFER); + read_offset = log_buf_state_local.read_ptr; + write_offset = log_buf_state_local.sampled_write_ptr; + full_count = log_buf_state_local.buffer_full_cnt; +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +index 991d4a02248d..2b878030d3e1 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +@@ -13,8 +13,158 @@ + #include "intel_guc_capture.h" + #include "intel_guc_log.h" + ++#if defined(CONFIG_DRM_I915_DEBUG_GUC) ++#define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_2M ++#define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE SZ_16M ++#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_4M ++#elif defined(CONFIG_DRM_I915_DEBUG_GEM) ++#define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_1M ++#define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE SZ_2M ++#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_4M ++#else ++#define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_8K ++#define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE SZ_64K ++#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE SZ_2M ++#endif ++ + static void guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log); + ++struct guc_log_section { ++ u32 max; ++ u32 flag; ++ u32 default_val; ++ const char *name; ++}; ++ ++static s32 scale_log_param(struct intel_guc_log *log, const struct guc_log_section *section, ++ s32 param) ++{ ++ /* -1 means default */ ++ if (param < 0) ++ return section->default_val; ++ ++ /* Check for 32-bit overflow */ ++ if (param >= SZ_4K) { ++ drm_err(&guc_to_gt(log_to_guc(log))->i915->drm, "Size too large for GuC %s log: %dMB!", ++ section->name, param); ++ return section->default_val; ++ } ++ ++ /* Param units are 1MB */ ++ return param * SZ_1M; ++} ++ ++static void _guc_log_init_sizes(struct intel_guc_log *log) ++{ ++ struct intel_guc *guc = log_to_guc(log); ++ struct drm_i915_private *i915 = guc_to_gt(guc)->i915; ++ static const struct guc_log_section sections[GUC_LOG_SECTIONS_LIMIT] = { ++ { ++ GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT, ++ GUC_LOG_LOG_ALLOC_UNITS, ++ GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE, ++ "crash dump" ++ }, ++ { ++ GUC_LOG_DEBUG_MASK >> GUC_LOG_DEBUG_SHIFT, ++ GUC_LOG_LOG_ALLOC_UNITS, ++ GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE, ++ "debug", ++ }, ++ { ++ GUC_LOG_CAPTURE_MASK >> GUC_LOG_CAPTURE_SHIFT, ++ GUC_LOG_CAPTURE_ALLOC_UNITS, ++ GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE, ++ "capture", ++ } ++ }; ++ s32 params[GUC_LOG_SECTIONS_LIMIT] = { ++ i915->params.guc_log_size_crash, ++ i915->params.guc_log_size_debug, ++ i915->params.guc_log_size_capture, ++ }; ++ int i; ++ ++ for (i = 0; i < GUC_LOG_SECTIONS_LIMIT; i++) ++ log->sizes[i].bytes = scale_log_param(log, sections + i, params[i]); ++ ++ /* If debug size > 1MB then bump default crash size to keep the same units */ ++ if (log->sizes[GUC_LOG_SECTIONS_DEBUG].bytes >= SZ_1M && ++ (i915->params.guc_log_size_crash == -1) && ++ GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE < SZ_1M) ++ log->sizes[GUC_LOG_SECTIONS_CRASH].bytes = SZ_1M; ++ ++ /* Prepare the GuC API structure fields: */ ++ for (i = 0; i < GUC_LOG_SECTIONS_LIMIT; i++) { ++ /* Convert to correct units */ ++ if ((log->sizes[i].bytes % SZ_1M) == 0) { ++ log->sizes[i].units = SZ_1M; ++ log->sizes[i].flag = sections[i].flag; ++ } else { ++ log->sizes[i].units = SZ_4K; ++ log->sizes[i].flag = 0; ++ } ++ ++ if (!IS_ALIGNED(log->sizes[i].bytes, log->sizes[i].units)) ++ drm_err(&i915->drm, "Mis-aligned GuC log %s size: 0x%X vs 0x%X!", ++ sections[i].name, log->sizes[i].bytes, log->sizes[i].units); ++ log->sizes[i].count = log->sizes[i].bytes / log->sizes[i].units; ++ ++ if (!log->sizes[i].count) { ++ drm_err(&i915->drm, "Zero GuC log %s size!", sections[i].name); ++ } else { ++ /* Size is +1 unit */ ++ log->sizes[i].count--; ++ } ++ ++ /* Clip to field size */ ++ if (log->sizes[i].count > sections[i].max) { ++ drm_err(&i915->drm, "GuC log %s size too large: %d vs %d!", ++ sections[i].name, log->sizes[i].count + 1, sections[i].max + 1); ++ log->sizes[i].count = sections[i].max; ++ } ++ } ++ ++ if (log->sizes[GUC_LOG_SECTIONS_CRASH].units != log->sizes[GUC_LOG_SECTIONS_DEBUG].units) { ++ drm_err(&i915->drm, "Unit mis-match for GuC log crash and debug sections: %d vs %d!", ++ log->sizes[GUC_LOG_SECTIONS_CRASH].units, ++ log->sizes[GUC_LOG_SECTIONS_DEBUG].units); ++ log->sizes[GUC_LOG_SECTIONS_CRASH].units = log->sizes[GUC_LOG_SECTIONS_DEBUG].units; ++ log->sizes[GUC_LOG_SECTIONS_CRASH].count = 0; ++ } ++ ++ log->sizes_initialised = true; ++} ++ ++static void guc_log_init_sizes(struct intel_guc_log *log) ++{ ++ if (log->sizes_initialised) ++ return; ++ ++ _guc_log_init_sizes(log); ++} ++ ++static u32 intel_guc_log_section_size_crash(struct intel_guc_log *log) ++{ ++ guc_log_init_sizes(log); ++ ++ return log->sizes[GUC_LOG_SECTIONS_CRASH].bytes; ++} ++ ++static u32 intel_guc_log_section_size_debug(struct intel_guc_log *log) ++{ ++ guc_log_init_sizes(log); ++ ++ return log->sizes[GUC_LOG_SECTIONS_DEBUG].bytes; ++} ++ ++u32 intel_guc_log_section_size_capture(struct intel_guc_log *log) ++{ ++ guc_log_init_sizes(log); ++ ++ return log->sizes[GUC_LOG_SECTIONS_CAPTURE].bytes; ++} ++ + static u32 intel_guc_log_size(struct intel_guc_log *log) + { + /* +@@ -38,7 +188,10 @@ static u32 intel_guc_log_size(struct intel_guc_log *log) + * | Capture logs | + * +===============================+ + CAPTURE_SIZE + */ +- return PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE + CAPTURE_BUFFER_SIZE; ++ return PAGE_SIZE + ++ intel_guc_log_section_size_crash(log) + ++ intel_guc_log_section_size_debug(log) + ++ intel_guc_log_section_size_capture(log); + } + + /** +@@ -165,7 +318,8 @@ static void guc_move_to_next_buf(struct intel_guc_log *log) + smp_wmb(); + + /* All data has been written, so now move the offset of sub buffer. */ +- relay_reserve(log->relay.channel, log->vma->obj->base.size - CAPTURE_BUFFER_SIZE); ++ relay_reserve(log->relay.channel, log->vma->obj->base.size - ++ intel_guc_log_section_size_capture(log)); + + /* Switch to the next sub buffer */ + relay_flush(log->relay.channel); +@@ -210,15 +364,16 @@ bool intel_guc_check_log_buf_overflow(struct intel_guc_log *log, + return overflow; + } + +-unsigned int intel_guc_get_log_buffer_size(enum guc_log_buffer_type type) ++unsigned int intel_guc_get_log_buffer_size(struct intel_guc_log *log, ++ enum guc_log_buffer_type type) + { + switch (type) { + case GUC_DEBUG_LOG_BUFFER: +- return DEBUG_BUFFER_SIZE; ++ return intel_guc_log_section_size_debug(log); + case GUC_CRASH_DUMP_LOG_BUFFER: +- return CRASH_BUFFER_SIZE; ++ return intel_guc_log_section_size_crash(log); + case GUC_CAPTURE_LOG_BUFFER: +- return CAPTURE_BUFFER_SIZE; ++ return intel_guc_log_section_size_capture(log); + default: + MISSING_CASE(type); + } +@@ -226,7 +381,8 @@ unsigned int intel_guc_get_log_buffer_size(enum guc_log_buffer_type type) + return 0; + } + +-size_t intel_guc_get_log_buffer_offset(enum guc_log_buffer_type type) ++size_t intel_guc_get_log_buffer_offset(struct intel_guc_log *log, ++ enum guc_log_buffer_type type) + { + enum guc_log_buffer_type i; + size_t offset = PAGE_SIZE;/* for the log_buffer_states */ +@@ -234,7 +390,7 @@ size_t intel_guc_get_log_buffer_offset(enum guc_log_buffer_type type) + for (i = GUC_DEBUG_LOG_BUFFER; i < GUC_MAX_LOG_BUFFER; ++i) { + if (i == type) + break; +- offset += intel_guc_get_log_buffer_size(i); ++ offset += intel_guc_get_log_buffer_size(log, i); + } + + return offset; +@@ -285,7 +441,7 @@ static void _guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log) + */ + memcpy(&log_buf_state_local, log_buf_state, + sizeof(struct guc_log_buffer_state)); +- buffer_size = intel_guc_get_log_buffer_size(type); ++ buffer_size = intel_guc_get_log_buffer_size(log, type); + read_offset = log_buf_state_local.read_ptr; + write_offset = log_buf_state_local.sampled_write_ptr; + full_cnt = log_buf_state_local.buffer_full_cnt; +@@ -400,7 +556,7 @@ static int guc_log_relay_create(struct intel_guc_log *log) + * Keep the size of sub buffers same as shared log buffer + * but GuC log-events excludes the error-state-capture logs + */ +- subbuf_size = log->vma->size - CAPTURE_BUFFER_SIZE; ++ subbuf_size = log->vma->size - intel_guc_log_section_size_capture(log); + + /* + * Store up to 8 snapshots, which is large enough to buffer sufficient +diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h +index dc9715411d62..02127703be80 100644 +--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h ++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h +@@ -15,20 +15,6 @@ + + struct intel_guc; + +-#if defined(CONFIG_DRM_I915_DEBUG_GUC) +-#define CRASH_BUFFER_SIZE SZ_2M +-#define DEBUG_BUFFER_SIZE SZ_16M +-#define CAPTURE_BUFFER_SIZE SZ_4M +-#elif defined(CONFIG_DRM_I915_DEBUG_GEM) +-#define CRASH_BUFFER_SIZE SZ_1M +-#define DEBUG_BUFFER_SIZE SZ_2M +-#define CAPTURE_BUFFER_SIZE SZ_4M +-#else +-#define CRASH_BUFFER_SIZE SZ_8K +-#define DEBUG_BUFFER_SIZE SZ_64K +-#define CAPTURE_BUFFER_SIZE SZ_2M +-#endif +- + /* + * While we're using plain log level in i915, GuC controls are much more... + * "elaborate"? We have a couple of bits for verbosity, separate bit for actual +@@ -46,10 +32,30 @@ struct intel_guc; + #define GUC_VERBOSITY_TO_LOG_LEVEL(x) ((x) + 2) + #define GUC_LOG_LEVEL_MAX GUC_VERBOSITY_TO_LOG_LEVEL(GUC_LOG_VERBOSITY_MAX) + ++enum { ++ GUC_LOG_SECTIONS_CRASH, ++ GUC_LOG_SECTIONS_DEBUG, ++ GUC_LOG_SECTIONS_CAPTURE, ++ GUC_LOG_SECTIONS_LIMIT ++}; ++ + struct intel_guc_log { + u32 level; ++ ++ /* Allocation settings */ ++ struct { ++ s32 bytes; /* Size in bytes */ ++ s32 units; /* GuC API units - 1MB or 4KB */ ++ s32 count; /* Number of API units */ ++ u32 flag; /* GuC API units flag */ ++ } sizes[GUC_LOG_SECTIONS_LIMIT]; ++ bool sizes_initialised; ++ ++ /* Combined buffer allocation */ + struct i915_vma *vma; + void *buf_addr; ++ ++ /* RelayFS support */ + struct { + bool buf_in_use; + bool started; +@@ -58,6 +64,7 @@ struct intel_guc_log { + struct mutex lock; + u32 full_count; + } relay; ++ + /* logging related stats */ + struct { + u32 sampled_overflow; +@@ -69,8 +76,9 @@ struct intel_guc_log { + void intel_guc_log_init_early(struct intel_guc_log *log); + bool intel_guc_check_log_buf_overflow(struct intel_guc_log *log, enum guc_log_buffer_type type, + unsigned int full_cnt); +-unsigned int intel_guc_get_log_buffer_size(enum guc_log_buffer_type type); +-size_t intel_guc_get_log_buffer_offset(enum guc_log_buffer_type type); ++unsigned int intel_guc_get_log_buffer_size(struct intel_guc_log *log, ++ enum guc_log_buffer_type type); ++size_t intel_guc_get_log_buffer_offset(struct intel_guc_log *log, enum guc_log_buffer_type type); + int intel_guc_log_create(struct intel_guc_log *log); + void intel_guc_log_destroy(struct intel_guc_log *log); + +@@ -92,4 +100,6 @@ void intel_guc_log_info(struct intel_guc_log *log, struct drm_printer *p); + int intel_guc_log_dump(struct intel_guc_log *log, struct drm_printer *p, + bool dump_load_err); + ++u32 intel_guc_log_section_size_capture(struct intel_guc_log *log); ++ + #endif +diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c +index 6fc475a5db61..06ca5b822111 100644 +--- a/drivers/gpu/drm/i915/i915_params.c ++++ b/drivers/gpu/drm/i915/i915_params.c +@@ -171,6 +171,18 @@ i915_param_named(guc_log_level, int, 0400, + "GuC firmware logging level. Requires GuC to be loaded. " + "(-1=auto [default], 0=disable, 1..4=enable with verbosity min..max)"); + ++i915_param_named(guc_log_size_crash, int, 0400, ++ "GuC firmware logging buffer size for crash dumps (in MB)" ++ "(-1=auto [default], NB: max = 4, other restrictions apply)"); ++ ++i915_param_named(guc_log_size_debug, int, 0400, ++ "GuC firmware logging buffer size for debug logs (in MB)" ++ "(-1=auto [default], NB: max = 16, other restrictions apply)"); ++ ++i915_param_named(guc_log_size_capture, int, 0400, ++ "GuC error capture register dump buffer size (in MB)" ++ "(-1=auto [default], NB: max = 4, other restrictions apply)"); ++ + i915_param_named_unsafe(guc_firmware_path, charp, 0400, + "GuC firmware path to use instead of the default one"); + +diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h +index 2733cb6cfe09..f684d1ab8707 100644 +--- a/drivers/gpu/drm/i915/i915_params.h ++++ b/drivers/gpu/drm/i915/i915_params.h +@@ -61,6 +61,9 @@ struct drm_printer; + param(int, invert_brightness, 0, 0600) \ + param(int, enable_guc, -1, 0400) \ + param(int, guc_log_level, -1, 0400) \ ++ param(int, guc_log_size_crash, -1, 0400) \ ++ param(int, guc_log_size_debug, -1, 0400) \ ++ param(int, guc_log_size_capture, -1, 0400) \ + param(char *, guc_firmware_path, NULL, 0400) \ + param(char *, huc_firmware_path, NULL, 0400) \ + param(char *, dmc_firmware_path, NULL, 0400) \ +-- +2.35.1 + diff --git a/queue-6.0/drm-lcdif-change-burst-size-to-256b.patch b/queue-6.0/drm-lcdif-change-burst-size-to-256b.patch new file mode 100644 index 00000000000..41c226f7a5e --- /dev/null +++ b/queue-6.0/drm-lcdif-change-burst-size-to-256b.patch @@ -0,0 +1,67 @@ +From b56378dca29bcb414d2490d52bb4dd098c0aacb2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Nov 2022 17:46:15 +0100 +Subject: drm: lcdif: change burst size to 256B + +From: Marco Felsch + +[ Upstream commit 2215cb3be5c28a1fd43036550c00c2371aeeba95 ] + +If a axi bus master with a higher priority do a lot of memory access +FIFO underruns can be inspected. Increase the burst size to 256B to +avoid such underruns and to improve the memory access efficiency. + +Fixes: 9db35bb349a0 ("drm: lcdif: Add support for i.MX8MP LCDIF variant") +Signed-off-by: Marco Felsch +Reviewed-by: Marek Vasut +Signed-off-by: Marek Vasut +Link: https://patchwork.freedesktop.org/patch/msgid/20221101164615.778299-1-m.felsch@pengutronix.de +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mxsfb/lcdif_kms.c | 14 ++++++++++++-- + drivers/gpu/drm/mxsfb/lcdif_regs.h | 4 ++++ + 2 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/mxsfb/lcdif_kms.c b/drivers/gpu/drm/mxsfb/lcdif_kms.c +index 11f881554f74..713b0d756f2a 100644 +--- a/drivers/gpu/drm/mxsfb/lcdif_kms.c ++++ b/drivers/gpu/drm/mxsfb/lcdif_kms.c +@@ -149,8 +149,18 @@ static void lcdif_set_mode(struct lcdif_drm_private *lcdif, u32 bus_flags) + CTRLDESCL0_1_WIDTH(m->crtc_hdisplay), + lcdif->base + LCDC_V8_CTRLDESCL0_1); + +- writel(CTRLDESCL0_3_PITCH(lcdif->crtc.primary->state->fb->pitches[0]), +- lcdif->base + LCDC_V8_CTRLDESCL0_3); ++ /* ++ * Undocumented P_SIZE and T_SIZE register but those written in the ++ * downstream kernel those registers control the AXI burst size. As of ++ * now there are two known values: ++ * 1 - 128Byte ++ * 2 - 256Byte ++ * Downstream set it to 256B burst size to improve the memory ++ * efficiency so set it here too. ++ */ ++ ctrl = CTRLDESCL0_3_P_SIZE(2) | CTRLDESCL0_3_T_SIZE(2) | ++ CTRLDESCL0_3_PITCH(lcdif->crtc.primary->state->fb->pitches[0]); ++ writel(ctrl, lcdif->base + LCDC_V8_CTRLDESCL0_3); + } + + static void lcdif_enable_controller(struct lcdif_drm_private *lcdif) +diff --git a/drivers/gpu/drm/mxsfb/lcdif_regs.h b/drivers/gpu/drm/mxsfb/lcdif_regs.h +index c70220651e3a..8e8bef175bf2 100644 +--- a/drivers/gpu/drm/mxsfb/lcdif_regs.h ++++ b/drivers/gpu/drm/mxsfb/lcdif_regs.h +@@ -190,6 +190,10 @@ + #define CTRLDESCL0_1_WIDTH(n) ((n) & 0xffff) + #define CTRLDESCL0_1_WIDTH_MASK GENMASK(15, 0) + ++#define CTRLDESCL0_3_P_SIZE(n) (((n) << 20) & CTRLDESCL0_3_P_SIZE_MASK) ++#define CTRLDESCL0_3_P_SIZE_MASK GENMASK(22, 20) ++#define CTRLDESCL0_3_T_SIZE(n) (((n) << 16) & CTRLDESCL0_3_T_SIZE_MASK) ++#define CTRLDESCL0_3_T_SIZE_MASK GENMASK(17, 16) + #define CTRLDESCL0_3_PITCH(n) ((n) & 0xffff) + #define CTRLDESCL0_3_PITCH_MASK GENMASK(15, 0) + +-- +2.35.1 + diff --git a/queue-6.0/drm-lcdif-set-and-enable-fifo-panic-threshold.patch b/queue-6.0/drm-lcdif-set-and-enable-fifo-panic-threshold.patch new file mode 100644 index 00000000000..f74a783af1c --- /dev/null +++ b/queue-6.0/drm-lcdif-set-and-enable-fifo-panic-threshold.patch @@ -0,0 +1,89 @@ +From d70e6462bc49eb0e3fbd4cc9b1dfc8d04a0531fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Nov 2022 16:26:29 +0100 +Subject: drm: lcdif: Set and enable FIFO Panic threshold + +From: Marek Vasut + +[ Upstream commit e3cac8f7749f78dacdf19c00ed5862a1db52239f ] + +In case the LCDIFv3 is used to drive a 4k panel via i.MX8MP HDMI bridge, +the LCDIFv3 becomes susceptible to FIFO underflows, these lead to nasty +flicker of the image on the panel, or image being shifted by half frame +horizontally every second frame. The flicker can be easily triggered by +running 3D application on top of weston compositor, like neverball or +chromium. Surprisingly glmark2-es2-wayland or glmark2-es2-drm does not +trigger this effect so easily. + +Configure the FIFO Panic threshold register and enable the FIFO Panic +mode, which internally boosts the NoC interconnect priority for LCDIFv3 +transactions in case of possible underflow. This mitigates the flicker +effect on 4k panels as well. + +Fixes: 9db35bb349a0 ("drm: lcdif: Add support for i.MX8MP LCDIF variant") +Signed-off-by: Marek Vasut +Tested-by: Liu Ying # i.MX8mp EVK +Reviewed-by: Liu Ying +Link: https://patchwork.freedesktop.org/patch/msgid/20221101152629.21768-1-marex@denx.de +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mxsfb/lcdif_kms.c | 16 ++++++++++++++++ + drivers/gpu/drm/mxsfb/lcdif_regs.h | 1 + + 2 files changed, 17 insertions(+) + +diff --git a/drivers/gpu/drm/mxsfb/lcdif_kms.c b/drivers/gpu/drm/mxsfb/lcdif_kms.c +index 713b0d756f2a..d419c61c3407 100644 +--- a/drivers/gpu/drm/mxsfb/lcdif_kms.c ++++ b/drivers/gpu/drm/mxsfb/lcdif_kms.c +@@ -5,6 +5,7 @@ + * This code is based on drivers/gpu/drm/mxsfb/mxsfb* + */ + ++#include + #include + #include + #include +@@ -167,6 +168,18 @@ static void lcdif_enable_controller(struct lcdif_drm_private *lcdif) + { + u32 reg; + ++ /* Set FIFO Panic watermarks, low 1/3, high 2/3 . */ ++ writel(FIELD_PREP(PANIC0_THRES_LOW_MASK, 1 * PANIC0_THRES_MAX / 3) | ++ FIELD_PREP(PANIC0_THRES_HIGH_MASK, 2 * PANIC0_THRES_MAX / 3), ++ lcdif->base + LCDC_V8_PANIC0_THRES); ++ ++ /* ++ * Enable FIFO Panic, this does not generate interrupt, but ++ * boosts NoC priority based on FIFO Panic watermarks. ++ */ ++ writel(INT_ENABLE_D1_PLANE_PANIC_EN, ++ lcdif->base + LCDC_V8_INT_ENABLE_D1); ++ + reg = readl(lcdif->base + LCDC_V8_DISP_PARA); + reg |= DISP_PARA_DISP_ON; + writel(reg, lcdif->base + LCDC_V8_DISP_PARA); +@@ -194,6 +207,9 @@ static void lcdif_disable_controller(struct lcdif_drm_private *lcdif) + reg = readl(lcdif->base + LCDC_V8_DISP_PARA); + reg &= ~DISP_PARA_DISP_ON; + writel(reg, lcdif->base + LCDC_V8_DISP_PARA); ++ ++ /* Disable FIFO Panic NoC priority booster. */ ++ writel(0, lcdif->base + LCDC_V8_INT_ENABLE_D1); + } + + static void lcdif_reset_block(struct lcdif_drm_private *lcdif) +diff --git a/drivers/gpu/drm/mxsfb/lcdif_regs.h b/drivers/gpu/drm/mxsfb/lcdif_regs.h +index 8e8bef175bf2..37f0d9a06b10 100644 +--- a/drivers/gpu/drm/mxsfb/lcdif_regs.h ++++ b/drivers/gpu/drm/mxsfb/lcdif_regs.h +@@ -252,6 +252,7 @@ + + #define PANIC0_THRES_LOW_MASK GENMASK(24, 16) + #define PANIC0_THRES_HIGH_MASK GENMASK(8, 0) ++#define PANIC0_THRES_MAX 511 + + #define LCDIF_MIN_XRES 120 + #define LCDIF_MIN_YRES 120 +-- +2.35.1 + diff --git a/queue-6.0/drm-lcdif-switch-to-limited-range-for-rgb-to-yuv-con.patch b/queue-6.0/drm-lcdif-switch-to-limited-range-for-rgb-to-yuv-con.patch new file mode 100644 index 00000000000..ebeabce0cf6 --- /dev/null +++ b/queue-6.0/drm-lcdif-switch-to-limited-range-for-rgb-to-yuv-con.patch @@ -0,0 +1,70 @@ +From c3e31f539085f68db0a2a595634bb8550081ee31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Sep 2022 11:39:54 +0300 +Subject: drm: lcdif: Switch to limited range for RGB to YUV conversion + +From: Laurent Pinchart + +[ Upstream commit ec39dee8b25229a646271815cc86a8fc865525cf ] + +Up to and including v1.3, HDMI supported limited quantization range only +for YCbCr. HDMI v1.4 introduced selectable quantization ranges, but this +feature isn't supported in the dw-hdmi driver that is used in +conjunction with the LCDIF in the i.MX8MP. The HDMI YCbCr output is thus +always advertised in the AVI infoframe as limited range. + +The LCDIF driver, on the other hand, configures the CSC to produce full +range YCbCr. This mismatch results in loss of details and incorrect +colours. Fix it by switching to limited range YCbCr. + +The coefficients are copied from drivers/media/platforms/nxp/imx-pxp.c +for coherency, as the hardware is most likely identical. + +Fixes: 9db35bb349a0 ("drm: lcdif: Add support for i.MX8MP LCDIF variant") +Signed-off-by: Laurent Pinchart +Reviewed-by: Marek Vasut +Reviewed-by: Kieran Bingham +Reviewed-by: Liu Ying +Signed-off-by: Marek Vasut +Link: https://patchwork.freedesktop.org/patch/msgid/20220930083955.31580-4-laurent.pinchart@ideasonboard.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mxsfb/lcdif_kms.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/mxsfb/lcdif_kms.c b/drivers/gpu/drm/mxsfb/lcdif_kms.c +index 1bec1279c8b5..11f881554f74 100644 +--- a/drivers/gpu/drm/mxsfb/lcdif_kms.c ++++ b/drivers/gpu/drm/mxsfb/lcdif_kms.c +@@ -53,16 +53,22 @@ static void lcdif_set_formats(struct lcdif_drm_private *lcdif, + writel(DISP_PARA_LINE_PATTERN_UYVY_H, + lcdif->base + LCDC_V8_DISP_PARA); + +- /* CSC: BT.601 Full Range RGB to YCbCr coefficients. */ +- writel(CSC0_COEF0_A2(0x096) | CSC0_COEF0_A1(0x04c), ++ /* ++ * CSC: BT.601 Limited Range RGB to YCbCr coefficients. ++ * ++ * |Y | | 0.2568 0.5041 0.0979| |R| |16 | ++ * |Cb| = |-0.1482 -0.2910 0.4392| * |G| + |128| ++ * |Cr| | 0.4392 0.4392 -0.3678| |B| |128| ++ */ ++ writel(CSC0_COEF0_A2(0x081) | CSC0_COEF0_A1(0x041), + lcdif->base + LCDC_V8_CSC0_COEF0); +- writel(CSC0_COEF1_B1(0x7d5) | CSC0_COEF1_A3(0x01d), ++ writel(CSC0_COEF1_B1(0x7db) | CSC0_COEF1_A3(0x019), + lcdif->base + LCDC_V8_CSC0_COEF1); +- writel(CSC0_COEF2_B3(0x080) | CSC0_COEF2_B2(0x7ac), ++ writel(CSC0_COEF2_B3(0x070) | CSC0_COEF2_B2(0x7b6), + lcdif->base + LCDC_V8_CSC0_COEF2); +- writel(CSC0_COEF3_C2(0x795) | CSC0_COEF3_C1(0x080), ++ writel(CSC0_COEF3_C2(0x7a2) | CSC0_COEF3_C1(0x070), + lcdif->base + LCDC_V8_CSC0_COEF3); +- writel(CSC0_COEF4_D1(0x000) | CSC0_COEF4_C3(0x7ec), ++ writel(CSC0_COEF4_D1(0x010) | CSC0_COEF4_C3(0x7ee), + lcdif->base + LCDC_V8_CSC0_COEF4); + writel(CSC0_COEF5_D3(0x080) | CSC0_COEF5_D2(0x080), + lcdif->base + LCDC_V8_CSC0_COEF5); +-- +2.35.1 + diff --git a/queue-6.0/drm-mediatek-fix-return-type-of-mtk_hdmi_bridge_mode.patch b/queue-6.0/drm-mediatek-fix-return-type-of-mtk_hdmi_bridge_mode.patch new file mode 100644 index 00000000000..ab8bf80da9d --- /dev/null +++ b/queue-6.0/drm-mediatek-fix-return-type-of-mtk_hdmi_bridge_mode.patch @@ -0,0 +1,59 @@ +From 037bb6a6fc060d5681a40dfa7281453d96cf9658 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Nov 2022 08:47:12 -0700 +Subject: drm/mediatek: Fix return type of mtk_hdmi_bridge_mode_valid() + +From: Nathan Chancellor + +[ Upstream commit 890d637523eec9d730e3885532fa1228ba678880 ] + +With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG), +indirect call targets are validated against the expected function +pointer prototype to make sure the call target is valid to help mitigate +ROP attacks. If they are not identical, there is a failure at run time, +which manifests as either a kernel panic or thread getting killed. A +proposed warning in clang aims to catch these at compile time, which +reveals: + + drivers/gpu/drm/mediatek/mtk_hdmi.c:1407:16: error: incompatible function pointer types initializing 'enum drm_mode_status (*)(struct drm_bridge *, const struct drm_display_info *, const struct drm_display_mode *)' with an expression of type 'int (struct drm_bridge *, const struct drm_display_info *, const struct drm_display_mode *)' [-Werror,-Wincompatible-function-pointer-types-strict] + .mode_valid = mtk_hdmi_bridge_mode_valid, + ^~~~~~~~~~~~~~~~~~~~~~~~~~ + 1 error generated. + +->mode_valid() in 'struct drm_bridge_funcs' expects a return type of +'enum drm_mode_status', not 'int'. Adjust the return type of +mtk_hdmi_bridge_mode_valid() to match the prototype's to resolve the +warning and CFI failure. + +Link: https://github.com/ClangBuiltLinux/linux/issues/1750 +Reported-by: Sami Tolvanen +Signed-off-by: Nathan Chancellor +Reviewed-by: Kees Cook +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Chun-Kuang Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_hdmi.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c +index 3196189429bc..7613b0fa2be6 100644 +--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c ++++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c +@@ -1203,9 +1203,10 @@ static enum drm_connector_status mtk_hdmi_detect(struct mtk_hdmi *hdmi) + return mtk_hdmi_update_plugged_status(hdmi); + } + +-static int mtk_hdmi_bridge_mode_valid(struct drm_bridge *bridge, +- const struct drm_display_info *info, +- const struct drm_display_mode *mode) ++static enum drm_mode_status ++mtk_hdmi_bridge_mode_valid(struct drm_bridge *bridge, ++ const struct drm_display_info *info, ++ const struct drm_display_mode *mode) + { + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); + struct drm_bridge *next_bridge; +-- +2.35.1 + diff --git a/queue-6.0/drm-mediatek-modify-dpi-power-on-off-sequence.patch b/queue-6.0/drm-mediatek-modify-dpi-power-on-off-sequence.patch new file mode 100644 index 00000000000..230928f3003 --- /dev/null +++ b/queue-6.0/drm-mediatek-modify-dpi-power-on-off-sequence.patch @@ -0,0 +1,66 @@ +From 87136b4f291661416e09fcac7b9edccd5d0806af Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Nov 2022 18:00:59 +0800 +Subject: drm/mediatek: Modify dpi power on/off sequence. + +From: Xinlei Lee + +[ Upstream commit ff446c0f6290185cefafe3b376bb86063a3a9f6a ] + +Modify dpi power on/off sequence so that the first gpio operation will +take effect. + +Fixes: 6bd4763fd532 ("drm/mediatek: set dpi pin mode to gpio low to avoid leakage current") +Signed-off-by: Xinlei Lee +Signed-off-by: Chun-Kuang Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_dpi.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c +index 630a4e301ef6..b11b5a2c0663 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dpi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c +@@ -462,9 +462,6 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi) + if (--dpi->refcount != 0) + return; + +- if (dpi->pinctrl && dpi->pins_gpio) +- pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio); +- + mtk_dpi_disable(dpi); + clk_disable_unprepare(dpi->pixel_clk); + clk_disable_unprepare(dpi->engine_clk); +@@ -489,9 +486,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi) + goto err_pixel; + } + +- if (dpi->pinctrl && dpi->pins_dpi) +- pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi); +- + return 0; + + err_pixel: +@@ -722,12 +716,18 @@ static void mtk_dpi_bridge_disable(struct drm_bridge *bridge) + struct mtk_dpi *dpi = bridge_to_dpi(bridge); + + mtk_dpi_power_off(dpi); ++ ++ if (dpi->pinctrl && dpi->pins_gpio) ++ pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio); + } + + static void mtk_dpi_bridge_enable(struct drm_bridge *bridge) + { + struct mtk_dpi *dpi = bridge_to_dpi(bridge); + ++ if (dpi->pinctrl && dpi->pins_dpi) ++ pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi); ++ + mtk_dpi_power_on(dpi); + mtk_dpi_set_display_mode(dpi, &dpi->mode); + mtk_dpi_enable(dpi); +-- +2.35.1 + diff --git a/queue-6.0/drm-meson-fix-return-type-of-meson_encoder_cvbs_mode.patch b/queue-6.0/drm-meson-fix-return-type-of-meson_encoder_cvbs_mode.patch new file mode 100644 index 00000000000..1d10f369387 --- /dev/null +++ b/queue-6.0/drm-meson-fix-return-type-of-meson_encoder_cvbs_mode.patch @@ -0,0 +1,59 @@ +From eb946849174c8b08b23d3f90aca0fbc3a0ed5fbc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Nov 2022 08:52:42 -0700 +Subject: drm/meson: Fix return type of meson_encoder_cvbs_mode_valid() + +From: Nathan Chancellor + +[ Upstream commit 6c4e4d35203301906afb53c6d1e1302d4c793c05 ] + +With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG), +indirect call targets are validated against the expected function +pointer prototype to make sure the call target is valid to help mitigate +ROP attacks. If they are not identical, there is a failure at run time, +which manifests as either a kernel panic or thread getting killed. A +proposed warning in clang aims to catch these at compile time, which +reveals: + + drivers/gpu/drm/meson/meson_encoder_cvbs.c:211:16: error: incompatible function pointer types initializing 'enum drm_mode_status (*)(struct drm_bridge *, const struct drm_display_info *, const struct drm_display_mode *)' with an expression of type 'int (struct drm_bridge *, const struct drm_display_info *, const struct drm_display_mode *)' [-Werror,-Wincompatible-function-pointer-types-strict] + .mode_valid = meson_encoder_cvbs_mode_valid, + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 1 error generated. + +->mode_valid() in 'struct drm_bridge_funcs' expects a return type of +'enum drm_mode_status', not 'int'. Adjust the return type of +meson_encoder_cvbs_mode_valid() to match the prototype's to resolve the +warning and CFI failure. + +Link: https://github.com/ClangBuiltLinux/linux/issues/1750 +Reported-by: Sami Tolvanen +Signed-off-by: Nathan Chancellor +Reviewed-by: Kees Cook +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/20221102155242.1927166-1-nathan@kernel.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/meson/meson_encoder_cvbs.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c +index 5675bc2a92cf..3f73b211fa8e 100644 +--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c ++++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c +@@ -116,9 +116,10 @@ static int meson_encoder_cvbs_get_modes(struct drm_bridge *bridge, + return i; + } + +-static int meson_encoder_cvbs_mode_valid(struct drm_bridge *bridge, +- const struct drm_display_info *display_info, +- const struct drm_display_mode *mode) ++static enum drm_mode_status ++meson_encoder_cvbs_mode_valid(struct drm_bridge *bridge, ++ const struct drm_display_info *display_info, ++ const struct drm_display_mode *mode) + { + if (meson_cvbs_get_mode(mode)) + return MODE_OK; +-- +2.35.1 + diff --git a/queue-6.0/drm-msm-a6xx-fix-speed-bin-detection-vs-probe-defer.patch b/queue-6.0/drm-msm-a6xx-fix-speed-bin-detection-vs-probe-defer.patch new file mode 100644 index 00000000000..fac513d1600 --- /dev/null +++ b/queue-6.0/drm-msm-a6xx-fix-speed-bin-detection-vs-probe-defer.patch @@ -0,0 +1,73 @@ +From 2db5be10781ebbb1fb92222780fe69f643b3562f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Nov 2022 07:46:34 -0800 +Subject: drm/msm/a6xx: Fix speed-bin detection vs probe-defer + +From: Rob Clark + +[ Upstream commit f6d1918794ef92b4e26b80c3d40365347b76b1fd ] + +If we get an error (other than -ENOENT) we need to propagate that up the +stack. Otherwise if the nvmem driver hasn't probed yet, we'll end up +end up claiming that we support all the OPPs which is not likely to be +true (and on some generations impossible to be true, ie. if there are +conflicting OPPs). + +v2: Update commit msg, gc unused label, etc +v3: Add previously missing \n's + +Fixes: fe7952c629da ("drm/msm: Add speed-bin support to a618 gpu") +Signed-off-by: Rob Clark +Reviewed-by: Douglas Anderson +Reviewed-by: Akhil P Oommen +Patchwork: https://patchwork.freedesktop.org/patch/511690/ +Link: https://lore.kernel.org/r/20221115154637.1613968-1-robdclark@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +index 4d501100b9e4..5804c35ae74b 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +@@ -1869,7 +1869,7 @@ static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse) + + if (val == UINT_MAX) { + DRM_DEV_ERROR(dev, +- "missing support for speed-bin: %u. Some OPPs may not be supported by hardware", ++ "missing support for speed-bin: %u. Some OPPs may not be supported by hardware\n", + fuse); + return UINT_MAX; + } +@@ -1879,7 +1879,7 @@ static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse) + + static int a6xx_set_supported_hw(struct device *dev, struct adreno_rev rev) + { +- u32 supp_hw = UINT_MAX; ++ u32 supp_hw; + u32 speedbin; + int ret; + +@@ -1891,15 +1891,13 @@ static int a6xx_set_supported_hw(struct device *dev, struct adreno_rev rev) + if (ret == -ENOENT) { + return 0; + } else if (ret) { +- DRM_DEV_ERROR(dev, +- "failed to read speed-bin (%d). Some OPPs may not be supported by hardware", +- ret); +- goto done; ++ dev_err_probe(dev, ret, ++ "failed to read speed-bin. Some OPPs may not be supported by hardware\n"); ++ return ret; + } + + supp_hw = fuse_to_supp_hw(dev, rev, speedbin); + +-done: + ret = devm_pm_opp_set_supported_hw(dev, &supp_hw, 1); + if (ret) + return ret; +-- +2.35.1 + diff --git a/queue-6.0/drm-msm-dpu-use-drm_dsc_config-instead-of-msm_displa.patch b/queue-6.0/drm-msm-dpu-use-drm_dsc_config-instead-of-msm_displa.patch new file mode 100644 index 00000000000..d2c87c27b20 --- /dev/null +++ b/queue-6.0/drm-msm-dpu-use-drm_dsc_config-instead-of-msm_displa.patch @@ -0,0 +1,305 @@ +From 05afbda2bca5b89a5ae7e4848b8e9af97210fa29 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Jul 2022 13:04:31 +0300 +Subject: drm/msm/dpu: use drm_dsc_config instead of msm_display_dsc_config + +From: Dmitry Baryshkov + +[ Upstream commit 46dd0c0658ff5783acce37dcfe437e2a79a9934e ] + +There is no need to use the struct msm_display_dsc_config wrapper inside +the dpu driver, use the struct drm_dsc_config directly to pass pps data. + +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Abhinav Kumar +Reviewed-by: Marijn Suijten +Patchwork: https://patchwork.freedesktop.org/patch/493340/ +Link: https://lore.kernel.org/r/20220711100432.455268-2-dmitry.baryshkov@linaro.org +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Rob Clark +Stable-dep-of: d3c1a8663d0d ("drm/msm/dpu1: Account for DSC's bits_per_pixel having 4 fractional bits") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 25 +++---- + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 2 +- + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 74 ++++++++++----------- + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 4 +- + drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 2 +- + 5 files changed, 54 insertions(+), 53 deletions(-) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +index 52a626117f70..7f5dba96b2ff 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +@@ -162,7 +162,7 @@ enum dpu_enc_rc_states { + * @vsync_event_work: worker to handle vsync event for autorefresh + * @topology: topology of the display + * @idle_timeout: idle timeout duration in milliseconds +- * @dsc: msm_display_dsc_config pointer, for DSC-enabled encoders ++ * @dsc: drm_dsc_config pointer, for DSC-enabled encoders + */ + struct dpu_encoder_virt { + struct drm_encoder base; +@@ -208,7 +208,7 @@ struct dpu_encoder_virt { + bool wide_bus_en; + + /* DSC configuration */ +- struct msm_display_dsc_config *dsc; ++ struct drm_dsc_config *dsc; + }; + + #define to_dpu_encoder_virt(x) container_of(x, struct dpu_encoder_virt, base) +@@ -1791,12 +1791,12 @@ static void dpu_encoder_vsync_event_work_handler(struct kthread_work *work) + } + + static u32 +-dpu_encoder_dsc_initial_line_calc(struct msm_display_dsc_config *dsc, ++dpu_encoder_dsc_initial_line_calc(struct drm_dsc_config *dsc, + u32 enc_ip_width) + { + int ssm_delay, total_pixels, soft_slice_per_enc; + +- soft_slice_per_enc = enc_ip_width / dsc->drm->slice_width; ++ soft_slice_per_enc = enc_ip_width / dsc->slice_width; + + /* + * minimum number of initial line pixels is a sum of: +@@ -1808,16 +1808,16 @@ dpu_encoder_dsc_initial_line_calc(struct msm_display_dsc_config *dsc, + * 5. 6 additional pixels as the output of the rate buffer is + * 48 bits wide + */ +- ssm_delay = ((dsc->drm->bits_per_component < 10) ? 84 : 92); +- total_pixels = ssm_delay * 3 + dsc->drm->initial_xmit_delay + 47; ++ ssm_delay = ((dsc->bits_per_component < 10) ? 84 : 92); ++ total_pixels = ssm_delay * 3 + dsc->initial_xmit_delay + 47; + if (soft_slice_per_enc > 1) + total_pixels += (ssm_delay * 3); +- return DIV_ROUND_UP(total_pixels, dsc->drm->slice_width); ++ return DIV_ROUND_UP(total_pixels, dsc->slice_width); + } + + static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, + struct dpu_hw_pingpong *hw_pp, +- struct msm_display_dsc_config *dsc, ++ struct drm_dsc_config *dsc, + u32 common_mode, + u32 initial_lines) + { +@@ -1835,7 +1835,7 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, + } + + static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, +- struct msm_display_dsc_config *dsc) ++ struct drm_dsc_config *dsc) + { + /* coding only for 2LM, 2enc, 1 dsc config */ + struct dpu_encoder_phys *enc_master = dpu_enc->cur_master; +@@ -1858,14 +1858,15 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, + } + } + +- pic_width = dsc->drm->pic_width; ++ dsc_common_mode = 0; ++ pic_width = dsc->pic_width; + + dsc_common_mode = DSC_MODE_MULTIPLEX | DSC_MODE_SPLIT_PANEL; + if (enc_master->intf_mode == INTF_MODE_VIDEO) + dsc_common_mode |= DSC_MODE_VIDEO; + +- this_frame_slices = pic_width / dsc->drm->slice_width; +- intf_ip_w = this_frame_slices * dsc->drm->slice_width; ++ this_frame_slices = pic_width / dsc->slice_width; ++ intf_ip_w = this_frame_slices * dsc->slice_width; + + /* + * dsc merge case: when using 2 encoders for the same stream, +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +index d4d1ecd416e3..9e7236ef34e6 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +@@ -36,7 +36,7 @@ struct msm_display_info { + uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY]; + bool is_cmd_mode; + bool is_te_using_watchdog_timer; +- struct msm_display_dsc_config *dsc; ++ struct drm_dsc_config *dsc; + }; + + /** +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +index 411689ae6382..f2ddcfb6f7ee 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +@@ -37,7 +37,7 @@ static void dpu_hw_dsc_disable(struct dpu_hw_dsc *dsc) + } + + static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc, +- struct msm_display_dsc_config *dsc, ++ struct drm_dsc_config *dsc, + u32 mode, + u32 initial_lines) + { +@@ -52,89 +52,89 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc, + if (is_cmd_mode) + initial_lines += 1; + +- slice_last_group_size = 3 - (dsc->drm->slice_width % 3); ++ slice_last_group_size = 3 - (dsc->slice_width % 3); + data = (initial_lines << 20); + data |= ((slice_last_group_size - 1) << 18); + /* bpp is 6.4 format, 4 LSBs bits are for fractional part */ +- data |= dsc->drm->bits_per_pixel << 12; +- lsb = dsc->drm->bits_per_pixel % 4; +- bpp = dsc->drm->bits_per_pixel / 4; ++ data |= dsc->bits_per_pixel << 12; ++ lsb = dsc->bits_per_pixel % 4; ++ bpp = dsc->bits_per_pixel / 4; + bpp *= 4; + bpp <<= 4; + bpp |= lsb; + + data |= bpp << 8; +- data |= (dsc->drm->block_pred_enable << 7); +- data |= (dsc->drm->line_buf_depth << 3); +- data |= (dsc->drm->simple_422 << 2); +- data |= (dsc->drm->convert_rgb << 1); +- data |= dsc->drm->bits_per_component; ++ data |= (dsc->block_pred_enable << 7); ++ data |= (dsc->line_buf_depth << 3); ++ data |= (dsc->simple_422 << 2); ++ data |= (dsc->convert_rgb << 1); ++ data |= dsc->bits_per_component; + + DPU_REG_WRITE(c, DSC_ENC, data); + +- data = dsc->drm->pic_width << 16; +- data |= dsc->drm->pic_height; ++ data = dsc->pic_width << 16; ++ data |= dsc->pic_height; + DPU_REG_WRITE(c, DSC_PICTURE, data); + +- data = dsc->drm->slice_width << 16; +- data |= dsc->drm->slice_height; ++ data = dsc->slice_width << 16; ++ data |= dsc->slice_height; + DPU_REG_WRITE(c, DSC_SLICE, data); + +- data = dsc->drm->slice_chunk_size << 16; ++ data = dsc->slice_chunk_size << 16; + DPU_REG_WRITE(c, DSC_CHUNK_SIZE, data); + +- data = dsc->drm->initial_dec_delay << 16; +- data |= dsc->drm->initial_xmit_delay; ++ data = dsc->initial_dec_delay << 16; ++ data |= dsc->initial_xmit_delay; + DPU_REG_WRITE(c, DSC_DELAY, data); + +- data = dsc->drm->initial_scale_value; ++ data = dsc->initial_scale_value; + DPU_REG_WRITE(c, DSC_SCALE_INITIAL, data); + +- data = dsc->drm->scale_decrement_interval; ++ data = dsc->scale_decrement_interval; + DPU_REG_WRITE(c, DSC_SCALE_DEC_INTERVAL, data); + +- data = dsc->drm->scale_increment_interval; ++ data = dsc->scale_increment_interval; + DPU_REG_WRITE(c, DSC_SCALE_INC_INTERVAL, data); + +- data = dsc->drm->first_line_bpg_offset; ++ data = dsc->first_line_bpg_offset; + DPU_REG_WRITE(c, DSC_FIRST_LINE_BPG_OFFSET, data); + +- data = dsc->drm->nfl_bpg_offset << 16; +- data |= dsc->drm->slice_bpg_offset; ++ data = dsc->nfl_bpg_offset << 16; ++ data |= dsc->slice_bpg_offset; + DPU_REG_WRITE(c, DSC_BPG_OFFSET, data); + +- data = dsc->drm->initial_offset << 16; +- data |= dsc->drm->final_offset; ++ data = dsc->initial_offset << 16; ++ data |= dsc->final_offset; + DPU_REG_WRITE(c, DSC_DSC_OFFSET, data); + +- det_thresh_flatness = 7 + 2 * (dsc->drm->bits_per_component - 8); ++ det_thresh_flatness = 7 + 2 * (dsc->bits_per_component - 8); + data = det_thresh_flatness << 10; +- data |= dsc->drm->flatness_max_qp << 5; +- data |= dsc->drm->flatness_min_qp; ++ data |= dsc->flatness_max_qp << 5; ++ data |= dsc->flatness_min_qp; + DPU_REG_WRITE(c, DSC_FLATNESS, data); + +- data = dsc->drm->rc_model_size; ++ data = dsc->rc_model_size; + DPU_REG_WRITE(c, DSC_RC_MODEL_SIZE, data); + +- data = dsc->drm->rc_tgt_offset_low << 18; +- data |= dsc->drm->rc_tgt_offset_high << 14; +- data |= dsc->drm->rc_quant_incr_limit1 << 9; +- data |= dsc->drm->rc_quant_incr_limit0 << 4; +- data |= dsc->drm->rc_edge_factor; ++ data = dsc->rc_tgt_offset_low << 18; ++ data |= dsc->rc_tgt_offset_high << 14; ++ data |= dsc->rc_quant_incr_limit1 << 9; ++ data |= dsc->rc_quant_incr_limit0 << 4; ++ data |= dsc->rc_edge_factor; + DPU_REG_WRITE(c, DSC_RC, data); + } + + static void dpu_hw_dsc_config_thresh(struct dpu_hw_dsc *hw_dsc, +- struct msm_display_dsc_config *dsc) ++ struct drm_dsc_config *dsc) + { +- struct drm_dsc_rc_range_parameters *rc = dsc->drm->rc_range_params; ++ struct drm_dsc_rc_range_parameters *rc = dsc->rc_range_params; + struct dpu_hw_blk_reg_map *c = &hw_dsc->hw; + u32 off; + int i; + + off = DSC_RC_BUF_THRESH; + for (i = 0; i < DSC_NUM_BUF_RANGES - 1 ; i++) { +- DPU_REG_WRITE(c, off, dsc->drm->rc_buf_thresh[i]); ++ DPU_REG_WRITE(c, off, dsc->rc_buf_thresh[i]); + off += 4; + } + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +index 45e4118f1fa2..c0b77fe1a696 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +@@ -31,7 +31,7 @@ struct dpu_hw_dsc_ops { + * @initial_lines: amount of initial lines to be used + */ + void (*dsc_config)(struct dpu_hw_dsc *hw_dsc, +- struct msm_display_dsc_config *dsc, ++ struct drm_dsc_config *dsc, + u32 mode, + u32 initial_lines); + +@@ -41,7 +41,7 @@ struct dpu_hw_dsc_ops { + * @dsc: panel dsc parameters + */ + void (*dsc_config_thresh)(struct dpu_hw_dsc *hw_dsc, +- struct msm_display_dsc_config *dsc); ++ struct drm_dsc_config *dsc); + }; + + struct dpu_hw_dsc { +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +index c99c7a218ddb..af5e027eb86f 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +@@ -582,7 +582,7 @@ static int _dpu_kms_initialize_dsi(struct drm_device *dev, + info.h_tile_instance[info.num_of_h_tiles++] = i; + info.is_cmd_mode = msm_dsi_is_cmd_mode(priv->dsi[i]); + +- info.dsc = msm_dsi_get_dsc_config(priv->dsi[i]); ++ info.dsc = msm_dsi_get_dsc_config(priv->dsi[i])->drm; + + if (msm_dsi_is_bonded_dsi(priv->dsi[i]) && priv->dsi[other]) { + rc = msm_dsi_modeset_init(priv->dsi[other], dev, encoder); +-- +2.35.1 + diff --git a/queue-6.0/drm-msm-dpu1-account-for-dsc-s-bits_per_pixel-having.patch b/queue-6.0/drm-msm-dpu1-account-for-dsc-s-bits_per_pixel-having.patch new file mode 100644 index 00000000000..cef50221fb7 --- /dev/null +++ b/queue-6.0/drm-msm-dpu1-account-for-dsc-s-bits_per_pixel-having.patch @@ -0,0 +1,69 @@ +From 71274d360a400694ffd7abea10047a059fdc2e5c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 20:28:23 +0200 +Subject: drm/msm/dpu1: Account for DSC's bits_per_pixel having 4 fractional + bits + +From: Marijn Suijten + +[ Upstream commit d3c1a8663d0ddb74eaa51121ccbb8340739a12a8 ] + +According to the comment this DPU register contains the bits per pixel +as a 6.4 fractional value, conveniently matching the contents of +bits_per_pixel in struct drm_dsc_config which also uses 4 fractional +bits. However, the downstream source this implementation was +copy-pasted from has its bpp field stored _without_ fractional part. + +This makes the entire convoluted math obsolete as it is impossible to +pull those 4 fractional bits out of thin air, by somehow trying to reuse +the lowest 2 bits of a non-fractional bpp (lsb = bpp % 4??). + +The rest of the code merely attempts to keep the integer part a multiple +of 4, which is rendered useless thanks to data |= dsc->bits_per_pixel << +12; already filling up those bits anyway (but not on downstream). + +Fixes: c110cfd1753e ("drm/msm/disp/dpu1: Add support for DSC") +Signed-off-by: Marijn Suijten +Reviewed-by: Abhinav Kumar +Reviewed-by: Dmitry Baryshkov +Reviewed-by: Vinod Koul +Patchwork: https://patchwork.freedesktop.org/patch/508946/ +Link: https://lore.kernel.org/r/20221026182824.876933-10-marijn.suijten@somainline.org +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +index f2ddcfb6f7ee..3662df698dae 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +@@ -42,7 +42,7 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc, + u32 initial_lines) + { + struct dpu_hw_blk_reg_map *c = &hw_dsc->hw; +- u32 data, lsb, bpp; ++ u32 data; + u32 slice_last_group_size; + u32 det_thresh_flatness; + bool is_cmd_mode = !(mode & DSC_MODE_VIDEO); +@@ -56,14 +56,7 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc, + data = (initial_lines << 20); + data |= ((slice_last_group_size - 1) << 18); + /* bpp is 6.4 format, 4 LSBs bits are for fractional part */ +- data |= dsc->bits_per_pixel << 12; +- lsb = dsc->bits_per_pixel % 4; +- bpp = dsc->bits_per_pixel / 4; +- bpp *= 4; +- bpp <<= 4; +- bpp |= lsb; +- +- data |= bpp << 8; ++ data |= (dsc->bits_per_pixel << 8); + data |= (dsc->block_pred_enable << 7); + data |= (dsc->line_buf_depth << 3); + data |= (dsc->simple_422 << 2); +-- +2.35.1 + diff --git a/queue-6.0/drm-msm-dsi-account-for-dsc-s-bits_per_pixel-having-.patch b/queue-6.0/drm-msm-dsi-account-for-dsc-s-bits_per_pixel-having-.patch new file mode 100644 index 00000000000..7469e8b774d --- /dev/null +++ b/queue-6.0/drm-msm-dsi-account-for-dsc-s-bits_per_pixel-having-.patch @@ -0,0 +1,95 @@ +From 39d4bd544e45541a57407d39da416246c86cbed1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 20:28:21 +0200 +Subject: drm/msm/dsi: Account for DSC's bits_per_pixel having 4 fractional + bits + +From: Marijn Suijten + +[ Upstream commit d2c277c61986942e99680cb67ce26423d0f42f11 ] + +drm_dsc_config's bits_per_pixel field holds a fractional value with 4 +bits, which all panel drivers should adhere to for +drm_dsc_pps_payload_pack() to generate a valid payload. All code in the +DSI driver here seems to assume that this field doesn't contain any +fractional bits, hence resulting in the wrong values being computed. +Since none of the calculations leave any room for fractional bits or +seem to indicate any possible area of support, disallow such values +altogether. calculate_rc_params() in intel_vdsc.c performs an identical +bitshift to get at this integer value. + +Fixes: b9080324d6ca ("drm/msm/dsi: add support for dsc data") +Reviewed-by: Abhinav Kumar +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Marijn Suijten +Patchwork: https://patchwork.freedesktop.org/patch/508938/ +Link: https://lore.kernel.org/r/20221026182824.876933-8-marijn.suijten@somainline.org +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/dsi/dsi_host.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c +index 0c80d0797a6a..27fef5169bed 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi_host.c ++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c +@@ -34,7 +34,7 @@ + + #define DSI_RESET_TOGGLE_DELAY_MS 20 + +-static int dsi_populate_dsc_params(struct drm_dsc_config *dsc); ++static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc); + + static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor) + { +@@ -984,6 +984,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) + u32 va_end = va_start + mode->vdisplay; + u32 hdisplay = mode->hdisplay; + u32 wc; ++ int ret; + + DBG(""); + +@@ -1019,7 +1020,9 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) + /* we do the calculations for dsc parameters here so that + * panel can use these parameters + */ +- dsi_populate_dsc_params(dsc); ++ ret = dsi_populate_dsc_params(msm_host, dsc); ++ if (ret) ++ return; + + /* Divide the display by 3 but keep back/font porch and + * pulse width same +@@ -1835,9 +1838,15 @@ static char bpg_offset[DSC_NUM_BUF_RANGES] = { + 2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12 + }; + +-static int dsi_populate_dsc_params(struct drm_dsc_config *dsc) ++static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc) + { + int i; ++ u16 bpp = dsc->bits_per_pixel >> 4; ++ ++ if (dsc->bits_per_pixel & 0xf) { ++ DRM_DEV_ERROR(&msm_host->pdev->dev, "DSI does not support fractional bits_per_pixel\n"); ++ return -EINVAL; ++ } + + dsc->rc_model_size = 8192; + dsc->first_line_bpg_offset = 12; +@@ -1858,8 +1867,8 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc) + dsc->rc_range_params[i].range_bpg_offset = bpg_offset[i]; + } + +- dsc->initial_offset = 6144; /* Not bpp 12 */ +- if (dsc->bits_per_pixel != 8) ++ dsc->initial_offset = 6144; /* Not bpp 12 */ ++ if (bpp != 8) + dsc->initial_offset = 2048; /* bpp = 12 */ + + if (dsc->bits_per_component <= 10) +-- +2.35.1 + diff --git a/queue-6.0/drm-msm-dsi-appropriately-set-dsc-mux_word_size-base.patch b/queue-6.0/drm-msm-dsi-appropriately-set-dsc-mux_word_size-base.patch new file mode 100644 index 00000000000..00e7d1531de --- /dev/null +++ b/queue-6.0/drm-msm-dsi-appropriately-set-dsc-mux_word_size-base.patch @@ -0,0 +1,55 @@ +From 62bbc14e6c346984c791c7b0b7e3cd2b74d7b69c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 20:28:19 +0200 +Subject: drm/msm/dsi: Appropriately set dsc->mux_word_size based on bpc + +From: Marijn Suijten + +[ Upstream commit 0ca870ca304d3449b2ccdc3f0bad9843ff1519f0 ] + +This field is currently unread but will come into effect when duplicated +code below is migrated to call drm_dsc_compute_rc_parameters(), which +uses the bpc-dependent value of the local variable mux_words_size in +much the same way. + +The hardcoded constant seems to be a remnant from the `/* bpc 8 */` +comment right above, indicating that this group of field assignments is +applicable to bpc = 8 exclusively and should probably bail out on +different bpc values, until constants for other bpc values are added (or +the current ones are confirmed to be correct across multiple bpc's). + +Fixes: b9080324d6ca ("drm/msm/dsi: add support for dsc data") +Reviewed-by: Abhinav Kumar +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Marijn Suijten +Patchwork: https://patchwork.freedesktop.org/patch/508943/ +Link: https://lore.kernel.org/r/20221026182824.876933-6-marijn.suijten@somainline.org +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c +index a99c54556f51..5e5eb1a10f94 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi_host.c ++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c +@@ -1873,6 +1873,7 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc) + if (dsc->bits_per_component == 12) + mux_words_size = 64; + ++ dsc->mux_word_size = mux_words_size; + dsc->initial_xmit_delay = 512; + dsc->initial_scale_value = 32; + dsc->first_line_bpg_offset = 12; +@@ -1883,7 +1884,6 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc) + dsc->flatness_max_qp = 12; + dsc->rc_quant_incr_limit0 = 11; + dsc->rc_quant_incr_limit1 = 11; +- dsc->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC; + + /* FIXME: need to call drm_dsc_compute_rc_parameters() so that rest of + * params are calculated +-- +2.35.1 + diff --git a/queue-6.0/drm-msm-dsi-disallow-8-bpc-dsc-configuration-for-alt.patch b/queue-6.0/drm-msm-dsi-disallow-8-bpc-dsc-configuration-for-alt.patch new file mode 100644 index 00000000000..950fea9ced2 --- /dev/null +++ b/queue-6.0/drm-msm-dsi-disallow-8-bpc-dsc-configuration-for-alt.patch @@ -0,0 +1,50 @@ +From 61d221251de3a590e1097a09770e1dbd82ed59e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 20:28:22 +0200 +Subject: drm/msm/dsi: Disallow 8 BPC DSC configuration for alternative BPC + values + +From: Marijn Suijten + +[ Upstream commit d053fbc449c47517b1f6516dbce2f917f2a9f51d ] + +According to the `/* bpc 8 */` comment below only values for a +bits_per_component of 8 are currently hardcoded in place. This is +further confirmed by downstream sources [1] containing different +constants for other BPC values (and different initial_offset too, +with an extra dependency on bits_per_pixel). Prevent future mishaps by +explicitly disallowing any other bits_per_component value until the +right parameters are put in place and tested. + +[1]: https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers/-/blob/DISPLAY.LA.2.0.r1-08000-WAIPIO.0/msm/sde_dsc_helper.c#L110-139 + +Fixes: b9080324d6ca ("drm/msm/dsi: add support for dsc data") +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Marijn Suijten +Patchwork: https://patchwork.freedesktop.org/patch/508942/ +Link: https://lore.kernel.org/r/20221026182824.876933-9-marijn.suijten@somainline.org +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/dsi/dsi_host.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c +index 27fef5169bed..c5805416854f 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi_host.c ++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c +@@ -1848,6 +1848,11 @@ static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc + return -EINVAL; + } + ++ if (dsc->bits_per_component != 8) { ++ DRM_DEV_ERROR(&msm_host->pdev->dev, "DSI does not support bits_per_component != 8 yet\n"); ++ return -EOPNOTSUPP; ++ } ++ + dsc->rc_model_size = 8192; + dsc->first_line_bpg_offset = 12; + dsc->rc_edge_factor = 6; +-- +2.35.1 + diff --git a/queue-6.0/drm-msm-dsi-migrate-to-drm_dsc_compute_rc_parameters.patch b/queue-6.0/drm-msm-dsi-migrate-to-drm_dsc_compute_rc_parameters.patch new file mode 100644 index 00000000000..c07ef08bdec --- /dev/null +++ b/queue-6.0/drm-msm-dsi-migrate-to-drm_dsc_compute_rc_parameters.patch @@ -0,0 +1,140 @@ +From 2af826c38608d6b611c30c7d42d039fddc8dae7e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 20:28:20 +0200 +Subject: drm/msm/dsi: Migrate to drm_dsc_compute_rc_parameters() + +From: Marijn Suijten + +[ Upstream commit c3a1aabce2d4087255de90100c3dad492e7d925c ] + +As per the FIXME this code is entirely duplicate with what is already +provided inside drm_dsc_compute_rc_parameters(), supposedly because that +function was yielding "incorrect" results while in reality the panel +driver(s?) used for testing were providing incorrect parameters. + +For example, this code from downstream assumed dsc->bits_per_pixel to +contain an integer value, whereas the upstream drm_dsc_config struct +stores it with 4 fractional bits. drm_dsc_compute_rc_parameters() +already accounts for this feat while the panel driver used for testing +[1] wasn't, hence making drm_dsc_compute_rc_parameters() seem like it +was returning an incorrect result. +Other users of dsc->bits_per_pixel inside dsi_populate_dsc_params() also +treat it in the same erroneous way, and will be addressed in a separate +patch. +In the end, using drm_dsc_compute_rc_parameters() spares both a lot of +duplicate code and erratic behaviour. + +[1]: https://git.linaro.org/people/vinod.koul/kernel.git/commit/?h=topic/pixel3_5.18-rc1&id=1d7d98ad564f1ec69e7525e07418918d90f247a1 + +Fixes: b9080324d6ca ("drm/msm/dsi: add support for dsc data") +Reviewed-by: Abhinav Kumar +Signed-off-by: Marijn Suijten +Reviewed-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/508939/ +Link: https://lore.kernel.org/r/20221026182824.876933-7-marijn.suijten@somainline.org +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/dsi/dsi_host.c | 64 +++--------------------------- + 1 file changed, 6 insertions(+), 58 deletions(-) + +diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c +index 5e5eb1a10f94..0c80d0797a6a 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi_host.c ++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c +@@ -21,6 +21,7 @@ + + #include