--- /dev/null
+From 56c179446fb209cea21f51e473036bdee9bad624 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Jun 2021 20:37:07 +0800
+Subject: ACPI: APEI: fix synchronous external aborts in user-mode
+
+From: Xiaofei Tan <tanxiaofei@huawei.com>
+
+[ Upstream commit ccb5ecdc2ddeaff744ee075b54cdff8a689e8fa7 ]
+
+Before commit 8fcc4ae6faf8 ("arm64: acpi: Make apei_claim_sea()
+synchronise with APEI's irq work"), do_sea() would unconditionally
+signal the affected task from the arch code. Since that change,
+the GHES driver sends the signals.
+
+This exposes a problem as errors the GHES driver doesn't understand
+or doesn't handle effectively are silently ignored. It will cause
+the errors get taken again, and circulate endlessly. User-space task
+get stuck in this loop.
+
+Existing firmware on Kunpeng9xx systems reports cache errors with the
+'ARM Processor Error' CPER records.
+
+Do memory failure handling for ARM Processor Error Section just like
+for Memory Error Section.
+
+Fixes: 8fcc4ae6faf8 ("arm64: acpi: Make apei_claim_sea() synchronise with APEI's irq work")
+Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
+Reviewed-by: James Morse <james.morse@arm.com>
+[ rjw: Subject edit ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/apei/ghes.c | 81 +++++++++++++++++++++++++++++++---------
+ 1 file changed, 64 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
+index fce7ade2aba9..0c8330ed1ffd 100644
+--- a/drivers/acpi/apei/ghes.c
++++ b/drivers/acpi/apei/ghes.c
+@@ -441,28 +441,35 @@ static void ghes_kick_task_work(struct callback_head *head)
+ gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, node_len);
+ }
+
+-static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata,
+- int sev)
++static bool ghes_do_memory_failure(u64 physical_addr, int flags)
+ {
+ unsigned long pfn;
+- int flags = -1;
+- int sec_sev = ghes_severity(gdata->error_severity);
+- struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
+
+ if (!IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE))
+ return false;
+
+- if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))
+- return false;
+-
+- pfn = mem_err->physical_addr >> PAGE_SHIFT;
++ pfn = PHYS_PFN(physical_addr);
+ if (!pfn_valid(pfn)) {
+ pr_warn_ratelimited(FW_WARN GHES_PFX
+ "Invalid address in generic error data: %#llx\n",
+- mem_err->physical_addr);
++ physical_addr);
+ return false;
+ }
+
++ memory_failure_queue(pfn, flags);
++ return true;
++}
++
++static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata,
++ int sev)
++{
++ int flags = -1;
++ int sec_sev = ghes_severity(gdata->error_severity);
++ struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
++
++ if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))
++ return false;
++
+ /* iff following two events can be handled properly by now */
+ if (sec_sev == GHES_SEV_CORRECTED &&
+ (gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED))
+@@ -470,14 +477,56 @@ static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata,
+ if (sev == GHES_SEV_RECOVERABLE && sec_sev == GHES_SEV_RECOVERABLE)
+ flags = 0;
+
+- if (flags != -1) {
+- memory_failure_queue(pfn, flags);
+- return true;
+- }
++ if (flags != -1)
++ return ghes_do_memory_failure(mem_err->physical_addr, flags);
+
+ return false;
+ }
+
++static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, int sev)
++{
++ struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);
++ bool queued = false;
++ int sec_sev, i;
++ char *p;
++
++ log_arm_hw_error(err);
++
++ sec_sev = ghes_severity(gdata->error_severity);
++ if (sev != GHES_SEV_RECOVERABLE || sec_sev != GHES_SEV_RECOVERABLE)
++ return false;
++
++ p = (char *)(err + 1);
++ for (i = 0; i < err->err_info_num; i++) {
++ struct cper_arm_err_info *err_info = (struct cper_arm_err_info *)p;
++ bool is_cache = (err_info->type == CPER_ARM_CACHE_ERROR);
++ bool has_pa = (err_info->validation_bits & CPER_ARM_INFO_VALID_PHYSICAL_ADDR);
++ const char *error_type = "unknown error";
++
++ /*
++ * The field (err_info->error_info & BIT(26)) is fixed to set to
++ * 1 in some old firmware of HiSilicon Kunpeng920. We assume that
++ * firmware won't mix corrected errors in an uncorrected section,
++ * and don't filter out 'corrected' error here.
++ */
++ if (is_cache && has_pa) {
++ queued = ghes_do_memory_failure(err_info->physical_fault_addr, 0);
++ p += err_info->length;
++ continue;
++ }
++
++ if (err_info->type < ARRAY_SIZE(cper_proc_error_type_strs))
++ error_type = cper_proc_error_type_strs[err_info->type];
++
++ pr_warn_ratelimited(FW_WARN GHES_PFX
++ "Unhandled processor error type: %s\n",
++ error_type);
++ p += err_info->length;
++ }
++
++ return queued;
++}
++
+ /*
+ * PCIe AER errors need to be sent to the AER driver for reporting and
+ * recovery. The GHES severities map to the following AER severities and
+@@ -605,9 +654,7 @@ static bool ghes_do_proc(struct ghes *ghes,
+ ghes_handle_aer(gdata);
+ }
+ else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
+- struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);
+-
+- log_arm_hw_error(err);
++ queued = ghes_handle_arm_hw_error(gdata, sev);
+ } else {
+ void *err = acpi_hest_get_payload(gdata);
+
+--
+2.30.2
+
--- /dev/null
+From 5166eeddc8f4eba4e924fbc4d07d8d08a07fbf4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 18:38:01 -0700
+Subject: ACPI: bgrt: Fix CFI violation
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit f37ccf8fce155d08ae2a4fb3db677911ced0c21a ]
+
+clang's Control Flow Integrity requires that every indirect call has a
+valid target, which is based on the type of the function pointer. The
+*_show() functions in this file are written as if they will be called
+from dev_attr_show(); however, they will be called from
+sysfs_kf_seq_show() because the files were created by
+sysfs_create_group() and the sysfs ops are based on kobj_sysfs_ops
+because of kobject_add_and_create(). Because the *_show() functions do
+not match the type of the show() member in struct kobj_attribute, there
+is a CFI violation.
+
+$ cat /sys/firmware/acpi/bgrt/{status,type,version,{x,y}offset}}
+1
+0
+1
+522
+307
+
+$ dmesg | grep "CFI failure"
+[ 267.761825] CFI failure (target: type_show.d5e1ad21498a5fd14edbc5c320906598.cfi_jt+0x0/0x8):
+[ 267.762246] CFI failure (target: xoffset_show.d5e1ad21498a5fd14edbc5c320906598.cfi_jt+0x0/0x8):
+[ 267.762584] CFI failure (target: status_show.d5e1ad21498a5fd14edbc5c320906598.cfi_jt+0x0/0x8):
+[ 267.762973] CFI failure (target: yoffset_show.d5e1ad21498a5fd14edbc5c320906598.cfi_jt+0x0/0x8):
+[ 267.763330] CFI failure (target: version_show.d5e1ad21498a5fd14edbc5c320906598.cfi_jt+0x0/0x8):
+
+Convert these functions to the type of the show() member in struct
+kobj_attribute so that there is no more CFI violation. Because these
+functions are all so similar, combine them into a macro.
+
+Fixes: d1ff4b1cdbab ("ACPI: Add support for exposing BGRT data")
+Link: https://github.com/ClangBuiltLinux/linux/issues/1406
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/bgrt.c | 57 ++++++++++++++-------------------------------
+ 1 file changed, 18 insertions(+), 39 deletions(-)
+
+diff --git a/drivers/acpi/bgrt.c b/drivers/acpi/bgrt.c
+index 19bb7f870204..e0d14017706e 100644
+--- a/drivers/acpi/bgrt.c
++++ b/drivers/acpi/bgrt.c
+@@ -15,40 +15,19 @@
+ static void *bgrt_image;
+ static struct kobject *bgrt_kobj;
+
+-static ssize_t version_show(struct device *dev,
+- struct device_attribute *attr, char *buf)
+-{
+- return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.version);
+-}
+-static DEVICE_ATTR_RO(version);
+-
+-static ssize_t status_show(struct device *dev,
+- struct device_attribute *attr, char *buf)
+-{
+- return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.status);
+-}
+-static DEVICE_ATTR_RO(status);
+-
+-static ssize_t type_show(struct device *dev,
+- struct device_attribute *attr, char *buf)
+-{
+- return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_type);
+-}
+-static DEVICE_ATTR_RO(type);
+-
+-static ssize_t xoffset_show(struct device *dev,
+- struct device_attribute *attr, char *buf)
+-{
+- return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_x);
+-}
+-static DEVICE_ATTR_RO(xoffset);
+-
+-static ssize_t yoffset_show(struct device *dev,
+- struct device_attribute *attr, char *buf)
+-{
+- return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_y);
+-}
+-static DEVICE_ATTR_RO(yoffset);
++#define BGRT_SHOW(_name, _member) \
++ static ssize_t _name##_show(struct kobject *kobj, \
++ struct kobj_attribute *attr, char *buf) \
++ { \
++ return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab._member); \
++ } \
++ struct kobj_attribute bgrt_attr_##_name = __ATTR_RO(_name)
++
++BGRT_SHOW(version, version);
++BGRT_SHOW(status, status);
++BGRT_SHOW(type, image_type);
++BGRT_SHOW(xoffset, image_offset_x);
++BGRT_SHOW(yoffset, image_offset_y);
+
+ static ssize_t image_read(struct file *file, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf, loff_t off, size_t count)
+@@ -60,11 +39,11 @@ static ssize_t image_read(struct file *file, struct kobject *kobj,
+ static BIN_ATTR_RO(image, 0); /* size gets filled in later */
+
+ static struct attribute *bgrt_attributes[] = {
+- &dev_attr_version.attr,
+- &dev_attr_status.attr,
+- &dev_attr_type.attr,
+- &dev_attr_xoffset.attr,
+- &dev_attr_yoffset.attr,
++ &bgrt_attr_version.attr,
++ &bgrt_attr_status.attr,
++ &bgrt_attr_type.attr,
++ &bgrt_attr_xoffset.attr,
++ &bgrt_attr_yoffset.attr,
+ NULL,
+ };
+
+--
+2.30.2
+
--- /dev/null
+From d0f49a21ce7dd082858f21be1342c431ef3ec196 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Jun 2021 17:36:50 +0800
+Subject: ACPI: bus: Call kobject_put() in acpi_init() error path
+
+From: Hanjun Guo <guohanjun@huawei.com>
+
+[ Upstream commit 4ac7a817f1992103d4e68e9837304f860b5e7300 ]
+
+Although the system will not be in a good condition or it will not
+boot if acpi_bus_init() fails, it is still necessary to put the
+kobject in the error path before returning to avoid leaking memory.
+
+Signed-off-by: Hanjun Guo <guohanjun@huawei.com>
+[ rjw: Subject and changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/bus.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
+index a4bd673934c0..44b4f02e2c6d 100644
+--- a/drivers/acpi/bus.c
++++ b/drivers/acpi/bus.c
+@@ -1321,6 +1321,7 @@ static int __init acpi_init(void)
+
+ result = acpi_bus_init();
+ if (result) {
++ kobject_put(acpi_kobj);
+ disable_acpi();
+ return result;
+ }
+--
+2.30.2
+
--- /dev/null
+From f6bb8b7e2990759cf7f26f4493242a4462b5a43e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 May 2021 11:09:50 +0800
+Subject: ACPI: EC: Make more Asus laptops use ECDT _GPE
+
+From: Chris Chiu <chris.chiu@canonical.com>
+
+[ Upstream commit 6306f0431914beaf220634ad36c08234006571d5 ]
+
+More ASUS laptops have the _GPE define in the DSDT table with a
+different value than the _GPE number in the ECDT.
+
+This is causing media keys not working on ASUS X505BA/BP, X542BA/BP
+
+Add model info to the quirks list.
+
+Signed-off-by: Chris Chiu <chris.chiu@canonical.com>
+Signed-off-by: Jian-Hong Pan <jhp@endlessos.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/ec.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index 13565629ce0a..e8c5da2b964a 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -1846,6 +1846,22 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "GL702VMK"),}, NULL},
+ {
++ ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BA", {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "X505BA"),}, NULL},
++ {
++ ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BP", {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "X505BP"),}, NULL},
++ {
++ ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BA", {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "X542BA"),}, NULL},
++ {
++ ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BP", {
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "X542BP"),}, NULL},
++ {
+ ec_honor_ecdt_gpe, "ASUS X550VXK", {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X550VXK"),}, NULL},
+--
+2.30.2
+
--- /dev/null
+From b109937a52ce4b70a4c81b9e30595e83943cfd5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Jun 2021 09:37:27 +0800
+Subject: ACPI: EC: trust DSDT GPE for certain HP laptop
+
+From: Zhang Rui <rui.zhang@intel.com>
+
+[ Upstream commit 4370cbf350dbaca984dbda9f9ce3fac45d6949d5 ]
+
+On HP Pavilion Gaming Laptop 15-cx0xxx, the ECDT EC and DSDT EC share
+the same port addresses but different GPEs. And the DSDT GPE is the
+right one to use.
+
+The current code duplicates DSDT EC with ECDT EC if the port addresses
+are the same, and uses ECDT GPE as a result, which breaks this machine.
+
+Introduce a new quirk for the HP laptop to trust the DSDT GPE,
+and avoid duplicating even if the port addresses are the same.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=209989
+Reported-and-tested-by: Shao Fu, Chen <leo881003@gmail.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/ec.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index e8c5da2b964a..87c3b4a099b9 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -183,6 +183,7 @@ static struct workqueue_struct *ec_query_wq;
+
+ static int EC_FLAGS_CORRECT_ECDT; /* Needs ECDT port address correction */
+ static int EC_FLAGS_IGNORE_DSDT_GPE; /* Needs ECDT GPE as correction setting */
++static int EC_FLAGS_TRUST_DSDT_GPE; /* Needs DSDT GPE as correction setting */
+ static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
+
+ /* --------------------------------------------------------------------------
+@@ -1593,7 +1594,8 @@ static int acpi_ec_add(struct acpi_device *device)
+ }
+
+ if (boot_ec && ec->command_addr == boot_ec->command_addr &&
+- ec->data_addr == boot_ec->data_addr) {
++ ec->data_addr == boot_ec->data_addr &&
++ !EC_FLAGS_TRUST_DSDT_GPE) {
+ /*
+ * Trust PNP0C09 namespace location rather than
+ * ECDT ID. But trust ECDT GPE rather than _GPE
+@@ -1816,6 +1818,18 @@ static int ec_correct_ecdt(const struct dmi_system_id *id)
+ return 0;
+ }
+
++/*
++ * Some ECDTs contain wrong GPE setting, but they share the same port addresses
++ * with DSDT EC, don't duplicate the DSDT EC with ECDT EC in this case.
++ * https://bugzilla.kernel.org/show_bug.cgi?id=209989
++ */
++static int ec_honor_dsdt_gpe(const struct dmi_system_id *id)
++{
++ pr_debug("Detected system needing DSDT GPE setting.\n");
++ EC_FLAGS_TRUST_DSDT_GPE = 1;
++ return 0;
++}
++
+ /*
+ * Some DSDTs contain wrong GPE setting.
+ * Asus FX502VD/VE, GL702VMK, X550VXK, X580VD
+@@ -1870,6 +1884,11 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X580VD"),}, NULL},
+ {
++ /* https://bugzilla.kernel.org/show_bug.cgi?id=209989 */
++ ec_honor_dsdt_gpe, "HP Pavilion Gaming Laptop 15-cx0xxx", {
++ DMI_MATCH(DMI_SYS_VENDOR, "HP"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-cx0xxx"),}, NULL},
++ {
+ ec_clear_on_resume, "Samsung hardware", {
+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL},
+ {},
+--
+2.30.2
+
--- /dev/null
+From 6084f263bd48885dace93a143874c8323389a9bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 May 2021 21:08:51 +0200
+Subject: ACPI: PM / fan: Put fan device IDs into separate header file
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit b9370dceabb7841c5e65ce4ee4405b9db5231fc4 ]
+
+The ACPI fan device IDs are shared between the fan driver and the
+device power management code. The former is modular, so it needs
+to include the table of device IDs for module autoloading and the
+latter needs that list to avoid attaching the generic ACPI PM domain
+to fan devices (which doesn't make sense) possibly before the fan
+driver module is loaded.
+
+Unfortunately, that requires the list of fan device IDs to be
+updated in two places which is prone to mistakes, so put it into
+a symbol definition in a separate header file so there is only one
+copy of it in case it needs to be updated again in the future.
+
+Fixes: b9ea0bae260f ("ACPI: PM: Avoid attaching ACPI PM domain to certain devices")
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/device_pm.c | 6 ++----
+ drivers/acpi/fan.c | 7 +++----
+ drivers/acpi/fan.h | 13 +++++++++++++
+ 3 files changed, 18 insertions(+), 8 deletions(-)
+ create mode 100644 drivers/acpi/fan.h
+
+diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
+index d260bc1f3e6e..9d2d3b9bb8b5 100644
+--- a/drivers/acpi/device_pm.c
++++ b/drivers/acpi/device_pm.c
+@@ -20,6 +20,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/suspend.h>
+
++#include "fan.h"
+ #include "internal.h"
+
+ /**
+@@ -1310,10 +1311,7 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on)
+ * with the generic ACPI PM domain.
+ */
+ static const struct acpi_device_id special_pm_ids[] = {
+- {"PNP0C0B", }, /* Generic ACPI fan */
+- {"INT3404", }, /* Fan */
+- {"INTC1044", }, /* Fan for Tiger Lake generation */
+- {"INTC1048", }, /* Fan for Alder Lake generation */
++ ACPI_FAN_DEVICE_IDS,
+ {}
+ };
+ struct acpi_device *adev = ACPI_COMPANION(dev);
+diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
+index 66c3983f0ccc..5cd0ceb50bc8 100644
+--- a/drivers/acpi/fan.c
++++ b/drivers/acpi/fan.c
+@@ -16,6 +16,8 @@
+ #include <linux/platform_device.h>
+ #include <linux/sort.h>
+
++#include "fan.h"
++
+ MODULE_AUTHOR("Paul Diefenbaugh");
+ MODULE_DESCRIPTION("ACPI Fan Driver");
+ MODULE_LICENSE("GPL");
+@@ -24,10 +26,7 @@ static int acpi_fan_probe(struct platform_device *pdev);
+ static int acpi_fan_remove(struct platform_device *pdev);
+
+ static const struct acpi_device_id fan_device_ids[] = {
+- {"PNP0C0B", 0},
+- {"INT3404", 0},
+- {"INTC1044", 0},
+- {"INTC1048", 0},
++ ACPI_FAN_DEVICE_IDS,
+ {"", 0},
+ };
+ MODULE_DEVICE_TABLE(acpi, fan_device_ids);
+diff --git a/drivers/acpi/fan.h b/drivers/acpi/fan.h
+new file mode 100644
+index 000000000000..dc9a6efa514b
+--- /dev/null
++++ b/drivers/acpi/fan.h
+@@ -0,0 +1,13 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++/*
++ * ACPI fan device IDs are shared between the fan driver and the device power
++ * management code.
++ *
++ * Add new device IDs before the generic ACPI fan one.
++ */
++#define ACPI_FAN_DEVICE_IDS \
++ {"INT3404", }, /* Fan */ \
++ {"INTC1044", }, /* Fan for Tiger Lake generation */ \
++ {"INTC1048", }, /* Fan for Alder Lake generation */ \
++ {"PNP0C0B", } /* Generic ACPI fan */
+--
+2.30.2
+
--- /dev/null
+From 5d2822d3c089d51d7ded3ef9e8a272fb48a98b2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 09:20:32 -0400
+Subject: ACPI: PM: s2idle: Add missing LPS0 functions for AMD
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit f59a905b962c34642e862b5edec35c0eda72d70d ]
+
+These are supposedly not required for AMD platforms,
+but at least some HP laptops seem to require it to
+properly turn off the keyboard backlight.
+
+Based on a patch from Marcin Bachry <hegel666@gmail.com>.
+
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1230
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/x86/s2idle.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
+index 2b69536cdccb..2d7ddb8a8cb6 100644
+--- a/drivers/acpi/x86/s2idle.c
++++ b/drivers/acpi/x86/s2idle.c
+@@ -42,6 +42,8 @@ static const struct acpi_device_id lps0_device_ids[] = {
+
+ /* AMD */
+ #define ACPI_LPS0_DSM_UUID_AMD "e3f32452-febc-43ce-9039-932122d37721"
++#define ACPI_LPS0_ENTRY_AMD 2
++#define ACPI_LPS0_EXIT_AMD 3
+ #define ACPI_LPS0_SCREEN_OFF_AMD 4
+ #define ACPI_LPS0_SCREEN_ON_AMD 5
+
+@@ -408,6 +410,7 @@ int acpi_s2idle_prepare_late(void)
+
+ if (acpi_s2idle_vendor_amd()) {
+ acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF_AMD);
++ acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY_AMD);
+ } else {
+ acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF);
+ acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY);
+@@ -422,6 +425,7 @@ void acpi_s2idle_restore_early(void)
+ return;
+
+ if (acpi_s2idle_vendor_amd()) {
++ acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT_AMD);
+ acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON_AMD);
+ } else {
+ acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT);
+--
+2.30.2
+
--- /dev/null
+From d6a7856a1acb1d125afd39173931a5128adff571 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 May 2021 17:15:14 -0500
+Subject: ACPI: processor idle: Fix up C-state latency if not ordered
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit 65ea8f2c6e230bdf71fed0137cf9e9d1b307db32 ]
+
+Generally, the C-state latency is provided by the _CST method or
+FADT, but some OEM platforms using AMD Picasso, Renoir, Van Gogh,
+and Cezanne set the C2 latency greater than C3's which causes the
+C2 state to be skipped.
+
+That will block the core entering PC6, which prevents S0ix working
+properly on Linux systems.
+
+In other operating systems, the latency values are not validated and
+this does not cause problems by skipping states.
+
+To avoid this issue on Linux, detect when latencies are not an
+arithmetic progression and sort them.
+
+Link: https://gitlab.freedesktop.org/agd5f/linux/-/commit/026d186e4592c1ee9c1cb44295912d0294508725
+Link: https://gitlab.freedesktop.org/drm/amd/-/issues/1230#note_712174
+Suggested-by: Prike Liang <Prike.Liang@amd.com>
+Suggested-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+[ rjw: Subject and changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/processor_idle.c | 40 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
+index 45a019619e4a..095c8aca141e 100644
+--- a/drivers/acpi/processor_idle.c
++++ b/drivers/acpi/processor_idle.c
+@@ -16,6 +16,7 @@
+ #include <linux/acpi.h>
+ #include <linux/dmi.h>
+ #include <linux/sched.h> /* need_resched() */
++#include <linux/sort.h>
+ #include <linux/tick.h>
+ #include <linux/cpuidle.h>
+ #include <linux/cpu.h>
+@@ -384,10 +385,37 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
+ return;
+ }
+
++static int acpi_cst_latency_cmp(const void *a, const void *b)
++{
++ const struct acpi_processor_cx *x = a, *y = b;
++
++ if (!(x->valid && y->valid))
++ return 0;
++ if (x->latency > y->latency)
++ return 1;
++ if (x->latency < y->latency)
++ return -1;
++ return 0;
++}
++static void acpi_cst_latency_swap(void *a, void *b, int n)
++{
++ struct acpi_processor_cx *x = a, *y = b;
++ u32 tmp;
++
++ if (!(x->valid && y->valid))
++ return;
++ tmp = x->latency;
++ x->latency = y->latency;
++ y->latency = tmp;
++}
++
+ static int acpi_processor_power_verify(struct acpi_processor *pr)
+ {
+ unsigned int i;
+ unsigned int working = 0;
++ unsigned int last_latency = 0;
++ unsigned int last_type = 0;
++ bool buggy_latency = false;
+
+ pr->power.timer_broadcast_on_state = INT_MAX;
+
+@@ -411,12 +439,24 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
+ }
+ if (!cx->valid)
+ continue;
++ if (cx->type >= last_type && cx->latency < last_latency)
++ buggy_latency = true;
++ last_latency = cx->latency;
++ last_type = cx->type;
+
+ lapic_timer_check_state(i, pr, cx);
+ tsc_check_state(cx->type);
+ working++;
+ }
+
++ if (buggy_latency) {
++ pr_notice("FW issue: working around C-state latencies out of order\n");
++ sort(&pr->power.states[1], max_cstate,
++ sizeof(struct acpi_processor_cx),
++ acpi_cst_latency_cmp,
++ acpi_cst_latency_swap);
++ }
++
+ lapic_timer_propagate_broadcast(pr);
+
+ return (working);
+--
+2.30.2
+
--- /dev/null
+From 509c3a6682055a672a6d5129bf0225d1eb3c026c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jun 2021 10:14:42 +0800
+Subject: ACPI: resources: Add checks for ACPI IRQ override
+
+From: Hui Wang <hui.wang@canonical.com>
+
+[ Upstream commit 0ec4e55e9f571f08970ed115ec0addc691eda613 ]
+
+The laptop keyboard doesn't work on many MEDION notebooks, but the
+keyboard works well under Windows and Unix.
+
+Through debugging, we found this log in the dmesg:
+
+ ACPI: IRQ 1 override to edge, high
+ pnp 00:03: Plug and Play ACPI device, IDs PNP0303 (active)
+
+ And we checked the IRQ definition in the DSDT, it is:
+
+ IRQ (Level, ActiveLow, Exclusive, )
+ {1}
+
+So the BIOS defines the keyboard IRQ to Level_Low, but the Linux
+kernel override it to Edge_High. If the Linux kernel is modified
+to skip the IRQ override, the keyboard will work normally.
+
+From the existing comment in acpi_dev_get_irqresource(), the override
+function only needs to be called when IRQ() or IRQNoFlags() is used
+to populate the resource descriptor, and according to Section 6.4.2.1
+of ACPI 6.4 [1], if IRQ() is empty or IRQNoFlags() is used, the IRQ
+is High true, edge sensitive and non-shareable. ACPICA also assumes
+that to be the case (see acpi_rs_set_irq[] in rsirq.c).
+
+In accordance with the above, check 3 additional conditions
+(EdgeSensitive, ActiveHigh and Exclusive) when deciding whether or
+not to treat an ACPI_RESOURCE_TYPE_IRQ resource as "legacy", in which
+case the IRQ override is applicable to it.
+
+Link: https://uefi.org/specs/ACPI/6.4/06_Device_Configuration/Device_Configuration.html#irq-descriptor # [1]
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=213031
+BugLink: http://bugs.launchpad.net/bugs/1909814
+Suggested-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reported-by: Manuel Krause <manuelkrause@netscape.net>
+Tested-by: Manuel Krause <manuelkrause@netscape.net>
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+[ rjw: Subject rewrite, changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/resource.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
+index ee78a210c606..dc01fb550b28 100644
+--- a/drivers/acpi/resource.c
++++ b/drivers/acpi/resource.c
+@@ -423,6 +423,13 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
+ }
+ }
+
++static bool irq_is_legacy(struct acpi_resource_irq *irq)
++{
++ return irq->triggering == ACPI_EDGE_SENSITIVE &&
++ irq->polarity == ACPI_ACTIVE_HIGH &&
++ irq->shareable == ACPI_EXCLUSIVE;
++}
++
+ /**
+ * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
+ * @ares: Input ACPI resource object.
+@@ -461,7 +468,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
+ }
+ acpi_dev_get_irqresource(res, irq->interrupts[index],
+ irq->triggering, irq->polarity,
+- irq->shareable, true);
++ irq->shareable, irq_is_legacy(irq));
+ break;
+ case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+ ext_irq = &ares->data.extended_irq;
+--
+2.30.2
+
--- /dev/null
+From b1faa1c22a1d7c727adec9cc935490f682731ed1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 19:53:18 +0200
+Subject: ACPI: scan: Rearrange dep_unmet initialization
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 6d27975851b134be8d2a170437210c9719e524aa ]
+
+The dep_unmet field in struct acpi_device is used to store the
+number of unresolved _DEP dependencies (that is, operation region
+dependencies for which there are no drivers present) for the ACPI
+device object represented by it.
+
+That field is initialized to 1 for all ACPI device objects in
+acpi_add_single_object(), via acpi_init_device_object(), so as to
+avoid evaluating _STA prematurely for battery device objects in
+acpi_scan_init_status(), and it is "fixed up" in acpi_bus_check_add()
+after the acpi_add_single_object() called by it has returned.
+
+This is not particularly straightforward and causes dep_unmet to
+remain 1 for device objects without dependencies created by invoking
+acpi_add_single_object() directly, outside acpi_bus_check_add().
+
+For this reason, rearrange acpi_add_single_object() to initialize
+dep_unmet completely before calling acpi_scan_init_status(), which
+requires passing one extra bool argument to it, and update all of
+its callers accordingly.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/scan.c | 60 +++++++++++++++++++++------------------------
+ 1 file changed, 28 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
+index e10d38ac7cf2..438df8da6d12 100644
+--- a/drivers/acpi/scan.c
++++ b/drivers/acpi/scan.c
+@@ -1671,8 +1671,20 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
+ device_initialize(&device->dev);
+ dev_set_uevent_suppress(&device->dev, true);
+ acpi_init_coherency(device);
+- /* Assume there are unmet deps to start with. */
+- device->dep_unmet = 1;
++}
++
++static void acpi_scan_dep_init(struct acpi_device *adev)
++{
++ struct acpi_dep_data *dep;
++
++ mutex_lock(&acpi_dep_list_lock);
++
++ list_for_each_entry(dep, &acpi_dep_list, node) {
++ if (dep->consumer == adev->handle)
++ adev->dep_unmet++;
++ }
++
++ mutex_unlock(&acpi_dep_list_lock);
+ }
+
+ void acpi_device_add_finalize(struct acpi_device *device)
+@@ -1688,7 +1700,7 @@ static void acpi_scan_init_status(struct acpi_device *adev)
+ }
+
+ static int acpi_add_single_object(struct acpi_device **child,
+- acpi_handle handle, int type)
++ acpi_handle handle, int type, bool dep_init)
+ {
+ struct acpi_device *device;
+ int result;
+@@ -1703,8 +1715,12 @@ static int acpi_add_single_object(struct acpi_device **child,
+ * acpi_bus_get_status() and use its quirk handling. Note that
+ * this must be done before the get power-/wakeup_dev-flags calls.
+ */
+- if (type == ACPI_BUS_TYPE_DEVICE || type == ACPI_BUS_TYPE_PROCESSOR)
++ if (type == ACPI_BUS_TYPE_DEVICE || type == ACPI_BUS_TYPE_PROCESSOR) {
++ if (dep_init)
++ acpi_scan_dep_init(device);
++
+ acpi_scan_init_status(device);
++ }
+
+ acpi_bus_get_power_flags(device);
+ acpi_bus_get_wakeup_device_flags(device);
+@@ -1886,22 +1902,6 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
+ return count;
+ }
+
+-static void acpi_scan_dep_init(struct acpi_device *adev)
+-{
+- struct acpi_dep_data *dep;
+-
+- adev->dep_unmet = 0;
+-
+- mutex_lock(&acpi_dep_list_lock);
+-
+- list_for_each_entry(dep, &acpi_dep_list, node) {
+- if (dep->consumer == adev->handle)
+- adev->dep_unmet++;
+- }
+-
+- mutex_unlock(&acpi_dep_list_lock);
+-}
+-
+ static bool acpi_bus_scan_second_pass;
+
+ static acpi_status acpi_bus_check_add(acpi_handle handle, bool check_dep,
+@@ -1949,19 +1949,15 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, bool check_dep,
+ return AE_OK;
+ }
+
+- acpi_add_single_object(&device, handle, type);
+- if (!device)
+- return AE_CTRL_DEPTH;
+-
+- acpi_scan_init_hotplug(device);
+ /*
+ * If check_dep is true at this point, the device has no dependencies,
+ * or the creation of the device object would have been postponed above.
+ */
+- if (check_dep)
+- device->dep_unmet = 0;
+- else
+- acpi_scan_dep_init(device);
++ acpi_add_single_object(&device, handle, type, !check_dep);
++ if (!device)
++ return AE_CTRL_DEPTH;
++
++ acpi_scan_init_hotplug(device);
+
+ out:
+ if (!*adev_p)
+@@ -2223,7 +2219,7 @@ int acpi_bus_register_early_device(int type)
+ struct acpi_device *device = NULL;
+ int result;
+
+- result = acpi_add_single_object(&device, NULL, type);
++ result = acpi_add_single_object(&device, NULL, type, false);
+ if (result)
+ return result;
+
+@@ -2243,7 +2239,7 @@ static int acpi_bus_scan_fixed(void)
+ struct acpi_device *device = NULL;
+
+ result = acpi_add_single_object(&device, NULL,
+- ACPI_BUS_TYPE_POWER_BUTTON);
++ ACPI_BUS_TYPE_POWER_BUTTON, false);
+ if (result)
+ return result;
+
+@@ -2259,7 +2255,7 @@ static int acpi_bus_scan_fixed(void)
+ struct acpi_device *device = NULL;
+
+ result = acpi_add_single_object(&device, NULL,
+- ACPI_BUS_TYPE_SLEEP_BUTTON);
++ ACPI_BUS_TYPE_SLEEP_BUTTON, false);
+ if (result)
+ return result;
+
+--
+2.30.2
+
--- /dev/null
+From f03317c875c5c1b42116f58c5cfd683c2e974cda Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Jun 2021 17:12:01 +0000
+Subject: ACPI: sysfs: Fix a buffer overrun problem with description_show()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Krzysztof Wilczyński <kw@linux.com>
+
+[ Upstream commit 888be6067b97132c3992866bbcf647572253ab3f ]
+
+Currently, a device description can be obtained using ACPI, if the _STR
+method exists for a particular device, and then exposed to the userspace
+via a sysfs object as a string value.
+
+If the _STR method is available for a given device then the data
+(usually a Unicode string) is read and stored in a buffer (of the
+ACPI_TYPE_BUFFER type) with a pointer to said buffer cached in the
+struct acpi_device_pnp for later access.
+
+The description_show() function is responsible for exposing the device
+description to the userspace via a corresponding sysfs object and
+internally calls the utf16s_to_utf8s() function with a pointer to the
+buffer that contains the Unicode string so that it can be converted from
+UTF16 encoding to UTF8 and thus allowing for the value to be safely
+stored and later displayed.
+
+When invoking the utf16s_to_utf8s() function, the description_show()
+function also sets a limit of the data that can be saved into a provided
+buffer as a result of the character conversion to be a total of
+PAGE_SIZE, and upon completion, the utf16s_to_utf8s() function returns
+an integer value denoting the number of bytes that have been written
+into the provided buffer.
+
+Following the execution of the utf16s_to_utf8s() a newline character
+will be added at the end of the resulting buffer so that when the value
+is read in the userspace through the sysfs object then it would include
+newline making it more accessible when working with the sysfs file
+system in the shell, etc. Normally, this wouldn't be a problem, but if
+the function utf16s_to_utf8s() happens to return the number of bytes
+written to be precisely PAGE_SIZE, then we would overrun the buffer and
+write the newline character outside the allotted space which can have
+undefined consequences or result in a failure.
+
+To fix this buffer overrun, ensure that there always is enough space
+left for the newline character to be safely appended.
+
+Fixes: d1efe3c324ea ("ACPI: Add new sysfs interface to export device description")
+Signed-off-by: Krzysztof Wilczyński <kw@linux.com>
+Reviewed-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/device_sysfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c
+index fa2c1c93072c..a393e0e09381 100644
+--- a/drivers/acpi/device_sysfs.c
++++ b/drivers/acpi/device_sysfs.c
+@@ -448,7 +448,7 @@ static ssize_t description_show(struct device *dev,
+ (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer,
+ acpi_dev->pnp.str_obj->buffer.length,
+ UTF16_LITTLE_ENDIAN, buf,
+- PAGE_SIZE);
++ PAGE_SIZE - 1);
+
+ buf[result++] = '\n';
+
+--
+2.30.2
+
--- /dev/null
+From daddbc82a659e9c4feca5e584bd8f7d102a0aa3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Jun 2021 16:24:33 +0100
+Subject: ACPI: tables: Add custom DSDT file as makefile prerequisite
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit d1059c1b1146870c52f3dac12cb7b6cbf39ed27f ]
+
+A custom DSDT file is mostly used during development or debugging,
+and in that case it is quite likely to want to rebuild the kernel
+after changing ONLY the content of the DSDT.
+
+This patch adds the custom DSDT as a prerequisite to tables.o
+to ensure a rebuild if the DSDT file is updated. Make will merge
+the prerequisites from multiple rules for the same target.
+
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/Makefile | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
+index 700b41adf2db..9aa82d527272 100644
+--- a/drivers/acpi/Makefile
++++ b/drivers/acpi/Makefile
+@@ -8,6 +8,11 @@ ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT
+ #
+ # ACPI Boot-Time Table Parsing
+ #
++ifeq ($(CONFIG_ACPI_CUSTOM_DSDT),y)
++tables.o: $(src)/../../include/$(subst $\",,$(CONFIG_ACPI_CUSTOM_DSDT_FILE)) ;
++
++endif
++
+ obj-$(CONFIG_ACPI) += tables.o
+ obj-$(CONFIG_X86) += blacklist.o
+
+--
+2.30.2
+
--- /dev/null
+From c19d2602d3a347c33c24b76479857db0298b1b15 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Jun 2021 19:58:12 +0800
+Subject: ACPI: tables: FPDT: Add missing acpi_put_table() in acpi_init_fpdt()
+
+From: Jing Xiangfeng <jingxiangfeng@huawei.com>
+
+[ Upstream commit dd9eaa23e72572d4f1c03f2e5d2e14a5b5793e79 ]
+
+acpi_init_fpdt() forgets to call acpi_put_table() in an error path.
+
+Add the missing function call to fix it.
+
+Fixes: d1eb86e59be0 ("ACPI: tables: introduce support for FPDT table")
+Signed-off-by: Jing Xiangfeng <jingxiangfeng@huawei.com>
+Acked-by: Zhang Rui <rui.zhang@intel.com>
+Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
+[ rjw: Subject and changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/acpi_fpdt.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/acpi_fpdt.c b/drivers/acpi/acpi_fpdt.c
+index a89a806a7a2a..4ee2ad234e3d 100644
+--- a/drivers/acpi/acpi_fpdt.c
++++ b/drivers/acpi/acpi_fpdt.c
+@@ -240,8 +240,10 @@ static int __init acpi_init_fpdt(void)
+ return 0;
+
+ fpdt_kobj = kobject_create_and_add("fpdt", acpi_kobj);
+- if (!fpdt_kobj)
++ if (!fpdt_kobj) {
++ acpi_put_table(header);
+ return -ENOMEM;
++ }
+
+ while (offset < header->length) {
+ subtable = (void *)header + offset;
+--
+2.30.2
+
--- /dev/null
+From 107e22e0fce0f95b246100b552040aeda77cb853 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Jun 2021 14:25:57 -0700
+Subject: ACPICA: Fix memory leak caused by _CID repair function
+
+From: Erik Kaneda <erik.kaneda@intel.com>
+
+[ Upstream commit c27bac0314131b11bccd735f7e8415ac6444b667 ]
+
+ACPICA commit 180cb53963aa876c782a6f52cc155d951b26051a
+
+According to the ACPI spec, _CID returns a package containing
+hardware ID's. Each element of an ASL package contains a reference
+count from the parent package as well as the element itself.
+
+Name (TEST, Package() {
+ "String object" // this package element has a reference count of 2
+})
+
+A memory leak was caused in the _CID repair function because it did
+not decrement the reference count created by the package. Fix the
+memory leak by calling acpi_ut_remove_reference on _CID package elements
+that represent a hardware ID (_HID).
+
+Link: https://github.com/acpica/acpica/commit/180cb539
+Tested-by: Shawn Guo <shawn.guo@linaro.org>
+Signed-off-by: Erik Kaneda <erik.kaneda@intel.com>
+Signed-off-by: Bob Moore <robert.moore@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/acpica/nsrepair2.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c
+index 14b71b41e845..38e10ab976e6 100644
+--- a/drivers/acpi/acpica/nsrepair2.c
++++ b/drivers/acpi/acpica/nsrepair2.c
+@@ -379,6 +379,13 @@ acpi_ns_repair_CID(struct acpi_evaluate_info *info,
+
+ (*element_ptr)->common.reference_count =
+ original_ref_count;
++
++ /*
++ * The original_element holds a reference from the package object
++ * that represents _HID. Since a new element was created by _HID,
++ * remove the reference from the _CID package.
++ */
++ acpi_ut_remove_reference(original_element);
+ }
+
+ element_ptr++;
+--
+2.30.2
+
--- /dev/null
+From 3c6e8d4fbb8a04802319afb7b44f2ee4f3985975 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Apr 2021 14:27:09 +0200
+Subject: Add a reference to ucounts for each cred
+
+From: Alexey Gladkov <legion@kernel.org>
+
+[ Upstream commit 905ae01c4ae2ae3df05bb141801b1db4b7d83c61 ]
+
+For RLIMIT_NPROC and some other rlimits the user_struct that holds the
+global limit is kept alive for the lifetime of a process by keeping it
+in struct cred. Adding a pointer to ucounts in the struct cred will
+allow to track RLIMIT_NPROC not only for user in the system, but for
+user in the user_namespace.
+
+Updating ucounts may require memory allocation which may fail. So, we
+cannot change cred.ucounts in the commit_creds() because this function
+cannot fail and it should always return 0. For this reason, we modify
+cred.ucounts before calling the commit_creds().
+
+Changelog
+
+v6:
+* Fix null-ptr-deref in is_ucounts_overlimit() detected by trinity. This
+ error was caused by the fact that cred_alloc_blank() left the ucounts
+ pointer empty.
+
+Reported-by: kernel test robot <oliver.sang@intel.com>
+Signed-off-by: Alexey Gladkov <legion@kernel.org>
+Link: https://lkml.kernel.org/r/b37aaef28d8b9b0d757e07ba6dd27281bbe39259.1619094428.git.legion@kernel.org
+Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/exec.c | 4 ++++
+ include/linux/cred.h | 2 ++
+ include/linux/user_namespace.h | 4 ++++
+ kernel/cred.c | 40 ++++++++++++++++++++++++++++++++++
+ kernel/fork.c | 6 +++++
+ kernel/sys.c | 12 ++++++++++
+ kernel/ucount.c | 40 +++++++++++++++++++++++++++++++---
+ kernel/user_namespace.c | 3 +++
+ 8 files changed, 108 insertions(+), 3 deletions(-)
+
+diff --git a/fs/exec.c b/fs/exec.c
+index 18594f11c31f..d7c4187ca023 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -1360,6 +1360,10 @@ int begin_new_exec(struct linux_binprm * bprm)
+ WRITE_ONCE(me->self_exec_id, me->self_exec_id + 1);
+ flush_signal_handlers(me, 0);
+
++ retval = set_cred_ucounts(bprm->cred);
++ if (retval < 0)
++ goto out_unlock;
++
+ /*
+ * install the new credentials for this executable
+ */
+diff --git a/include/linux/cred.h b/include/linux/cred.h
+index 14971322e1a0..65014e50d5fa 100644
+--- a/include/linux/cred.h
++++ b/include/linux/cred.h
+@@ -143,6 +143,7 @@ struct cred {
+ #endif
+ struct user_struct *user; /* real user ID subscription */
+ struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */
++ struct ucounts *ucounts;
+ struct group_info *group_info; /* supplementary groups for euid/fsgid */
+ /* RCU deletion */
+ union {
+@@ -169,6 +170,7 @@ extern int set_security_override_from_ctx(struct cred *, const char *);
+ extern int set_create_files_as(struct cred *, struct inode *);
+ extern int cred_fscmp(const struct cred *, const struct cred *);
+ extern void __init cred_init(void);
++extern int set_cred_ucounts(struct cred *);
+
+ /*
+ * check for validity of credentials
+diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
+index 1d08dbbcfe32..bfa6463f8a95 100644
+--- a/include/linux/user_namespace.h
++++ b/include/linux/user_namespace.h
+@@ -104,11 +104,15 @@ struct ucounts {
+ };
+
+ extern struct user_namespace init_user_ns;
++extern struct ucounts init_ucounts;
+
+ bool setup_userns_sysctls(struct user_namespace *ns);
+ void retire_userns_sysctls(struct user_namespace *ns);
+ struct ucounts *inc_ucount(struct user_namespace *ns, kuid_t uid, enum ucount_type type);
+ void dec_ucount(struct ucounts *ucounts, enum ucount_type type);
++struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid);
++struct ucounts *get_ucounts(struct ucounts *ucounts);
++void put_ucounts(struct ucounts *ucounts);
+
+ #ifdef CONFIG_USER_NS
+
+diff --git a/kernel/cred.c b/kernel/cred.c
+index e1d274cd741b..642d62f7b46d 100644
+--- a/kernel/cred.c
++++ b/kernel/cred.c
+@@ -60,6 +60,7 @@ struct cred init_cred = {
+ .user = INIT_USER,
+ .user_ns = &init_user_ns,
+ .group_info = &init_groups,
++ .ucounts = &init_ucounts,
+ };
+
+ static inline void set_cred_subscribers(struct cred *cred, int n)
+@@ -119,6 +120,8 @@ static void put_cred_rcu(struct rcu_head *rcu)
+ if (cred->group_info)
+ put_group_info(cred->group_info);
+ free_uid(cred->user);
++ if (cred->ucounts)
++ put_ucounts(cred->ucounts);
+ put_user_ns(cred->user_ns);
+ kmem_cache_free(cred_jar, cred);
+ }
+@@ -222,6 +225,7 @@ struct cred *cred_alloc_blank(void)
+ #ifdef CONFIG_DEBUG_CREDENTIALS
+ new->magic = CRED_MAGIC;
+ #endif
++ new->ucounts = get_ucounts(&init_ucounts);
+
+ if (security_cred_alloc_blank(new, GFP_KERNEL_ACCOUNT) < 0)
+ goto error;
+@@ -284,6 +288,11 @@ struct cred *prepare_creds(void)
+
+ if (security_prepare_creds(new, old, GFP_KERNEL_ACCOUNT) < 0)
+ goto error;
++
++ new->ucounts = get_ucounts(new->ucounts);
++ if (!new->ucounts)
++ goto error;
++
+ validate_creds(new);
+ return new;
+
+@@ -363,6 +372,8 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
+ ret = create_user_ns(new);
+ if (ret < 0)
+ goto error_put;
++ if (set_cred_ucounts(new) < 0)
++ goto error_put;
+ }
+
+ #ifdef CONFIG_KEYS
+@@ -653,6 +664,31 @@ int cred_fscmp(const struct cred *a, const struct cred *b)
+ }
+ EXPORT_SYMBOL(cred_fscmp);
+
++int set_cred_ucounts(struct cred *new)
++{
++ struct task_struct *task = current;
++ const struct cred *old = task->real_cred;
++ struct ucounts *old_ucounts = new->ucounts;
++
++ if (new->user == old->user && new->user_ns == old->user_ns)
++ return 0;
++
++ /*
++ * This optimization is needed because alloc_ucounts() uses locks
++ * for table lookups.
++ */
++ if (old_ucounts && old_ucounts->ns == new->user_ns && uid_eq(old_ucounts->uid, new->euid))
++ return 0;
++
++ if (!(new->ucounts = alloc_ucounts(new->user_ns, new->euid)))
++ return -EAGAIN;
++
++ if (old_ucounts)
++ put_ucounts(old_ucounts);
++
++ return 0;
++}
++
+ /*
+ * initialise the credentials stuff
+ */
+@@ -719,6 +755,10 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
+ if (security_prepare_creds(new, old, GFP_KERNEL_ACCOUNT) < 0)
+ goto error;
+
++ new->ucounts = get_ucounts(new->ucounts);
++ if (!new->ucounts)
++ goto error;
++
+ put_cred(old);
+ validate_creds(new);
+ return new;
+diff --git a/kernel/fork.c b/kernel/fork.c
+index a070caed5c8e..24a689df61c9 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -2997,6 +2997,12 @@ int ksys_unshare(unsigned long unshare_flags)
+ if (err)
+ goto bad_unshare_cleanup_cred;
+
++ if (new_cred) {
++ err = set_cred_ucounts(new_cred);
++ if (err)
++ goto bad_unshare_cleanup_cred;
++ }
++
+ if (new_fs || new_fd || do_sysvsem || new_cred || new_nsproxy) {
+ if (do_sysvsem) {
+ /*
+diff --git a/kernel/sys.c b/kernel/sys.c
+index 3a583a29815f..142ee040f573 100644
+--- a/kernel/sys.c
++++ b/kernel/sys.c
+@@ -558,6 +558,10 @@ long __sys_setreuid(uid_t ruid, uid_t euid)
+ if (retval < 0)
+ goto error;
+
++ retval = set_cred_ucounts(new);
++ if (retval < 0)
++ goto error;
++
+ return commit_creds(new);
+
+ error:
+@@ -616,6 +620,10 @@ long __sys_setuid(uid_t uid)
+ if (retval < 0)
+ goto error;
+
++ retval = set_cred_ucounts(new);
++ if (retval < 0)
++ goto error;
++
+ return commit_creds(new);
+
+ error:
+@@ -691,6 +699,10 @@ long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
+ if (retval < 0)
+ goto error;
+
++ retval = set_cred_ucounts(new);
++ if (retval < 0)
++ goto error;
++
+ return commit_creds(new);
+
+ error:
+diff --git a/kernel/ucount.c b/kernel/ucount.c
+index 8d8874f1c35e..1f4455874aa0 100644
+--- a/kernel/ucount.c
++++ b/kernel/ucount.c
+@@ -8,6 +8,12 @@
+ #include <linux/kmemleak.h>
+ #include <linux/user_namespace.h>
+
++struct ucounts init_ucounts = {
++ .ns = &init_user_ns,
++ .uid = GLOBAL_ROOT_UID,
++ .count = 1,
++};
++
+ #define UCOUNTS_HASHTABLE_BITS 10
+ static struct hlist_head ucounts_hashtable[(1 << UCOUNTS_HASHTABLE_BITS)];
+ static DEFINE_SPINLOCK(ucounts_lock);
+@@ -129,7 +135,15 @@ static struct ucounts *find_ucounts(struct user_namespace *ns, kuid_t uid, struc
+ return NULL;
+ }
+
+-static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid)
++static void hlist_add_ucounts(struct ucounts *ucounts)
++{
++ struct hlist_head *hashent = ucounts_hashentry(ucounts->ns, ucounts->uid);
++ spin_lock_irq(&ucounts_lock);
++ hlist_add_head(&ucounts->node, hashent);
++ spin_unlock_irq(&ucounts_lock);
++}
++
++struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid)
+ {
+ struct hlist_head *hashent = ucounts_hashentry(ns, uid);
+ struct ucounts *ucounts, *new;
+@@ -164,7 +178,26 @@ static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid)
+ return ucounts;
+ }
+
+-static void put_ucounts(struct ucounts *ucounts)
++struct ucounts *get_ucounts(struct ucounts *ucounts)
++{
++ unsigned long flags;
++
++ if (!ucounts)
++ return NULL;
++
++ spin_lock_irqsave(&ucounts_lock, flags);
++ if (ucounts->count == INT_MAX) {
++ WARN_ONCE(1, "ucounts: counter has reached its maximum value");
++ ucounts = NULL;
++ } else {
++ ucounts->count += 1;
++ }
++ spin_unlock_irqrestore(&ucounts_lock, flags);
++
++ return ucounts;
++}
++
++void put_ucounts(struct ucounts *ucounts)
+ {
+ unsigned long flags;
+
+@@ -198,7 +231,7 @@ struct ucounts *inc_ucount(struct user_namespace *ns, kuid_t uid,
+ {
+ struct ucounts *ucounts, *iter, *bad;
+ struct user_namespace *tns;
+- ucounts = get_ucounts(ns, uid);
++ ucounts = alloc_ucounts(ns, uid);
+ for (iter = ucounts; iter; iter = tns->ucounts) {
+ int max;
+ tns = iter->ns;
+@@ -241,6 +274,7 @@ static __init int user_namespace_sysctl_init(void)
+ BUG_ON(!user_header);
+ BUG_ON(!setup_userns_sysctls(&init_user_ns));
+ #endif
++ hlist_add_ucounts(&init_ucounts);
+ return 0;
+ }
+ subsys_initcall(user_namespace_sysctl_init);
+diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
+index 8d62863721b0..27670ab7a4ed 100644
+--- a/kernel/user_namespace.c
++++ b/kernel/user_namespace.c
+@@ -1340,6 +1340,9 @@ static int userns_install(struct nsset *nsset, struct ns_common *ns)
+ put_user_ns(cred->user_ns);
+ set_cred_user_ns(cred, get_user_ns(user_ns));
+
++ if (set_cred_ucounts(cred) < 0)
++ return -EINVAL;
++
+ return 0;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 525b94620834f273a52be66e712214801c04d1d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Jun 2021 20:49:36 +0200
+Subject: ALSA: firewire-lib: Fix 'amdtp_domain_start()' when no
+ AMDTP_OUT_STREAM stream is found
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 0cbbeaf370221fc469c95945dd3c1198865c5fe4 ]
+
+The intent here is to return an error code if we don't find what we are
+looking for in the 'list_for_each_entry()' loop.
+
+'s' is not NULL if the list is empty or if we scan the complete list.
+Introduce a new 'found' variable to handle such cases.
+
+Fixes: 60dd49298ec5 ("ALSA: firewire-lib: handle several AMDTP streams in callback handler of IRQ target")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Acked-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Link: https://lore.kernel.org/r/9c9a53a4905984a570ba5672cbab84f2027dedc1.1624560484.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/firewire/amdtp-stream.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c
+index 5805c5de39fb..7a282d8e7148 100644
+--- a/sound/firewire/amdtp-stream.c
++++ b/sound/firewire/amdtp-stream.c
+@@ -1404,14 +1404,17 @@ int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle)
+ unsigned int queue_size;
+ struct amdtp_stream *s;
+ int cycle;
++ bool found = false;
+ int err;
+
+ // Select an IT context as IRQ target.
+ list_for_each_entry(s, &d->streams, list) {
+- if (s->direction == AMDTP_OUT_STREAM)
++ if (s->direction == AMDTP_OUT_STREAM) {
++ found = true;
+ break;
++ }
+ }
+- if (!s)
++ if (!found)
+ return -ENXIO;
+ d->irq_target = s;
+
+--
+2.30.2
+
--- /dev/null
+From 1518b5e12895d0a7788e3cde4f706d2e273077ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Jun 2021 00:49:04 +0200
+Subject: arm64: dts: marvell: armada-37xx: Fix reg for standard variant of
+ UART
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit 2cbfdedef39fb5994b8f1e1df068eb8440165975 ]
+
+UART1 (standard variant with DT node name 'uart0') has register space
+0x12000-0x12018 and not whole size 0x200. So fix also this in example.
+
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Fixes: c737abc193d1 ("arm64: dts: marvell: Fix A37xx UART0 register size")
+Link: https://lore.kernel.org/r/20210624224909.6350-6-pali@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+index 456dcd4a7793..6ffbb099fcac 100644
+--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+@@ -134,7 +134,7 @@
+
+ uart0: serial@12000 {
+ compatible = "marvell,armada-3700-uart";
+- reg = <0x12000 0x200>;
++ reg = <0x12000 0x18>;
+ clocks = <&xtalclk>;
+ interrupts =
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+--
+2.30.2
+
--- /dev/null
+From d9dc74ce1988148f591c1dec91c937c4fbb9f415 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 10:46:23 +0100
+Subject: arm64: entry: don't instrument entry code with KCOV
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit bf6fa2c0dda751863c3446aa64d733013bec4a19 ]
+
+The code in entry-common.c runs at exception entry and return
+boundaries, where portions of the kernel environment aren't available.
+For example, RCU may not be watching, and lockdep state may be
+out-of-sync with the hardware. Due to this, it is not sound to
+instrument this code.
+
+We generally avoid instrumentation by marking the entry functions as
+`noinstr`, but currently this doesn't inhibit KCOV instrumentation.
+Prevent this by disabling KCOV for the entire compilation unit.
+
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Acked-by: Catalin Marinas <catalin.marinas@arm.com>
+Acked-by: Marc Zyngier <maz@kernel.org>
+Cc: James Morse <james.morse@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20210607094624.34689-20-mark.rutland@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/Makefile | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
+index 6cc97730790e..787c3c83edd7 100644
+--- a/arch/arm64/kernel/Makefile
++++ b/arch/arm64/kernel/Makefile
+@@ -14,6 +14,11 @@ CFLAGS_REMOVE_return_address.o = $(CC_FLAGS_FTRACE)
+ CFLAGS_REMOVE_syscall.o = -fstack-protector -fstack-protector-strong
+ CFLAGS_syscall.o += -fno-stack-protector
+
++# It's not safe to invoke KCOV when portions of the kernel environment aren't
++# available or are out-of-sync with HW state. Since `noinstr` doesn't always
++# inhibit KCOV instrumentation, disable it for the entire compilation unit.
++KCOV_INSTRUMENT_entry.o := n
++
+ # Object file lists.
+ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \
+ entry-common.o entry-fpsimd.o process.o ptrace.o \
+--
+2.30.2
+
--- /dev/null
+From 634b019be478f00ef8c234ac057f704a797583b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jun 2021 15:02:58 +0530
+Subject: arm64/mm: Fix ttbr0 values stored in struct thread_info for
+ software-pan
+
+From: Anshuman Khandual <anshuman.khandual@arm.com>
+
+[ Upstream commit 9163f01130304fab1f74683d7d44632da7bda637 ]
+
+When using CONFIG_ARM64_SW_TTBR0_PAN, a task's thread_info::ttbr0 must be
+the TTBR0_EL1 value used to run userspace. With 52-bit PAs, the PA must be
+packed into the TTBR using phys_to_ttbr(), but we forget to do this in some
+of the SW PAN code. Thus, if the value is installed into TTBR0_EL1 (as may
+happen in the uaccess routines), this could result in UNPREDICTABLE
+behaviour.
+
+Since hardware with 52-bit PA support almost certainly has HW PAN, which
+will be used in preference, this shouldn't be a practical issue, but let's
+fix this for consistency.
+
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: James Morse <james.morse@arm.com>
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: linux-kernel@vger.kernel.org
+Fixes: 529c4b05a3cb ("arm64: handle 52-bit addresses in TTBR")
+Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
+Link: https://lore.kernel.org/r/1623749578-11231-1-git-send-email-anshuman.khandual@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/mmu_context.h | 4 ++--
+ arch/arm64/kernel/setup.c | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
+index d3cef9133539..eeb210997149 100644
+--- a/arch/arm64/include/asm/mmu_context.h
++++ b/arch/arm64/include/asm/mmu_context.h
+@@ -177,9 +177,9 @@ static inline void update_saved_ttbr0(struct task_struct *tsk,
+ return;
+
+ if (mm == &init_mm)
+- ttbr = __pa_symbol(reserved_pg_dir);
++ ttbr = phys_to_ttbr(__pa_symbol(reserved_pg_dir));
+ else
+- ttbr = virt_to_phys(mm->pgd) | ASID(mm) << 48;
++ ttbr = phys_to_ttbr(virt_to_phys(mm->pgd)) | ASID(mm) << 48;
+
+ WRITE_ONCE(task_thread_info(tsk)->ttbr0, ttbr);
+ }
+diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
+index 61845c0821d9..68b30e8c22db 100644
+--- a/arch/arm64/kernel/setup.c
++++ b/arch/arm64/kernel/setup.c
+@@ -381,7 +381,7 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
+ * faults in case uaccess_enable() is inadvertently called by the init
+ * thread.
+ */
+- init_task.thread_info.ttbr0 = __pa_symbol(reserved_pg_dir);
++ init_task.thread_info.ttbr0 = phys_to_ttbr(__pa_symbol(reserved_pg_dir));
+ #endif
+
+ if (boot_args[1] || boot_args[2] || boot_args[3]) {
+--
+2.30.2
+
--- /dev/null
+From 38e5739279aebf196fbfc8058d7c4fa523c5f3c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 May 2021 15:59:45 +0800
+Subject: arm64: perf: Convert snprintf to sysfs_emit
+
+From: Tian Tao <tiantao6@hisilicon.com>
+
+[ Upstream commit a5740e955540181f4ab8f076cc9795c6bbe4d730 ]
+
+Use sysfs_emit instead of snprintf to avoid buf overrun,because in
+sysfs_emit it strictly checks whether buf is null or buf whether
+pagesize aligned, otherwise it returns an error.
+
+Signed-off-by: Tian Tao <tiantao6@hisilicon.com>
+Link: https://lore.kernel.org/r/1621497585-30887-1-git-send-email-tiantao6@hisilicon.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/perf_event.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
+index f594957e29bd..44b6eda69a81 100644
+--- a/arch/arm64/kernel/perf_event.c
++++ b/arch/arm64/kernel/perf_event.c
+@@ -312,7 +312,7 @@ static ssize_t slots_show(struct device *dev, struct device_attribute *attr,
+ struct arm_pmu *cpu_pmu = container_of(pmu, struct arm_pmu, pmu);
+ u32 slots = cpu_pmu->reg_pmmir & ARMV8_PMU_SLOTS_MASK;
+
+- return snprintf(page, PAGE_SIZE, "0x%08x\n", slots);
++ return sysfs_emit(page, "0x%08x\n", slots);
+ }
+
+ static DEVICE_ATTR_RO(slots);
+--
+2.30.2
+
--- /dev/null
+From 8ce7f29872a2fbcf2c59cd6d1960f657cf4d05b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 18:07:41 +0300
+Subject: ASoC: atmel-i2s: Fix usage of capture and playback at the same time
+
+From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
+
+[ Upstream commit 3b7961a326f8a7e03f54a19f02fedae8d488b80f ]
+
+For both capture and playback streams to work at the same time, only the
+needed values from a register need to be updated. Also, clocks should be
+enabled only when the first stream is started and stopped when there is no
+running stream.
+
+Fixes: b543e467d1a9 ("ASoC: atmel-i2s: add driver for the new Atmel I2S controller")
+Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
+Link: https://lore.kernel.org/r/20210618150741.401739-2-codrin.ciubotariu@microchip.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/atmel/atmel-i2s.c | 34 ++++++++++++++++++++++++++--------
+ 1 file changed, 26 insertions(+), 8 deletions(-)
+
+diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c
+index 48c158535ff6..e5c4625b7771 100644
+--- a/sound/soc/atmel/atmel-i2s.c
++++ b/sound/soc/atmel/atmel-i2s.c
+@@ -200,6 +200,7 @@ struct atmel_i2s_dev {
+ unsigned int fmt;
+ const struct atmel_i2s_gck_param *gck_param;
+ const struct atmel_i2s_caps *caps;
++ int clk_use_no;
+ };
+
+ static irqreturn_t atmel_i2s_interrupt(int irq, void *dev_id)
+@@ -321,9 +322,16 @@ static int atmel_i2s_hw_params(struct snd_pcm_substream *substream,
+ {
+ struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
+ bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+- unsigned int mr = 0;
++ unsigned int mr = 0, mr_mask;
+ int ret;
+
++ mr_mask = ATMEL_I2SC_MR_FORMAT_MASK | ATMEL_I2SC_MR_MODE_MASK |
++ ATMEL_I2SC_MR_DATALENGTH_MASK;
++ if (is_playback)
++ mr_mask |= ATMEL_I2SC_MR_TXMONO;
++ else
++ mr_mask |= ATMEL_I2SC_MR_RXMONO;
++
+ switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ mr |= ATMEL_I2SC_MR_FORMAT_I2S;
+@@ -402,7 +410,7 @@ static int atmel_i2s_hw_params(struct snd_pcm_substream *substream,
+ return -EINVAL;
+ }
+
+- return regmap_write(dev->regmap, ATMEL_I2SC_MR, mr);
++ return regmap_update_bits(dev->regmap, ATMEL_I2SC_MR, mr_mask, mr);
+ }
+
+ static int atmel_i2s_switch_mck_generator(struct atmel_i2s_dev *dev,
+@@ -495,18 +503,28 @@ static int atmel_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+ is_master = (mr & ATMEL_I2SC_MR_MODE_MASK) == ATMEL_I2SC_MR_MODE_MASTER;
+
+ /* If master starts, enable the audio clock. */
+- if (is_master && mck_enabled)
+- err = atmel_i2s_switch_mck_generator(dev, true);
+- if (err)
+- return err;
++ if (is_master && mck_enabled) {
++ if (!dev->clk_use_no) {
++ err = atmel_i2s_switch_mck_generator(dev, true);
++ if (err)
++ return err;
++ }
++ dev->clk_use_no++;
++ }
+
+ err = regmap_write(dev->regmap, ATMEL_I2SC_CR, cr);
+ if (err)
+ return err;
+
+ /* If master stops, disable the audio clock. */
+- if (is_master && !mck_enabled)
+- err = atmel_i2s_switch_mck_generator(dev, false);
++ if (is_master && !mck_enabled) {
++ if (dev->clk_use_no == 1) {
++ err = atmel_i2s_switch_mck_generator(dev, false);
++ if (err)
++ return err;
++ }
++ dev->clk_use_no--;
++ }
+
+ return err;
+ }
+--
+2.30.2
+
--- /dev/null
+From ec3b7f40769600a753965c5fddbda52608347759 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 18:07:40 +0300
+Subject: ASoC: atmel-i2s: Set symmetric sample bits
+
+From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
+
+[ Upstream commit 489a830a25e1730aebf7ff53430c170db9a1771b ]
+
+The I2S needs to have the same sample bits for both capture and playback
+streams.
+
+Fixes: b543e467d1a9 ("ASoC: atmel-i2s: add driver for the new Atmel I2S controller")
+Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
+Link: https://lore.kernel.org/r/20210618150741.401739-1-codrin.ciubotariu@microchip.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/atmel/atmel-i2s.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c
+index 584656cc7d3c..48c158535ff6 100644
+--- a/sound/soc/atmel/atmel-i2s.c
++++ b/sound/soc/atmel/atmel-i2s.c
+@@ -542,6 +542,7 @@ static struct snd_soc_dai_driver atmel_i2s_dai = {
+ },
+ .ops = &atmel_i2s_dai_ops,
+ .symmetric_rate = 1,
++ .symmetric_sample_bits = 1,
+ };
+
+ static const struct snd_soc_component_driver atmel_i2s_component = {
+--
+2.30.2
+
--- /dev/null
+From a544f2f97e4abffe4023766646d5b54a299fa353 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jun 2021 14:56:04 +0100
+Subject: ASoC: cs42l42: Correct definition of CS42L42_ADC_PDN_MASK
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit fac165f22ac947b55407cd3a60a2a9824f905235 ]
+
+The definition of CS42L42_ADC_PDN_MASK was incorrectly defined
+as the HP_PDN bit.
+
+Fixes: 2c394ca79604 ("ASoC: Add support for CS42L42 codec")
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Link: https://lore.kernel.org/r/20210616135604.19363-1-rf@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/cs42l42.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h
+index 36b763f0d1a0..386c40f9ed31 100644
+--- a/sound/soc/codecs/cs42l42.h
++++ b/sound/soc/codecs/cs42l42.h
+@@ -79,7 +79,7 @@
+ #define CS42L42_HP_PDN_SHIFT 3
+ #define CS42L42_HP_PDN_MASK (1 << CS42L42_HP_PDN_SHIFT)
+ #define CS42L42_ADC_PDN_SHIFT 2
+-#define CS42L42_ADC_PDN_MASK (1 << CS42L42_HP_PDN_SHIFT)
++#define CS42L42_ADC_PDN_MASK (1 << CS42L42_ADC_PDN_SHIFT)
+ #define CS42L42_PDN_ALL_SHIFT 0
+ #define CS42L42_PDN_ALL_MASK (1 << CS42L42_PDN_ALL_SHIFT)
+
+--
+2.30.2
+
--- /dev/null
+From 1dc10be0b595f33bf67d4db7cbfa3eed72c57e00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Jun 2021 14:18:38 +0800
+Subject: ASoC: fsl_spdif: Fix error handler with pm_runtime_enable
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit 28108d71ee11a7232e1102effab3361049dcd3b8 ]
+
+There is error message when defer probe happens:
+
+fsl-spdif-dai 2dab0000.spdif: Unbalanced pm_runtime_enable!
+
+Fix the error handler with pm_runtime_enable and add
+fsl_spdif_remove() for pm_runtime_disable.
+
+Fixes: 9cb2b3796e08 ("ASoC: fsl_spdif: Add pm runtime function")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1623392318-26304-1-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_spdif.c | 20 +++++++++++++++++---
+ 1 file changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
+index c631de325a6e..5636837eb511 100644
+--- a/sound/soc/fsl/fsl_spdif.c
++++ b/sound/soc/fsl/fsl_spdif.c
+@@ -1375,16 +1375,29 @@ static int fsl_spdif_probe(struct platform_device *pdev)
+ &spdif_priv->cpu_dai_drv, 1);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
+- return ret;
++ goto err_pm_disable;
+ }
+
+ ret = imx_pcm_dma_init(pdev, IMX_SPDIF_DMABUF_SIZE);
+- if (ret && ret != -EPROBE_DEFER)
+- dev_err(&pdev->dev, "imx_pcm_dma_init failed: %d\n", ret);
++ if (ret) {
++ dev_err_probe(&pdev->dev, ret, "imx_pcm_dma_init failed\n");
++ goto err_pm_disable;
++ }
++
++ return ret;
+
++err_pm_disable:
++ pm_runtime_disable(&pdev->dev);
+ return ret;
+ }
+
++static int fsl_spdif_remove(struct platform_device *pdev)
++{
++ pm_runtime_disable(&pdev->dev);
++
++ return 0;
++}
++
+ #ifdef CONFIG_PM
+ static int fsl_spdif_runtime_suspend(struct device *dev)
+ {
+@@ -1487,6 +1500,7 @@ static struct platform_driver fsl_spdif_driver = {
+ .pm = &fsl_spdif_pm,
+ },
+ .probe = fsl_spdif_probe,
++ .remove = fsl_spdif_remove,
+ };
+
+ module_platform_driver(fsl_spdif_driver);
+--
+2.30.2
+
--- /dev/null
+From 8bca0757bc665582879e3709eb9f04b9916d7318 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 20:31:24 +0800
+Subject: ASoC: fsl_spdif: Fix unexpected interrupt after suspend
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit a7a0a2feb957e446b2bcf732f245ba04fc8b6314 ]
+
+When system enter suspend, the machine driver suspend callback
+function will be called, then the cpu driver trigger callback
+(SNDRV_PCM_TRIGGER_SUSPEND) be called, it would disable the
+interrupt.
+
+But the machine driver suspend and cpu dai driver suspend order
+maybe changed, the cpu dai driver's suspend callback is called before
+machine driver's suppend callback, then the interrupt is not cleared
+successfully in trigger callback.
+
+So need to clear interrupts in cpu dai driver's suspend callback
+to avoid such issue.
+
+Fixes: 9cb2b3796e08 ("ASoC: fsl_spdif: Add pm runtime function")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Reviewed-by: Fabio Estevam <festevam@gmail.com>
+Link: https://lore.kernel.org/r/1624365084-7934-1-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_spdif.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
+index 5636837eb511..53499bc71fa9 100644
+--- a/sound/soc/fsl/fsl_spdif.c
++++ b/sound/soc/fsl/fsl_spdif.c
+@@ -1404,6 +1404,9 @@ static int fsl_spdif_runtime_suspend(struct device *dev)
+ struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev);
+ int i;
+
++ /* Disable all the interrupts */
++ regmap_update_bits(spdif_priv->regmap, REG_SPDIF_SIE, 0xffffff, 0);
++
+ regmap_read(spdif_priv->regmap, REG_SPDIF_SRPC,
+ &spdif_priv->regcache_srpc);
+ regcache_cache_only(spdif_priv->regmap, true);
+--
+2.30.2
+
--- /dev/null
+From 7a3c219f11b10bfcd318d0b4e8f71b902185cb8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 20:38:33 +0800
+Subject: ASoC: fsl_xcvr: disable all interrupts when suspend happens
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit ea837090b388245744988083313f6e9c7c9b9699 ]
+
+There is an unhandled interrupt after suspend, which cause endless
+interrupt when system resume, so system may hang.
+
+Disable all interrupts in runtime suspend callback to avoid above
+issue.
+
+Fixes: 28564486866f ("ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Reviewed-by: Fabio Estevam <festevam@gmail.com>
+Link: https://lore.kernel.org/r/1624019913-3380-1-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_xcvr.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
+index 6cb558165848..46f3f2c68756 100644
+--- a/sound/soc/fsl/fsl_xcvr.c
++++ b/sound/soc/fsl/fsl_xcvr.c
+@@ -1233,6 +1233,16 @@ static __maybe_unused int fsl_xcvr_runtime_suspend(struct device *dev)
+ struct fsl_xcvr *xcvr = dev_get_drvdata(dev);
+ int ret;
+
++ /*
++ * Clear interrupts, when streams starts or resumes after
++ * suspend, interrupts are enabled in prepare(), so no need
++ * to enable interrupts in resume().
++ */
++ ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0,
++ FSL_XCVR_IRQ_EARC_ALL, 0);
++ if (ret < 0)
++ dev_err(dev, "Failed to clear IER0: %d\n", ret);
++
+ /* Assert M0+ reset */
+ ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
+ FSL_XCVR_EXT_CTRL_CORE_RESET,
+--
+2.30.2
+
--- /dev/null
+From bd9d97e80537bfa1169b41c527a933bcd06683d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 May 2021 12:45:14 +0800
+Subject: ASoC: hisilicon: fix missing clk_disable_unprepare() on error in
+ hi6210_i2s_startup()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 375904e3931955fcf0a847f029b2492a117efc43 ]
+
+After calling clk_prepare_enable(), clk_disable_unprepare() need
+be called when calling clk_set_rate() failed.
+
+Fixes: 0bf750f4cbe1 ("ASoC: hisilicon: Add hi6210 i2s audio driver")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20210518044514.607010-1-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/hisilicon/hi6210-i2s.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/sound/soc/hisilicon/hi6210-i2s.c b/sound/soc/hisilicon/hi6210-i2s.c
+index 907f5f1f7b44..ff05b9779e4b 100644
+--- a/sound/soc/hisilicon/hi6210-i2s.c
++++ b/sound/soc/hisilicon/hi6210-i2s.c
+@@ -102,18 +102,15 @@ static int hi6210_i2s_startup(struct snd_pcm_substream *substream,
+
+ for (n = 0; n < i2s->clocks; n++) {
+ ret = clk_prepare_enable(i2s->clk[n]);
+- if (ret) {
+- while (n--)
+- clk_disable_unprepare(i2s->clk[n]);
+- return ret;
+- }
++ if (ret)
++ goto err_unprepare_clk;
+ }
+
+ ret = clk_set_rate(i2s->clk[CLK_I2S_BASE], 49152000);
+ if (ret) {
+ dev_err(i2s->dev, "%s: setting 49.152MHz base rate failed %d\n",
+ __func__, ret);
+- return ret;
++ goto err_unprepare_clk;
+ }
+
+ /* enable clock before frequency division */
+@@ -165,6 +162,11 @@ static int hi6210_i2s_startup(struct snd_pcm_substream *substream,
+ hi6210_write_reg(i2s, HII2S_SW_RST_N, val);
+
+ return 0;
++
++err_unprepare_clk:
++ while (n--)
++ clk_disable_unprepare(i2s->clk[n]);
++ return ret;
+ }
+
+ static void hi6210_i2s_shutdown(struct snd_pcm_substream *substream,
+--
+2.30.2
+
--- /dev/null
+From bb130a22051dd935c10f4e2fe1ad2daa60717fa9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 18:56:32 +0300
+Subject: ASoC: Intel: sof_sdw: add quirk support for Brya and BT-offload
+
+From: Vamshi Krishna Gopal <vamshi.krishna.gopal@intel.com>
+
+[ Upstream commit 03effde3a2ea1d82c4dd6b634fc6174545d2c34f ]
+
+Brya is another ADL-P product.
+
+AlderLake has support for Bluetooth audio offload capability.
+Enable the BT-offload quirk for ADL-P Brya and the Intel RVP.
+
+Signed-off-by: Vamshi Krishna Gopal <vamshi.krishna.gopal@intel.com>
+Signed-off-by: Yong Zhi <yong.zhi@intel.com>
+Reviewed-by: Bard Liao <bard.liao@intel.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+Link: https://lore.kernel.org/r/20210521155632.3736393-2-kai.vehmanen@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/sof_sdw.c | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
+index dfad2ad129ab..35ad448902c7 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -197,7 +197,21 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
+ .driver_data = (void *)(SOF_RT711_JD_SRC_JD1 |
+ SOF_SDW_TGL_HDMI |
+ SOF_RT715_DAI_ID_FIX |
+- SOF_SDW_PCH_DMIC),
++ SOF_SDW_PCH_DMIC |
++ SOF_BT_OFFLOAD_SSP(2) |
++ SOF_SSP_BT_OFFLOAD_PRESENT),
++ },
++ {
++ .callback = sof_sdw_quirk_cb,
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Google"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Brya"),
++ },
++ .driver_data = (void *)(SOF_SDW_TGL_HDMI |
++ SOF_SDW_PCH_DMIC |
++ SOF_SDW_FOUR_SPK |
++ SOF_BT_OFFLOAD_SSP(2) |
++ SOF_SSP_BT_OFFLOAD_PRESENT),
+ },
+ {}
+ };
+--
+2.30.2
+
--- /dev/null
+From 8eab0ff16a37e7eb026aa165994e5b141f6176c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 11:37:02 -0500
+Subject: ASoC: Intel: sof_sdw: add SOF_RT715_DAI_ID_FIX for AlderLake
+
+From: Libin Yang <libin.yang@intel.com>
+
+[ Upstream commit 81cd42e5174ba7918edd3d006406ce21ebaa8507 ]
+
+AlderLake needs the flag SOF_RT715_DAI_ID_FIX if it is using the
+rt715 DMIC.
+
+Reviewed-by: Bard Liao <bard.liao@intel.com>
+Signed-off-by: Libin Yang <libin.yang@intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210505163705.305616-11-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/sof_sdw.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
+index ecd3f90f4bbe..dfad2ad129ab 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -196,6 +196,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
+ },
+ .driver_data = (void *)(SOF_RT711_JD_SRC_JD1 |
+ SOF_SDW_TGL_HDMI |
++ SOF_RT715_DAI_ID_FIX |
+ SOF_SDW_PCH_DMIC),
+ },
+ {}
+--
+2.30.2
+
--- /dev/null
+From 703d7f915266290b1793d2cf132dead459f3647d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Jun 2021 14:40:48 -0500
+Subject: ASoC: Intel: sof_sdw: use mach data for ADL RVP DMIC count
+
+From: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+
+[ Upstream commit 505351329d26e684588a6919c0407b8a0f5c3813 ]
+
+On the reference boards, number of PCH dmics may vary and the number
+should be taken from driver machine data. Remove the SOF_SDW_PCH_DMIC
+quirk to make DMIC number configurable.
+
+Fixes:d25bbe80485f8 ("ASoC: Intel: sof_sdw: add quirk for new ADL-P Rvp")
+
+BugLink: https://github.com/thesofproject/sof/issues/4185
+Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210621194057.21711-2-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/sof_sdw.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
+index 35ad448902c7..dd93f663803b 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -197,7 +197,6 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
+ .driver_data = (void *)(SOF_RT711_JD_SRC_JD1 |
+ SOF_SDW_TGL_HDMI |
+ SOF_RT715_DAI_ID_FIX |
+- SOF_SDW_PCH_DMIC |
+ SOF_BT_OFFLOAD_SSP(2) |
+ SOF_SSP_BT_OFFLOAD_PRESENT),
+ },
+--
+2.30.2
+
--- /dev/null
+From 577381a02f4d93eeb2e06f26b5d90ee0c4a645c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 17:22:25 -0500
+Subject: ASoC: max98373-sdw: add missing memory allocation check
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit 468a272ca49cc4e2f58f3c360643c3f6d313c146 ]
+
+We forgot to test that devm_kcalloc doesn't return NULL.
+
+Fixes: 349dd23931d1 ('ASoC: max98373: don't access volatile registers in bias level off')
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
+Reviewed-by: Bard Liao <bard.liao@intel.com>
+Link: https://lore.kernel.org/r/20210607222239.582139-2-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/max98373-sdw.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/soc/codecs/max98373-sdw.c b/sound/soc/codecs/max98373-sdw.c
+index f3a12205cd48..c7a3506046db 100644
+--- a/sound/soc/codecs/max98373-sdw.c
++++ b/sound/soc/codecs/max98373-sdw.c
+@@ -787,6 +787,8 @@ static int max98373_init(struct sdw_slave *slave, struct regmap *regmap)
+ max98373->cache = devm_kcalloc(dev, max98373->cache_num,
+ sizeof(*max98373->cache),
+ GFP_KERNEL);
++ if (!max98373->cache)
++ return -ENOMEM;
+
+ for (i = 0; i < max98373->cache_num; i++)
+ max98373->cache[i].reg = max98373_sdw_cache_reg[i];
+--
+2.30.2
+
--- /dev/null
+From 3573359f26efee9af95a6b7ae51ebe9e8ff2da92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 17:22:26 -0500
+Subject: ASoC: max98373-sdw: use first_hw_init flag on resume
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit bf881170311ea74ff30c3be0be8fb097132ce696 ]
+
+The intent of the status check on resume was to verify if a SoundWire
+peripheral reported ATTACHED before waiting for the initialization to
+complete. This is required to avoid timeouts that will happen with
+'ghost' devices that are exposed in the platform firmware but are not
+populated in hardware.
+
+Unfortunately we used 'hw_init' instead of 'first_hw_init'. Due to
+another error, the resume operation never timed out, but the volume
+settings were not properly restored.
+
+This patch renames the status flag to 'first_hw_init' for consistency
+with other drivers.
+
+BugLink: https://github.com/thesofproject/linux/issues/2637
+Fixes: 56a5b7910e96 ('ASoC: codecs: max98373: add SoundWire support')
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
+Reviewed-by: Bard Liao <bard.liao@intel.com>
+Link: https://lore.kernel.org/r/20210607222239.582139-3-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/max98373-sdw.c | 12 ++++++------
+ sound/soc/codecs/max98373.h | 2 +-
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/sound/soc/codecs/max98373-sdw.c b/sound/soc/codecs/max98373-sdw.c
+index c7a3506046db..dc520effc61c 100644
+--- a/sound/soc/codecs/max98373-sdw.c
++++ b/sound/soc/codecs/max98373-sdw.c
+@@ -271,7 +271,7 @@ static __maybe_unused int max98373_resume(struct device *dev)
+ struct max98373_priv *max98373 = dev_get_drvdata(dev);
+ unsigned long time;
+
+- if (!max98373->hw_init)
++ if (!max98373->first_hw_init)
+ return 0;
+
+ if (!slave->unattach_request)
+@@ -362,7 +362,7 @@ static int max98373_io_init(struct sdw_slave *slave)
+ struct device *dev = &slave->dev;
+ struct max98373_priv *max98373 = dev_get_drvdata(dev);
+
+- if (max98373->pm_init_once) {
++ if (max98373->first_hw_init) {
+ regcache_cache_only(max98373->regmap, false);
+ regcache_cache_bypass(max98373->regmap, true);
+ }
+@@ -370,7 +370,7 @@ static int max98373_io_init(struct sdw_slave *slave)
+ /*
+ * PM runtime is only enabled when a Slave reports as Attached
+ */
+- if (!max98373->pm_init_once) {
++ if (!max98373->first_hw_init) {
+ /* set autosuspend parameters */
+ pm_runtime_set_autosuspend_delay(dev, 3000);
+ pm_runtime_use_autosuspend(dev);
+@@ -462,12 +462,12 @@ static int max98373_io_init(struct sdw_slave *slave)
+ regmap_write(max98373->regmap, MAX98373_R20B5_BDE_EN, 1);
+ regmap_write(max98373->regmap, MAX98373_R20E2_LIMITER_EN, 1);
+
+- if (max98373->pm_init_once) {
++ if (max98373->first_hw_init) {
+ regcache_cache_bypass(max98373->regmap, false);
+ regcache_mark_dirty(max98373->regmap);
+ }
+
+- max98373->pm_init_once = true;
++ max98373->first_hw_init = true;
+ max98373->hw_init = true;
+
+ pm_runtime_mark_last_busy(dev);
+@@ -797,7 +797,7 @@ static int max98373_init(struct sdw_slave *slave, struct regmap *regmap)
+ max98373_slot_config(dev, max98373);
+
+ max98373->hw_init = false;
+- max98373->pm_init_once = false;
++ max98373->first_hw_init = false;
+
+ /* codec registration */
+ ret = devm_snd_soc_register_component(dev, &soc_codec_dev_max98373_sdw,
+diff --git a/sound/soc/codecs/max98373.h b/sound/soc/codecs/max98373.h
+index 73a2cf69d84a..e1810b3b1620 100644
+--- a/sound/soc/codecs/max98373.h
++++ b/sound/soc/codecs/max98373.h
+@@ -226,7 +226,7 @@ struct max98373_priv {
+ /* variables to support soundwire */
+ struct sdw_slave *slave;
+ bool hw_init;
+- bool pm_init_once;
++ bool first_hw_init;
+ int slot;
+ unsigned int rx_mask;
+ };
+--
+2.30.2
+
--- /dev/null
+From 9936214969d51f441ffbc95a0aabb283f21694b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 6 Jun 2021 16:31:09 +0200
+Subject: ASoC: mediatek: mtk-btcvsd: Fix an error handling path in
+ 'mtk_btcvsd_snd_probe()'
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit b6052c3c7a78f5e2b9756c92ef77c0b56435f107 ]
+
+If an error occurs after a successful 'of_iomap()' call, it must be undone
+by a corresponding 'iounmap()' call, as already done in the remove
+function.
+
+While at it, remove the useless initialization of 'ret' at the beginning of
+the function.
+
+Fixes: 4bd8597dc36c ("ASoC: mediatek: add btcvsd driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/0c2ba562c3364e61bfbd5b3013a99dfa0d9045d7.1622989685.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/mediatek/common/mtk-btcvsd.c | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/sound/soc/mediatek/common/mtk-btcvsd.c b/sound/soc/mediatek/common/mtk-btcvsd.c
+index f85b5ea180ec..d884bb7c0fc7 100644
+--- a/sound/soc/mediatek/common/mtk-btcvsd.c
++++ b/sound/soc/mediatek/common/mtk-btcvsd.c
+@@ -1281,7 +1281,7 @@ static const struct snd_soc_component_driver mtk_btcvsd_snd_platform = {
+
+ static int mtk_btcvsd_snd_probe(struct platform_device *pdev)
+ {
+- int ret = 0;
++ int ret;
+ int irq_id;
+ u32 offset[5] = {0, 0, 0, 0, 0};
+ struct mtk_btcvsd_snd *btcvsd;
+@@ -1337,7 +1337,8 @@ static int mtk_btcvsd_snd_probe(struct platform_device *pdev)
+ btcvsd->bt_sram_bank2_base = of_iomap(dev->of_node, 1);
+ if (!btcvsd->bt_sram_bank2_base) {
+ dev_err(dev, "iomap bt_sram_bank2_base fail\n");
+- return -EIO;
++ ret = -EIO;
++ goto unmap_pkv_err;
+ }
+
+ btcvsd->infra = syscon_regmap_lookup_by_phandle(dev->of_node,
+@@ -1345,7 +1346,8 @@ static int mtk_btcvsd_snd_probe(struct platform_device *pdev)
+ if (IS_ERR(btcvsd->infra)) {
+ dev_err(dev, "cannot find infra controller: %ld\n",
+ PTR_ERR(btcvsd->infra));
+- return PTR_ERR(btcvsd->infra);
++ ret = PTR_ERR(btcvsd->infra);
++ goto unmap_bank2_err;
+ }
+
+ /* get offset */
+@@ -1354,7 +1356,7 @@ static int mtk_btcvsd_snd_probe(struct platform_device *pdev)
+ ARRAY_SIZE(offset));
+ if (ret) {
+ dev_warn(dev, "%s(), get offset fail, ret %d\n", __func__, ret);
+- return ret;
++ goto unmap_bank2_err;
+ }
+ btcvsd->infra_misc_offset = offset[0];
+ btcvsd->conn_bt_cvsd_mask = offset[1];
+@@ -1373,8 +1375,18 @@ static int mtk_btcvsd_snd_probe(struct platform_device *pdev)
+ mtk_btcvsd_snd_set_state(btcvsd, btcvsd->tx, BT_SCO_STATE_IDLE);
+ mtk_btcvsd_snd_set_state(btcvsd, btcvsd->rx, BT_SCO_STATE_IDLE);
+
+- return devm_snd_soc_register_component(dev, &mtk_btcvsd_snd_platform,
+- NULL, 0);
++ ret = devm_snd_soc_register_component(dev, &mtk_btcvsd_snd_platform,
++ NULL, 0);
++ if (ret)
++ goto unmap_bank2_err;
++
++ return 0;
++
++unmap_bank2_err:
++ iounmap(btcvsd->bt_sram_bank2_base);
++unmap_pkv_err:
++ iounmap(btcvsd->bt_pkv_base);
++ return ret;
+ }
+
+ static int mtk_btcvsd_snd_remove(struct platform_device *pdev)
+--
+2.30.2
+
--- /dev/null
+From 513184977713c1215e0d9b337ec3654f1ca74409 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 May 2021 15:58:47 +0800
+Subject: ASoC: rk3328: fix missing clk_disable_unprepare() on error in
+ rk3328_platform_probe()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit d14eece945a8068a017995f7512ea2beac21e34b ]
+
+Fix the missing clk_disable_unprepare() before return
+from rk3328_platform_probe() in the error handling case.
+
+Fixes: c32759035ad2 ("ASoC: rockchip: support ACODEC for rk3328")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20210518075847.1116983-1-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rk3328_codec.c | 28 ++++++++++++++++++++++------
+ 1 file changed, 22 insertions(+), 6 deletions(-)
+
+diff --git a/sound/soc/codecs/rk3328_codec.c b/sound/soc/codecs/rk3328_codec.c
+index bfefefcc76d8..758d439e8c7a 100644
+--- a/sound/soc/codecs/rk3328_codec.c
++++ b/sound/soc/codecs/rk3328_codec.c
+@@ -474,7 +474,8 @@ static int rk3328_platform_probe(struct platform_device *pdev)
+ rk3328->pclk = devm_clk_get(&pdev->dev, "pclk");
+ if (IS_ERR(rk3328->pclk)) {
+ dev_err(&pdev->dev, "can't get acodec pclk\n");
+- return PTR_ERR(rk3328->pclk);
++ ret = PTR_ERR(rk3328->pclk);
++ goto err_unprepare_mclk;
+ }
+
+ ret = clk_prepare_enable(rk3328->pclk);
+@@ -484,19 +485,34 @@ static int rk3328_platform_probe(struct platform_device *pdev)
+ }
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+- if (IS_ERR(base))
+- return PTR_ERR(base);
++ if (IS_ERR(base)) {
++ ret = PTR_ERR(base);
++ goto err_unprepare_pclk;
++ }
+
+ rk3328->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+ &rk3328_codec_regmap_config);
+- if (IS_ERR(rk3328->regmap))
+- return PTR_ERR(rk3328->regmap);
++ if (IS_ERR(rk3328->regmap)) {
++ ret = PTR_ERR(rk3328->regmap);
++ goto err_unprepare_pclk;
++ }
+
+ platform_set_drvdata(pdev, rk3328);
+
+- return devm_snd_soc_register_component(&pdev->dev, &soc_codec_rk3328,
++ ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_rk3328,
+ rk3328_dai,
+ ARRAY_SIZE(rk3328_dai));
++ if (ret)
++ goto err_unprepare_pclk;
++
++ return 0;
++
++err_unprepare_pclk:
++ clk_disable_unprepare(rk3328->pclk);
++
++err_unprepare_mclk:
++ clk_disable_unprepare(rk3328->mclk);
++ return ret;
+ }
+
+ static const struct of_device_id rk3328_codec_of_match[] __maybe_unused = {
+--
+2.30.2
+
--- /dev/null
+From 31f8f12249a467f18fa545a8104e8670633836ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 May 2021 15:12:09 +0900
+Subject: ASoC: rsnd: tidyup loop on rsnd_adg_clk_query()
+
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+
+[ Upstream commit cf9d5c6619fadfc41cf8f5154cb990cc38e3da85 ]
+
+commit 06e8f5c842f2d ("ASoC: rsnd: don't call clk_get_rate() under
+atomic context") used saved clk_rate, thus for_each_rsnd_clk()
+is no longer needed. This patch fixes it.
+
+Fixes: 06e8f5c842f2d ("ASoC: rsnd: don't call clk_get_rate() under atomic context")
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Link: https://lore.kernel.org/r/87v978oe2u.wl-kuninori.morimoto.gx@renesas.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sh/rcar/adg.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
+index 0b8ae3eee148..93751099465d 100644
+--- a/sound/soc/sh/rcar/adg.c
++++ b/sound/soc/sh/rcar/adg.c
+@@ -290,7 +290,6 @@ static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)
+ int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate)
+ {
+ struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
+- struct clk *clk;
+ int i;
+ int sel_table[] = {
+ [CLKA] = 0x1,
+@@ -303,10 +302,9 @@ int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate)
+ * find suitable clock from
+ * AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC/AUDIO_CLKI.
+ */
+- for_each_rsnd_clk(clk, adg, i) {
++ for (i = 0; i < CLKMAX; i++)
+ if (rate == adg->clk_rate[i])
+ return sel_table[i];
+- }
+
+ /*
+ * find divided clock from BRGA/BRGB
+--
+2.30.2
+
--- /dev/null
+From 998c517cbc96da9de0b941ae06ec7a18242a8340 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 17:22:27 -0500
+Subject: ASoC: rt1308-sdw: use first_hw_init flag on resume
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit 30e102dab5fad1db71684f8ac5e1ac74e49da06d ]
+
+The intent of the status check on resume was to verify if a SoundWire
+peripheral reported ATTACHED before waiting for the initialization to
+complete. This is required to avoid timeouts that will happen with
+'ghost' devices that are exposed in the platform firmware but are not
+populated in hardware.
+
+Unfortunately we used 'hw_init' instead of 'first_hw_init'. Due to
+another error, the resume operation never timed out, but the volume
+settings were not properly restored.
+
+BugLink: https://github.com/thesofproject/linux/issues/2908
+BugLink: https://github.com/thesofproject/linux/issues/2637
+Fixes: a87a6653a28c0 ('ASoC: rt1308-sdw: add rt1308 SdW amplifier driver')
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
+Reviewed-by: Bard Liao <bard.liao@intel.com>
+Link: https://lore.kernel.org/r/20210607222239.582139-4-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt1308-sdw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c
+index 1c226994aebd..f716668de640 100644
+--- a/sound/soc/codecs/rt1308-sdw.c
++++ b/sound/soc/codecs/rt1308-sdw.c
+@@ -709,7 +709,7 @@ static int __maybe_unused rt1308_dev_resume(struct device *dev)
+ struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev);
+ unsigned long time;
+
+- if (!rt1308->hw_init)
++ if (!rt1308->first_hw_init)
+ return 0;
+
+ if (!slave->unattach_request)
+--
+2.30.2
+
--- /dev/null
+From d5f5303d41886e5bbc42bc17914a8e489ed5865e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 17:22:28 -0500
+Subject: ASoC: rt1316-sdw: use first_hw_init flag on resume
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit ebe2ef60ed76c1afd8ec84e1bfd1868e3456e96b ]
+
+The intent of the status check on resume was to verify if a SoundWire
+peripheral reported ATTACHED before waiting for the initialization to
+complete. This is required to avoid timeouts that will happen with
+'ghost' devices that are exposed in the platform firmware but are not
+populated in hardware.
+
+Unfortunately we used 'hw_init' instead of 'first_hw_init'. Due to
+another error, the resume operation never timed out, but the volume
+settings were not properly restored.
+
+BugLink: https://github.com/thesofproject/linux/issues/2908
+BugLink: https://github.com/thesofproject/linux/issues/2637
+Fixes: 2b719fd20f327 ('ASoC: rt1316: Add RT1316 SDCA vendor-specific driver')
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
+Reviewed-by: Bard Liao <bard.liao@intel.com>
+Link: https://lore.kernel.org/r/20210607222239.582139-5-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt1316-sdw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/rt1316-sdw.c b/sound/soc/codecs/rt1316-sdw.c
+index 3b029c56467d..09b4914bba1b 100644
+--- a/sound/soc/codecs/rt1316-sdw.c
++++ b/sound/soc/codecs/rt1316-sdw.c
+@@ -701,7 +701,7 @@ static int __maybe_unused rt1316_dev_resume(struct device *dev)
+ struct rt1316_sdw_priv *rt1316 = dev_get_drvdata(dev);
+ unsigned long time;
+
+- if (!rt1316->hw_init)
++ if (!rt1316->first_hw_init)
+ return 0;
+
+ if (!slave->unattach_request)
+--
+2.30.2
+
--- /dev/null
+From 84c95197cdf65bf667ef14db0bf34e1b5c4fef96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 May 2021 00:51:50 -0700
+Subject: ASoC: rt5682: Disable irq on shutdown
+
+From: Stephen Boyd <swboyd@chromium.org>
+
+[ Upstream commit 47bcb1c7108363418cd578283333d72e310dfeaa ]
+
+We cancel the work queues, and reset the device on shutdown, but the irq
+isn't disabled so the work queues could be queued again. Let's disable
+the irq during shutdown so that we don't have to worry about this device
+trying to do anything anymore. This fixes a problem seen where the i2c
+bus is shutdown at reboot but this device irq still comes in and tries
+to make another i2c transaction when the bus doesn't work.
+
+Cc: Jairaj Arava <jairaj.arava@intel.com>
+Cc: Sathyanarayana Nujella <sathyanarayana.nujella@intel.com>
+Cc: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
+Cc: Shuming Fan <shumingf@realtek.com>
+Cc: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Fixes: 45a2702ce109 ("ASoC: rt5682: Fix panic in rt5682_jack_detect_handler happening during system shutdown")
+Signed-off-by: Stephen Boyd <swboyd@chromium.org>
+Link: https://lore.kernel.org/r/20210508075151.1626903-1-swboyd@chromium.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt5682-i2c.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/codecs/rt5682-i2c.c b/sound/soc/codecs/rt5682-i2c.c
+index 8ea9f1d9fec0..cd964e023d96 100644
+--- a/sound/soc/codecs/rt5682-i2c.c
++++ b/sound/soc/codecs/rt5682-i2c.c
+@@ -273,6 +273,7 @@ static void rt5682_i2c_shutdown(struct i2c_client *client)
+ {
+ struct rt5682_priv *rt5682 = i2c_get_clientdata(client);
+
++ disable_irq(client->irq);
+ cancel_delayed_work_sync(&rt5682->jack_detect_work);
+ cancel_delayed_work_sync(&rt5682->jd_check_work);
+
+--
+2.30.2
+
--- /dev/null
+From 518da6dda383f50735ed531a8bce0073aeef94f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 17:22:36 -0500
+Subject: ASoC: rt5682: Fix a problem with error handling in the io init
+ function of the soundwire
+
+From: Oder Chiou <oder_chiou@realtek.com>
+
+[ Upstream commit 9266d95405ae0c078f188ec8bca3a004631be429 ]
+
+The device checking error should be a jump to pm_runtime_put_autosuspend()
+as done before returning value.
+
+Fixes: 867f8d18df4f ('ASoC: rt5682: fix getting the wrong device id when the suspend_stress_test')
+Reviewed-by: Bard Liao <bard.liao@intel.com>
+Signed-off-by: Oder Chiou <oder_chiou@realtek.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210607222239.582139-13-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt5682-sdw.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c
+index 8e4bb9dd194e..529a85fd0a00 100644
+--- a/sound/soc/codecs/rt5682-sdw.c
++++ b/sound/soc/codecs/rt5682-sdw.c
+@@ -408,9 +408,11 @@ static int rt5682_io_init(struct device *dev, struct sdw_slave *slave)
+ usleep_range(30000, 30005);
+ loop--;
+ }
++
+ if (val != DEVICE_ID) {
+ dev_err(dev, "Device with ID register %x is not rt5682\n", val);
+- return -ENODEV;
++ ret = -ENODEV;
++ goto err_nodev;
+ }
+
+ if (rt5682->first_hw_init) {
+@@ -486,10 +488,11 @@ reinit:
+ rt5682->hw_init = true;
+ rt5682->first_hw_init = true;
+
++err_nodev:
+ pm_runtime_mark_last_busy(&slave->dev);
+ pm_runtime_put_autosuspend(&slave->dev);
+
+- dev_dbg(&slave->dev, "%s hw_init complete\n", __func__);
++ dev_dbg(&slave->dev, "%s hw_init complete: %d\n", __func__, ret);
+
+ return ret;
+ }
+--
+2.30.2
+
--- /dev/null
+From 5214ccec930ab292c548780e6f6fde9212788d4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 17:22:37 -0500
+Subject: ASoC: rt5682-sdw: set regcache_cache_only false before reading
+ RT5682_DEVICE_ID
+
+From: Bard Liao <yung-chuan.liao@linux.intel.com>
+
+[ Upstream commit c0372bc873dd29f325ee908351e0bd5b08d4d608 ]
+
+RT5682_DEVICE_ID is a volatile register, we can not read it in cache
+only mode.
+
+Fixes: 03f6fc6de919 ("ASoC: rt5682: Add the soundwire support")
+Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210607222239.582139-14-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt5682-sdw.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c
+index 529a85fd0a00..54873730bec5 100644
+--- a/sound/soc/codecs/rt5682-sdw.c
++++ b/sound/soc/codecs/rt5682-sdw.c
+@@ -400,6 +400,11 @@ static int rt5682_io_init(struct device *dev, struct sdw_slave *slave)
+
+ pm_runtime_get_noresume(&slave->dev);
+
++ if (rt5682->first_hw_init) {
++ regcache_cache_only(rt5682->regmap, false);
++ regcache_cache_bypass(rt5682->regmap, true);
++ }
++
+ while (loop > 0) {
+ regmap_read(rt5682->regmap, RT5682_DEVICE_ID, &val);
+ if (val == DEVICE_ID)
+@@ -415,11 +420,6 @@ static int rt5682_io_init(struct device *dev, struct sdw_slave *slave)
+ goto err_nodev;
+ }
+
+- if (rt5682->first_hw_init) {
+- regcache_cache_only(rt5682->regmap, false);
+- regcache_cache_bypass(rt5682->regmap, true);
+- }
+-
+ rt5682_calibrate(rt5682);
+
+ if (rt5682->first_hw_init) {
+--
+2.30.2
+
--- /dev/null
+From 6f999522af75fe184c5308a6f4d8206d0e412ec5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 17:22:29 -0500
+Subject: ASoC: rt5682-sdw: use first_hw_init flag on resume
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit 5361a42114689f875a9748299cadb4b1adbee6f4 ]
+
+The intent of the status check on resume was to verify if a SoundWire
+peripheral reported ATTACHED before waiting for the initialization to
+complete. This is required to avoid timeouts that will happen with
+'ghost' devices that are exposed in the platform firmware but are not
+populated in hardware.
+
+Unfortunately we used 'hw_init' instead of 'first_hw_init'. Due to
+another error, the resume operation never timed out, but the volume
+settings were not properly restored.
+
+BugLink: https://github.com/thesofproject/linux/issues/2908
+BugLink: https://github.com/thesofproject/linux/issues/2637
+Fixes: 03f6fc6de9192 ('ASoC: rt5682: Add the soundwire support')
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
+Reviewed-by: Bard Liao <bard.liao@intel.com>
+Link: https://lore.kernel.org/r/20210607222239.582139-6-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt5682-sdw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c
+index e78ba3b064c4..8e4bb9dd194e 100644
+--- a/sound/soc/codecs/rt5682-sdw.c
++++ b/sound/soc/codecs/rt5682-sdw.c
+@@ -743,7 +743,7 @@ static int __maybe_unused rt5682_dev_resume(struct device *dev)
+ struct rt5682_priv *rt5682 = dev_get_drvdata(dev);
+ unsigned long time;
+
+- if (!rt5682->hw_init)
++ if (!rt5682->first_hw_init)
+ return 0;
+
+ if (!slave->unattach_request)
+--
+2.30.2
+
--- /dev/null
+From 4b6d378d8fc7ed8c910f00227d74104cd85c1750 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 17:22:30 -0500
+Subject: ASoC: rt700-sdw: use first_hw_init flag on resume
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit a9e54e5fbe396b546771cf77b43ce7c75e212278 ]
+
+The intent of the status check on resume was to verify if a SoundWire
+peripheral reported ATTACHED before waiting for the initialization to
+complete. This is required to avoid timeouts that will happen with
+'ghost' devices that are exposed in the platform firmware but are not
+populated in hardware.
+
+Unfortunately we used 'hw_init' instead of 'first_hw_init'. Due to
+another error, the resume operation never timed out, but the volume
+settings were not properly restored.
+
+BugLink: https://github.com/thesofproject/linux/issues/2908
+BugLink: https://github.com/thesofproject/linux/issues/2637
+Fixes: 7d2a5f9ae41e3 ('ASoC: rt700: add rt700 codec driver')
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
+Reviewed-by: Bard Liao <bard.liao@intel.com>
+Link: https://lore.kernel.org/r/20210607222239.582139-7-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt700-sdw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/rt700-sdw.c b/sound/soc/codecs/rt700-sdw.c
+index ff9c081fd52a..d1d9c0f455b4 100644
+--- a/sound/soc/codecs/rt700-sdw.c
++++ b/sound/soc/codecs/rt700-sdw.c
+@@ -498,7 +498,7 @@ static int __maybe_unused rt700_dev_resume(struct device *dev)
+ struct rt700_priv *rt700 = dev_get_drvdata(dev);
+ unsigned long time;
+
+- if (!rt700->hw_init)
++ if (!rt700->first_hw_init)
+ return 0;
+
+ if (!slave->unattach_request)
+--
+2.30.2
+
--- /dev/null
+From fb048a7637dd585890495526f99918381e42b8b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 17:22:39 -0500
+Subject: ASoC: rt711-sdca: handle mbq_regmap in rt711_sdca_io_init
+
+From: Bard Liao <yung-chuan.liao@linux.intel.com>
+
+[ Upstream commit bcc0f0c078771e983a7e602eb14efa02f811445f ]
+
+We currently only hangle rt711->regmap in rt711_sdca_io_init(), and
+rt711->mbq_regmap is missing.
+
+Fixes: 7ad4d237e7c4a ('ASoC: rt711-sdca: Add RT711 SDCA vendor-specific driver')
+Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210607222239.582139-16-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt711-sdca.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c
+index 24a084e0b48a..0b0c230dcf71 100644
+--- a/sound/soc/codecs/rt711-sdca.c
++++ b/sound/soc/codecs/rt711-sdca.c
+@@ -1500,6 +1500,8 @@ int rt711_sdca_io_init(struct device *dev, struct sdw_slave *slave)
+ if (rt711->first_hw_init) {
+ regcache_cache_only(rt711->regmap, false);
+ regcache_cache_bypass(rt711->regmap, true);
++ regcache_cache_only(rt711->mbq_regmap, false);
++ regcache_cache_bypass(rt711->mbq_regmap, true);
+ } else {
+ /*
+ * PM runtime is only enabled when a Slave reports as Attached
+@@ -1565,6 +1567,8 @@ int rt711_sdca_io_init(struct device *dev, struct sdw_slave *slave)
+ if (rt711->first_hw_init) {
+ regcache_cache_bypass(rt711->regmap, false);
+ regcache_mark_dirty(rt711->regmap);
++ regcache_cache_bypass(rt711->mbq_regmap, false);
++ regcache_mark_dirty(rt711->mbq_regmap);
+ } else
+ rt711->first_hw_init = true;
+
+--
+2.30.2
+
--- /dev/null
+From 42891d9938fdcdc752ac9ffb3f6f169e5a822d29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 17:22:38 -0500
+Subject: ASoC: rt711-sdca-sdw: add readable for SDW_SDCA_CTL() registers
+
+From: Bard Liao <yung-chuan.liao@linux.intel.com>
+
+[ Upstream commit 5ad1ba99e4784929588c79e9810f5610825f0411 ]
+
+SDW_SDCA_CTL() registers are used but are not set to readable.
+
+Fixes: 7ad4d237e7c4a ('ASoC: rt711-sdca: Add RT711 SDCA vendor-specific driver')
+Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210607222239.582139-15-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt711-sdca-sdw.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/sound/soc/codecs/rt711-sdca-sdw.c b/sound/soc/codecs/rt711-sdca-sdw.c
+index b84e64233d96..03cd3e0142f9 100644
+--- a/sound/soc/codecs/rt711-sdca-sdw.c
++++ b/sound/soc/codecs/rt711-sdca-sdw.c
+@@ -75,6 +75,16 @@ static bool rt711_sdca_mbq_readable_register(struct device *dev, unsigned int re
+ case 0x5b00000 ... 0x5b000ff:
+ case 0x5f00000 ... 0x5f000ff:
+ case 0x6100000 ... 0x61000ff:
++ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU05, RT711_SDCA_CTL_FU_VOLUME, CH_L):
++ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU05, RT711_SDCA_CTL_FU_VOLUME, CH_R):
++ case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_USER_FU1E, RT711_SDCA_CTL_FU_VOLUME, CH_L):
++ case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_USER_FU1E, RT711_SDCA_CTL_FU_VOLUME, CH_R):
++ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, RT711_SDCA_CTL_FU_VOLUME, CH_L):
++ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, RT711_SDCA_CTL_FU_VOLUME, CH_R):
++ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_PLATFORM_FU44, RT711_SDCA_CTL_FU_CH_GAIN, CH_L):
++ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_PLATFORM_FU44, RT711_SDCA_CTL_FU_CH_GAIN, CH_R):
++ case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_PLATFORM_FU15, RT711_SDCA_CTL_FU_CH_GAIN, CH_L):
++ case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_PLATFORM_FU15, RT711_SDCA_CTL_FU_CH_GAIN, CH_R):
+ return true;
+ default:
+ return false;
+--
+2.30.2
+
--- /dev/null
+From 6cdb49d964187b7c693109fdb1b292947b2c7406 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 17:22:31 -0500
+Subject: ASoC: rt711-sdca-sdw: use first_hw_init flag on resume
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit b32cab09707bb7fd851128633157c92716df6781 ]
+
+The intent of the status check on resume was to verify if a SoundWire
+peripheral reported ATTACHED before waiting for the initialization to
+complete. This is required to avoid timeouts that will happen with
+'ghost' devices that are exposed in the platform firmware but are not
+populated in hardware.
+
+Unfortunately we used 'hw_init' instead of 'first_hw_init'. Due to
+another error, the resume operation never timed out, but the volume
+settings were not properly restored.
+
+BugLink: https://github.com/thesofproject/linux/issues/2908
+BugLink: https://github.com/thesofproject/linux/issues/2637
+Fixes: 7ad4d237e7c4a ('ASoC: rt711-sdca: Add RT711 SDCA vendor-specific driver')
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
+Reviewed-by: Bard Liao <bard.liao@intel.com>
+Link: https://lore.kernel.org/r/20210607222239.582139-8-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt711-sdca-sdw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/rt711-sdca-sdw.c b/sound/soc/codecs/rt711-sdca-sdw.c
+index 9685c8905468..b84e64233d96 100644
+--- a/sound/soc/codecs/rt711-sdca-sdw.c
++++ b/sound/soc/codecs/rt711-sdca-sdw.c
+@@ -380,7 +380,7 @@ static int __maybe_unused rt711_sdca_dev_resume(struct device *dev)
+ struct rt711_sdca_priv *rt711 = dev_get_drvdata(dev);
+ unsigned long time;
+
+- if (!rt711->hw_init)
++ if (!rt711->first_hw_init)
+ return 0;
+
+ if (!slave->unattach_request)
+--
+2.30.2
+
--- /dev/null
+From 5d281e0d8aaabd4fb367138670a711d0e5ff0a0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 17:22:32 -0500
+Subject: ASoC: rt711-sdw: use first_hw_init flag on resume
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit a0897ebca669f09a2e02206a9c48a738af655329 ]
+
+The intent of the status check on resume was to verify if a SoundWire
+peripheral reported ATTACHED before waiting for the initialization to
+complete. This is required to avoid timeouts that will happen with
+'ghost' devices that are exposed in the platform firmware but are not
+populated in hardware.
+
+Unfortunately we used 'hw_init' instead of 'first_hw_init'. Due to
+another error, the resume operation never timed out, but the volume
+settings were not properly restored.
+
+BugLink: https://github.com/thesofproject/linux/issues/2908
+BugLink: https://github.com/thesofproject/linux/issues/2637
+Fixes: 320b8b0d13b81 ('ASoC: rt711: add rt711 codec driver')
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
+Reviewed-by: Bard Liao <bard.liao@intel.com>
+Link: https://lore.kernel.org/r/20210607222239.582139-9-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt711-sdw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/rt711-sdw.c b/sound/soc/codecs/rt711-sdw.c
+index 8f5ebe92d407..15299084429f 100644
+--- a/sound/soc/codecs/rt711-sdw.c
++++ b/sound/soc/codecs/rt711-sdw.c
+@@ -501,7 +501,7 @@ static int __maybe_unused rt711_dev_resume(struct device *dev)
+ struct rt711_priv *rt711 = dev_get_drvdata(dev);
+ unsigned long time;
+
+- if (!rt711->hw_init)
++ if (!rt711->first_hw_init)
+ return 0;
+
+ if (!slave->unattach_request)
+--
+2.30.2
+
--- /dev/null
+From f5c11b44b48b0dc6f5711d4532a47094ca3f1b4b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 17:22:35 -0500
+Subject: ASoC: rt715-sdca: fix clock stop prepare timeout issue
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jack Yu <jack.yu@realtek.com>
+
+[ Upstream commit e343d34a9c912fc5c321e2a9fbc02e9dc9534ade ]
+
+Fix clock stop prepare timeout issue (#2853).
+The trigger of internal circuit which belong to
+“SDCA preset stuffs” was not set correctly in previous driver,
+which could block clock_stop_preparation state.
+Add the correct register setting to fix it.
+
+Fixes: 20d17057f0a8c ('ASoC: rt715-sdca: Add RT715 sdca vendor-specific driver')
+Signed-off-by: Jack Yu <jack.yu@realtek.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210607222239.582139-12-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt715-sdca-sdw.c | 1 +
+ sound/soc/codecs/rt715-sdca-sdw.h | 1 +
+ sound/soc/codecs/rt715-sdca.c | 3 +++
+ sound/soc/codecs/rt715-sdca.h | 1 +
+ 4 files changed, 6 insertions(+)
+
+diff --git a/sound/soc/codecs/rt715-sdca-sdw.c b/sound/soc/codecs/rt715-sdca-sdw.c
+index 7646bbe739f1..a5c673f43d82 100644
+--- a/sound/soc/codecs/rt715-sdca-sdw.c
++++ b/sound/soc/codecs/rt715-sdca-sdw.c
+@@ -70,6 +70,7 @@ static bool rt715_sdca_mbq_readable_register(struct device *dev, unsigned int re
+ case 0x2000036:
+ case 0x2000037:
+ case 0x2000039:
++ case 0x2000044:
+ case 0x6100000:
+ return true;
+ default:
+diff --git a/sound/soc/codecs/rt715-sdca-sdw.h b/sound/soc/codecs/rt715-sdca-sdw.h
+index cd365bb60747..0cbc14844f8c 100644
+--- a/sound/soc/codecs/rt715-sdca-sdw.h
++++ b/sound/soc/codecs/rt715-sdca-sdw.h
+@@ -113,6 +113,7 @@ static const struct reg_default rt715_mbq_reg_defaults_sdca[] = {
+ { 0x2000036, 0x0000 },
+ { 0x2000037, 0x0000 },
+ { 0x2000039, 0xaa81 },
++ { 0x2000044, 0x0202 },
+ { 0x6100000, 0x0100 },
+ { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
+ RT715_SDCA_FU_VOL_CTRL, CH_01), 0x00 },
+diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c
+index d82166f1a378..66e166568c50 100644
+--- a/sound/soc/codecs/rt715-sdca.c
++++ b/sound/soc/codecs/rt715-sdca.c
+@@ -1054,6 +1054,9 @@ int rt715_sdca_io_init(struct device *dev, struct sdw_slave *slave)
+ rt715_sdca_index_update_bits(rt715, RT715_VENDOR_REG,
+ RT715_REV_1, 0x40, 0x40);
+ }
++ /* DFLL Calibration trigger */
++ rt715_sdca_index_update_bits(rt715, RT715_VENDOR_REG,
++ RT715_DFLL_VAD, 0x1, 0x1);
+ /* trigger mode = VAD enable */
+ regmap_write(rt715->regmap,
+ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN,
+diff --git a/sound/soc/codecs/rt715-sdca.h b/sound/soc/codecs/rt715-sdca.h
+index 0c1fdd5bc7ca..90881b455ece 100644
+--- a/sound/soc/codecs/rt715-sdca.h
++++ b/sound/soc/codecs/rt715-sdca.h
+@@ -81,6 +81,7 @@ struct rt715_sdca_kcontrol_private {
+ #define RT715_AD_FUNC_EN 0x36
+ #define RT715_REV_1 0x37
+ #define RT715_SDW_INPUT_SEL 0x39
++#define RT715_DFLL_VAD 0x44
+ #define RT715_EXT_DMIC_CLK_CTRL2 0x54
+
+ /* Index (NID:61h) */
+--
+2.30.2
+
--- /dev/null
+From 163750e0ba6492c6676b566a467b340ef94a42de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 17:22:33 -0500
+Subject: ASoC: rt715-sdca-sdw: use first_hw_init flag on resume
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit d34d0897a753f42c8a7a6af3866781dd57344a45 ]
+
+The intent of the status check on resume was to verify if a SoundWire
+peripheral reported ATTACHED before waiting for the initialization to
+complete. This is required to avoid timeouts that will happen with
+'ghost' devices that are exposed in the platform firmware but are not
+populated in hardware.
+
+Unfortunately we used 'hw_init' instead of 'first_hw_init'. Due to
+another error, the resume operation never timed out, but the volume
+settings were not properly restored.
+
+This patch renames the status flag to 'first_hw_init' for consistency
+with other drivers (was 'first_init')
+
+BugLink: https://github.com/thesofproject/linux/issues/2908
+BugLink: https://github.com/thesofproject/linux/issues/2637
+Fixes: 20d17057f0a8c ('ASoC: rt715-sdca: Add RT715 sdca vendor-specific driver')
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
+Reviewed-by: Bard Liao <bard.liao@intel.com>
+Link: https://lore.kernel.org/r/20210607222239.582139-10-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt715-sdca-sdw.c | 2 +-
+ sound/soc/codecs/rt715-sdca.c | 6 +++---
+ sound/soc/codecs/rt715-sdca.h | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/sound/soc/codecs/rt715-sdca-sdw.c b/sound/soc/codecs/rt715-sdca-sdw.c
+index 1350798406f0..7646bbe739f1 100644
+--- a/sound/soc/codecs/rt715-sdca-sdw.c
++++ b/sound/soc/codecs/rt715-sdca-sdw.c
+@@ -224,7 +224,7 @@ static int __maybe_unused rt715_dev_resume(struct device *dev)
+ struct rt715_sdca_priv *rt715 = dev_get_drvdata(dev);
+ unsigned long time;
+
+- if (!rt715->hw_init)
++ if (!rt715->first_hw_init)
+ return 0;
+
+ if (!slave->unattach_request)
+diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c
+index 7db76c19e048..d82166f1a378 100644
+--- a/sound/soc/codecs/rt715-sdca.c
++++ b/sound/soc/codecs/rt715-sdca.c
+@@ -997,7 +997,7 @@ int rt715_sdca_init(struct device *dev, struct regmap *mbq_regmap,
+ * HW init will be performed when device reports present
+ */
+ rt715->hw_init = false;
+- rt715->first_init = false;
++ rt715->first_hw_init = false;
+
+ ret = devm_snd_soc_register_component(dev,
+ &soc_codec_dev_rt715_sdca,
+@@ -1018,7 +1018,7 @@ int rt715_sdca_io_init(struct device *dev, struct sdw_slave *slave)
+ /*
+ * PM runtime is only enabled when a Slave reports as Attached
+ */
+- if (!rt715->first_init) {
++ if (!rt715->first_hw_init) {
+ /* set autosuspend parameters */
+ pm_runtime_set_autosuspend_delay(&slave->dev, 3000);
+ pm_runtime_use_autosuspend(&slave->dev);
+@@ -1031,7 +1031,7 @@ int rt715_sdca_io_init(struct device *dev, struct sdw_slave *slave)
+
+ pm_runtime_enable(&slave->dev);
+
+- rt715->first_init = true;
++ rt715->first_hw_init = true;
+ }
+
+ pm_runtime_get_noresume(&slave->dev);
+diff --git a/sound/soc/codecs/rt715-sdca.h b/sound/soc/codecs/rt715-sdca.h
+index 85ce4d95e5eb..0c1fdd5bc7ca 100644
+--- a/sound/soc/codecs/rt715-sdca.h
++++ b/sound/soc/codecs/rt715-sdca.h
+@@ -27,7 +27,7 @@ struct rt715_sdca_priv {
+ enum sdw_slave_status status;
+ struct sdw_bus_params params;
+ bool hw_init;
+- bool first_init;
++ bool first_hw_init;
+ int l_is_unmute;
+ int r_is_unmute;
+ int hw_sdw_ver;
+--
+2.30.2
+
--- /dev/null
+From dd97428ba950135c153607a269ed59dfdd6d2332 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 17:22:34 -0500
+Subject: ASoC: rt715-sdw: use first_hw_init flag on resume
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit dbc07517ab173688ef11234d1099bc1e24e4f14b ]
+
+The intent of the status check on resume was to verify if a SoundWire
+peripheral reported ATTACHED before waiting for the initialization to
+complete. This is required to avoid timeouts that will happen with
+'ghost' devices that are exposed in the platform firmware but are not
+populated in hardware.
+
+Unfortunately we used 'hw_init' instead of 'first_hw_init'. Due to
+another error, the resume operation never timed out, but the volume
+settings were not properly restored.
+
+BugLink: https://github.com/thesofproject/linux/issues/2908
+BugLink: https://github.com/thesofproject/linux/issues/2637
+Fixes: d1ede0641b05e ('ASoC: rt715: add RT715 codec driver')
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
+Reviewed-by: Bard Liao <bard.liao@intel.com>
+Link: https://lore.kernel.org/r/20210607222239.582139-11-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt715-sdw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/rt715-sdw.c b/sound/soc/codecs/rt715-sdw.c
+index 81a1dd77b6f6..a7b21b03c08b 100644
+--- a/sound/soc/codecs/rt715-sdw.c
++++ b/sound/soc/codecs/rt715-sdw.c
+@@ -541,7 +541,7 @@ static int __maybe_unused rt715_dev_resume(struct device *dev)
+ struct rt715_priv *rt715 = dev_get_drvdata(dev);
+ unsigned long time;
+
+- if (!rt715->hw_init)
++ if (!rt715->first_hw_init)
+ return 0;
+
+ if (!slave->unattach_request)
+--
+2.30.2
+
--- /dev/null
+From a769926061891e44f420b46f34af067e9c612074 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 May 2021 17:41:28 +0300
+Subject: ath10k: add missing error return code in ath10k_pci_probe()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit e2783e2f39ba99178dedfc1646d5cc0979d1bab3 ]
+
+When chip_id is not supported, the resources will be freed
+on path err_unsupported, these resources will also be freed
+when calling ath10k_pci_remove(), it will cause double free,
+so return -ENODEV when it doesn't support the device with wrong
+chip_id.
+
+Fixes: c0c378f9907c ("ath10k: remove target soc ps code")
+Fixes: 7505f7c3ec1d ("ath10k: create a chip revision whitelist")
+Fixes: f8914a14623a ("ath10k: restore QCA9880-AR1A (v1) detection")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210522105822.1091848-3-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath10k/pci.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
+index 463cf3f8f8a5..71878ab35b93 100644
+--- a/drivers/net/wireless/ath/ath10k/pci.c
++++ b/drivers/net/wireless/ath/ath10k/pci.c
+@@ -3685,8 +3685,10 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
+ ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS);
+ if (bus_params.chip_id != 0xffffffff) {
+ if (!ath10k_pci_chip_is_supported(pdev->device,
+- bus_params.chip_id))
++ bus_params.chip_id)) {
++ ret = -ENODEV;
+ goto err_unsupported;
++ }
+ }
+ }
+
+@@ -3697,11 +3699,15 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
+ }
+
+ bus_params.chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS);
+- if (bus_params.chip_id == 0xffffffff)
++ if (bus_params.chip_id == 0xffffffff) {
++ ret = -ENODEV;
+ goto err_unsupported;
++ }
+
+- if (!ath10k_pci_chip_is_supported(pdev->device, bus_params.chip_id))
++ if (!ath10k_pci_chip_is_supported(pdev->device, bus_params.chip_id)) {
++ ret = -ENODEV;
+ goto err_unsupported;
++ }
+
+ ret = ath10k_core_register(ar, &bus_params);
+ if (ret) {
+--
+2.30.2
+
--- /dev/null
+From d51b94e465d9f7b6e545dff90a594f128e7040a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 18:46:17 +0800
+Subject: ath10k: Fix an error code in ath10k_add_interface()
+
+From: Yang Li <yang.lee@linux.alibaba.com>
+
+[ Upstream commit e9ca70c735ce66fc6a0e02c8b6958434f74ef8de ]
+
+When the code execute this if statement, the value of ret is 0.
+However, we can see from the ath10k_warn() log that the value of
+ret should be -EINVAL.
+
+Clean up smatch warning:
+
+drivers/net/wireless/ath/ath10k/mac.c:5596 ath10k_add_interface() warn:
+missing error code 'ret'
+
+Reported-by: Abaci Robot <abaci@linux.alibaba.com>
+Fixes: ccec9038c721 ("ath10k: enable raw encap mode and software crypto engine")
+Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/1621939577-62218-1-git-send-email-yang.lee@linux.alibaba.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath10k/mac.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
+index 5ce4f8d038b9..c272b290fa73 100644
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -5592,6 +5592,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
+
+ if (arvif->nohwcrypt &&
+ !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
++ ret = -EINVAL;
+ ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");
+ goto err;
+ }
+--
+2.30.2
+
--- /dev/null
+From 8d9c62b5b3f657edc7a08fac1624b8daec6b7219 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 May 2021 17:41:28 +0300
+Subject: ath10k: go to path err_unsupported when chip id is not supported
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 9e88dd431d2345acdb7a549f3e88aaf4c2a307a1 ]
+
+When chip id is not supported, it go to path err_unsupported
+to print the error message.
+
+Fixes: f8914a14623a ("ath10k: restore QCA9880-AR1A (v1) detection")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210522105822.1091848-2-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath10k/pci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
+index e7fde635e0ee..463cf3f8f8a5 100644
+--- a/drivers/net/wireless/ath/ath10k/pci.c
++++ b/drivers/net/wireless/ath/ath10k/pci.c
+@@ -3701,7 +3701,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
+ goto err_unsupported;
+
+ if (!ath10k_pci_chip_is_supported(pdev->device, bus_params.chip_id))
+- goto err_free_irq;
++ goto err_unsupported;
+
+ ret = ath10k_core_register(ar, &bus_params);
+ if (ret) {
+--
+2.30.2
+
--- /dev/null
+From 960284c1414424d7c80e2c8cc9050c3eb91f7221 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 May 2021 11:50:54 +0200
+Subject: ath11k: Fix an error handling path in
+ ath11k_core_fetch_board_data_api_n()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 515bda1d1e51c64edf2a384a58801f85a80a3f2d ]
+
+All error paths but this one 'goto err' in order to release some
+resources.
+Fix this.
+
+Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/e959eb544f3cb04258507d8e25a6f12eab126bde.1621676864.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
+index 77ce3347ab86..595e83fe0990 100644
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -488,7 +488,8 @@ static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab,
+ if (len < ALIGN(ie_len, 4)) {
+ ath11k_err(ab, "invalid length for board ie_id %d ie_len %zu len %zu\n",
+ ie_id, ie_len, len);
+- return -EINVAL;
++ ret = -EINVAL;
++ goto err;
+ }
+
+ switch (ie_id) {
+--
+2.30.2
+
--- /dev/null
+From 4f6b394b9b8febc701967d0fabcf73b54e8411ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 15:30:28 +0200
+Subject: ath11k: send beacon template after vdev_start/restart during csa
+
+From: Seevalamuthu Mariappan <seevalam@codeaurora.org>
+
+[ Upstream commit 979ebc54cf13bd1e3eb6e21766d208d5de984fb8 ]
+
+Firmware has added assert if beacon template is received after
+vdev_down. Firmware expects beacon template after vdev_start
+and before vdev_up. This change is needed to support MBSSID EMA
+cases in firmware.
+
+Hence, Change the sequence in ath11k as expected from firmware.
+This new change is not causing any issues with older
+firmware.
+
+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1.r3-00011-QCAHKSWPL_SILICONZ-1
+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1.r4-00008-QCAHKSWPL_SILICONZ-1
+
+Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
+Signed-off-by: Seevalamuthu Mariappan <seevalam@codeaurora.org>
+[sven@narfation.org: added tested-on/fixes information]
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210525133028.2805615-1-sven@narfation.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/mac.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
+index 9d0ff150ec30..eb52332dbe3f 100644
+--- a/drivers/net/wireless/ath/ath11k/mac.c
++++ b/drivers/net/wireless/ath/ath11k/mac.c
+@@ -5379,11 +5379,6 @@ ath11k_mac_update_vif_chan(struct ath11k *ar,
+ if (WARN_ON(!arvif->is_up))
+ continue;
+
+- ret = ath11k_mac_setup_bcn_tmpl(arvif);
+- if (ret)
+- ath11k_warn(ab, "failed to update bcn tmpl during csa: %d\n",
+- ret);
+-
+ ret = ath11k_mac_vdev_restart(arvif, &vifs[i].new_ctx->def);
+ if (ret) {
+ ath11k_warn(ab, "failed to restart vdev %d: %d\n",
+@@ -5391,6 +5386,11 @@ ath11k_mac_update_vif_chan(struct ath11k *ar,
+ continue;
+ }
+
++ ret = ath11k_mac_setup_bcn_tmpl(arvif);
++ if (ret)
++ ath11k_warn(ab, "failed to update bcn tmpl during csa: %d\n",
++ ret);
++
+ ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
+ arvif->bssid);
+ if (ret) {
+--
+2.30.2
+
--- /dev/null
+From b49269c9b39404f843f726ada6ff3340053c21b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 12:57:16 +0300
+Subject: backlight: lm3630a_bl: Put fwnode in error case during ->probe()
+
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+
+[ Upstream commit 6d1c32dbedd7d7e7372aa38033ec8782c39f6379 ]
+
+device_for_each_child_node() bumps a reference counting of a returned variable.
+We have to balance it whenever we return to the caller.
+
+Cc: Brian Masney <masneyb@onstation.org>
+Cc: Dan Murphy <dmurphy@ti.com>
+Fixes: 8fbce8efe15cd ("backlight: lm3630a: Add firmware node support")
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Brian Masney <masneyb@onstation.org>
+Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/backlight/lm3630a_bl.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c
+index e88a2b0e5904..662029d6a3dc 100644
+--- a/drivers/video/backlight/lm3630a_bl.c
++++ b/drivers/video/backlight/lm3630a_bl.c
+@@ -482,8 +482,10 @@ static int lm3630a_parse_node(struct lm3630a_chip *pchip,
+
+ device_for_each_child_node(pchip->dev, node) {
+ ret = lm3630a_parse_bank(pdata, node, &seen_led_sources);
+- if (ret)
++ if (ret) {
++ fwnode_handle_put(node);
+ return ret;
++ }
+ }
+
+ return ret;
+--
+2.30.2
+
--- /dev/null
+From 5847d8f0fde2022a5569a442814a05f2c5aa5233 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 11:36:33 +0200
+Subject: bfq: Remove merged request already in bfq_requests_merged()
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit a921c655f2033dd1ce1379128efe881dda23ea37 ]
+
+Currently, bfq does very little in bfq_requests_merged() and handles all
+the request cleanup in bfq_finish_requeue_request() called from
+blk_mq_free_request(). That is currently safe only because
+blk_mq_free_request() is called shortly after bfq_requests_merged()
+while bfqd->lock is still held. However to fix a lock inversion between
+bfqd->lock and ioc->lock, we need to call blk_mq_free_request() after
+dropping bfqd->lock. That would mean that already merged request could
+be seen by other processes inside bfq queues and possibly dispatched to
+the device which is wrong. So move cleanup of the request from
+bfq_finish_requeue_request() to bfq_requests_merged().
+
+Acked-by: Paolo Valente <paolo.valente@linaro.org>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20210623093634.27879-2-jack@suse.cz
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bfq-iosched.c | 41 +++++++++++++----------------------------
+ 1 file changed, 13 insertions(+), 28 deletions(-)
+
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index 2adb1e69c9d2..d00c89f6ba59 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -2405,7 +2405,7 @@ static void bfq_requests_merged(struct request_queue *q, struct request *rq,
+ *next_bfqq = bfq_init_rq(next);
+
+ if (!bfqq)
+- return;
++ goto remove;
+
+ /*
+ * If next and rq belong to the same bfq_queue and next is older
+@@ -2428,6 +2428,14 @@ static void bfq_requests_merged(struct request_queue *q, struct request *rq,
+ bfqq->next_rq = rq;
+
+ bfqg_stats_update_io_merged(bfqq_group(bfqq), next->cmd_flags);
++remove:
++ /* Merged request may be in the IO scheduler. Remove it. */
++ if (!RB_EMPTY_NODE(&next->rb_node)) {
++ bfq_remove_request(next->q, next);
++ if (next_bfqq)
++ bfqg_stats_update_io_remove(bfqq_group(next_bfqq),
++ next->cmd_flags);
++ }
+ }
+
+ /* Must be called with bfqq != NULL */
+@@ -6376,6 +6384,7 @@ static void bfq_finish_requeue_request(struct request *rq)
+ {
+ struct bfq_queue *bfqq = RQ_BFQQ(rq);
+ struct bfq_data *bfqd;
++ unsigned long flags;
+
+ /*
+ * rq either is not associated with any icq, or is an already
+@@ -6393,39 +6402,15 @@ static void bfq_finish_requeue_request(struct request *rq)
+ rq->io_start_time_ns,
+ rq->cmd_flags);
+
++ spin_lock_irqsave(&bfqd->lock, flags);
+ if (likely(rq->rq_flags & RQF_STARTED)) {
+- unsigned long flags;
+-
+- spin_lock_irqsave(&bfqd->lock, flags);
+-
+ if (rq == bfqd->waited_rq)
+ bfq_update_inject_limit(bfqd, bfqq);
+
+ bfq_completed_request(bfqq, bfqd);
+- bfq_finish_requeue_request_body(bfqq);
+-
+- spin_unlock_irqrestore(&bfqd->lock, flags);
+- } else {
+- /*
+- * Request rq may be still/already in the scheduler,
+- * in which case we need to remove it (this should
+- * never happen in case of requeue). And we cannot
+- * defer such a check and removal, to avoid
+- * inconsistencies in the time interval from the end
+- * of this function to the start of the deferred work.
+- * This situation seems to occur only in process
+- * context, as a consequence of a merge. In the
+- * current version of the code, this implies that the
+- * lock is held.
+- */
+-
+- if (!RB_EMPTY_NODE(&rq->rb_node)) {
+- bfq_remove_request(rq->q, rq);
+- bfqg_stats_update_io_remove(bfqq_group(bfqq),
+- rq->cmd_flags);
+- }
+- bfq_finish_requeue_request_body(bfqq);
+ }
++ bfq_finish_requeue_request_body(bfqq);
++ spin_unlock_irqrestore(&bfqd->lock, flags);
+
+ /*
+ * Reset private fields. In case of a requeue, this allows
+--
+2.30.2
+
--- /dev/null
+From a53306f72d1a7f065ef5303fb2ec673b35877dfa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 May 2021 23:22:35 +0800
+Subject: blk-mq: clear stale request in tags->rq[] before freeing one request
+ pool
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit bd63141d585bef14f4caf111f6d0e27fe2300ec6 ]
+
+refcount_inc_not_zero() in bt_tags_iter() still may read one freed
+request.
+
+Fix the issue by the following approach:
+
+1) hold a per-tags spinlock when reading ->rqs[tag] and calling
+refcount_inc_not_zero in bt_tags_iter()
+
+2) clearing stale request referred via ->rqs[tag] before freeing
+request pool, the per-tags spinlock is held for clearing stale
+->rq[tag]
+
+So after we cleared stale requests, bt_tags_iter() won't observe
+freed request any more, also the clearing will wait for pending
+request reference.
+
+The idea of clearing ->rqs[] is borrowed from John Garry's previous
+patch and one recent David's patch.
+
+Tested-by: John Garry <john.garry@huawei.com>
+Reviewed-by: David Jeffery <djeffery@redhat.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20210511152236.763464-4-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-mq-tag.c | 9 +++++++--
+ block/blk-mq-tag.h | 6 ++++++
+ block/blk-mq.c | 46 +++++++++++++++++++++++++++++++++++++++++-----
+ 3 files changed, 54 insertions(+), 7 deletions(-)
+
+diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
+index 544edf2c56a5..1671dae43030 100644
+--- a/block/blk-mq-tag.c
++++ b/block/blk-mq-tag.c
+@@ -202,10 +202,14 @@ struct bt_iter_data {
+ static struct request *blk_mq_find_and_get_req(struct blk_mq_tags *tags,
+ unsigned int bitnr)
+ {
+- struct request *rq = tags->rqs[bitnr];
++ struct request *rq;
++ unsigned long flags;
+
++ spin_lock_irqsave(&tags->lock, flags);
++ rq = tags->rqs[bitnr];
+ if (!rq || !refcount_inc_not_zero(&rq->ref))
+- return NULL;
++ rq = NULL;
++ spin_unlock_irqrestore(&tags->lock, flags);
+ return rq;
+ }
+
+@@ -538,6 +542,7 @@ struct blk_mq_tags *blk_mq_init_tags(unsigned int total_tags,
+
+ tags->nr_tags = total_tags;
+ tags->nr_reserved_tags = reserved_tags;
++ spin_lock_init(&tags->lock);
+
+ if (blk_mq_is_sbitmap_shared(flags))
+ return tags;
+diff --git a/block/blk-mq-tag.h b/block/blk-mq-tag.h
+index 7d3e6b333a4a..f887988e5ef6 100644
+--- a/block/blk-mq-tag.h
++++ b/block/blk-mq-tag.h
+@@ -20,6 +20,12 @@ struct blk_mq_tags {
+ struct request **rqs;
+ struct request **static_rqs;
+ struct list_head page_list;
++
++ /*
++ * used to clear request reference in rqs[] before freeing one
++ * request pool
++ */
++ spinlock_t lock;
+ };
+
+ extern struct blk_mq_tags *blk_mq_init_tags(unsigned int nr_tags,
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index debfa5cd8025..dd371f321d35 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -2307,6 +2307,45 @@ queue_exit:
+ return BLK_QC_T_NONE;
+ }
+
++static size_t order_to_size(unsigned int order)
++{
++ return (size_t)PAGE_SIZE << order;
++}
++
++/* called before freeing request pool in @tags */
++static void blk_mq_clear_rq_mapping(struct blk_mq_tag_set *set,
++ struct blk_mq_tags *tags, unsigned int hctx_idx)
++{
++ struct blk_mq_tags *drv_tags = set->tags[hctx_idx];
++ struct page *page;
++ unsigned long flags;
++
++ list_for_each_entry(page, &tags->page_list, lru) {
++ unsigned long start = (unsigned long)page_address(page);
++ unsigned long end = start + order_to_size(page->private);
++ int i;
++
++ for (i = 0; i < set->queue_depth; i++) {
++ struct request *rq = drv_tags->rqs[i];
++ unsigned long rq_addr = (unsigned long)rq;
++
++ if (rq_addr >= start && rq_addr < end) {
++ WARN_ON_ONCE(refcount_read(&rq->ref) != 0);
++ cmpxchg(&drv_tags->rqs[i], rq, NULL);
++ }
++ }
++ }
++
++ /*
++ * Wait until all pending iteration is done.
++ *
++ * Request reference is cleared and it is guaranteed to be observed
++ * after the ->lock is released.
++ */
++ spin_lock_irqsave(&drv_tags->lock, flags);
++ spin_unlock_irqrestore(&drv_tags->lock, flags);
++}
++
+ void blk_mq_free_rqs(struct blk_mq_tag_set *set, struct blk_mq_tags *tags,
+ unsigned int hctx_idx)
+ {
+@@ -2325,6 +2364,8 @@ void blk_mq_free_rqs(struct blk_mq_tag_set *set, struct blk_mq_tags *tags,
+ }
+ }
+
++ blk_mq_clear_rq_mapping(set, tags, hctx_idx);
++
+ while (!list_empty(&tags->page_list)) {
+ page = list_first_entry(&tags->page_list, struct page, lru);
+ list_del_init(&page->lru);
+@@ -2384,11 +2425,6 @@ struct blk_mq_tags *blk_mq_alloc_rq_map(struct blk_mq_tag_set *set,
+ return tags;
+ }
+
+-static size_t order_to_size(unsigned int order)
+-{
+- return (size_t)PAGE_SIZE << order;
+-}
+-
+ static int blk_mq_init_request(struct blk_mq_tag_set *set, struct request *rq,
+ unsigned int hctx_idx, int node)
+ {
+--
+2.30.2
+
--- /dev/null
+From f31eb930c4ff55cddc4bd14a51265616a5a43490 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 May 2021 23:22:34 +0800
+Subject: blk-mq: grab rq->refcount before calling ->fn in
+ blk_mq_tagset_busy_iter
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 2e315dc07df009c3e29d6926871f62a30cfae394 ]
+
+Grab rq->refcount before calling ->fn in blk_mq_tagset_busy_iter(), and
+this way will prevent the request from being re-used when ->fn is
+running. The approach is same as what we do during handling timeout.
+
+Fix request use-after-free(UAF) related with completion race or queue
+releasing:
+
+- If one rq is referred before rq->q is frozen, then queue won't be
+frozen before the request is released during iteration.
+
+- If one rq is referred after rq->q is frozen, refcount_inc_not_zero()
+will return false, and we won't iterate over this request.
+
+However, still one request UAF not covered: refcount_inc_not_zero() may
+read one freed request, and it will be handled in next patch.
+
+Tested-by: John Garry <john.garry@huawei.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20210511152236.763464-3-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-mq-tag.c | 44 +++++++++++++++++++++++++++++++++-----------
+ block/blk-mq.c | 14 +++++++++-----
+ block/blk-mq.h | 1 +
+ 3 files changed, 43 insertions(+), 16 deletions(-)
+
+diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
+index 2a37731e8244..544edf2c56a5 100644
+--- a/block/blk-mq-tag.c
++++ b/block/blk-mq-tag.c
+@@ -199,6 +199,16 @@ struct bt_iter_data {
+ bool reserved;
+ };
+
++static struct request *blk_mq_find_and_get_req(struct blk_mq_tags *tags,
++ unsigned int bitnr)
++{
++ struct request *rq = tags->rqs[bitnr];
++
++ if (!rq || !refcount_inc_not_zero(&rq->ref))
++ return NULL;
++ return rq;
++}
++
+ static bool bt_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data)
+ {
+ struct bt_iter_data *iter_data = data;
+@@ -206,18 +216,22 @@ static bool bt_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data)
+ struct blk_mq_tags *tags = hctx->tags;
+ bool reserved = iter_data->reserved;
+ struct request *rq;
++ bool ret = true;
+
+ if (!reserved)
+ bitnr += tags->nr_reserved_tags;
+- rq = tags->rqs[bitnr];
+-
+ /*
+ * We can hit rq == NULL here, because the tagging functions
+ * test and set the bit before assigning ->rqs[].
+ */
+- if (rq && rq->q == hctx->queue && rq->mq_hctx == hctx)
+- return iter_data->fn(hctx, rq, iter_data->data, reserved);
+- return true;
++ rq = blk_mq_find_and_get_req(tags, bitnr);
++ if (!rq)
++ return true;
++
++ if (rq->q == hctx->queue && rq->mq_hctx == hctx)
++ ret = iter_data->fn(hctx, rq, iter_data->data, reserved);
++ blk_mq_put_rq_ref(rq);
++ return ret;
+ }
+
+ /**
+@@ -264,6 +278,8 @@ static bool bt_tags_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data)
+ struct blk_mq_tags *tags = iter_data->tags;
+ bool reserved = iter_data->flags & BT_TAG_ITER_RESERVED;
+ struct request *rq;
++ bool ret = true;
++ bool iter_static_rqs = !!(iter_data->flags & BT_TAG_ITER_STATIC_RQS);
+
+ if (!reserved)
+ bitnr += tags->nr_reserved_tags;
+@@ -272,16 +288,19 @@ static bool bt_tags_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data)
+ * We can hit rq == NULL here, because the tagging functions
+ * test and set the bit before assigning ->rqs[].
+ */
+- if (iter_data->flags & BT_TAG_ITER_STATIC_RQS)
++ if (iter_static_rqs)
+ rq = tags->static_rqs[bitnr];
+ else
+- rq = tags->rqs[bitnr];
++ rq = blk_mq_find_and_get_req(tags, bitnr);
+ if (!rq)
+ return true;
+- if ((iter_data->flags & BT_TAG_ITER_STARTED) &&
+- !blk_mq_request_started(rq))
+- return true;
+- return iter_data->fn(rq, iter_data->data, reserved);
++
++ if (!(iter_data->flags & BT_TAG_ITER_STARTED) ||
++ blk_mq_request_started(rq))
++ ret = iter_data->fn(rq, iter_data->data, reserved);
++ if (!iter_static_rqs)
++ blk_mq_put_rq_ref(rq);
++ return ret;
+ }
+
+ /**
+@@ -348,6 +367,9 @@ void blk_mq_all_tag_iter(struct blk_mq_tags *tags, busy_tag_iter_fn *fn,
+ * indicates whether or not @rq is a reserved request. Return
+ * true to continue iterating tags, false to stop.
+ * @priv: Will be passed as second argument to @fn.
++ *
++ * We grab one request reference before calling @fn and release it after
++ * @fn returns.
+ */
+ void blk_mq_tagset_busy_iter(struct blk_mq_tag_set *tagset,
+ busy_tag_iter_fn *fn, void *priv)
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index c86c01bfecdb..debfa5cd8025 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -909,6 +909,14 @@ static bool blk_mq_req_expired(struct request *rq, unsigned long *next)
+ return false;
+ }
+
++void blk_mq_put_rq_ref(struct request *rq)
++{
++ if (is_flush_rq(rq, rq->mq_hctx))
++ rq->end_io(rq, 0);
++ else if (refcount_dec_and_test(&rq->ref))
++ __blk_mq_free_request(rq);
++}
++
+ static bool blk_mq_check_expired(struct blk_mq_hw_ctx *hctx,
+ struct request *rq, void *priv, bool reserved)
+ {
+@@ -942,11 +950,7 @@ static bool blk_mq_check_expired(struct blk_mq_hw_ctx *hctx,
+ if (blk_mq_req_expired(rq, next))
+ blk_mq_rq_timed_out(rq, reserved);
+
+- if (is_flush_rq(rq, hctx))
+- rq->end_io(rq, 0);
+- else if (refcount_dec_and_test(&rq->ref))
+- __blk_mq_free_request(rq);
+-
++ blk_mq_put_rq_ref(rq);
+ return true;
+ }
+
+diff --git a/block/blk-mq.h b/block/blk-mq.h
+index 9ce64bc4a6c8..556368d2c5b6 100644
+--- a/block/blk-mq.h
++++ b/block/blk-mq.h
+@@ -47,6 +47,7 @@ void blk_mq_add_to_requeue_list(struct request *rq, bool at_head,
+ void blk_mq_flush_busy_ctxs(struct blk_mq_hw_ctx *hctx, struct list_head *list);
+ struct request *blk_mq_dequeue_from_ctx(struct blk_mq_hw_ctx *hctx,
+ struct blk_mq_ctx *start);
++void blk_mq_put_rq_ref(struct request *rq);
+
+ /*
+ * Internal helpers for allocating/freeing the request map
+--
+2.30.2
+
--- /dev/null
+From c9f06fdcd8a65a86d600564fe631793abe43e826 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Jun 2021 10:02:48 +0800
+Subject: blk-mq: update hctx->dispatch_busy in case of real scheduler
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit cb9516be7708a2a18ec0a19fe3a225b5b3bc92c7 ]
+
+Commit 6e6fcbc27e77 ("blk-mq: support batching dispatch in case of io")
+starts to support io batching submission by using hctx->dispatch_busy.
+
+However, blk_mq_update_dispatch_busy() isn't changed to update hctx->dispatch_busy
+in that commit, so fix the issue by updating hctx->dispatch_busy in case
+of real scheduler.
+
+Reported-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Fixes: 6e6fcbc27e77 ("blk-mq: support batching dispatch in case of io")
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20210625020248.1630497-1-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-mq.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index dd371f321d35..c732aa581124 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -1224,9 +1224,6 @@ static void blk_mq_update_dispatch_busy(struct blk_mq_hw_ctx *hctx, bool busy)
+ {
+ unsigned int ewma;
+
+- if (hctx->queue->elevator)
+- return;
+-
+ ewma = hctx->dispatch_busy;
+
+ if (!ewma && !busy)
+--
+2.30.2
+
--- /dev/null
+From 8f11f390eaf5e132d857405d82be3ceccfaa7cd7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Jun 2021 17:36:59 +0800
+Subject: blk-wbt: introduce a new disable state to prevent false positive by
+ rwb_enabled()
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+[ Upstream commit 1d0903d61e9645c6330b94247b96dd873dfc11c8 ]
+
+Now that we disable wbt by simply zero out rwb->wb_normal in
+wbt_disable_default() when switch elevator to bfq, but it's not safe
+because it will become false positive if we change queue depth. If it
+become false positive between wbt_wait() and wbt_track() when submit
+write request, it will lead to drop rqw->inflight to -1 in wbt_done(),
+which will end up trigger IO hung. Fix this issue by introduce a new
+state which mean the wbt was disabled.
+
+Fixes: a79050434b45 ("blk-rq-qos: refactor out common elements of blk-wbt")
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Link: https://lore.kernel.org/r/20210619093700.920393-2-yi.zhang@huawei.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-wbt.c | 5 +++--
+ block/blk-wbt.h | 1 +
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/block/blk-wbt.c b/block/blk-wbt.c
+index 42aed0160f86..b098ac6a84f0 100644
+--- a/block/blk-wbt.c
++++ b/block/blk-wbt.c
+@@ -77,7 +77,8 @@ enum {
+
+ static inline bool rwb_enabled(struct rq_wb *rwb)
+ {
+- return rwb && rwb->wb_normal != 0;
++ return rwb && rwb->enable_state != WBT_STATE_OFF_DEFAULT &&
++ rwb->wb_normal != 0;
+ }
+
+ static void wb_timestamp(struct rq_wb *rwb, unsigned long *var)
+@@ -702,7 +703,7 @@ void wbt_disable_default(struct request_queue *q)
+ rwb = RQWB(rqos);
+ if (rwb->enable_state == WBT_STATE_ON_DEFAULT) {
+ blk_stat_deactivate(rwb->cb);
+- rwb->wb_normal = 0;
++ rwb->enable_state = WBT_STATE_OFF_DEFAULT;
+ }
+ }
+ EXPORT_SYMBOL_GPL(wbt_disable_default);
+diff --git a/block/blk-wbt.h b/block/blk-wbt.h
+index 16bdc85b8df9..2eb01becde8c 100644
+--- a/block/blk-wbt.h
++++ b/block/blk-wbt.h
+@@ -34,6 +34,7 @@ enum {
+ enum {
+ WBT_STATE_ON_DEFAULT = 1,
+ WBT_STATE_ON_MANUAL = 2,
++ WBT_STATE_OFF_DEFAULT
+ };
+
+ struct rq_wb {
+--
+2.30.2
+
--- /dev/null
+From 5f341c53bbc1863c2f4b1b9f5597b7452d9a121b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Jun 2021 17:37:00 +0800
+Subject: blk-wbt: make sure throttle is enabled properly
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+[ Upstream commit 76a8040817b4b9c69b53f9b326987fa891b4082a ]
+
+After commit a79050434b45 ("blk-rq-qos: refactor out common elements of
+blk-wbt"), if throttle was disabled by wbt_disable_default(), we could
+not enable again, fix this by set enable_state back to
+WBT_STATE_ON_DEFAULT.
+
+Fixes: a79050434b45 ("blk-rq-qos: refactor out common elements of blk-wbt")
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Link: https://lore.kernel.org/r/20210619093700.920393-3-yi.zhang@huawei.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-wbt.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/block/blk-wbt.c b/block/blk-wbt.c
+index b098ac6a84f0..f5e5ac915bf7 100644
+--- a/block/blk-wbt.c
++++ b/block/blk-wbt.c
+@@ -637,9 +637,13 @@ void wbt_set_write_cache(struct request_queue *q, bool write_cache_on)
+ void wbt_enable_default(struct request_queue *q)
+ {
+ struct rq_qos *rqos = wbt_rq_qos(q);
++
+ /* Throttling already enabled? */
+- if (rqos)
++ if (rqos) {
++ if (RQWB(rqos)->enable_state == WBT_STATE_OFF_DEFAULT)
++ RQWB(rqos)->enable_state = WBT_STATE_ON_DEFAULT;
+ return;
++ }
+
+ /* Queue not registered? Maybe shutting down... */
+ if (!blk_queue_registered(q))
+--
+2.30.2
+
--- /dev/null
+From 037c91213b953d6141122cb515b1ed032213f4bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 May 2021 23:22:33 +0800
+Subject: block: avoid double io accounting for flush request
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 84da7acc3ba53af26f15c4b0ada446127b7a7836 ]
+
+For flush request, rq->end_io() may be called two times, one is from
+timeout handling(blk_mq_check_expired()), another is from normal
+completion(__blk_mq_end_request()).
+
+Move blk_account_io_flush() after flush_rq->ref drops to zero, so
+io accounting can be done just once for flush request.
+
+Fixes: b68663186577 ("block: add iostat counters for flush requests")
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Tested-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20210511152236.763464-2-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-flush.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/block/blk-flush.c b/block/blk-flush.c
+index 7942ca6ed321..1002f6c58181 100644
+--- a/block/blk-flush.c
++++ b/block/blk-flush.c
+@@ -219,8 +219,6 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error)
+ unsigned long flags = 0;
+ struct blk_flush_queue *fq = blk_get_flush_queue(q, flush_rq->mq_ctx);
+
+- blk_account_io_flush(flush_rq);
+-
+ /* release the tag's ownership to the req cloned from */
+ spin_lock_irqsave(&fq->mq_flush_lock, flags);
+
+@@ -230,6 +228,7 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error)
+ return;
+ }
+
++ blk_account_io_flush(flush_rq);
+ /*
+ * Flush request has to be marked as IDLE when it is really ended
+ * because its .end_io() is called from timeout code path too for
+--
+2.30.2
+
--- /dev/null
+From 2b6c4af9835bb09b8cb9d3c51b5b447615a9bf1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Jun 2021 16:09:46 +0200
+Subject: block, bfq: avoid delayed merge of async queues
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Paolo Valente <paolo.valente@linaro.org>
+
+[ Upstream commit bd3664b362381c4c1473753ebedf0ab242a60d1d ]
+
+Since commit 430a67f9d616 ("block, bfq: merge bursts of newly-created
+queues"), BFQ may schedule a merge between a newly created sync
+bfq_queue, say Q2, and the last sync bfq_queue created, say Q1. To this
+goal, BFQ stores the address of Q1 in the field bic->stable_merge_bfqq
+of the bic associated with Q2. So, when the time for the possible merge
+arrives, BFQ knows which bfq_queue to merge Q2 with. In particular,
+BFQ checks for possible merges on request arrivals.
+
+Yet the same bic may also be associated with an async bfq_queue, say
+Q3. So, if a request for Q3 arrives, then the above check may happen
+to be executed while the bfq_queue at hand is Q3, instead of Q2. In
+this case, Q1 happens to be merged with an async bfq_queue. This is
+not only a conceptual mistake, because async queues are to be kept out
+of queue merging, but also a bug that leads to inconsistent states.
+
+This commits simply filters async queues out of delayed merges.
+
+Fixes: 430a67f9d616 ("block, bfq: merge bursts of newly-created queues")
+Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
+Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
+Link: https://lore.kernel.org/r/20210619140948.98712-6-paolo.valente@linaro.org
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bfq-iosched.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index d00c89f6ba59..7c62bf093199 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -2703,7 +2703,13 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ * costly and complicated.
+ */
+ if (unlikely(!bfqd->nonrot_with_queueing)) {
+- if (bic->stable_merge_bfqq &&
++ /*
++ * Make sure also that bfqq is sync, because
++ * bic->stable_merge_bfqq may point to some queue (for
++ * stable merging) also if bic is associated with a
++ * sync queue, but this bfqq is async
++ */
++ if (bfq_bfqq_sync(bfqq) && bic->stable_merge_bfqq &&
+ !bfq_bfqq_just_created(bfqq) &&
+ time_is_before_jiffies(bfqq->split_time +
+ msecs_to_jiffies(200))) {
+--
+2.30.2
+
--- /dev/null
+From ba265995ae3b46c5cb79728d420fff6ad7eca5cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Jun 2021 16:09:43 +0200
+Subject: block, bfq: fix delayed stable merge check
+
+From: Luca Mariotti <mariottiluca1@hotmail.it>
+
+[ Upstream commit e03f2ab78a4a673e4af23c3b855591c48b9de4d7 ]
+
+When attempting to schedule a merge of a given bfq_queue with the currently
+in-service bfq_queue or with a cooperating bfq_queue among the scheduled
+bfq_queues, delayed stable merge is checked for rotational or non-queueing
+devs. For this stable merge to be performed, some conditions must be met.
+If the current bfq_queue underwent some split from some merged bfq_queue,
+one of these conditions is that two hundred milliseconds must elapse from
+split, otherwise this condition is always met.
+
+Unfortunately, by mistake, time_is_after_jiffies() was written instead of
+time_is_before_jiffies() for this check, verifying that less than two
+hundred milliseconds have elapsed instead of verifying that at least two
+hundred milliseconds have elapsed.
+
+Fix this issue by replacing time_is_after_jiffies() with
+time_is_before_jiffies().
+
+Signed-off-by: Luca Mariotti <mariottiluca1@hotmail.it>
+Signed-off-by: Paolo Valente <paolo.valente@unimore.it>
+Signed-off-by: Pietro Pedroni <pedroni.pietro.96@gmail.com>
+Link: https://lore.kernel.org/r/20210619140948.98712-3-paolo.valente@linaro.org
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bfq-iosched.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index acd1f881273e..2adb1e69c9d2 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -2697,7 +2697,7 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ if (unlikely(!bfqd->nonrot_with_queueing)) {
+ if (bic->stable_merge_bfqq &&
+ !bfq_bfqq_just_created(bfqq) &&
+- time_is_after_jiffies(bfqq->split_time +
++ time_is_before_jiffies(bfqq->split_time +
+ msecs_to_jiffies(200))) {
+ struct bfq_queue *stable_merge_bfqq =
+ bic->stable_merge_bfqq;
+--
+2.30.2
+
--- /dev/null
+From 40c1c3f5b4aedbb726137d5b5f11d2074dcbfce8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Jun 2021 16:09:48 +0200
+Subject: block, bfq: reset waker pointer with shared queues
+
+From: Paolo Valente <paolo.valente@linaro.org>
+
+[ Upstream commit 9a2ac41b13c573703d6689f51f3e27dd658324be ]
+
+Commit 85686d0dc194 ("block, bfq: keep shared queues out of the waker
+mechanism") leaves shared bfq_queues out of the waker-detection
+mechanism. It attains this goal by not updating the pointer
+last_completed_rq_bfqq, if the last request completed belongs to a
+shared bfq_queue (so that the pointer will not point to the shared
+bfq_queue).
+
+Yet this has a side effect: the pointer last_completed_rq_bfqq keeps
+pointing, deceptively, to a bfq_queue that actually is not the last
+one to have had a request completed. As a consequence, such a
+bfq_queue may deceptively be considered as a waker of some bfq_queue,
+even of some shared bfq_queue.
+
+To address this issue, reset last_completed_rq_bfqq if the last
+request completed belongs to a shared queue.
+
+Fixes: 85686d0dc194 ("block, bfq: keep shared queues out of the waker mechanism")
+Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
+Link: https://lore.kernel.org/r/20210619140948.98712-8-paolo.valente@linaro.org
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bfq-iosched.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index 7c62bf093199..2a2e6e4ff0b4 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -6143,11 +6143,13 @@ static void bfq_completed_request(struct bfq_queue *bfqq, struct bfq_data *bfqd)
+ * of other queues. But a false waker will unjustly steal
+ * bandwidth to its supposedly woken queue. So considering
+ * also shared queues in the waking mechanism may cause more
+- * control troubles than throughput benefits. Then do not set
+- * last_completed_rq_bfqq to bfqq if bfqq is a shared queue.
++ * control troubles than throughput benefits. Then reset
++ * last_completed_rq_bfqq if bfqq is a shared queue.
+ */
+ if (!bfq_bfqq_coop(bfqq))
+ bfqd->last_completed_rq_bfqq = bfqq;
++ else
++ bfqd->last_completed_rq_bfqq = NULL;
+
+ /*
+ * If we are waiting to discover whether the request pattern
+--
+2.30.2
+
--- /dev/null
+From 0dd854162565979f1e4dfb9bf84f0bc3d8ac5b0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jun 2021 10:33:12 +0800
+Subject: block: fix discard request merge
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 2705dfb2094777e405e065105e307074af8965c1 ]
+
+ll_new_hw_segment() is reached only in case of single range discard
+merge, and we don't have max discard segment size limit actually, so
+it is wrong to run the following check:
+
+if (req->nr_phys_segments + nr_phys_segs > blk_rq_get_max_segments(req))
+
+it may be always false since req->nr_phys_segments is initialized as
+one, and bio's segment count is still 1, blk_rq_get_max_segments(reg)
+is 1 too.
+
+Fix the issue by not doing the check and bypassing the calculation of
+discard request's nr_phys_segments.
+
+Based on analysis from Wang Shanker.
+
+Cc: Christoph Hellwig <hch@lst.de>
+Reported-by: Wang Shanker <shankerwangmiao@gmail.com>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20210628023312.1903255-1-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-merge.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/block/blk-merge.c b/block/blk-merge.c
+index 4d97fb6dd226..bcdff1879c34 100644
+--- a/block/blk-merge.c
++++ b/block/blk-merge.c
+@@ -559,10 +559,14 @@ static inline unsigned int blk_rq_get_max_segments(struct request *rq)
+ static inline int ll_new_hw_segment(struct request *req, struct bio *bio,
+ unsigned int nr_phys_segs)
+ {
+- if (req->nr_phys_segments + nr_phys_segs > blk_rq_get_max_segments(req))
++ if (blk_integrity_merge_bio(req->q, req, bio) == false)
+ goto no_merge;
+
+- if (blk_integrity_merge_bio(req->q, req, bio) == false)
++ /* discard request merge won't add new segment */
++ if (req_op(req) == REQ_OP_DISCARD)
++ return 1;
++
++ if (req->nr_phys_segments + nr_phys_segs > blk_rq_get_max_segments(req))
+ goto no_merge;
+
+ /*
+--
+2.30.2
+
--- /dev/null
+From a73adf049cc0f5f1768f6f3239b8f1e5f6627512 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jun 2021 09:58:21 +0800
+Subject: block: fix race between adding/removing rq qos and normal IO
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 2cafe29a8d03f02a3d16193bdaae2f3e82a423f9 ]
+
+Yi reported several kernel panics on:
+
+[16687.001777] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008
+...
+[16687.163549] pc : __rq_qos_track+0x38/0x60
+
+or
+
+[ 997.690455] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000020
+...
+[ 997.850347] pc : __rq_qos_done+0x2c/0x50
+
+Turns out it is caused by race between adding rq qos(wbt) and normal IO
+because rq_qos_add can be run when IO is being submitted, fix this issue
+by freezing queue before adding/deleting rq qos to queue.
+
+rq_qos_exit() needn't to freeze queue because it is called after queue
+has been frozen.
+
+iolatency calls rq_qos_add() during allocating queue, so freezing won't
+add delay because queue usage refcount works at atomic mode at that
+time.
+
+iocost calls rq_qos_add() when writing cgroup attribute file, that is
+fine to freeze queue at that time since we usually freeze queue when
+storing to queue sysfs attribute, meantime iocost only exists on the
+root cgroup.
+
+wbt_init calls it in blk_register_queue() and queue sysfs attribute
+store(queue_wb_lat_store() when write it 1st time in case of !BLK_WBT_MQ),
+the following patch will speedup the queue freezing in wbt_init.
+
+Reported-by: Yi Zhang <yi.zhang@redhat.com>
+Cc: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Tested-by: Yi Zhang <yi.zhang@redhat.com>
+Link: https://lore.kernel.org/r/20210609015822.103433-2-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-rq-qos.h | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/block/blk-rq-qos.h b/block/blk-rq-qos.h
+index 2bc43e94f4c4..2bcb3495e376 100644
+--- a/block/blk-rq-qos.h
++++ b/block/blk-rq-qos.h
+@@ -7,6 +7,7 @@
+ #include <linux/blk_types.h>
+ #include <linux/atomic.h>
+ #include <linux/wait.h>
++#include <linux/blk-mq.h>
+
+ #include "blk-mq-debugfs.h"
+
+@@ -99,8 +100,21 @@ static inline void rq_wait_init(struct rq_wait *rq_wait)
+
+ static inline void rq_qos_add(struct request_queue *q, struct rq_qos *rqos)
+ {
++ /*
++ * No IO can be in-flight when adding rqos, so freeze queue, which
++ * is fine since we only support rq_qos for blk-mq queue.
++ *
++ * Reuse ->queue_lock for protecting against other concurrent
++ * rq_qos adding/deleting
++ */
++ blk_mq_freeze_queue(q);
++
++ spin_lock_irq(&q->queue_lock);
+ rqos->next = q->rq_qos;
+ q->rq_qos = rqos;
++ spin_unlock_irq(&q->queue_lock);
++
++ blk_mq_unfreeze_queue(q);
+
+ if (rqos->ops->debugfs_attrs)
+ blk_mq_debugfs_register_rqos(rqos);
+@@ -110,12 +124,22 @@ static inline void rq_qos_del(struct request_queue *q, struct rq_qos *rqos)
+ {
+ struct rq_qos **cur;
+
++ /*
++ * See comment in rq_qos_add() about freezing queue & using
++ * ->queue_lock.
++ */
++ blk_mq_freeze_queue(q);
++
++ spin_lock_irq(&q->queue_lock);
+ for (cur = &q->rq_qos; *cur; cur = &(*cur)->next) {
+ if (*cur == rqos) {
+ *cur = rqos->next;
+ break;
+ }
+ }
++ spin_unlock_irq(&q->queue_lock);
++
++ blk_mq_unfreeze_queue(q);
+
+ blk_mq_debugfs_unregister_rqos(rqos);
+ }
+--
+2.30.2
+
--- /dev/null
+From d143292e7c49dd541d769efb68962154749a0238 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Jun 2021 20:30:30 +0800
+Subject: block: fix trace completion for chained bio
+
+From: Edward Hsieh <edwardh@synology.com>
+
+[ Upstream commit 60b6a7e6a0f4382cd689f9afdac816964fec2921 ]
+
+For chained bio, trace_block_bio_complete in bio_endio is currently called
+only by the parent bio once upon all chained bio completed.
+However, the sector and size for the parent bio are modified in bio_split.
+Therefore, the size and sector of the complete events might not match the
+queue events in blktrace.
+
+The original fix of bio completion trace <fbbaf700e7b1> ("block: trace
+completion of all bios.") wants multiple complete events to correspond
+to one queue event but missed this.
+
+The issue can be reproduced by md/raid5 read with bio cross chunks.
+
+To fix, move trace completion into the loop for every chained bio to call.
+
+Fixes: fbbaf700e7b1 ("block: trace completion of all bios.")
+Reviewed-by: Wade Liang <wadel@synology.com>
+Reviewed-by: BingJing Chang <bingjingc@synology.com>
+Signed-off-by: Edward Hsieh <edwardh@synology.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20210624123030.27014-1-edwardh@synology.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bio.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/block/bio.c b/block/bio.c
+index 44205dfb6b60..1fab762e079b 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -1375,8 +1375,7 @@ static inline bool bio_remaining_done(struct bio *bio)
+ *
+ * bio_endio() can be called several times on a bio that has been chained
+ * using bio_chain(). The ->bi_end_io() function will only be called the
+- * last time. At this point the BLK_TA_COMPLETE tracing event will be
+- * generated if BIO_TRACE_COMPLETION is set.
++ * last time.
+ **/
+ void bio_endio(struct bio *bio)
+ {
+@@ -1389,6 +1388,11 @@ again:
+ if (bio->bi_bdev)
+ rq_qos_done_bio(bio->bi_bdev->bd_disk->queue, bio);
+
++ if (bio->bi_bdev && bio_flagged(bio, BIO_TRACE_COMPLETION)) {
++ trace_block_bio_complete(bio->bi_bdev->bd_disk->queue, bio);
++ bio_clear_flag(bio, BIO_TRACE_COMPLETION);
++ }
++
+ /*
+ * Need to have a real endio function for chained bios, otherwise
+ * various corner cases will break (like stacking block devices that
+@@ -1402,11 +1406,6 @@ again:
+ goto again;
+ }
+
+- if (bio->bi_bdev && bio_flagged(bio, BIO_TRACE_COMPLETION)) {
+- trace_block_bio_complete(bio->bi_bdev->bd_disk->queue, bio);
+- bio_clear_flag(bio, BIO_TRACE_COMPLETION);
+- }
+-
+ blk_throtl_bio_endio(bio);
+ /* release cgroup info */
+ bio_uninit(bio);
+--
+2.30.2
+
--- /dev/null
+From 727dea5d4c98d9b046b2db7bacc6f203b6fc6a11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Mar 2021 11:01:44 +0800
+Subject: block_dump: remove block_dump feature in mark_inode_dirty()
+
+From: zhangyi (F) <yi.zhang@huawei.com>
+
+[ Upstream commit 12e0613715e1cf305fffafaf0e89d810d9a85cc0 ]
+
+block_dump is an old debugging interface, one of it's functions is used
+to print the information about who write which file on disk. If we
+enable block_dump through /proc/sys/vm/block_dump and turn on debug log
+level, we can gather information about write process name, target file
+name and disk from kernel message. This feature is realized in
+block_dump___mark_inode_dirty(), it print above information into kernel
+message directly when marking inode dirty, so it is noisy and can easily
+trigger log storm. At the same time, get the dentry refcount is also not
+safe, we found it will lead to deadlock on ext4 file system with
+data=journal mode.
+
+After tracepoints has been introduced into the kernel, we got a
+tracepoint in __mark_inode_dirty(), which is a better replacement of
+block_dump___mark_inode_dirty(). The only downside is that it only trace
+the inode number and not a file name, but it probably doesn't matter
+because the original printed file name in block_dump is not accurate in
+some cases, and we can still find it through the inode number and device
+id. So this patch delete the dirting inode part of block_dump feature.
+
+Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20210313030146.2882027-2-yi.zhang@huawei.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fs-writeback.c | 25 -------------------------
+ 1 file changed, 25 deletions(-)
+
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index e91980f49388..7c46d1588a19 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -2205,28 +2205,6 @@ int dirtytime_interval_handler(struct ctl_table *table, int write,
+ return ret;
+ }
+
+-static noinline void block_dump___mark_inode_dirty(struct inode *inode)
+-{
+- if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) {
+- struct dentry *dentry;
+- const char *name = "?";
+-
+- dentry = d_find_alias(inode);
+- if (dentry) {
+- spin_lock(&dentry->d_lock);
+- name = (const char *) dentry->d_name.name;
+- }
+- printk(KERN_DEBUG
+- "%s(%d): dirtied inode %lu (%s) on %s\n",
+- current->comm, task_pid_nr(current), inode->i_ino,
+- name, inode->i_sb->s_id);
+- if (dentry) {
+- spin_unlock(&dentry->d_lock);
+- dput(dentry);
+- }
+- }
+-}
+-
+ /**
+ * __mark_inode_dirty - internal function to mark an inode dirty
+ *
+@@ -2296,9 +2274,6 @@ void __mark_inode_dirty(struct inode *inode, int flags)
+ (dirtytime && (inode->i_state & I_DIRTY_INODE)))
+ return;
+
+- if (unlikely(block_dump))
+- block_dump___mark_inode_dirty(inode);
+-
+ spin_lock(&inode->i_lock);
+ if (dirtytime && (inode->i_state & I_DIRTY_INODE))
+ goto out_unlock_inode;
+--
+2.30.2
+
--- /dev/null
+From 7386e901dd227fd22ae4807c14be9ffa4d1fbadf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 20:59:02 -0700
+Subject: Bluetooth: Fix handling of HCI_LE_Advertising_Set_Terminated event
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 23837a6d7a1a61818ed94a6b8af552d6cf7d32d5 ]
+
+Error status of this event means that it has ended due reasons other
+than a connection:
+
+ 'If advertising has terminated as a result of the advertising duration
+ elapsing, the Status parameter shall be set to the error code
+ Advertising Timeout (0x3C).'
+
+ 'If advertising has terminated because the
+ Max_Extended_Advertising_Events was reached, the Status parameter
+ shall be set to the error code Limit Reached (0x43).'
+
+Fixes: acf0aeae431a0 ("Bluetooth: Handle ADv set terminated event")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 7d05f6c476d6..b077d150ac52 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -5296,8 +5296,19 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb)
+
+ BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+
+- if (ev->status)
++ if (ev->status) {
++ struct adv_info *adv;
++
++ adv = hci_find_adv_instance(hdev, ev->handle);
++ if (!adv)
++ return;
++
++ /* Remove advertising as it has been terminated */
++ hci_remove_adv_instance(hdev, ev->handle);
++ mgmt_advertising_removed(NULL, hdev, ev->handle);
++
+ return;
++ }
+
+ conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->conn_handle));
+ if (conn) {
+--
+2.30.2
+
--- /dev/null
+From bd23e52bf5e99e3aa6b32a493f9b49883b6f50a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jun 2021 11:09:27 -0700
+Subject: Bluetooth: Fix Set Extended (Scan Response) Data
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit c9ed0a7077306f9d41d74fb006ab5dbada8349c5 ]
+
+These command do have variable length and the length can go up to 251,
+so this changes the struct to not use a fixed size and then when
+creating the PDU only the actual length of the data send to the
+controller.
+
+Fixes: a0fb3726ba551 ("Bluetooth: Use Set ext adv/scan rsp data if controller supports")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci.h | 6 ++--
+ include/net/bluetooth/hci_core.h | 8 ++---
+ net/bluetooth/hci_request.c | 51 ++++++++++++++++++--------------
+ 3 files changed, 37 insertions(+), 28 deletions(-)
+
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index ea4ae551c426..18b135dc968b 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -1774,13 +1774,15 @@ struct hci_cp_ext_adv_set {
+ __u8 max_events;
+ } __packed;
+
++#define HCI_MAX_EXT_AD_LENGTH 251
++
+ #define HCI_OP_LE_SET_EXT_ADV_DATA 0x2037
+ struct hci_cp_le_set_ext_adv_data {
+ __u8 handle;
+ __u8 operation;
+ __u8 frag_pref;
+ __u8 length;
+- __u8 data[HCI_MAX_AD_LENGTH];
++ __u8 data[];
+ } __packed;
+
+ #define HCI_OP_LE_SET_EXT_SCAN_RSP_DATA 0x2038
+@@ -1789,7 +1791,7 @@ struct hci_cp_le_set_ext_scan_rsp_data {
+ __u8 operation;
+ __u8 frag_pref;
+ __u8 length;
+- __u8 data[HCI_MAX_AD_LENGTH];
++ __u8 data[];
+ } __packed;
+
+ #define LE_SET_ADV_DATA_OP_COMPLETE 0x03
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index c73ac52af186..89c8406dddb4 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -228,9 +228,9 @@ struct adv_info {
+ __u16 remaining_time;
+ __u16 duration;
+ __u16 adv_data_len;
+- __u8 adv_data[HCI_MAX_AD_LENGTH];
++ __u8 adv_data[HCI_MAX_EXT_AD_LENGTH];
+ __u16 scan_rsp_len;
+- __u8 scan_rsp_data[HCI_MAX_AD_LENGTH];
++ __u8 scan_rsp_data[HCI_MAX_EXT_AD_LENGTH];
+ __s8 tx_power;
+ __u32 min_interval;
+ __u32 max_interval;
+@@ -550,9 +550,9 @@ struct hci_dev {
+ DECLARE_BITMAP(dev_flags, __HCI_NUM_FLAGS);
+
+ __s8 adv_tx_power;
+- __u8 adv_data[HCI_MAX_AD_LENGTH];
++ __u8 adv_data[HCI_MAX_EXT_AD_LENGTH];
+ __u8 adv_data_len;
+- __u8 scan_rsp_data[HCI_MAX_AD_LENGTH];
++ __u8 scan_rsp_data[HCI_MAX_EXT_AD_LENGTH];
+ __u8 scan_rsp_data_len;
+
+ struct list_head adv_instances;
+diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
+index fa9125b782f8..b069f640394d 100644
+--- a/net/bluetooth/hci_request.c
++++ b/net/bluetooth/hci_request.c
+@@ -1697,30 +1697,33 @@ void __hci_req_update_scan_rsp_data(struct hci_request *req, u8 instance)
+ return;
+
+ if (ext_adv_capable(hdev)) {
+- struct hci_cp_le_set_ext_scan_rsp_data cp;
++ struct {
++ struct hci_cp_le_set_ext_scan_rsp_data cp;
++ u8 data[HCI_MAX_EXT_AD_LENGTH];
++ } pdu;
+
+- memset(&cp, 0, sizeof(cp));
++ memset(&pdu, 0, sizeof(pdu));
+
+ if (instance)
+ len = create_instance_scan_rsp_data(hdev, instance,
+- cp.data);
++ pdu.data);
+ else
+- len = create_default_scan_rsp_data(hdev, cp.data);
++ len = create_default_scan_rsp_data(hdev, pdu.data);
+
+ if (hdev->scan_rsp_data_len == len &&
+- !memcmp(cp.data, hdev->scan_rsp_data, len))
++ !memcmp(pdu.data, hdev->scan_rsp_data, len))
+ return;
+
+- memcpy(hdev->scan_rsp_data, cp.data, sizeof(cp.data));
++ memcpy(hdev->scan_rsp_data, pdu.data, len);
+ hdev->scan_rsp_data_len = len;
+
+- cp.handle = instance;
+- cp.length = len;
+- cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;
+- cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG;
++ pdu.cp.handle = instance;
++ pdu.cp.length = len;
++ pdu.cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;
++ pdu.cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG;
+
+- hci_req_add(req, HCI_OP_LE_SET_EXT_SCAN_RSP_DATA, sizeof(cp),
+- &cp);
++ hci_req_add(req, HCI_OP_LE_SET_EXT_SCAN_RSP_DATA,
++ sizeof(pdu.cp) + len, &pdu.cp);
+ } else {
+ struct hci_cp_le_set_scan_rsp_data cp;
+
+@@ -1843,26 +1846,30 @@ void __hci_req_update_adv_data(struct hci_request *req, u8 instance)
+ return;
+
+ if (ext_adv_capable(hdev)) {
+- struct hci_cp_le_set_ext_adv_data cp;
++ struct {
++ struct hci_cp_le_set_ext_adv_data cp;
++ u8 data[HCI_MAX_EXT_AD_LENGTH];
++ } pdu;
+
+- memset(&cp, 0, sizeof(cp));
++ memset(&pdu, 0, sizeof(pdu));
+
+- len = create_instance_adv_data(hdev, instance, cp.data);
++ len = create_instance_adv_data(hdev, instance, pdu.data);
+
+ /* There's nothing to do if the data hasn't changed */
+ if (hdev->adv_data_len == len &&
+- memcmp(cp.data, hdev->adv_data, len) == 0)
++ memcmp(pdu.data, hdev->adv_data, len) == 0)
+ return;
+
+- memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
++ memcpy(hdev->adv_data, pdu.data, len);
+ hdev->adv_data_len = len;
+
+- cp.length = len;
+- cp.handle = instance;
+- cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;
+- cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG;
++ pdu.cp.length = len;
++ pdu.cp.handle = instance;
++ pdu.cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;
++ pdu.cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG;
+
+- hci_req_add(req, HCI_OP_LE_SET_EXT_ADV_DATA, sizeof(cp), &cp);
++ hci_req_add(req, HCI_OP_LE_SET_EXT_ADV_DATA,
++ sizeof(pdu.cp) + len, &pdu.cp);
+ } else {
+ struct hci_cp_le_set_adv_data cp;
+
+--
+2.30.2
+
--- /dev/null
+From a90c4cca728da12df98e6ad6abb2a72c35cf8a64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 May 2021 11:45:02 -0700
+Subject: Bluetooth: mgmt: Fix slab-out-of-bounds in tlv_data_is_valid
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 799acb9347915bfe4eac0ff2345b468f0a1ca207 ]
+
+This fixes parsing of LTV entries when the length is 0.
+
+Found with:
+
+tools/mgmt-tester -s "Add Advertising - Success (ScRsp only)"
+
+Add Advertising - Success (ScRsp only) - run
+ Sending Add Advertising (0x003e)
+ Test condition added, total 1
+[ 11.004577] ==================================================================
+[ 11.005292] BUG: KASAN: slab-out-of-bounds in tlv_data_is_valid+0x87/0xe0
+[ 11.005984] Read of size 1 at addr ffff888002c695b0 by task mgmt-tester/87
+[ 11.006711]
+[ 11.007176]
+[ 11.007429] Allocated by task 87:
+[ 11.008151]
+[ 11.008438] The buggy address belongs to the object at ffff888002c69580
+[ 11.008438] which belongs to the cache kmalloc-64 of size 64
+[ 11.010526] The buggy address is located 48 bytes inside of
+[ 11.010526] 64-byte region [ffff888002c69580, ffff888002c695c0)
+[ 11.012423] The buggy address belongs to the page:
+[ 11.013291]
+[ 11.013544] Memory state around the buggy address:
+[ 11.014359] ffff888002c69480: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
+[ 11.015453] ffff888002c69500: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
+[ 11.016232] >ffff888002c69580: 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc
+[ 11.017010] ^
+[ 11.017547] ffff888002c69600: 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc
+[ 11.018296] ffff888002c69680: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
+[ 11.019116] ==================================================================
+
+Fixes: 2bb36870e8cb2 ("Bluetooth: Unify advertising instance flags check")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index f9be7f9084d6..023a98f7c992 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -7585,6 +7585,9 @@ static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data,
+ for (i = 0, cur_len = 0; i < len; i += (cur_len + 1)) {
+ cur_len = data[i];
+
++ if (!cur_len)
++ continue;
++
+ if (data[i + 1] == EIR_FLAGS &&
+ (!is_adv_data || flags_managed(adv_flags)))
+ return false;
+--
+2.30.2
+
--- /dev/null
+From 888788b6c2d14bf1be7334203ef8503cc7a5fa8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Apr 2021 17:53:14 +0100
+Subject: Bluetooth: virtio_bt: add missing null pointer check on alloc_skb
+ call return
+
+From: Colin Ian King <colin.king@canonical.com>
+
+[ Upstream commit 1cb027f2f803d0a7abe9c291f0625e6bccd25999 ]
+
+The call to alloc_skb with the GFP_KERNEL flag can return a null sk_buff
+pointer, so add a null check to avoid any null pointer deference issues.
+
+Addresses-Coverity: ("Dereference null return value")
+Fixes: afd2daa26c7a ("Bluetooth: Add support for virtio transport driver")
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/virtio_bt.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/bluetooth/virtio_bt.c b/drivers/bluetooth/virtio_bt.c
+index c804db7e90f8..57908ce4fae8 100644
+--- a/drivers/bluetooth/virtio_bt.c
++++ b/drivers/bluetooth/virtio_bt.c
+@@ -34,6 +34,9 @@ static int virtbt_add_inbuf(struct virtio_bluetooth *vbt)
+ int err;
+
+ skb = alloc_skb(1000, GFP_KERNEL);
++ if (!skb)
++ return -ENOMEM;
++
+ sg_init_one(sg, skb->data, 1000);
+
+ err = virtqueue_add_inbuf(vq, sg, 1, skb, GFP_KERNEL);
+--
+2.30.2
+
--- /dev/null
+From 5857b3dbeb07c35d45bfcb0f9c35b818c31e4d34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jun 2021 17:09:51 -0700
+Subject: bpf: Do not change gso_size during bpf_skb_change_proto()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maciej Żenczykowski <maze@google.com>
+
+[ Upstream commit 364745fbe981a4370f50274475da4675661104df ]
+
+This is technically a backwards incompatible change in behaviour, but I'm
+going to argue that it is very unlikely to break things, and likely to fix
+*far* more then it breaks.
+
+In no particular order, various reasons follow:
+
+(a) I've long had a bug assigned to myself to debug a super rare kernel crash
+on Android Pixel phones which can (per stacktrace) be traced back to BPF clat
+IPv6 to IPv4 protocol conversion causing some sort of ugly failure much later
+on during transmit deep in the GSO engine, AFAICT precisely because of this
+change to gso_size, though I've never been able to manually reproduce it. I
+believe it may be related to the particular network offload support of attached
+USB ethernet dongle being used for tethering off of an IPv6-only cellular
+connection. The reason might be we end up with more segments than max permitted,
+or with a GSO packet with only one segment... (either way we break some
+assumption and hit a BUG_ON)
+
+(b) There is no check that the gso_size is > 20 when reducing it by 20, so we
+might end up with a negative (or underflowing) gso_size or a gso_size of 0.
+This can't possibly be good. Indeed this is probably somehow exploitable (or
+at least can result in a kernel crash) by delivering crafted packets and perhaps
+triggering an infinite loop or a divide by zero... As a reminder: gso_size (MSS)
+is related to MTU, but not directly derived from it: gso_size/MSS may be
+significantly smaller then one would get by deriving from local MTU. And on
+some NICs (which do loose MTU checking on receive, it may even potentially be
+larger, for example my work pc with 1500 MTU can receive 1520 byte frames [and
+sometimes does due to bugs in a vendor plat46 implementation]). Indeed even just
+going from 21 to 1 is potentially problematic because it increases the number
+of segments by a factor of 21 (think DoS, or some other crash due to too many
+segments).
+
+(c) It's always safe to not increase the gso_size, because it doesn't result in
+the max packet size increasing. So the skb_increase_gso_size() call was always
+unnecessary for correctness (and outright undesirable, see later). As such the
+only part which is potentially dangerous (ie. could cause backwards compatibility
+issues) is the removal of the skb_decrease_gso_size() call.
+
+(d) If the packets are ultimately destined to the local device, then there is
+absolutely no benefit to playing around with gso_size. It only matters if the
+packets will egress the device. ie. we're either forwarding, or transmitting
+from the device.
+
+(e) This logic only triggers for packets which are GSO. It does not trigger for
+skbs which are not GSO. It will not convert a non-GSO MTU sized packet into a
+GSO packet (and you don't even know what the MTU is, so you can't even fix it).
+As such your transmit path must *already* be able to handle an MTU 20 bytes
+larger then your receive path (for IPv4 to IPv6 translation) - and indeed 28
+bytes larger due to IPv4 fragments. Thus removing the skb_decrease_gso_size()
+call doesn't actually increase the size of the packets your transmit side must
+be able to handle. ie. to handle non-GSO max-MTU packets, the IPv4/IPv6 device/
+route MTUs must already be set correctly. Since for example with an IPv4 egress
+MTU of 1500, IPv4 to IPv6 translation will already build 1520 byte IPv6 frames,
+so you need a 1520 byte device MTU. This means if your IPv6 device's egress
+MTU is 1280, your IPv4 route must be 1260 (and actually 1252, because of the
+need to handle fragments). This is to handle normal non-GSO packets. Thus the
+reduction is simply not needed for GSO packets, because when they're correctly
+built, they will already be the right size.
+
+(f) TSO/GSO should be able to exactly undo GRO: the number of packets (TCP
+segments) should not be modified, so that TCP's MSS counting works correctly
+(this matters for congestion control). If protocol conversion changes the
+gso_size, then the number of TCP segments may increase or decrease. Packet loss
+after protocol conversion can result in partial loss of MSS segments that the
+sender sent. How's the sending TCP stack going to react to receiving ACKs/SACKs
+in the middle of the segments it sent?
+
+(g) skb_{decrease,increase}_gso_size() are already no-ops for GSO_BY_FRAGS
+case (besides triggering WARN_ON_ONCE). This means you already cannot guarantee
+that gso_size (and thus resulting packet MTU) is changed. ie. you must assume
+it won't be changed.
+
+(h) changing gso_size is outright buggy for UDP GSO packets, where framing
+matters (I believe that's also the case for SCTP, but it's already excluded
+by [g]). So the only remaining case is TCP, which also doesn't want it
+(see [f]).
+
+(i) see also the reasoning on the previous attempt at fixing this
+(commit fa7b83bf3b156c767f3e4a25bbf3817b08f3ff8e) which shows that the current
+behaviour causes TCP packet loss:
+
+ In the forwarding path GRO -> BPF 6 to 4 -> GSO for TCP traffic, the
+ coalesced packet payload can be > MSS, but < MSS + 20.
+
+ bpf_skb_proto_6_to_4() will upgrade the MSS and it can be > the payload
+ length. After then tcp_gso_segment checks for the payload length if it
+ is <= MSS. The condition is causing the packet to be dropped.
+
+ tcp_gso_segment():
+ [...]
+ mss = skb_shinfo(skb)->gso_size;
+ if (unlikely(skb->len <= mss)) goto out;
+ [...]
+
+Thus changing the gso_size is simply a very bad idea. Increasing is unnecessary
+and buggy, and decreasing can go negative.
+
+Fixes: 6578171a7ff0 ("bpf: add bpf_skb_change_proto helper")
+Signed-off-by: Maciej Żenczykowski <maze@google.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Dongseok Yi <dseok.yi@samsung.com>
+Cc: Willem de Bruijn <willemb@google.com>
+Link: https://lore.kernel.org/bpf/CANP3RGfjLikQ6dg=YpBU0OeHvyv7JOki7CyOUS9modaXAi-9vQ@mail.gmail.com
+Link: https://lore.kernel.org/bpf/20210617000953.2787453-2-zenczykowski@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/filter.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 65ab4e21c087..6541358a770b 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -3263,8 +3263,6 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb)
+ shinfo->gso_type |= SKB_GSO_TCPV6;
+ }
+
+- /* Due to IPv6 header, MSS needs to be downgraded. */
+- skb_decrease_gso_size(shinfo, len_diff);
+ /* Header must be checked, and gso_segs recomputed. */
+ shinfo->gso_type |= SKB_GSO_DODGY;
+ shinfo->gso_segs = 0;
+@@ -3304,8 +3302,6 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb)
+ shinfo->gso_type |= SKB_GSO_TCPV4;
+ }
+
+- /* Due to IPv4 header, MSS can be upgraded. */
+- skb_increase_gso_size(shinfo, len_diff);
+ /* Header must be checked, and gso_segs recomputed. */
+ shinfo->gso_type |= SKB_GSO_DODGY;
+ shinfo->gso_segs = 0;
+--
+2.30.2
+
--- /dev/null
+From 0254ae67e658724fc47df5744e9f088ce05695df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Jun 2021 21:34:39 +0700
+Subject: bpf: Fix integer overflow in argument calculation for
+ bpf_map_area_alloc
+
+From: Bui Quang Minh <minhquangbui99@gmail.com>
+
+[ Upstream commit 7dd5d437c258bbf4cc15b35229e5208b87b8b4e0 ]
+
+In 32-bit architecture, the result of sizeof() is a 32-bit integer so
+the expression becomes the multiplication between 2 32-bit integer which
+can potentially leads to integer overflow. As a result,
+bpf_map_area_alloc() allocates less memory than needed.
+
+Fix this by casting 1 operand to u64.
+
+Fixes: 0d2c4f964050 ("bpf: Eliminate rlimit-based memory accounting for sockmap and sockhash maps")
+Fixes: 99c51064fb06 ("devmap: Use bpf_map_area_alloc() for allocating hash buckets")
+Fixes: 546ac1ffb70d ("bpf: add devmap, a map for storing net device references")
+Signed-off-by: Bui Quang Minh <minhquangbui99@gmail.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20210613143440.71975-1-minhquangbui99@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/devmap.c | 4 ++--
+ net/core/sock_map.c | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
+index aa516472ce46..3b45c23286c0 100644
+--- a/kernel/bpf/devmap.c
++++ b/kernel/bpf/devmap.c
+@@ -92,7 +92,7 @@ static struct hlist_head *dev_map_create_hash(unsigned int entries,
+ int i;
+ struct hlist_head *hash;
+
+- hash = bpf_map_area_alloc(entries * sizeof(*hash), numa_node);
++ hash = bpf_map_area_alloc((u64) entries * sizeof(*hash), numa_node);
+ if (hash != NULL)
+ for (i = 0; i < entries; i++)
+ INIT_HLIST_HEAD(&hash[i]);
+@@ -143,7 +143,7 @@ static int dev_map_init_map(struct bpf_dtab *dtab, union bpf_attr *attr)
+
+ spin_lock_init(&dtab->index_lock);
+ } else {
+- dtab->netdev_map = bpf_map_area_alloc(dtab->map.max_entries *
++ dtab->netdev_map = bpf_map_area_alloc((u64) dtab->map.max_entries *
+ sizeof(struct bpf_dtab_netdev *),
+ dtab->map.numa_node);
+ if (!dtab->netdev_map)
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c
+index 6f1b82b8ad49..60decd6420ca 100644
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -48,7 +48,7 @@ static struct bpf_map *sock_map_alloc(union bpf_attr *attr)
+ bpf_map_init_from_attr(&stab->map, attr);
+ raw_spin_lock_init(&stab->lock);
+
+- stab->sks = bpf_map_area_alloc(stab->map.max_entries *
++ stab->sks = bpf_map_area_alloc((u64) stab->map.max_entries *
+ sizeof(struct sock *),
+ stab->map.numa_node);
+ if (!stab->sks) {
+--
+2.30.2
+
--- /dev/null
+From d32b10e8775f95cc98b1337e7036338c7f06d6a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jun 2021 23:14:04 -0700
+Subject: bpf: Fix libelf endian handling in resolv_btfids
+
+From: Tony Ambardar <tony.ambardar@gmail.com>
+
+[ Upstream commit 61e8aeda9398925f8c6fc290585bdd9727d154c4 ]
+
+The vmlinux ".BTF_ids" ELF section is declared in btf_ids.h to hold a list
+of zero-filled BTF IDs, which is then patched at link-time with correct
+values by resolv_btfids. The section is flagged as "allocable" to preclude
+compression, but notably the section contents (BTF IDs) are untyped.
+
+When patching the BTF IDs, resolve_btfids writes in host-native endianness
+and relies on libelf for any required translation on reading and updating
+vmlinux. However, since the type of the .BTF_ids section content defaults
+to ELF_T_BYTE (i.e. unsigned char), no translation occurs. This results in
+incorrect patched values when cross-compiling to non-native endianness,
+and can manifest as kernel Oops and test failures which are difficult to
+troubleshoot [1].
+
+Explicitly set the type of patched data to ELF_T_WORD, the architecture-
+neutral ELF type corresponding to the u32 BTF IDs. This enables libelf to
+transparently perform any needed endian conversions.
+
+Fixes: fbbb68de80a4 ("bpf: Add resolve_btfids tool to resolve BTF IDs in ELF object")
+Signed-off-by: Tony Ambardar <Tony.Ambardar@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Frank Eigler <fche@redhat.com>
+Cc: Mark Wielaard <mark@klomp.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Yonghong Song <yhs@fb.com>
+Link: https://lore.kernel.org/bpf/CAPGftE_eY-Zdi3wBcgDfkz_iOr1KF10n=9mJHm1_a_PykcsoeA@mail.gmail.com [1]
+Link: https://lore.kernel.org/bpf/20210618061404.818569-1-Tony.Ambardar@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/resolve_btfids/main.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
+index 7550fd9c3188..3ad9301b0f00 100644
+--- a/tools/bpf/resolve_btfids/main.c
++++ b/tools/bpf/resolve_btfids/main.c
+@@ -655,6 +655,9 @@ static int symbols_patch(struct object *obj)
+ if (sets_patch(obj))
+ return -1;
+
++ /* Set type to ensure endian translation occurs. */
++ obj->efile.idlist->d_type = ELF_T_WORD;
++
+ elf_flagdata(obj->efile.idlist, ELF_C_SET, ELF_F_DIRTY);
+
+ err = elf_update(obj->efile.elf, ELF_C_WRITE);
+--
+2.30.2
+
--- /dev/null
+From 2c414852e35cafbd2bc6db9a8da4a3fcf3d88ee0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jun 2021 15:55:00 -0700
+Subject: bpf: Fix null ptr deref with mixed tail calls and subprogs
+
+From: John Fastabend <john.fastabend@gmail.com>
+
+[ Upstream commit 7506d211b932870155bcb39e3dd9e39fab45a7c7 ]
+
+The sub-programs prog->aux->poke_tab[] is populated in jit_subprogs() and
+then used when emitting 'BPF_JMP|BPF_TAIL_CALL' insn->code from the
+individual JITs. The poke_tab[] to use is stored in the insn->imm by
+the code adding it to that array slot. The JIT then uses imm to find the
+right entry for an individual instruction. In the x86 bpf_jit_comp.c
+this is done by calling emit_bpf_tail_call_direct with the poke_tab[]
+of the imm value.
+
+However, we observed the below null-ptr-deref when mixing tail call
+programs with subprog programs. For this to happen we just need to
+mix bpf-2-bpf calls and tailcalls with some extra calls or instructions
+that would be patched later by one of the fixup routines. So whats
+happening?
+
+Before the fixup_call_args() -- where the jit op is done -- various
+code patching is done by do_misc_fixups(). This may increase the
+insn count, for example when we patch map_lookup_up using map_gen_lookup
+hook. This does two things. First, it means the instruction index,
+insn_idx field, of a tail call instruction will move by a 'delta'.
+
+In verifier code,
+
+ struct bpf_jit_poke_descriptor desc = {
+ .reason = BPF_POKE_REASON_TAIL_CALL,
+ .tail_call.map = BPF_MAP_PTR(aux->map_ptr_state),
+ .tail_call.key = bpf_map_key_immediate(aux),
+ .insn_idx = i + delta,
+ };
+
+Then subprog start values subprog_info[i].start will be updated
+with the delta and any poke descriptor index will also be updated
+with the delta in adjust_poke_desc(). If we look at the adjust
+subprog starts though we see its only adjusted when the delta
+occurs before the new instructions,
+
+ /* NOTE: fake 'exit' subprog should be updated as well. */
+ for (i = 0; i <= env->subprog_cnt; i++) {
+ if (env->subprog_info[i].start <= off)
+ continue;
+
+Earlier subprograms are not changed because their start values
+are not moved. But, adjust_poke_desc() does the offset + delta
+indiscriminately. The result is poke descriptors are potentially
+corrupted.
+
+Then in jit_subprogs() we only populate the poke_tab[]
+when the above insn_idx is less than the next subprogram start. From
+above we corrupted our insn_idx so we might incorrectly assume a
+poke descriptor is not used in a subprogram omitting it from the
+subprogram. And finally when the jit runs it does the deref of poke_tab
+when emitting the instruction and crashes with below. Because earlier
+step omitted the poke descriptor.
+
+The fix is straight forward with above context. Simply move same logic
+from adjust_subprog_starts() into adjust_poke_descs() and only adjust
+insn_idx when needed.
+
+[ 82.396354] bpf_testmod: version magic '5.12.0-rc2alu+ SMP preempt mod_unload ' should be '5.12.0+ SMP preempt mod_unload '
+[ 82.623001] loop10: detected capacity change from 0 to 8
+[ 88.487424] ==================================================================
+[ 88.487438] BUG: KASAN: null-ptr-deref in do_jit+0x184a/0x3290
+[ 88.487455] Write of size 8 at addr 0000000000000008 by task test_progs/5295
+[ 88.487471] CPU: 7 PID: 5295 Comm: test_progs Tainted: G I 5.12.0+ #386
+[ 88.487483] Hardware name: Dell Inc. Precision 5820 Tower/002KVM, BIOS 1.9.2 01/24/2019
+[ 88.487490] Call Trace:
+[ 88.487498] dump_stack+0x93/0xc2
+[ 88.487515] kasan_report.cold+0x5f/0xd8
+[ 88.487530] ? do_jit+0x184a/0x3290
+[ 88.487542] do_jit+0x184a/0x3290
+ ...
+[ 88.487709] bpf_int_jit_compile+0x248/0x810
+ ...
+[ 88.487765] bpf_check+0x3718/0x5140
+ ...
+[ 88.487920] bpf_prog_load+0xa22/0xf10
+
+Fixes: a748c6975dea3 ("bpf: propagate poke descriptors to subprograms")
+Reported-by: Jussi Maki <joamaki@gmail.com>
+Signed-off-by: John Fastabend <john.fastabend@gmail.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Reviewed-by: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index c6a27574242d..6e2ebcb0d66f 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -11459,7 +11459,7 @@ static void adjust_subprog_starts(struct bpf_verifier_env *env, u32 off, u32 len
+ }
+ }
+
+-static void adjust_poke_descs(struct bpf_prog *prog, u32 len)
++static void adjust_poke_descs(struct bpf_prog *prog, u32 off, u32 len)
+ {
+ struct bpf_jit_poke_descriptor *tab = prog->aux->poke_tab;
+ int i, sz = prog->aux->size_poke_tab;
+@@ -11467,6 +11467,8 @@ static void adjust_poke_descs(struct bpf_prog *prog, u32 len)
+
+ for (i = 0; i < sz; i++) {
+ desc = &tab[i];
++ if (desc->insn_idx <= off)
++ continue;
+ desc->insn_idx += len - 1;
+ }
+ }
+@@ -11487,7 +11489,7 @@ static struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 of
+ if (adjust_insn_aux_data(env, new_prog, off, len))
+ return NULL;
+ adjust_subprog_starts(env, off, len);
+- adjust_poke_descs(new_prog, len);
++ adjust_poke_descs(new_prog, off, len);
+ return new_prog;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 85a9c55e3263bb8cdc496e56faf28b06551ea3fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 03:55:26 -0700
+Subject: bpf: Fix regression on BPF_OBJ_GET with non-O_RDWR flags
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maciej Żenczykowski <maze@google.com>
+
+[ Upstream commit 5dec6d96d12d33900ec315972c8e47a73bcc378d ]
+
+This reverts commit d37300ed1821 ("bpf: program: Refuse non-O_RDWR flags
+in BPF_OBJ_GET"). It breaks Android userspace which expects to be able to
+fetch programs with just read permissions.
+
+See: https://cs.android.com/android/platform/superproject/+/master:frameworks/libs/net/common/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h;drc=7005c764be23d31fa1d69e826b4a2f6689a8c81e;l=124
+
+Side-note: another option to fix it would be to extend bpf_prog_new_fd()
+and to pass in used file mode flags in the same way as we do for maps via
+bpf_map_new_fd(). Meaning, they'd end up in anon_inode_getfd() and thus
+would be retained for prog fd operations with bpf() syscall. Right now
+these flags are not checked with progs since they are immutable for their
+lifetime (as opposed to maps which can be updated from user space). In
+future this could potentially change with new features, but at that point
+it's still fine to do the bpf_prog_new_fd() extension when needed. For a
+simple stable fix, a revert is less churn.
+
+Fixes: d37300ed1821 ("bpf: program: Refuse non-O_RDWR flags in BPF_OBJ_GET")
+Signed-off-by: Maciej Żenczykowski <maze@google.com>
+[ Daniel: added side-note to commit message ]
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Lorenz Bauer <lmb@cloudflare.com>
+Acked-by: Greg Kroah-Hartman <gregkh@google.com>
+Link: https://lore.kernel.org/bpf/20210618105526.265003-1-zenczykowski@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/inode.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c
+index b4ebd60a6c16..80da1db47c68 100644
+--- a/kernel/bpf/inode.c
++++ b/kernel/bpf/inode.c
+@@ -543,7 +543,7 @@ int bpf_obj_get_user(const char __user *pathname, int flags)
+ return PTR_ERR(raw);
+
+ if (type == BPF_TYPE_PROG)
+- ret = (f_flags != O_RDWR) ? -EINVAL : bpf_prog_new_fd(raw);
++ ret = bpf_prog_new_fd(raw);
+ else if (type == BPF_TYPE_MAP)
+ ret = bpf_map_new_fd(raw, f_flags);
+ else if (type == BPF_TYPE_LINK)
+--
+2.30.2
+
--- /dev/null
+From 6d7d2a3e971b26c7f58586bc05cbcdbd2133e22e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 16:30:26 +0530
+Subject: bpf, x86: Fix extable offset calculation
+
+From: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
+
+[ Upstream commit 328aac5ecd119ede3633f7d17969b1ff34ccc784 ]
+
+Commit 4c5de127598e1 ("bpf: Emit explicit NULL pointer checks for PROBE_LDX
+instructions.") is emitting a couple of instructions before the actual load.
+Consider those additional instructions while calculating extable offset.
+
+Fixes: 4c5de127598e1 ("bpf: Emit explicit NULL pointer checks for PROBE_LDX instructions.")
+Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/20210622110026.1157847-1-ravi.bangoria@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/net/bpf_jit_comp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
+index 2a2e290fa5d8..a3d867f22153 100644
+--- a/arch/x86/net/bpf_jit_comp.c
++++ b/arch/x86/net/bpf_jit_comp.c
+@@ -1297,7 +1297,7 @@ st: if (is_imm8(insn->off))
+ emit_ldx(&prog, BPF_SIZE(insn->code), dst_reg, src_reg, insn->off);
+ if (BPF_MODE(insn->code) == BPF_PROBE_MEM) {
+ struct exception_table_entry *ex;
+- u8 *_insn = image + proglen;
++ u8 *_insn = image + proglen + (start_of_ldx - temp);
+ s64 delta;
+
+ /* populate jmp_offset for JMP above */
+--
+2.30.2
+
--- /dev/null
+From 834cc105d1b9044cd21dabf5acfbd4ea5636f360 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 12:09:18 +0800
+Subject: bpfilter: Specify the log level for the kmsg message
+
+From: Gary Lin <glin@suse.com>
+
+[ Upstream commit a196fa78a26571359740f701cf30d774eb8a72cb ]
+
+Per the kmsg document [0], if we don't specify the log level with a
+prefix "<N>" in the message string, the default log level will be
+applied to the message. Since the default level could be warning(4),
+this would make the log utility such as journalctl treat the message,
+"Started bpfilter", as a warning. To avoid confusion, this commit
+adds the prefix "<5>" to make the message always a notice.
+
+ [0] https://www.kernel.org/doc/Documentation/ABI/testing/dev-kmsg
+
+Fixes: 36c4357c63f3 ("net: bpfilter: print umh messages to /dev/kmsg")
+Reported-by: Martin Loviska <mloviska@suse.com>
+Signed-off-by: Gary Lin <glin@suse.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Dmitrii Banshchikov <me@ubique.spb.ru>
+Link: https://lore.kernel.org/bpf/20210623040918.8683-1-glin@suse.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bpfilter/main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bpfilter/main.c b/net/bpfilter/main.c
+index 05e1cfc1e5cd..291a92546246 100644
+--- a/net/bpfilter/main.c
++++ b/net/bpfilter/main.c
+@@ -57,7 +57,7 @@ int main(void)
+ {
+ debug_f = fopen("/dev/kmsg", "w");
+ setvbuf(debug_f, 0, _IOLBF, 0);
+- fprintf(debug_f, "Started bpfilter\n");
++ fprintf(debug_f, "<5>Started bpfilter\n");
+ loop();
+ fclose(debug_f);
+ return 0;
+--
+2.30.2
+
--- /dev/null
+From c558233f34022be0f2590b6dec93fe729a2b9337 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 May 2021 13:20:12 +0000
+Subject: brcmfmac: correctly report average RSSI in station info
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alvin Šipraga <ALSI@bang-olufsen.dk>
+
+[ Upstream commit 9a1590934d9a02e570636432b93052c0c035f31f ]
+
+The rx_lastpkt_rssi field provided by the firmware is suitable for
+NL80211_STA_INFO_{SIGNAL,CHAIN_SIGNAL}, while the rssi field is an
+average. Fix up the assignments and set the correct STA_INFO bits. This
+lets userspace know that the average RSSI is part of the station info.
+
+Fixes: cae355dc90db ("brcmfmac: Add RSSI information to get_station.")
+Signed-off-by: Alvin Šipraga <alsi@bang-olufsen.dk>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210506132010.3964484-2-alsi@bang-olufsen.dk
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../broadcom/brcm80211/brcmfmac/cfg80211.c | 36 ++++++++++---------
+ 1 file changed, 20 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+index afa75cb83221..d8822a01d277 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -2767,8 +2767,9 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
+ struct brcmf_sta_info_le sta_info_le;
+ u32 sta_flags;
+ u32 is_tdls_peer;
+- s32 total_rssi;
+- s32 count_rssi;
++ s32 total_rssi_avg = 0;
++ s32 total_rssi = 0;
++ s32 count_rssi = 0;
+ int rssi;
+ u32 i;
+
+@@ -2834,24 +2835,27 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES);
+ sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
+ }
+- total_rssi = 0;
+- count_rssi = 0;
+ for (i = 0; i < BRCMF_ANT_MAX; i++) {
+- if (sta_info_le.rssi[i]) {
+- sinfo->chains |= BIT(count_rssi);
+- sinfo->chain_signal_avg[count_rssi] =
+- sta_info_le.rssi[i];
+- sinfo->chain_signal[count_rssi] =
+- sta_info_le.rssi[i];
+- total_rssi += sta_info_le.rssi[i];
+- count_rssi++;
+- }
++ if (sta_info_le.rssi[i] == 0 ||
++ sta_info_le.rx_lastpkt_rssi[i] == 0)
++ continue;
++ sinfo->chains |= BIT(count_rssi);
++ sinfo->chain_signal[count_rssi] =
++ sta_info_le.rx_lastpkt_rssi[i];
++ sinfo->chain_signal_avg[count_rssi] =
++ sta_info_le.rssi[i];
++ total_rssi += sta_info_le.rx_lastpkt_rssi[i];
++ total_rssi_avg += sta_info_le.rssi[i];
++ count_rssi++;
+ }
+ if (count_rssi) {
+- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL);
+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
+- total_rssi /= count_rssi;
+- sinfo->signal = total_rssi;
++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG);
++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL);
++ sinfo->filled |=
++ BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG);
++ sinfo->signal = total_rssi / count_rssi;
++ sinfo->signal_avg = total_rssi_avg / count_rssi;
+ } else if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
+ &ifp->vif->sme_state)) {
+ memset(&scb_val, 0, sizeof(scb_val));
+--
+2.30.2
+
--- /dev/null
+From 21abb0d8ded438891d80500e24070864150600ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Jun 2021 16:43:05 +0200
+Subject: brcmfmac: Delete second brcm folder hierarchy
+
+From: Matthias Brugger <mbrugger@suse.com>
+
+[ Upstream commit 4a26aafe4886a4ec9965171c280ce16df30dc362 ]
+
+BRCMF_FW_DEFAULT_PATH already defines the brcm folder, delete the second
+folder to match with Linux firmware repository layout.
+
+Fixes: 75729e110e68 ("brcmfmac: expose firmware config files through modinfo")
+Signed-off-by: Matthias Brugger <mbrugger@suse.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210602144305.4481-1-matthias.bgg@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+index 3a1c98a046f0..faf5f8e5eee3 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -626,8 +626,8 @@ BRCMF_FW_DEF(4373, "brcmfmac4373-sdio");
+ BRCMF_FW_DEF(43012, "brcmfmac43012-sdio");
+
+ /* firmware config files */
+-MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac*-sdio.*.txt");
+-MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac*-pcie.*.txt");
++MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-sdio.*.txt");
++MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.txt");
+
+ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
+ BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143),
+--
+2.30.2
+
--- /dev/null
+From ca8b8af7f46a599cbd3a7fd9e95c7a592ebf18a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Jun 2021 18:01:28 +0800
+Subject: brcmfmac: Fix a double-free in brcmf_sdio_bus_reset
+
+From: Tong Tiangen <tongtiangen@huawei.com>
+
+[ Upstream commit 7ea7a1e05c7ff5ffc9f9ec1f0849f6ceb7fcd57c ]
+
+brcmf_sdiod_remove has been called inside brcmf_sdiod_probe when fails,
+so there's no need to call another one. Otherwise, sdiodev->freezer
+would be double freed.
+
+Fixes: 7836102a750a ("brcmfmac: reset SDIO bus on a firmware crash")
+Signed-off-by: Tong Tiangen <tongtiangen@huawei.com>
+Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210601100128.69561-1-tongtiangen@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+index 16ed325795a8..3a1c98a046f0 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -4162,7 +4162,6 @@ static int brcmf_sdio_bus_reset(struct device *dev)
+ if (ret) {
+ brcmf_err("Failed to probe after sdio device reset: ret %d\n",
+ ret);
+- brcmf_sdiod_remove(sdiodev);
+ }
+
+ return ret;
+--
+2.30.2
+
--- /dev/null
+From 9e6e1fe3a7a962a868cdb09ab2cc0bb9c5320033 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 May 2021 13:20:12 +0000
+Subject: brcmfmac: fix setting of station info chains bitmask
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alvin Šipraga <ALSI@bang-olufsen.dk>
+
+[ Upstream commit feb45643762172110cb3a44f99dd54304f33b711 ]
+
+The sinfo->chains field is a bitmask for filled values in chain_signal
+and chain_signal_avg, not a count. Treat it as such so that the driver
+can properly report per-chain RSSI information.
+
+Before (MIMO mode):
+
+ $ iw dev wlan0 station dump
+ ...
+ signal: -51 [-51] dBm
+
+After (MIMO mode):
+
+ $ iw dev wlan0 station dump
+ ...
+ signal: -53 [-53, -54] dBm
+
+Fixes: cae355dc90db ("brcmfmac: Add RSSI information to get_station.")
+Signed-off-by: Alvin Šipraga <alsi@bang-olufsen.dk>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210506132010.3964484-1-alsi@bang-olufsen.dk
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+index f4405d7861b6..afa75cb83221 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -2838,6 +2838,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
+ count_rssi = 0;
+ for (i = 0; i < BRCMF_ANT_MAX; i++) {
+ if (sta_info_le.rssi[i]) {
++ sinfo->chains |= BIT(count_rssi);
+ sinfo->chain_signal_avg[count_rssi] =
+ sta_info_le.rssi[i];
+ sinfo->chain_signal[count_rssi] =
+@@ -2848,8 +2849,6 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
+ }
+ if (count_rssi) {
+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL);
+- sinfo->chains = count_rssi;
+-
+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
+ total_rssi /= count_rssi;
+ sinfo->signal = total_rssi;
+--
+2.30.2
+
--- /dev/null
+From 8f8e008a75e89138f730c990550454e47b189335 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 May 2021 22:58:30 +0200
+Subject: brcmsmac: mac80211_if: Fix a resource leak in an error handling path
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 9a25344d5177c2b9285532236dc3d10a091f39a8 ]
+
+If 'brcms_attach()' fails, we must undo the previous 'ieee80211_alloc_hw()'
+as already done in the remove function.
+
+Fixes: 5b435de0d786 ("net: wireless: add brcm80211 drivers")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/8fbc171a1a493b38db5a6f0873c6021fca026a6c.1620852921.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
+index 39f3af2d0439..eadac0f5590f 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
+@@ -1220,6 +1220,7 @@ static int brcms_bcma_probe(struct bcma_device *pdev)
+ {
+ struct brcms_info *wl;
+ struct ieee80211_hw *hw;
++ int ret;
+
+ dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n",
+ pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class,
+@@ -1244,11 +1245,16 @@ static int brcms_bcma_probe(struct bcma_device *pdev)
+ wl = brcms_attach(pdev);
+ if (!wl) {
+ pr_err("%s: brcms_attach failed!\n", __func__);
+- return -ENODEV;
++ ret = -ENODEV;
++ goto err_free_ieee80211;
+ }
+ brcms_led_register(wl);
+
+ return 0;
++
++err_free_ieee80211:
++ ieee80211_free_hw(hw);
++ return ret;
+ }
+
+ static int brcms_suspend(struct bcma_device *pdev)
+--
+2.30.2
+
--- /dev/null
+From aea8f90d30d74766d362df0092845ca07d9452c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 16:44:09 -0400
+Subject: btrfs: abort transaction if we fail to update the delayed inode
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit 04587ad9bef6ce9d510325b4ba9852b6129eebdb ]
+
+If we fail to update the delayed inode we need to abort the transaction,
+because we could leave an inode with the improper counts or some other
+such corruption behind.
+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/delayed-inode.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
+index 3091540fc22a..3bb8b919d2c1 100644
+--- a/fs/btrfs/delayed-inode.c
++++ b/fs/btrfs/delayed-inode.c
+@@ -1050,6 +1050,14 @@ err_out:
+ btrfs_delayed_inode_release_metadata(fs_info, node, (ret < 0));
+ btrfs_release_delayed_inode(node);
+
++ /*
++ * If we fail to update the delayed inode we need to abort the
++ * transaction, because we could leave the inode with the improper
++ * counts behind.
++ */
++ if (ret && ret != -ENOENT)
++ btrfs_abort_transaction(trans, ret);
++
+ return ret;
+
+ search:
+--
+2.30.2
+
--- /dev/null
+From 8bd560c8bbd370911285f9cd32b0ed36023679a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 May 2021 11:21:31 -0400
+Subject: btrfs: always abort the transaction if we abort a trans handle
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit 5963ffcaf383134985a5a2d8a4baa582d3999e0a ]
+
+While stress testing our error handling I noticed that sometimes we
+would still commit the transaction even though we had aborted the
+transaction.
+
+Currently we track if a trans handle has dirtied any metadata, and if it
+hasn't we mark the filesystem as having an error (so no new transactions
+can be started), but we will allow the current transaction to complete
+as we do not mark the transaction itself as having been aborted.
+
+This sounds good in theory, but we were not properly tracking IO errors
+in btrfs_finish_ordered_io, and thus committing the transaction with
+bogus free space data. This isn't necessarily a problem per-se with the
+free space cache, as the other guards in place would have kept us from
+accepting the free space cache as valid, but highlights a real world
+case where we had a bug and could have corrupted the filesystem because
+of it.
+
+This "skip abort on empty trans handle" is nice in theory, but assumes
+we have perfect error handling everywhere, which we clearly do not.
+Also we do not allow further transactions to be started, so all this
+does is save the last transaction that was happening, which doesn't
+necessarily gain us anything other than the potential for real
+corruption.
+
+Remove this particular bit of code, if we decide we need to abort the
+transaction then abort the current one and keep us from doing real harm
+to the file system, regardless of whether this specific trans handle
+dirtied anything or not.
+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/ctree.c | 5 +----
+ fs/btrfs/extent-tree.c | 1 -
+ fs/btrfs/super.c | 11 -----------
+ fs/btrfs/transaction.c | 8 --------
+ fs/btrfs/transaction.h | 1 -
+ 5 files changed, 1 insertion(+), 25 deletions(-)
+
+diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
+index a484fb72a01f..4bc3ca2cbd7d 100644
+--- a/fs/btrfs/ctree.c
++++ b/fs/btrfs/ctree.c
+@@ -596,7 +596,6 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
+ trans->transid, fs_info->generation);
+
+ if (!should_cow_block(trans, root, buf)) {
+- trans->dirty = true;
+ *cow_ret = buf;
+ return 0;
+ }
+@@ -1788,10 +1787,8 @@ again:
+ * then we don't want to set the path blocking,
+ * so we test it here
+ */
+- if (!should_cow_block(trans, root, b)) {
+- trans->dirty = true;
++ if (!should_cow_block(trans, root, b))
+ goto cow_done;
+- }
+
+ /*
+ * must have write locks on this node and the
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index 3d5c35e4cb76..d2f39a122d89 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -4784,7 +4784,6 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+ set_extent_dirty(&trans->transaction->dirty_pages, buf->start,
+ buf->start + buf->len - 1, GFP_NOFS);
+ }
+- trans->dirty = true;
+ /* this returns a buffer locked for blocking */
+ return buf;
+ }
+diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
+index 4a396c1147f1..bc613218c8c5 100644
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -299,17 +299,6 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans,
+ struct btrfs_fs_info *fs_info = trans->fs_info;
+
+ WRITE_ONCE(trans->aborted, errno);
+- /* Nothing used. The other threads that have joined this
+- * transaction may be able to continue. */
+- if (!trans->dirty && list_empty(&trans->new_bgs)) {
+- const char *errstr;
+-
+- errstr = btrfs_decode_error(errno);
+- btrfs_warn(fs_info,
+- "%s:%d: Aborting unused transaction(%s).",
+- function, line, errstr);
+- return;
+- }
+ WRITE_ONCE(trans->transaction->aborted, errno);
+ /* Wake up anybody who may be waiting on this transaction */
+ wake_up(&fs_info->transaction_wait);
+diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
+index b423d3b30173..37450c7644ca 100644
+--- a/fs/btrfs/transaction.c
++++ b/fs/btrfs/transaction.c
+@@ -2076,14 +2076,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
+
+ ASSERT(refcount_read(&trans->use_count) == 1);
+
+- /*
+- * Some places just start a transaction to commit it. We need to make
+- * sure that if this commit fails that the abort code actually marks the
+- * transaction as failed, so set trans->dirty to make the abort code do
+- * the right thing.
+- */
+- trans->dirty = true;
+-
+ /* Stop the commit early if ->aborted is set */
+ if (TRANS_ABORTED(cur_trans)) {
+ ret = cur_trans->aborted;
+diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
+index 364cfbb4c5c5..c49e2266b28b 100644
+--- a/fs/btrfs/transaction.h
++++ b/fs/btrfs/transaction.h
+@@ -143,7 +143,6 @@ struct btrfs_trans_handle {
+ bool allocating_chunk;
+ bool can_flush_pending_bgs;
+ bool reloc_reserved;
+- bool dirty;
+ bool in_fsync;
+ struct btrfs_root *root;
+ struct btrfs_fs_info *fs_info;
+--
+2.30.2
+
--- /dev/null
+From b524f44ee742f9368ec27463714ccec6ea54a924 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jul 2020 18:38:05 +0200
+Subject: btrfs: clear log tree recovering status if starting transaction fails
+
+From: David Sterba <dsterba@suse.com>
+
+[ Upstream commit 1aeb6b563aea18cd55c73cf666d1d3245a00f08c ]
+
+When a log recovery is in progress, lots of operations have to take that
+into account, so we keep this status per tree during the operation. Long
+time ago error handling revamp patch 79787eaab461 ("btrfs: replace many
+BUG_ONs with proper error handling") removed clearing of the status in
+an error branch. Add it back as was intended in e02119d5a7b4 ("Btrfs:
+Add a write ahead tree log to optimize synchronous operations").
+
+There are probably no visible effects, log replay is done only during
+mount and if it fails all structures are cleared so the stale status
+won't be kept.
+
+Fixes: 79787eaab461 ("btrfs: replace many BUG_ONs with proper error handling")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: Anand Jain <anand.jain@oracle.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/tree-log.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
+index dbcf8bb2f3b9..760d950752f5 100644
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -6371,6 +6371,7 @@ next:
+ error:
+ if (wc.trans)
+ btrfs_end_transaction(wc.trans);
++ clear_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags);
+ btrfs_free_path(path);
+ return ret;
+ }
+--
+2.30.2
+
--- /dev/null
+From 76c8ac71ffaa6aa6b85b02ffc05a03e396e787c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jun 2021 05:23:02 +0000
+Subject: btrfs: disable build on platforms having page size 256K
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit b05fbcc36be1f8597a1febef4892053a0b2f3f60 ]
+
+With a config having PAGE_SIZE set to 256K, BTRFS build fails
+with the following message
+
+ include/linux/compiler_types.h:326:38: error: call to
+ '__compiletime_assert_791' declared with attribute error:
+ BUILD_BUG_ON failed: (BTRFS_MAX_COMPRESSED % PAGE_SIZE) != 0
+
+BTRFS_MAX_COMPRESSED being 128K, BTRFS cannot support platforms with
+256K pages at the time being.
+
+There are two platforms that can select 256K pages:
+ - hexagon
+ - powerpc
+
+Disable BTRFS when 256K page size is selected. Supporting this would
+require changes to the subpage mode that's currently being developed.
+Given that 256K is many times larger than page sizes commonly used and
+for what the algorithms and structures have been tuned, it's out of
+scope and disabling build is a reasonable option.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+[ update changelog ]
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/Kconfig | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/btrfs/Kconfig b/fs/btrfs/Kconfig
+index 68b95ad82126..520a0f6a7d9e 100644
+--- a/fs/btrfs/Kconfig
++++ b/fs/btrfs/Kconfig
+@@ -18,6 +18,8 @@ config BTRFS_FS
+ select RAID6_PQ
+ select XOR_BLOCKS
+ select SRCU
++ depends on !PPC_256K_PAGES # powerpc
++ depends on !PAGE_SIZE_256KB # hexagon
+
+ help
+ Btrfs is a general purpose copy-on-write filesystem with extents,
+--
+2.30.2
+
--- /dev/null
+From 9c342ea9c41d1835609e8e99016760c08a96e26b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 May 2021 16:50:55 +0800
+Subject: btrfs: don't clear page extent mapped if we're not invalidating the
+ full page
+
+From: Qu Wenruo <wqu@suse.com>
+
+[ Upstream commit bcd77455d590eaa0422a5e84ae852007cfce574a ]
+
+[BUG]
+With current btrfs subpage rw support, the following script can lead to
+fs hang:
+
+ $ mkfs.btrfs -f -s 4k $dev
+ $ mount $dev -o nospace_cache $mnt
+ $ fsstress -w -n 100 -p 1 -s 1608140256 -v -d $mnt
+
+The fs will hang at btrfs_start_ordered_extent().
+
+[CAUSE]
+In above test case, btrfs_invalidate() will be called with the following
+parameters:
+
+ offset = 0 length = 53248 page dirty = 1 subpage dirty bitmap = 0x2000
+
+Since @offset is 0, btrfs_invalidate() will try to invalidate the full
+page, and finally call clear_page_extent_mapped() which will detach
+subpage structure from the page.
+
+And since the page no longer has subpage structure, the subpage dirty
+bitmap will be cleared, preventing the dirty range from being written
+back, thus no way to wake up the ordered extent.
+
+[FIX]
+Just follow other filesystems, only to invalidate the page if the range
+covers the full page.
+
+There are cases like truncate_setsize() which can call
+btrfs_invalidatepage() with offset == 0 and length != 0 for the last
+page of an inode.
+
+Although the old code will still try to invalidate the full page, we are
+still safe to just wait for ordered extent to finish.
+So it shouldn't cause extra problems.
+
+Tested-by: Ritesh Harjani <riteshh@linux.ibm.com> # [ppc64]
+Tested-by: Anand Jain <anand.jain@oracle.com> # [aarch64]
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/inode.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index fc6325efe2e8..9229549697ce 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -8390,7 +8390,19 @@ static void btrfs_invalidatepage(struct page *page, unsigned int offset,
+ */
+ wait_on_page_writeback(page);
+
+- if (offset) {
++ /*
++ * For subpage case, we have call sites like
++ * btrfs_punch_hole_lock_range() which passes range not aligned to
++ * sectorsize.
++ * If the range doesn't cover the full page, we don't need to and
++ * shouldn't clear page extent mapped, as page->private can still
++ * record subpage dirty bits for other part of the range.
++ *
++ * For cases that can invalidate the full even the range doesn't
++ * cover the full page, like invalidating the last page, we're
++ * still safe to wait for ordered extent to finish.
++ */
++ if (!(offset == 0 && length == PAGE_SIZE)) {
+ btrfs_releasepage(page, GFP_NOFS);
+ return;
+ }
+--
+2.30.2
+
--- /dev/null
+From a080f66b7f8b531a1be4cf530e576742319987f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 16:44:08 -0400
+Subject: btrfs: fix error handling in __btrfs_update_delayed_inode
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit bb385bedded3ccbd794559600de4a09448810f4a ]
+
+If we get an error while looking up the inode item we'll simply bail
+without cleaning up the delayed node. This results in this style of
+warning happening on commit:
+
+ WARNING: CPU: 0 PID: 76403 at fs/btrfs/delayed-inode.c:1365 btrfs_assert_delayed_root_empty+0x5b/0x90
+ CPU: 0 PID: 76403 Comm: fsstress Tainted: G W 5.13.0-rc1+ #373
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-2.fc32 04/01/2014
+ RIP: 0010:btrfs_assert_delayed_root_empty+0x5b/0x90
+ RSP: 0018:ffffb8bb815a7e50 EFLAGS: 00010286
+ RAX: 0000000000000000 RBX: ffff95d6d07e1888 RCX: ffff95d6c0fa3000
+ RDX: 0000000000000002 RSI: 000000000029e91c RDI: ffff95d6c0fc8060
+ RBP: ffff95d6c0fc8060 R08: 00008d6d701a2c1d R09: 0000000000000000
+ R10: ffff95d6d1760ea0 R11: 0000000000000001 R12: ffff95d6c15a4d00
+ R13: ffff95d6c0fa3000 R14: 0000000000000000 R15: ffffb8bb815a7e90
+ FS: 00007f490e8dbb80(0000) GS:ffff95d73bc00000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007f6e75555cb0 CR3: 00000001101ce001 CR4: 0000000000370ef0
+ Call Trace:
+ btrfs_commit_transaction+0x43c/0xb00
+ ? finish_wait+0x80/0x80
+ ? vfs_fsync_range+0x90/0x90
+ iterate_supers+0x8c/0x100
+ ksys_sync+0x50/0x90
+ __do_sys_sync+0xa/0x10
+ do_syscall_64+0x3d/0x80
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+Because the iref isn't dropped and this leaves an elevated node->count,
+so any release just re-queues it onto the delayed inodes list. Fix this
+by going to the out label to handle the proper cleanup of the delayed
+node.
+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/delayed-inode.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
+index 1a88f6214ebc..3091540fc22a 100644
+--- a/fs/btrfs/delayed-inode.c
++++ b/fs/btrfs/delayed-inode.c
+@@ -1009,12 +1009,10 @@ static int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
+ nofs_flag = memalloc_nofs_save();
+ ret = btrfs_lookup_inode(trans, root, path, &key, mod);
+ memalloc_nofs_restore(nofs_flag);
+- if (ret > 0) {
+- btrfs_release_path(path);
+- return -ENOENT;
+- } else if (ret < 0) {
+- return ret;
+- }
++ if (ret > 0)
++ ret = -ENOENT;
++ if (ret < 0)
++ goto out;
+
+ leaf = path->nodes[0];
+ inode_item = btrfs_item_ptr(leaf, path->slots[0],
+--
+2.30.2
+
--- /dev/null
+From c8e07d10d221aa84cdc6a8524617d83ff364881c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 May 2021 16:50:54 +0800
+Subject: btrfs: fix the filemap_range_has_page() call in
+ btrfs_punch_hole_lock_range()
+
+From: Qu Wenruo <wqu@suse.com>
+
+[ Upstream commit 0528476b6ac7832f31e2ed740a57ae31316b124e ]
+
+[BUG]
+With current subpage RW support, the following script can hang the fs
+with 64K page size.
+
+ # mkfs.btrfs -f -s 4k $dev
+ # mount $dev -o nospace_cache $mnt
+ # fsstress -w -n 50 -p 1 -s 1607749395 -d $mnt
+
+The kernel will do an infinite loop in btrfs_punch_hole_lock_range().
+
+[CAUSE]
+In btrfs_punch_hole_lock_range() we:
+
+- Truncate page cache range
+- Lock extent io tree
+- Wait any ordered extents in the range.
+
+We exit the loop until we meet all the following conditions:
+
+- No ordered extent in the lock range
+- No page is in the lock range
+
+The latter condition has a pitfall, it only works for sector size ==
+PAGE_SIZE case.
+
+While can't handle the following subpage case:
+
+ 0 32K 64K 96K 128K
+ | |///////||//////| ||
+
+lockstart=32K
+lockend=96K - 1
+
+In this case, although the range crosses 2 pages,
+truncate_pagecache_range() will invalidate no page at all, but only zero
+the [32K, 96K) range of the two pages.
+
+Thus filemap_range_has_page(32K, 96K-1) will always return true, thus we
+will never meet the loop exit condition.
+
+[FIX]
+Fix the problem by doing page alignment for the lock range.
+
+Function filemap_range_has_page() has already handled lend < lstart
+case, we only need to round up @lockstart, and round_down @lockend for
+truncate_pagecache_range().
+
+This modification should not change any thing for sector size ==
+PAGE_SIZE case, as in that case our range is already page aligned.
+
+Tested-by: Ritesh Harjani <riteshh@linux.ibm.com> # [ppc64]
+Tested-by: Anand Jain <anand.jain@oracle.com> # [aarch64]
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/file.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
+index 55f68422061d..7e6ed97a6d08 100644
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -2483,6 +2483,17 @@ static int btrfs_punch_hole_lock_range(struct inode *inode,
+ const u64 lockend,
+ struct extent_state **cached_state)
+ {
++ /*
++ * For subpage case, if the range is not at page boundary, we could
++ * have pages at the leading/tailing part of the range.
++ * This could lead to dead loop since filemap_range_has_page()
++ * will always return true.
++ * So here we need to do extra page alignment for
++ * filemap_range_has_page().
++ */
++ const u64 page_lockstart = round_up(lockstart, PAGE_SIZE);
++ const u64 page_lockend = round_down(lockend + 1, PAGE_SIZE) - 1;
++
+ while (1) {
+ struct btrfs_ordered_extent *ordered;
+ int ret;
+@@ -2503,7 +2514,7 @@ static int btrfs_punch_hole_lock_range(struct inode *inode,
+ (ordered->file_offset + ordered->num_bytes <= lockstart ||
+ ordered->file_offset > lockend)) &&
+ !filemap_range_has_page(inode->i_mapping,
+- lockstart, lockend)) {
++ page_lockstart, page_lockend)) {
+ if (ordered)
+ btrfs_put_ordered_extent(ordered);
+ break;
+--
+2.30.2
+
--- /dev/null
+From 8c5d84726f63689fc46808639b6588ab3b35e34d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Apr 2021 19:02:46 +0800
+Subject: btrfs: scrub: fix subpage repair error caused by hard coded PAGE_SIZE
+
+From: Qu Wenruo <wqu@suse.com>
+
+[ Upstream commit 8df507cbb5952719353c912a021b66c27641e90c ]
+
+[BUG]
+For the following file layout, scrub will not be able to repair all
+these two repairable error, but in fact make one corruption even
+unrepairable:
+
+ inode offset 0 4k 8K
+Mirror 1 |XXXXXX| |
+Mirror 2 | |XXXXXX|
+
+[CAUSE]
+The root cause is the hard coded PAGE_SIZE, which makes scrub repair to
+go crazy for subpage.
+
+For above case, when reading the first sector, we use PAGE_SIZE other
+than sectorsize to read, which makes us to read the full range [0, 64K).
+In fact, after 8K there may be no data at all, we can just get some
+garbage.
+
+Then when doing the repair, we also writeback a full page from mirror 2,
+this means, we will also writeback the corrupted data in mirror 2 back
+to mirror 1, leaving the range [4K, 8K) unrepairable.
+
+[FIX]
+This patch will modify the following PAGE_SIZE use with sectorsize:
+
+- scrub_print_warning_inode()
+ Remove the min() and replace PAGE_SIZE with sectorsize.
+ The min() makes no sense, as csum is done for the full sector with
+ padding.
+
+ This fixes a bug that subpage report extra length like:
+ checksum error at logical 298844160 on dev /dev/mapper/arm_nvme-test,
+ physical 575668224, root 5, inode 257, offset 0, length 12288, links 1 (path: file)
+
+ Where the error is only 1 sector.
+
+- scrub_handle_errored_block()
+ Comments with PAGE|page involved, all changed to sector.
+
+- scrub_setup_recheck_block()
+- scrub_repair_page_from_good_copy()
+- scrub_add_page_to_wr_bio()
+- scrub_wr_submit()
+- scrub_add_page_to_rd_bio()
+- scrub_block_complete()
+ Replace PAGE_SIZE with sectorsize.
+ This solves several problems where we read/write extra range for
+ subpage case.
+
+RAID56 code is excluded intentionally, as RAID56 has extra PAGE_SIZE
+usage, and is not really safe enough.
+Thus we will reject RAID56 for subpage in later commit.
+
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/scrub.c | 82 +++++++++++++++++++++++++-----------------------
+ 1 file changed, 42 insertions(+), 40 deletions(-)
+
+diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
+index 485cda3eb8d7..6af901539ef2 100644
+--- a/fs/btrfs/scrub.c
++++ b/fs/btrfs/scrub.c
+@@ -626,7 +626,6 @@ nomem:
+ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root,
+ void *warn_ctx)
+ {
+- u64 isize;
+ u32 nlink;
+ int ret;
+ int i;
+@@ -662,7 +661,6 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root,
+ eb = swarn->path->nodes[0];
+ inode_item = btrfs_item_ptr(eb, swarn->path->slots[0],
+ struct btrfs_inode_item);
+- isize = btrfs_inode_size(eb, inode_item);
+ nlink = btrfs_inode_nlink(eb, inode_item);
+ btrfs_release_path(swarn->path);
+
+@@ -691,12 +689,12 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root,
+ */
+ for (i = 0; i < ipath->fspath->elem_cnt; ++i)
+ btrfs_warn_in_rcu(fs_info,
+-"%s at logical %llu on dev %s, physical %llu, root %llu, inode %llu, offset %llu, length %llu, links %u (path: %s)",
++"%s at logical %llu on dev %s, physical %llu, root %llu, inode %llu, offset %llu, length %u, links %u (path: %s)",
+ swarn->errstr, swarn->logical,
+ rcu_str_deref(swarn->dev->name),
+ swarn->physical,
+ root, inum, offset,
+- min(isize - offset, (u64)PAGE_SIZE), nlink,
++ fs_info->sectorsize, nlink,
+ (char *)(unsigned long)ipath->fspath->val[i]);
+
+ btrfs_put_root(local_root);
+@@ -885,25 +883,25 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check)
+ * read all mirrors one after the other. This includes to
+ * re-read the extent or metadata block that failed (that was
+ * the cause that this fixup code is called) another time,
+- * page by page this time in order to know which pages
++ * sector by sector this time in order to know which sectors
+ * caused I/O errors and which ones are good (for all mirrors).
+ * It is the goal to handle the situation when more than one
+ * mirror contains I/O errors, but the errors do not
+ * overlap, i.e. the data can be repaired by selecting the
+- * pages from those mirrors without I/O error on the
+- * particular pages. One example (with blocks >= 2 * PAGE_SIZE)
+- * would be that mirror #1 has an I/O error on the first page,
+- * the second page is good, and mirror #2 has an I/O error on
+- * the second page, but the first page is good.
+- * Then the first page of the first mirror can be repaired by
+- * taking the first page of the second mirror, and the
+- * second page of the second mirror can be repaired by
+- * copying the contents of the 2nd page of the 1st mirror.
+- * One more note: if the pages of one mirror contain I/O
++ * sectors from those mirrors without I/O error on the
++ * particular sectors. One example (with blocks >= 2 * sectorsize)
++ * would be that mirror #1 has an I/O error on the first sector,
++ * the second sector is good, and mirror #2 has an I/O error on
++ * the second sector, but the first sector is good.
++ * Then the first sector of the first mirror can be repaired by
++ * taking the first sector of the second mirror, and the
++ * second sector of the second mirror can be repaired by
++ * copying the contents of the 2nd sector of the 1st mirror.
++ * One more note: if the sectors of one mirror contain I/O
+ * errors, the checksum cannot be verified. In order to get
+ * the best data for repairing, the first attempt is to find
+ * a mirror without I/O errors and with a validated checksum.
+- * Only if this is not possible, the pages are picked from
++ * Only if this is not possible, the sectors are picked from
+ * mirrors with I/O errors without considering the checksum.
+ * If the latter is the case, at the end, the checksum of the
+ * repaired area is verified in order to correctly maintain
+@@ -1060,26 +1058,26 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check)
+
+ /*
+ * In case of I/O errors in the area that is supposed to be
+- * repaired, continue by picking good copies of those pages.
+- * Select the good pages from mirrors to rewrite bad pages from
++ * repaired, continue by picking good copies of those sectors.
++ * Select the good sectors from mirrors to rewrite bad sectors from
+ * the area to fix. Afterwards verify the checksum of the block
+ * that is supposed to be repaired. This verification step is
+ * only done for the purpose of statistic counting and for the
+ * final scrub report, whether errors remain.
+ * A perfect algorithm could make use of the checksum and try
+- * all possible combinations of pages from the different mirrors
++ * all possible combinations of sectors from the different mirrors
+ * until the checksum verification succeeds. For example, when
+- * the 2nd page of mirror #1 faces I/O errors, and the 2nd page
++ * the 2nd sector of mirror #1 faces I/O errors, and the 2nd sector
+ * of mirror #2 is readable but the final checksum test fails,
+- * then the 2nd page of mirror #3 could be tried, whether now
++ * then the 2nd sector of mirror #3 could be tried, whether now
+ * the final checksum succeeds. But this would be a rare
+ * exception and is therefore not implemented. At least it is
+ * avoided that the good copy is overwritten.
+ * A more useful improvement would be to pick the sectors
+ * without I/O error based on sector sizes (512 bytes on legacy
+- * disks) instead of on PAGE_SIZE. Then maybe 512 byte of one
++ * disks) instead of on sectorsize. Then maybe 512 byte of one
+ * mirror could be repaired by taking 512 byte of a different
+- * mirror, even if other 512 byte sectors in the same PAGE_SIZE
++ * mirror, even if other 512 byte sectors in the same sectorsize
+ * area are unreadable.
+ */
+ success = 1;
+@@ -1260,7 +1258,7 @@ static int scrub_setup_recheck_block(struct scrub_block *original_sblock,
+ {
+ struct scrub_ctx *sctx = original_sblock->sctx;
+ struct btrfs_fs_info *fs_info = sctx->fs_info;
+- u64 length = original_sblock->page_count * PAGE_SIZE;
++ u64 length = original_sblock->page_count * fs_info->sectorsize;
+ u64 logical = original_sblock->pagev[0]->logical;
+ u64 generation = original_sblock->pagev[0]->generation;
+ u64 flags = original_sblock->pagev[0]->flags;
+@@ -1283,13 +1281,13 @@ static int scrub_setup_recheck_block(struct scrub_block *original_sblock,
+ */
+
+ while (length > 0) {
+- sublen = min_t(u64, length, PAGE_SIZE);
++ sublen = min_t(u64, length, fs_info->sectorsize);
+ mapped_length = sublen;
+ bbio = NULL;
+
+ /*
+- * with a length of PAGE_SIZE, each returned stripe
+- * represents one mirror
++ * With a length of sectorsize, each returned stripe represents
++ * one mirror
+ */
+ btrfs_bio_counter_inc_blocked(fs_info);
+ ret = btrfs_map_sblock(fs_info, BTRFS_MAP_GET_READ_MIRRORS,
+@@ -1480,7 +1478,7 @@ static void scrub_recheck_block(struct btrfs_fs_info *fs_info,
+ bio = btrfs_io_bio_alloc(1);
+ bio_set_dev(bio, spage->dev->bdev);
+
+- bio_add_page(bio, spage->page, PAGE_SIZE, 0);
++ bio_add_page(bio, spage->page, fs_info->sectorsize, 0);
+ bio->bi_iter.bi_sector = spage->physical >> 9;
+ bio->bi_opf = REQ_OP_READ;
+
+@@ -1544,6 +1542,7 @@ static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad,
+ struct scrub_page *spage_bad = sblock_bad->pagev[page_num];
+ struct scrub_page *spage_good = sblock_good->pagev[page_num];
+ struct btrfs_fs_info *fs_info = sblock_bad->sctx->fs_info;
++ const u32 sectorsize = fs_info->sectorsize;
+
+ BUG_ON(spage_bad->page == NULL);
+ BUG_ON(spage_good->page == NULL);
+@@ -1563,8 +1562,8 @@ static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad,
+ bio->bi_iter.bi_sector = spage_bad->physical >> 9;
+ bio->bi_opf = REQ_OP_WRITE;
+
+- ret = bio_add_page(bio, spage_good->page, PAGE_SIZE, 0);
+- if (PAGE_SIZE != ret) {
++ ret = bio_add_page(bio, spage_good->page, sectorsize, 0);
++ if (ret != sectorsize) {
+ bio_put(bio);
+ return -EIO;
+ }
+@@ -1642,6 +1641,7 @@ static int scrub_add_page_to_wr_bio(struct scrub_ctx *sctx,
+ {
+ struct scrub_bio *sbio;
+ int ret;
++ const u32 sectorsize = sctx->fs_info->sectorsize;
+
+ mutex_lock(&sctx->wr_lock);
+ again:
+@@ -1681,16 +1681,16 @@ again:
+ bio->bi_iter.bi_sector = sbio->physical >> 9;
+ bio->bi_opf = REQ_OP_WRITE;
+ sbio->status = 0;
+- } else if (sbio->physical + sbio->page_count * PAGE_SIZE !=
++ } else if (sbio->physical + sbio->page_count * sectorsize !=
+ spage->physical_for_dev_replace ||
+- sbio->logical + sbio->page_count * PAGE_SIZE !=
++ sbio->logical + sbio->page_count * sectorsize !=
+ spage->logical) {
+ scrub_wr_submit(sctx);
+ goto again;
+ }
+
+- ret = bio_add_page(sbio->bio, spage->page, PAGE_SIZE, 0);
+- if (ret != PAGE_SIZE) {
++ ret = bio_add_page(sbio->bio, spage->page, sectorsize, 0);
++ if (ret != sectorsize) {
+ if (sbio->page_count < 1) {
+ bio_put(sbio->bio);
+ sbio->bio = NULL;
+@@ -1729,7 +1729,8 @@ static void scrub_wr_submit(struct scrub_ctx *sctx)
+ btrfsic_submit_bio(sbio->bio);
+
+ if (btrfs_is_zoned(sctx->fs_info))
+- sctx->write_pointer = sbio->physical + sbio->page_count * PAGE_SIZE;
++ sctx->write_pointer = sbio->physical + sbio->page_count *
++ sctx->fs_info->sectorsize;
+ }
+
+ static void scrub_wr_bio_end_io(struct bio *bio)
+@@ -2006,6 +2007,7 @@ static int scrub_add_page_to_rd_bio(struct scrub_ctx *sctx,
+ {
+ struct scrub_block *sblock = spage->sblock;
+ struct scrub_bio *sbio;
++ const u32 sectorsize = sctx->fs_info->sectorsize;
+ int ret;
+
+ again:
+@@ -2044,9 +2046,9 @@ again:
+ bio->bi_iter.bi_sector = sbio->physical >> 9;
+ bio->bi_opf = REQ_OP_READ;
+ sbio->status = 0;
+- } else if (sbio->physical + sbio->page_count * PAGE_SIZE !=
++ } else if (sbio->physical + sbio->page_count * sectorsize !=
+ spage->physical ||
+- sbio->logical + sbio->page_count * PAGE_SIZE !=
++ sbio->logical + sbio->page_count * sectorsize !=
+ spage->logical ||
+ sbio->dev != spage->dev) {
+ scrub_submit(sctx);
+@@ -2054,8 +2056,8 @@ again:
+ }
+
+ sbio->pagev[sbio->page_count] = spage;
+- ret = bio_add_page(sbio->bio, spage->page, PAGE_SIZE, 0);
+- if (ret != PAGE_SIZE) {
++ ret = bio_add_page(sbio->bio, spage->page, sectorsize, 0);
++ if (ret != sectorsize) {
+ if (sbio->page_count < 1) {
+ bio_put(sbio->bio);
+ sbio->bio = NULL;
+@@ -2398,7 +2400,7 @@ static void scrub_block_complete(struct scrub_block *sblock)
+ if (sblock->sparity && corrupted && !sblock->data_corrected) {
+ u64 start = sblock->pagev[0]->logical;
+ u64 end = sblock->pagev[sblock->page_count - 1]->logical +
+- PAGE_SIZE;
++ sblock->sctx->fs_info->sectorsize;
+
+ ASSERT(end - start <= U32_MAX);
+ scrub_parity_mark_sectors_error(sblock->sparity,
+--
+2.30.2
+
--- /dev/null
+From 962398cb4e1f3306f342a54672fd2ff20aa1648b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 May 2021 20:00:14 +0200
+Subject: btrfs: sysfs: fix format string for some discard stats
+
+From: David Sterba <dsterba@suse.com>
+
+[ Upstream commit 8c5ec995616f1202ab92e195fd75d6f60d86f85c ]
+
+The type of discard_bitmap_bytes and discard_extent_bytes is u64 so the
+format should be %llu, though the actual values would hardly ever
+overflow to negative values.
+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: Anand Jain <anand.jain@oracle.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/sysfs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
+index 436ac7b4b334..4f5b14cd3a19 100644
+--- a/fs/btrfs/sysfs.c
++++ b/fs/btrfs/sysfs.c
+@@ -429,7 +429,7 @@ static ssize_t btrfs_discard_bitmap_bytes_show(struct kobject *kobj,
+ {
+ struct btrfs_fs_info *fs_info = discard_to_fs_info(kobj);
+
+- return scnprintf(buf, PAGE_SIZE, "%lld\n",
++ return scnprintf(buf, PAGE_SIZE, "%llu\n",
+ fs_info->discard_ctl.discard_bitmap_bytes);
+ }
+ BTRFS_ATTR(discard, discard_bitmap_bytes, btrfs_discard_bitmap_bytes_show);
+@@ -451,7 +451,7 @@ static ssize_t btrfs_discard_extent_bytes_show(struct kobject *kobj,
+ {
+ struct btrfs_fs_info *fs_info = discard_to_fs_info(kobj);
+
+- return scnprintf(buf, PAGE_SIZE, "%lld\n",
++ return scnprintf(buf, PAGE_SIZE, "%llu\n",
+ fs_info->discard_ctl.discard_extent_bytes);
+ }
+ BTRFS_ATTR(discard, discard_extent_bytes, btrfs_discard_extent_bytes_show);
+--
+2.30.2
+
--- /dev/null
+From e936ed1ca93c12f3e467c185f35d402ab2620b60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Jun 2021 14:38:42 +0200
+Subject: can: j1939: j1939_sk_setsockopt(): prevent allocation of j1939 filter
+ for optlen == 0
+
+From: Norbert Slusarek <nslusarek@gmx.net>
+
+[ Upstream commit aaf473d0100f64abc88560e2bea905805bcf2a8e ]
+
+If optval != NULL and optlen == 0 are specified for SO_J1939_FILTER in
+j1939_sk_setsockopt(), memdup_sockptr() will return ZERO_PTR for 0
+size allocation. The new filter will be mistakenly assigned ZERO_PTR.
+This patch checks for optlen != 0 and filter will be assigned NULL in
+case of optlen == 0.
+
+Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol")
+Link: https://lore.kernel.org/r/20210620123842.117975-1-nslusarek@gmx.net
+Signed-off-by: Norbert Slusarek <nslusarek@gmx.net>
+Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/j1939/socket.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c
+index fce8bc8afeb7..e1a399821238 100644
+--- a/net/can/j1939/socket.c
++++ b/net/can/j1939/socket.c
+@@ -676,7 +676,7 @@ static int j1939_sk_setsockopt(struct socket *sock, int level, int optname,
+
+ switch (optname) {
+ case SO_J1939_FILTER:
+- if (!sockptr_is_null(optval)) {
++ if (!sockptr_is_null(optval) && optlen != 0) {
+ struct j1939_filter *f;
+ int c;
+
+--
+2.30.2
+
--- /dev/null
+From 6c5e3a6047eb9661a43343b7fe9ed6809a989d98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 20:06:17 +0800
+Subject: char: pcmcia: error out if 'num_bytes_read' is greater than 4 in
+ set_protocol()
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 37188559c610f1b7eec83c8e448936c361c578de ]
+
+Theoretically, it will cause index out of bounds error if
+'num_bytes_read' is greater than 4. As we expect it(and was tested)
+never to be greater than 4, error out if it happens.
+
+Fixes: c1986ee9bea3 ("[PATCH] New Omnikey Cardman 4000 driver")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20210521120617.138396-1-yukuai3@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/pcmcia/cm4000_cs.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
+index 89681f07bc78..9468e9520cee 100644
+--- a/drivers/char/pcmcia/cm4000_cs.c
++++ b/drivers/char/pcmcia/cm4000_cs.c
+@@ -544,6 +544,10 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
+ io_read_num_rec_bytes(iobase, &num_bytes_read);
+ if (num_bytes_read >= 4) {
+ DEBUGP(2, dev, "NumRecBytes = %i\n", num_bytes_read);
++ if (num_bytes_read > 4) {
++ rc = -EIO;
++ goto exit_setprotocol;
++ }
+ break;
+ }
+ usleep_range(10000, 11000);
+--
+2.30.2
+
--- /dev/null
+From 4db3b2a1920749660ffbd982d233fb06b5e345fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 12:58:20 -0300
+Subject: cifs: fix check of dfs interlinks
+
+From: Paulo Alcantara <pc@cjr.nz>
+
+[ Upstream commit 889c2a700799f3b6f82210925e1faf4a9b833c4a ]
+
+Interlink is a special type of DFS link that resolves to a different
+DFS domain-based namespace. To determine whether it is an interlink
+or not, check if ReferralServers and StorageServers bits are set to 1
+and 0 respectively in ReferralHeaderFlags, as specified in MS-DFSC
+3.1.5.4.5 Determining Whether a Referral Response is an Interlink.
+
+Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+Reviewed-by: Aurelien Aptel <aaptel@suse.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/dfs_cache.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c
+index b1fa30fefe1f..8e16ee1e5fd1 100644
+--- a/fs/cifs/dfs_cache.c
++++ b/fs/cifs/dfs_cache.c
+@@ -25,8 +25,7 @@
+ #define CACHE_HTABLE_SIZE 32
+ #define CACHE_MAX_ENTRIES 64
+
+-#define IS_INTERLINK_SET(v) ((v) & (DFSREF_REFERRAL_SERVER | \
+- DFSREF_STORAGE_SERVER))
++#define IS_DFS_INTERLINK(v) (((v) & DFSREF_REFERRAL_SERVER) && !((v) & DFSREF_STORAGE_SERVER))
+
+ struct cache_dfs_tgt {
+ char *name;
+@@ -171,7 +170,7 @@ static int dfscache_proc_show(struct seq_file *m, void *v)
+ "cache entry: path=%s,type=%s,ttl=%d,etime=%ld,hdr_flags=0x%x,ref_flags=0x%x,interlink=%s,path_consumed=%d,expired=%s\n",
+ ce->path, ce->srvtype == DFS_TYPE_ROOT ? "root" : "link",
+ ce->ttl, ce->etime.tv_nsec, ce->ref_flags, ce->hdr_flags,
+- IS_INTERLINK_SET(ce->hdr_flags) ? "yes" : "no",
++ IS_DFS_INTERLINK(ce->hdr_flags) ? "yes" : "no",
+ ce->path_consumed, cache_entry_expired(ce) ? "yes" : "no");
+
+ list_for_each_entry(t, &ce->tlist, list) {
+@@ -240,7 +239,7 @@ static inline void dump_ce(const struct cache_entry *ce)
+ ce->srvtype == DFS_TYPE_ROOT ? "root" : "link", ce->ttl,
+ ce->etime.tv_nsec,
+ ce->hdr_flags, ce->ref_flags,
+- IS_INTERLINK_SET(ce->hdr_flags) ? "yes" : "no",
++ IS_DFS_INTERLINK(ce->hdr_flags) ? "yes" : "no",
+ ce->path_consumed,
+ cache_entry_expired(ce) ? "yes" : "no");
+ dump_tgts(ce);
+--
+2.30.2
+
--- /dev/null
+From 8d63e57f21659ec23da3a6331733a58351127654 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Jun 2021 15:28:04 -0500
+Subject: cifs: fix missing spinlock around update to ses->status
+
+From: Steve French <stfrench@microsoft.com>
+
+[ Upstream commit 0060a4f28a9ef45ae8163c0805e944a2b1546762 ]
+
+In the other places where we update ses->status we protect the
+updates via GlobalMid_Lock. So to be consistent add the same
+locking around it in cifs_put_smb_ses where it was missing.
+
+Addresses-Coverity: 1268904 ("Data race condition")
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/cifsglob.h | 3 ++-
+ fs/cifs/connect.c | 5 ++++-
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
+index 8488d7024462..706a2aeba1de 100644
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -896,7 +896,7 @@ struct cifs_ses {
+ struct mutex session_mutex;
+ struct TCP_Server_Info *server; /* pointer to server info */
+ int ses_count; /* reference counter */
+- enum statusEnum status;
++ enum statusEnum status; /* updates protected by GlobalMid_Lock */
+ unsigned overrideSecFlg; /* if non-zero override global sec flags */
+ char *serverOS; /* name of operating system underlying server */
+ char *serverNOS; /* name of network operating system of server */
+@@ -1795,6 +1795,7 @@ require use of the stronger protocol */
+ * list operations on pending_mid_q and oplockQ
+ * updates to XID counters, multiplex id and SMB sequence numbers
+ * list operations on global DnotifyReqList
++ * updates to ses->status
+ * tcp_ses_lock protects:
+ * list operations on tcp and SMB session lists
+ * tcon->open_file_lock protects the list of open files hanging off the tcon
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 495c395f9def..eb6c10fa6741 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -1617,9 +1617,12 @@ void cifs_put_smb_ses(struct cifs_ses *ses)
+ spin_unlock(&cifs_tcp_ses_lock);
+ return;
+ }
++ spin_unlock(&cifs_tcp_ses_lock);
++
++ spin_lock(&GlobalMid_Lock);
+ if (ses->status == CifsGood)
+ ses->status = CifsExiting;
+- spin_unlock(&cifs_tcp_ses_lock);
++ spin_unlock(&GlobalMid_Lock);
+
+ cifs_free_ipc(ses);
+
+--
+2.30.2
+
--- /dev/null
+From b7b89b86900834812ef25d082536fc1941141e38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Jun 2021 15:53:18 -0500
+Subject: cifs: fix SMB1 error path in cifs_get_file_info_unix
+
+From: Steve French <stfrench@microsoft.com>
+
+[ Upstream commit e39df24169a2ceb0d359eb3a05ff982711f2eb32 ]
+
+We were trying to fill in uninitialized file attributes in the error case.
+
+Addresses-Coverity: 139689 ("Uninitialized variables")
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/inode.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
+index 1dfa57982522..f60f068d33e8 100644
+--- a/fs/cifs/inode.c
++++ b/fs/cifs/inode.c
+@@ -367,9 +367,12 @@ cifs_get_file_info_unix(struct file *filp)
+ } else if (rc == -EREMOTE) {
+ cifs_create_dfs_fattr(&fattr, inode->i_sb);
+ rc = 0;
+- }
++ } else
++ goto cifs_gfiunix_out;
+
+ rc = cifs_fattr_to_inode(inode, &fattr);
++
++cifs_gfiunix_out:
+ free_xid(xid);
+ return rc;
+ }
+--
+2.30.2
+
--- /dev/null
+From cf54b6966adfd6fed10857f157cd430c7f0ee78d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Jun 2021 15:31:01 +1000
+Subject: cifs: improve fallocate emulation
+
+From: Ronnie Sahlberg <lsahlber@redhat.com>
+
+[ Upstream commit 966a3cb7c7db786452a87afdc3b48858fc4d4d6b ]
+
+RHBZ: 1866684
+
+We don't have a real fallocate in the SMB2 protocol so we used to emulate fallocate
+by simply switching the file to become non-sparse. But as that could potantially consume
+a lot more data than we intended to fallocate (large sparse file and fallocating a thin
+slice in the middle) we would only do this IFF the fallocate request was for virtually
+the entire file.
+
+This patch improves this and starts allowing us to fallocate smaller chunks of a file by
+overwriting the region with 0, for the parts that are unallocated.
+
+The method used is to first query the server for FSCTL_QUERY_ALLOCATED_RANGES to find what
+is unallocated in the fallocate range and then to only overwrite-with-zero the unallocated
+ranges to fill in the holes.
+
+As overwriting-with-zero is different from just allocating blocks, and potentially much
+more expensive, we limit this to only allow fallocate ranges up to 1Mb in size.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
+Acked-by: Aurelien Aptel <aaptel@suse.com>
+Acked-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smb2ops.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 133 insertions(+)
+
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index 21ef51d338e0..b68ba92893b6 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -3601,6 +3601,119 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
+ return rc;
+ }
+
++static int smb3_simple_fallocate_write_range(unsigned int xid,
++ struct cifs_tcon *tcon,
++ struct cifsFileInfo *cfile,
++ loff_t off, loff_t len,
++ char *buf)
++{
++ struct cifs_io_parms io_parms = {0};
++ int nbytes;
++ struct kvec iov[2];
++
++ io_parms.netfid = cfile->fid.netfid;
++ io_parms.pid = current->tgid;
++ io_parms.tcon = tcon;
++ io_parms.persistent_fid = cfile->fid.persistent_fid;
++ io_parms.volatile_fid = cfile->fid.volatile_fid;
++ io_parms.offset = off;
++ io_parms.length = len;
++
++ /* iov[0] is reserved for smb header */
++ iov[1].iov_base = buf;
++ iov[1].iov_len = io_parms.length;
++ return SMB2_write(xid, &io_parms, &nbytes, iov, 1);
++}
++
++static int smb3_simple_fallocate_range(unsigned int xid,
++ struct cifs_tcon *tcon,
++ struct cifsFileInfo *cfile,
++ loff_t off, loff_t len)
++{
++ struct file_allocated_range_buffer in_data, *out_data = NULL, *tmp_data;
++ u32 out_data_len;
++ char *buf = NULL;
++ loff_t l;
++ int rc;
++
++ in_data.file_offset = cpu_to_le64(off);
++ in_data.length = cpu_to_le64(len);
++ rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
++ cfile->fid.volatile_fid,
++ FSCTL_QUERY_ALLOCATED_RANGES, true,
++ (char *)&in_data, sizeof(in_data),
++ 1024 * sizeof(struct file_allocated_range_buffer),
++ (char **)&out_data, &out_data_len);
++ if (rc)
++ goto out;
++ /*
++ * It is already all allocated
++ */
++ if (out_data_len == 0)
++ goto out;
++
++ buf = kzalloc(1024 * 1024, GFP_KERNEL);
++ if (buf == NULL) {
++ rc = -ENOMEM;
++ goto out;
++ }
++
++ tmp_data = out_data;
++ while (len) {
++ /*
++ * The rest of the region is unmapped so write it all.
++ */
++ if (out_data_len == 0) {
++ rc = smb3_simple_fallocate_write_range(xid, tcon,
++ cfile, off, len, buf);
++ goto out;
++ }
++
++ if (out_data_len < sizeof(struct file_allocated_range_buffer)) {
++ rc = -EINVAL;
++ goto out;
++ }
++
++ if (off < le64_to_cpu(tmp_data->file_offset)) {
++ /*
++ * We are at a hole. Write until the end of the region
++ * or until the next allocated data,
++ * whichever comes next.
++ */
++ l = le64_to_cpu(tmp_data->file_offset) - off;
++ if (len < l)
++ l = len;
++ rc = smb3_simple_fallocate_write_range(xid, tcon,
++ cfile, off, l, buf);
++ if (rc)
++ goto out;
++ off = off + l;
++ len = len - l;
++ if (len == 0)
++ goto out;
++ }
++ /*
++ * We are at a section of allocated data, just skip forward
++ * until the end of the data or the end of the region
++ * we are supposed to fallocate, whichever comes first.
++ */
++ l = le64_to_cpu(tmp_data->length);
++ if (len < l)
++ l = len;
++ off += l;
++ len -= l;
++
++ tmp_data = &tmp_data[1];
++ out_data_len -= sizeof(struct file_allocated_range_buffer);
++ }
++
++ out:
++ kfree(out_data);
++ kfree(buf);
++ return rc;
++}
++
++
+ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,
+ loff_t off, loff_t len, bool keep_size)
+ {
+@@ -3661,6 +3774,26 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,
+ }
+
+ if ((keep_size == true) || (i_size_read(inode) >= off + len)) {
++ /*
++ * At this point, we are trying to fallocate an internal
++ * regions of a sparse file. Since smb2 does not have a
++ * fallocate command we have two otions on how to emulate this.
++ * We can either turn the entire file to become non-sparse
++ * which we only do if the fallocate is for virtually
++ * the whole file, or we can overwrite the region with zeroes
++ * using SMB2_write, which could be prohibitevly expensive
++ * if len is large.
++ */
++ /*
++ * We are only trying to fallocate a small region so
++ * just write it with zero.
++ */
++ if (len <= 1024 * 1024) {
++ rc = smb3_simple_fallocate_range(xid, tcon, cfile,
++ off, len);
++ goto out;
++ }
++
+ /*
+ * Check if falloc starts within first few pages of file
+ * and ends within a few pages of the end of file to
+--
+2.30.2
+
--- /dev/null
+From bcf4f8eb15f12b3f715ec0bbdb9ce3aa902e0e0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jun 2021 13:42:56 -0300
+Subject: cifs: retry lookup and readdir when EAGAIN is returned.
+
+From: Thiago Rafael Becker <trbecker@gmail.com>
+
+[ Upstream commit 6efa994e35a402ae4ae2161b6439c94b64816cee ]
+
+According to the investigation performed by Jacob Shivers at Red Hat,
+cifs_lookup and cifs_readdir leak EAGAIN when the user session is
+deleted on the server. Fix this issue by implementing a retry with
+limits, as is implemented in cifs_revalidate_dentry_attr.
+
+Reproducer based on the work by Jacob Shivers:
+
+ ~~~
+ $ cat readdir-cifs-test.sh
+ #!/bin/bash
+
+ # Install and configure powershell and sshd on the windows
+ # server as descibed in
+ # https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_overview
+ # This script uses expect(1)
+
+ USER=dude
+ SERVER=192.168.0.2
+ RPATH=root
+ PASS='password'
+
+ function debug_funcs {
+ for line in $@ ; do
+ echo "func $line +p" > /sys/kernel/debug/dynamic_debug/control
+ done
+ }
+
+ function setup {
+ echo 1 > /proc/fs/cifs/cifsFYI
+ debug_funcs wait_for_compound_request \
+ smb2_query_dir_first cifs_readdir \
+ compound_send_recv cifs_reconnect_tcon \
+ generic_ip_connect cifs_reconnect \
+ smb2_reconnect_server smb2_reconnect \
+ cifs_readv_from_socket cifs_readv_receive
+ tcpdump -i eth0 -w cifs.pcap host 192.168.2.182 & sleep 5
+ dmesg -C
+ }
+
+ function test_call {
+ if [[ $1 == 1 ]] ; then
+ tracer="strace -tt -f -s 4096 -o trace-$(date -Iseconds).txt"
+ fi
+ # Change the command here to anything appropriate
+ $tracer ls $2 > /dev/null
+ res=$?
+ if [[ $1 == 1 ]] ; then
+ if [[ $res == 0 ]] ; then
+ 1>&2 echo success
+ else
+ 1>&2 echo "failure ($res)"
+ fi
+ fi
+ }
+
+ mountpoint /mnt > /dev/null || mount -t cifs -o username=$USER,pass=$PASS //$SERVER/$RPATH /mnt
+
+ test_call 0 /mnt/
+
+ /usr/bin/expect << EOF
+ set timeout 60
+
+ spawn ssh $USER@$SERVER
+
+ expect "yes/no" {
+ send "yes\r"
+ expect "*?assword" { send "$PASS\r" }
+ } "*?assword" { send "$PASS\r" }
+
+ expect ">" { send "powershell close-smbsession -force\r" }
+ expect ">" { send "exit\r" }
+ expect eof
+ EOF
+
+ sysctl -w vm.drop_caches=2 > /dev/null
+ sysctl -w vm.drop_caches=2 > /dev/null
+
+ setup
+
+ test_call 1 /mnt/
+ ~~~
+
+Signed-off-by: Thiago Rafael Becker <trbecker@gmail.com>
+Acked-by: Ronnie Sahlberg <lsahlber@redhat.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/dir.c | 4 ++++
+ fs/cifs/smb2ops.c | 5 +++++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
+index 6bcd3e8f7cda..7c641f9a3dac 100644
+--- a/fs/cifs/dir.c
++++ b/fs/cifs/dir.c
+@@ -630,6 +630,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
+ struct inode *newInode = NULL;
+ const char *full_path;
+ void *page;
++ int retry_count = 0;
+
+ xid = get_xid();
+
+@@ -673,6 +674,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
+ cifs_dbg(FYI, "Full path: %s inode = 0x%p\n",
+ full_path, d_inode(direntry));
+
++again:
+ if (pTcon->posix_extensions)
+ rc = smb311_posix_get_inode_info(&newInode, full_path, parent_dir_inode->i_sb, xid);
+ else if (pTcon->unix_ext) {
+@@ -687,6 +689,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
+ /* since paths are not looked up by component - the parent
+ directories are presumed to be good here */
+ renew_parental_timestamps(direntry);
++ } else if (rc == -EAGAIN && retry_count++ < 10) {
++ goto again;
+ } else if (rc == -ENOENT) {
+ cifs_set_time(direntry, jiffies);
+ newInode = NULL;
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index b68ba92893b6..903de7449aa3 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -2325,6 +2325,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
+ struct smb2_query_directory_rsp *qd_rsp = NULL;
+ struct smb2_create_rsp *op_rsp = NULL;
+ struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
++ int retry_count = 0;
+
+ utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
+ if (!utf16_path)
+@@ -2372,10 +2373,14 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
+
+ smb2_set_related(&rqst[1]);
+
++again:
+ rc = compound_send_recv(xid, tcon->ses, server,
+ flags, 2, rqst,
+ resp_buftype, rsp_iov);
+
++ if (rc == -EAGAIN && retry_count++ < 10)
++ goto again;
++
+ /* If the open failed there is nothing to do */
+ op_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
+ if (op_rsp == NULL || op_rsp->sync_hdr.Status != STATUS_SUCCESS) {
+--
+2.30.2
+
--- /dev/null
+From f1cfa3b1d7acbe9004b889b5c665da175a8fd4a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jun 2021 23:05:24 +0300
+Subject: clk: actions: Fix AHPPREDIV-H-AHB clock chain on Owl S500 SoC
+
+From: Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
+
+[ Upstream commit fd90b5b9045274360b12cea0f2ce50f3bcfb25cc ]
+
+There are a few issues with the setup of the Actions Semi Owl S500 SoC's
+clock chain involving AHPPREDIV, H and AHB clocks:
+
+* AHBPREDIV clock is defined as a muxer only, although it also acts as
+ a divider.
+* H clock is using a wrong divider register offset
+* AHB is defined as a multi-rate factor clock, but it is actually just
+ a fixed pass clock.
+
+Let's provide the following fixes:
+
+* Change AHBPREDIV clock to an ungated OWL_COMP_DIV definition.
+* Use the correct register shift value in the OWL_DIVIDER definition
+ for H clock
+* Drop the unneeded 'ahb_factor_table[]' and change AHB clock to an
+ ungated OWL_COMP_FIXED_FACTOR definition.
+
+Fixes: ed6b4795ece4 ("clk: actions: Add clock driver for S500 SoC")
+Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
+Link: https://lore.kernel.org/r/21c1abd19a7089b65a34852ac6513961be88cbe1.1623354574.git.cristian.ciocaltea@gmail.com
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/actions/owl-s500.c | 19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/clk/actions/owl-s500.c b/drivers/clk/actions/owl-s500.c
+index 42d6899755e6..cbeb51c804eb 100644
+--- a/drivers/clk/actions/owl-s500.c
++++ b/drivers/clk/actions/owl-s500.c
+@@ -153,11 +153,6 @@ static struct clk_factor_table hde_factor_table[] = {
+ { 0, 0, 0 },
+ };
+
+-static struct clk_factor_table ahb_factor_table[] = {
+- { 1, 1, 2 }, { 2, 1, 3 },
+- { 0, 0, 0 },
+-};
+-
+ static struct clk_div_table rmii_ref_div_table[] = {
+ { 0, 4 }, { 1, 10 },
+ { 0, 0 },
+@@ -186,7 +181,6 @@ static struct clk_div_table nand_div_table[] = {
+
+ /* mux clock */
+ static OWL_MUX(dev_clk, "dev_clk", dev_clk_mux_p, CMU_DEVPLL, 12, 1, CLK_SET_RATE_PARENT);
+-static OWL_MUX(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p, CMU_BUSCLK1, 8, 3, CLK_SET_RATE_PARENT);
+
+ /* gate clocks */
+ static OWL_GATE(gpio_clk, "gpio_clk", "apb_clk", CMU_DEVCLKEN0, 18, 0, 0);
+@@ -199,16 +193,25 @@ static OWL_GATE(timer_clk, "timer_clk", "hosc", CMU_DEVCLKEN1, 27, 0, 0);
+ static OWL_GATE(hdmi_clk, "hdmi_clk", "hosc", CMU_DEVCLKEN1, 3, 0, 0);
+
+ /* divider clocks */
+-static OWL_DIVIDER(h_clk, "h_clk", "ahbprediv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0);
++static OWL_DIVIDER(h_clk, "h_clk", "ahbprediv_clk", CMU_BUSCLK1, 2, 2, NULL, 0, 0);
+ static OWL_DIVIDER(apb_clk, "apb_clk", "ahb_clk", CMU_BUSCLK1, 14, 2, NULL, 0, 0);
+ static OWL_DIVIDER(rmii_ref_clk, "rmii_ref_clk", "ethernet_pll_clk", CMU_ETHERNETPLL, 1, 1, rmii_ref_div_table, 0, 0);
+
+ /* factor clocks */
+-static OWL_FACTOR(ahb_clk, "ahb_clk", "h_clk", CMU_BUSCLK1, 2, 2, ahb_factor_table, 0, 0);
+ static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 4, de_factor_table, 0, 0);
+ static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 4, de_factor_table, 0, 0);
+
+ /* composite clocks */
++static OWL_COMP_DIV(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p,
++ OWL_MUX_HW(CMU_BUSCLK1, 8, 3),
++ { 0 },
++ OWL_DIVIDER_HW(CMU_BUSCLK1, 12, 2, 0, NULL),
++ CLK_SET_RATE_PARENT);
++
++static OWL_COMP_FIXED_FACTOR(ahb_clk, "ahb_clk", "h_clk",
++ { 0 },
++ 1, 1, 0);
++
+ static OWL_COMP_FACTOR(vce_clk, "vce_clk", hde_clk_mux_p,
+ OWL_MUX_HW(CMU_VCECLK, 4, 2),
+ OWL_GATE_HW(CMU_DEVCLKEN0, 26, 0),
+--
+2.30.2
+
--- /dev/null
+From f4892fbe62de10c5df1f1a02f89d1020f542e7e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jun 2021 23:05:23 +0300
+Subject: clk: actions: Fix bisp_factor_table based clocks on Owl S500 SoC
+
+From: Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
+
+[ Upstream commit a8f1f03caa51aa7a69c671aa87c475034db7d368 ]
+
+The following clocks of the Actions Semi Owl S500 SoC have been defined
+to use a shared clock factor table 'bisp_factor_table[]': DE[1-2], VCE,
+VDE, BISP, SENSOR[0-1]
+
+There are several issues involved in this approach:
+
+* 'bisp_factor_table[]' describes the configuration of a regular 8-rates
+ divider, so its usage is redundant. Additionally, judging by the BISP
+ clock context, it is incomplete since it maps only 8 out of 12
+ possible entries.
+
+* The clocks mentioned above are not identical in terms of the available
+ rates, therefore cannot rely on the same factor table. Specifically,
+ BISP and SENSOR* are standard 12-rate dividers so their configuration
+ should rely on a proper clock div table, while VCE and VDE require a
+ factor table that is a actually a subset of the one needed for DE[1-2]
+ clocks.
+
+Let's fix this by implementing the following:
+
+* Add new factor tables 'de_factor_table' and 'hde_factor_table' to
+ properly handle DE[1-2], VCE and VDE clocks.
+
+* Add a common div table 'std12rate_div_table' for BISP and SENSOR[0-1]
+ clocks converted to OWL_COMP_DIV.
+
+* Drop the now unused 'bisp_factor_table[]'.
+
+Additionally, drop the CLK_IGNORE_UNUSED flag for SENSOR[0-1] since
+there is no reason to always keep ON those clocks.
+
+Fixes: ed6b4795ece4 ("clk: actions: Add clock driver for S500 SoC")
+Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/e675820a46cd9930d8d576c6cae61d41c1a8416f.1623354574.git.cristian.ciocaltea@gmail.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/actions/owl-s500.c | 44 ++++++++++++++++++++++------------
+ 1 file changed, 29 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/clk/actions/owl-s500.c b/drivers/clk/actions/owl-s500.c
+index 42abdf964044..42d6899755e6 100644
+--- a/drivers/clk/actions/owl-s500.c
++++ b/drivers/clk/actions/owl-s500.c
+@@ -140,9 +140,16 @@ static struct clk_factor_table sd_factor_table[] = {
+ { 0, 0, 0 },
+ };
+
+-static struct clk_factor_table bisp_factor_table[] = {
+- { 0, 1, 1 }, { 1, 1, 2 }, { 2, 1, 3 }, { 3, 1, 4 },
+- { 4, 1, 5 }, { 5, 1, 6 }, { 6, 1, 7 }, { 7, 1, 8 },
++static struct clk_factor_table de_factor_table[] = {
++ { 0, 1, 1 }, { 1, 2, 3 }, { 2, 1, 2 }, { 3, 2, 5 },
++ { 4, 1, 3 }, { 5, 1, 4 }, { 6, 1, 6 }, { 7, 1, 8 },
++ { 8, 1, 12 },
++ { 0, 0, 0 },
++};
++
++static struct clk_factor_table hde_factor_table[] = {
++ { 0, 1, 1 }, { 1, 2, 3 }, { 2, 1, 2 }, { 3, 2, 5 },
++ { 4, 1, 3 }, { 5, 1, 4 }, { 6, 1, 6 }, { 7, 1, 8 },
+ { 0, 0, 0 },
+ };
+
+@@ -156,6 +163,13 @@ static struct clk_div_table rmii_ref_div_table[] = {
+ { 0, 0 },
+ };
+
++static struct clk_div_table std12rate_div_table[] = {
++ { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
++ { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 },
++ { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 },
++ { 0, 0 },
++};
++
+ static struct clk_div_table i2s_div_table[] = {
+ { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
+ { 4, 6 }, { 5, 8 }, { 6, 12 }, { 7, 16 },
+@@ -191,39 +205,39 @@ static OWL_DIVIDER(rmii_ref_clk, "rmii_ref_clk", "ethernet_pll_clk", CMU_ETHERNE
+
+ /* factor clocks */
+ static OWL_FACTOR(ahb_clk, "ahb_clk", "h_clk", CMU_BUSCLK1, 2, 2, ahb_factor_table, 0, 0);
+-static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 3, bisp_factor_table, 0, 0);
+-static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 3, bisp_factor_table, 0, 0);
++static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 4, de_factor_table, 0, 0);
++static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 4, de_factor_table, 0, 0);
+
+ /* composite clocks */
+ static OWL_COMP_FACTOR(vce_clk, "vce_clk", hde_clk_mux_p,
+ OWL_MUX_HW(CMU_VCECLK, 4, 2),
+ OWL_GATE_HW(CMU_DEVCLKEN0, 26, 0),
+- OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, bisp_factor_table),
++ OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, hde_factor_table),
+ 0);
+
+ static OWL_COMP_FACTOR(vde_clk, "vde_clk", hde_clk_mux_p,
+ OWL_MUX_HW(CMU_VDECLK, 4, 2),
+ OWL_GATE_HW(CMU_DEVCLKEN0, 25, 0),
+- OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, bisp_factor_table),
++ OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, hde_factor_table),
+ 0);
+
+-static OWL_COMP_FACTOR(bisp_clk, "bisp_clk", bisp_clk_mux_p,
++static OWL_COMP_DIV(bisp_clk, "bisp_clk", bisp_clk_mux_p,
+ OWL_MUX_HW(CMU_BISPCLK, 4, 1),
+ OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0),
+- OWL_FACTOR_HW(CMU_BISPCLK, 0, 3, 0, bisp_factor_table),
++ OWL_DIVIDER_HW(CMU_BISPCLK, 0, 4, 0, std12rate_div_table),
+ 0);
+
+-static OWL_COMP_FACTOR(sensor0_clk, "sensor0_clk", sensor_clk_mux_p,
++static OWL_COMP_DIV(sensor0_clk, "sensor0_clk", sensor_clk_mux_p,
+ OWL_MUX_HW(CMU_SENSORCLK, 4, 1),
+ OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0),
+- OWL_FACTOR_HW(CMU_SENSORCLK, 0, 3, 0, bisp_factor_table),
+- CLK_IGNORE_UNUSED);
++ OWL_DIVIDER_HW(CMU_SENSORCLK, 0, 4, 0, std12rate_div_table),
++ 0);
+
+-static OWL_COMP_FACTOR(sensor1_clk, "sensor1_clk", sensor_clk_mux_p,
++static OWL_COMP_DIV(sensor1_clk, "sensor1_clk", sensor_clk_mux_p,
+ OWL_MUX_HW(CMU_SENSORCLK, 4, 1),
+ OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0),
+- OWL_FACTOR_HW(CMU_SENSORCLK, 8, 3, 0, bisp_factor_table),
+- CLK_IGNORE_UNUSED);
++ OWL_DIVIDER_HW(CMU_SENSORCLK, 8, 4, 0, std12rate_div_table),
++ 0);
+
+ static OWL_COMP_FACTOR(sd0_clk, "sd0_clk", sd_clk_mux_p,
+ OWL_MUX_HW(CMU_SD0CLK, 9, 1),
+--
+2.30.2
+
--- /dev/null
+From dc797800166fbd302716de064c37f9f0ca7fb676 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jun 2021 23:05:22 +0300
+Subject: clk: actions: Fix SD clocks factor table on Owl S500 SoC
+
+From: Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
+
+[ Upstream commit fe1f71e338d77814da3ef44e9f64d32981a6ccdf ]
+
+Drop the unsupported entries in the factor table used for the SD[0-2]
+clocks definitions on the Actions Semi Owl S500 SoC.
+
+Fixes: ed6b4795ece4 ("clk: actions: Add clock driver for S500 SoC")
+Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/196c948d708a22b8198c95f064a0f6b6820f9980.1623354574.git.cristian.ciocaltea@gmail.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/actions/owl-s500.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/clk/actions/owl-s500.c b/drivers/clk/actions/owl-s500.c
+index 75b7186185b0..42abdf964044 100644
+--- a/drivers/clk/actions/owl-s500.c
++++ b/drivers/clk/actions/owl-s500.c
+@@ -127,8 +127,7 @@ static struct clk_factor_table sd_factor_table[] = {
+ { 12, 1, 13 }, { 13, 1, 14 }, { 14, 1, 15 }, { 15, 1, 16 },
+ { 16, 1, 17 }, { 17, 1, 18 }, { 18, 1, 19 }, { 19, 1, 20 },
+ { 20, 1, 21 }, { 21, 1, 22 }, { 22, 1, 23 }, { 23, 1, 24 },
+- { 24, 1, 25 }, { 25, 1, 26 }, { 26, 1, 27 }, { 27, 1, 28 },
+- { 28, 1, 29 }, { 29, 1, 30 }, { 30, 1, 31 }, { 31, 1, 32 },
++ { 24, 1, 25 },
+
+ /* bit8: /128 */
+ { 256, 1, 1 * 128 }, { 257, 1, 2 * 128 }, { 258, 1, 3 * 128 }, { 259, 1, 4 * 128 },
+@@ -137,8 +136,7 @@ static struct clk_factor_table sd_factor_table[] = {
+ { 268, 1, 13 * 128 }, { 269, 1, 14 * 128 }, { 270, 1, 15 * 128 }, { 271, 1, 16 * 128 },
+ { 272, 1, 17 * 128 }, { 273, 1, 18 * 128 }, { 274, 1, 19 * 128 }, { 275, 1, 20 * 128 },
+ { 276, 1, 21 * 128 }, { 277, 1, 22 * 128 }, { 278, 1, 23 * 128 }, { 279, 1, 24 * 128 },
+- { 280, 1, 25 * 128 }, { 281, 1, 26 * 128 }, { 282, 1, 27 * 128 }, { 283, 1, 28 * 128 },
+- { 284, 1, 29 * 128 }, { 285, 1, 30 * 128 }, { 286, 1, 31 * 128 }, { 287, 1, 32 * 128 },
++ { 280, 1, 25 * 128 },
+ { 0, 0, 0 },
+ };
+
+--
+2.30.2
+
--- /dev/null
+From b15ab87a1740da5c1cfaac8ce6def552abb437ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jun 2021 23:05:21 +0300
+Subject: clk: actions: Fix UART clock dividers on Owl S500 SoC
+
+From: Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
+
+[ Upstream commit 2dca2a619a907579e3e65e7c1789230c2b912e88 ]
+
+Use correct divider registers for the Actions Semi Owl S500 SoC's UART
+clocks.
+
+Fixes: ed6b4795ece4 ("clk: actions: Add clock driver for S500 SoC")
+Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/4714d05982b19ac5fec2ed74f54be42d8238e392.1623354574.git.cristian.ciocaltea@gmail.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/actions/owl-s500.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/clk/actions/owl-s500.c b/drivers/clk/actions/owl-s500.c
+index 61bb224f6330..75b7186185b0 100644
+--- a/drivers/clk/actions/owl-s500.c
++++ b/drivers/clk/actions/owl-s500.c
+@@ -305,7 +305,7 @@ static OWL_COMP_FIXED_FACTOR(i2c3_clk, "i2c3_clk", "ethernet_pll_clk",
+ static OWL_COMP_DIV(uart0_clk, "uart0_clk", uart_clk_mux_p,
+ OWL_MUX_HW(CMU_UART0CLK, 16, 1),
+ OWL_GATE_HW(CMU_DEVCLKEN1, 6, 0),
+- OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
++ OWL_DIVIDER_HW(CMU_UART0CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
+ CLK_IGNORE_UNUSED);
+
+ static OWL_COMP_DIV(uart1_clk, "uart1_clk", uart_clk_mux_p,
+@@ -317,31 +317,31 @@ static OWL_COMP_DIV(uart1_clk, "uart1_clk", uart_clk_mux_p,
+ static OWL_COMP_DIV(uart2_clk, "uart2_clk", uart_clk_mux_p,
+ OWL_MUX_HW(CMU_UART2CLK, 16, 1),
+ OWL_GATE_HW(CMU_DEVCLKEN1, 8, 0),
+- OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
++ OWL_DIVIDER_HW(CMU_UART2CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
+ CLK_IGNORE_UNUSED);
+
+ static OWL_COMP_DIV(uart3_clk, "uart3_clk", uart_clk_mux_p,
+ OWL_MUX_HW(CMU_UART3CLK, 16, 1),
+ OWL_GATE_HW(CMU_DEVCLKEN1, 19, 0),
+- OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
++ OWL_DIVIDER_HW(CMU_UART3CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
+ CLK_IGNORE_UNUSED);
+
+ static OWL_COMP_DIV(uart4_clk, "uart4_clk", uart_clk_mux_p,
+ OWL_MUX_HW(CMU_UART4CLK, 16, 1),
+ OWL_GATE_HW(CMU_DEVCLKEN1, 20, 0),
+- OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
++ OWL_DIVIDER_HW(CMU_UART4CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
+ CLK_IGNORE_UNUSED);
+
+ static OWL_COMP_DIV(uart5_clk, "uart5_clk", uart_clk_mux_p,
+ OWL_MUX_HW(CMU_UART5CLK, 16, 1),
+ OWL_GATE_HW(CMU_DEVCLKEN1, 21, 0),
+- OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
++ OWL_DIVIDER_HW(CMU_UART5CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
+ CLK_IGNORE_UNUSED);
+
+ static OWL_COMP_DIV(uart6_clk, "uart6_clk", uart_clk_mux_p,
+ OWL_MUX_HW(CMU_UART6CLK, 16, 1),
+ OWL_GATE_HW(CMU_DEVCLKEN1, 18, 0),
+- OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
++ OWL_DIVIDER_HW(CMU_UART6CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL),
+ CLK_IGNORE_UNUSED);
+
+ static OWL_COMP_DIV(i2srx_clk, "i2srx_clk", i2s_clk_mux_p,
+--
+2.30.2
+
--- /dev/null
+From a06eabbc06e5b768b70571c76d07ee357980bb26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 May 2021 20:01:35 +0200
+Subject: clk: imx8mq: remove SYS PLL 1/2 clock gates
+
+From: Lucas Stach <l.stach@pengutronix.de>
+
+[ Upstream commit c586f53ae159c6c1390f093a1ec94baef2df9f3a ]
+
+Remove the PLL clock gates as the allowing to gate the sys1_pll_266m breaks
+the uSDHC module which is sporadically unable to enumerate devices after
+this change. Also it makes AMP clock management harder with no obvious
+benefit to Linux, so just revert the change.
+
+Link: https://lore.kernel.org/r/20210528180135.1640876-1-l.stach@pengutronix.de
+Fixes: b04383b6a558 ("clk: imx8mq: Define gates for pll1/2 fixed dividers")
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Reviewed-by: Abel Vesa <abel.vesa@nxp.com>
+Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx8mq.c | 56 ++++++++----------------
+ include/dt-bindings/clock/imx8mq-clock.h | 19 --------
+ 2 files changed, 18 insertions(+), 57 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
+index b08019e1faf9..c491bc9c61ce 100644
+--- a/drivers/clk/imx/clk-imx8mq.c
++++ b/drivers/clk/imx/clk-imx8mq.c
+@@ -358,46 +358,26 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
+ hws[IMX8MQ_VIDEO2_PLL_OUT] = imx_clk_hw_sscg_pll("video2_pll_out", video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, base + 0x54, 0);
+
+ /* SYS PLL1 fixed output */
+- hws[IMX8MQ_SYS1_PLL_40M_CG] = imx_clk_hw_gate("sys1_pll_40m_cg", "sys1_pll_out", base + 0x30, 9);
+- hws[IMX8MQ_SYS1_PLL_80M_CG] = imx_clk_hw_gate("sys1_pll_80m_cg", "sys1_pll_out", base + 0x30, 11);
+- hws[IMX8MQ_SYS1_PLL_100M_CG] = imx_clk_hw_gate("sys1_pll_100m_cg", "sys1_pll_out", base + 0x30, 13);
+- hws[IMX8MQ_SYS1_PLL_133M_CG] = imx_clk_hw_gate("sys1_pll_133m_cg", "sys1_pll_out", base + 0x30, 15);
+- hws[IMX8MQ_SYS1_PLL_160M_CG] = imx_clk_hw_gate("sys1_pll_160m_cg", "sys1_pll_out", base + 0x30, 17);
+- hws[IMX8MQ_SYS1_PLL_200M_CG] = imx_clk_hw_gate("sys1_pll_200m_cg", "sys1_pll_out", base + 0x30, 19);
+- hws[IMX8MQ_SYS1_PLL_266M_CG] = imx_clk_hw_gate("sys1_pll_266m_cg", "sys1_pll_out", base + 0x30, 21);
+- hws[IMX8MQ_SYS1_PLL_400M_CG] = imx_clk_hw_gate("sys1_pll_400m_cg", "sys1_pll_out", base + 0x30, 23);
+- hws[IMX8MQ_SYS1_PLL_800M_CG] = imx_clk_hw_gate("sys1_pll_800m_cg", "sys1_pll_out", base + 0x30, 25);
+-
+- hws[IMX8MQ_SYS1_PLL_40M] = imx_clk_hw_fixed_factor("sys1_pll_40m", "sys1_pll_40m_cg", 1, 20);
+- hws[IMX8MQ_SYS1_PLL_80M] = imx_clk_hw_fixed_factor("sys1_pll_80m", "sys1_pll_80m_cg", 1, 10);
+- hws[IMX8MQ_SYS1_PLL_100M] = imx_clk_hw_fixed_factor("sys1_pll_100m", "sys1_pll_100m_cg", 1, 8);
+- hws[IMX8MQ_SYS1_PLL_133M] = imx_clk_hw_fixed_factor("sys1_pll_133m", "sys1_pll_133m_cg", 1, 6);
+- hws[IMX8MQ_SYS1_PLL_160M] = imx_clk_hw_fixed_factor("sys1_pll_160m", "sys1_pll_160m_cg", 1, 5);
+- hws[IMX8MQ_SYS1_PLL_200M] = imx_clk_hw_fixed_factor("sys1_pll_200m", "sys1_pll_200m_cg", 1, 4);
+- hws[IMX8MQ_SYS1_PLL_266M] = imx_clk_hw_fixed_factor("sys1_pll_266m", "sys1_pll_266m_cg", 1, 3);
+- hws[IMX8MQ_SYS1_PLL_400M] = imx_clk_hw_fixed_factor("sys1_pll_400m", "sys1_pll_400m_cg", 1, 2);
+- hws[IMX8MQ_SYS1_PLL_800M] = imx_clk_hw_fixed_factor("sys1_pll_800m", "sys1_pll_800m_cg", 1, 1);
++ hws[IMX8MQ_SYS1_PLL_40M] = imx_clk_hw_fixed_factor("sys1_pll_40m", "sys1_pll_out", 1, 20);
++ hws[IMX8MQ_SYS1_PLL_80M] = imx_clk_hw_fixed_factor("sys1_pll_80m", "sys1_pll_out", 1, 10);
++ hws[IMX8MQ_SYS1_PLL_100M] = imx_clk_hw_fixed_factor("sys1_pll_100m", "sys1_pll_out", 1, 8);
++ hws[IMX8MQ_SYS1_PLL_133M] = imx_clk_hw_fixed_factor("sys1_pll_133m", "sys1_pll_out", 1, 6);
++ hws[IMX8MQ_SYS1_PLL_160M] = imx_clk_hw_fixed_factor("sys1_pll_160m", "sys1_pll_out", 1, 5);
++ hws[IMX8MQ_SYS1_PLL_200M] = imx_clk_hw_fixed_factor("sys1_pll_200m", "sys1_pll_out", 1, 4);
++ hws[IMX8MQ_SYS1_PLL_266M] = imx_clk_hw_fixed_factor("sys1_pll_266m", "sys1_pll_out", 1, 3);
++ hws[IMX8MQ_SYS1_PLL_400M] = imx_clk_hw_fixed_factor("sys1_pll_400m", "sys1_pll_out", 1, 2);
++ hws[IMX8MQ_SYS1_PLL_800M] = imx_clk_hw_fixed_factor("sys1_pll_800m", "sys1_pll_out", 1, 1);
+
+ /* SYS PLL2 fixed output */
+- hws[IMX8MQ_SYS2_PLL_50M_CG] = imx_clk_hw_gate("sys2_pll_50m_cg", "sys2_pll_out", base + 0x3c, 9);
+- hws[IMX8MQ_SYS2_PLL_100M_CG] = imx_clk_hw_gate("sys2_pll_100m_cg", "sys2_pll_out", base + 0x3c, 11);
+- hws[IMX8MQ_SYS2_PLL_125M_CG] = imx_clk_hw_gate("sys2_pll_125m_cg", "sys2_pll_out", base + 0x3c, 13);
+- hws[IMX8MQ_SYS2_PLL_166M_CG] = imx_clk_hw_gate("sys2_pll_166m_cg", "sys2_pll_out", base + 0x3c, 15);
+- hws[IMX8MQ_SYS2_PLL_200M_CG] = imx_clk_hw_gate("sys2_pll_200m_cg", "sys2_pll_out", base + 0x3c, 17);
+- hws[IMX8MQ_SYS2_PLL_250M_CG] = imx_clk_hw_gate("sys2_pll_250m_cg", "sys2_pll_out", base + 0x3c, 19);
+- hws[IMX8MQ_SYS2_PLL_333M_CG] = imx_clk_hw_gate("sys2_pll_333m_cg", "sys2_pll_out", base + 0x3c, 21);
+- hws[IMX8MQ_SYS2_PLL_500M_CG] = imx_clk_hw_gate("sys2_pll_500m_cg", "sys2_pll_out", base + 0x3c, 23);
+- hws[IMX8MQ_SYS2_PLL_1000M_CG] = imx_clk_hw_gate("sys2_pll_1000m_cg", "sys2_pll_out", base + 0x3c, 25);
+-
+- hws[IMX8MQ_SYS2_PLL_50M] = imx_clk_hw_fixed_factor("sys2_pll_50m", "sys2_pll_50m_cg", 1, 20);
+- hws[IMX8MQ_SYS2_PLL_100M] = imx_clk_hw_fixed_factor("sys2_pll_100m", "sys2_pll_100m_cg", 1, 10);
+- hws[IMX8MQ_SYS2_PLL_125M] = imx_clk_hw_fixed_factor("sys2_pll_125m", "sys2_pll_125m_cg", 1, 8);
+- hws[IMX8MQ_SYS2_PLL_166M] = imx_clk_hw_fixed_factor("sys2_pll_166m", "sys2_pll_166m_cg", 1, 6);
+- hws[IMX8MQ_SYS2_PLL_200M] = imx_clk_hw_fixed_factor("sys2_pll_200m", "sys2_pll_200m_cg", 1, 5);
+- hws[IMX8MQ_SYS2_PLL_250M] = imx_clk_hw_fixed_factor("sys2_pll_250m", "sys2_pll_250m_cg", 1, 4);
+- hws[IMX8MQ_SYS2_PLL_333M] = imx_clk_hw_fixed_factor("sys2_pll_333m", "sys2_pll_333m_cg", 1, 3);
+- hws[IMX8MQ_SYS2_PLL_500M] = imx_clk_hw_fixed_factor("sys2_pll_500m", "sys2_pll_500m_cg", 1, 2);
+- hws[IMX8MQ_SYS2_PLL_1000M] = imx_clk_hw_fixed_factor("sys2_pll_1000m", "sys2_pll_1000m_cg", 1, 1);
++ hws[IMX8MQ_SYS2_PLL_50M] = imx_clk_hw_fixed_factor("sys2_pll_50m", "sys2_pll_out", 1, 20);
++ hws[IMX8MQ_SYS2_PLL_100M] = imx_clk_hw_fixed_factor("sys2_pll_100m", "sys2_pll_out", 1, 10);
++ hws[IMX8MQ_SYS2_PLL_125M] = imx_clk_hw_fixed_factor("sys2_pll_125m", "sys2_pll_out", 1, 8);
++ hws[IMX8MQ_SYS2_PLL_166M] = imx_clk_hw_fixed_factor("sys2_pll_166m", "sys2_pll_out", 1, 6);
++ hws[IMX8MQ_SYS2_PLL_200M] = imx_clk_hw_fixed_factor("sys2_pll_200m", "sys2_pll_out", 1, 5);
++ hws[IMX8MQ_SYS2_PLL_250M] = imx_clk_hw_fixed_factor("sys2_pll_250m", "sys2_pll_out", 1, 4);
++ hws[IMX8MQ_SYS2_PLL_333M] = imx_clk_hw_fixed_factor("sys2_pll_333m", "sys2_pll_out", 1, 3);
++ hws[IMX8MQ_SYS2_PLL_500M] = imx_clk_hw_fixed_factor("sys2_pll_500m", "sys2_pll_out", 1, 2);
++ hws[IMX8MQ_SYS2_PLL_1000M] = imx_clk_hw_fixed_factor("sys2_pll_1000m", "sys2_pll_out", 1, 1);
+
+ hws[IMX8MQ_CLK_MON_AUDIO_PLL1_DIV] = imx_clk_hw_divider("audio_pll1_out_monitor", "audio_pll1_bypass", base + 0x78, 0, 3);
+ hws[IMX8MQ_CLK_MON_AUDIO_PLL2_DIV] = imx_clk_hw_divider("audio_pll2_out_monitor", "audio_pll2_bypass", base + 0x78, 4, 3);
+diff --git a/include/dt-bindings/clock/imx8mq-clock.h b/include/dt-bindings/clock/imx8mq-clock.h
+index 82e907ce7bdd..afa74d7ba100 100644
+--- a/include/dt-bindings/clock/imx8mq-clock.h
++++ b/include/dt-bindings/clock/imx8mq-clock.h
+@@ -405,25 +405,6 @@
+
+ #define IMX8MQ_VIDEO2_PLL1_REF_SEL 266
+
+-#define IMX8MQ_SYS1_PLL_40M_CG 267
+-#define IMX8MQ_SYS1_PLL_80M_CG 268
+-#define IMX8MQ_SYS1_PLL_100M_CG 269
+-#define IMX8MQ_SYS1_PLL_133M_CG 270
+-#define IMX8MQ_SYS1_PLL_160M_CG 271
+-#define IMX8MQ_SYS1_PLL_200M_CG 272
+-#define IMX8MQ_SYS1_PLL_266M_CG 273
+-#define IMX8MQ_SYS1_PLL_400M_CG 274
+-#define IMX8MQ_SYS1_PLL_800M_CG 275
+-#define IMX8MQ_SYS2_PLL_50M_CG 276
+-#define IMX8MQ_SYS2_PLL_100M_CG 277
+-#define IMX8MQ_SYS2_PLL_125M_CG 278
+-#define IMX8MQ_SYS2_PLL_166M_CG 279
+-#define IMX8MQ_SYS2_PLL_200M_CG 280
+-#define IMX8MQ_SYS2_PLL_250M_CG 281
+-#define IMX8MQ_SYS2_PLL_333M_CG 282
+-#define IMX8MQ_SYS2_PLL_500M_CG 283
+-#define IMX8MQ_SYS2_PLL_1000M_CG 284
+-
+ #define IMX8MQ_CLK_GPU_CORE 285
+ #define IMX8MQ_CLK_GPU_SHADER 286
+ #define IMX8MQ_CLK_M4_CORE 287
+--
+2.30.2
+
--- /dev/null
+From 0f8ace2714628b8204131456c26f2f38691cab38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Apr 2021 11:03:25 +0200
+Subject: clk: meson: g12a: fix gp0 and hifi ranges
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit bc794f8c56abddf709f1f84fcb2a3c9e7d9cc9b4 ]
+
+While some SoC samples are able to lock with a PLL factor of 55, others
+samples can't. ATM, a minimum of 60 appears to work on all the samples
+I have tried.
+
+Even with 60, it sometimes takes a long time for the PLL to eventually
+lock. The documentation says that the minimum rate of these PLLs DCO
+should be 3GHz, a factor of 125. Let's use that to be on the safe side.
+
+With factor range changed, the PLL seems to lock quickly (enough) so far.
+It is still unclear if the range was the only reason for the delay.
+
+Fixes: 085a4ea93d54 ("clk: meson: g12a: add peripheral clock controller")
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Acked-by: Neil Armstrong <narmstrong@baylibre.com>
+Link: https://lore.kernel.org/r/20210429090325.60970-1-jbrunet@baylibre.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/meson/g12a.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
+index b080359b4645..a805bac93c11 100644
+--- a/drivers/clk/meson/g12a.c
++++ b/drivers/clk/meson/g12a.c
+@@ -1603,7 +1603,7 @@ static struct clk_regmap g12b_cpub_clk_trace = {
+ };
+
+ static const struct pll_mult_range g12a_gp0_pll_mult_range = {
+- .min = 55,
++ .min = 125,
+ .max = 255,
+ };
+
+--
+2.30.2
+
--- /dev/null
+From f4acb2f38ff3e82ee8e94412d9dc4b8756487864 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Jun 2021 22:28:52 -0400
+Subject: clk: qcom: clk-alpha-pll: fix CAL_L write in alpha_pll_fabia_prepare
+
+From: Jonathan Marek <jonathan@marek.ca>
+
+[ Upstream commit 7f54bf2640e877c8a9b4cc7e2b29f82e3ca1a284 ]
+
+Caught this when looking at alpha-pll code. Untested but it is clear that
+this was intended to write to PLL_CAL_L_VAL and not PLL_ALPHA_VAL.
+
+Fixes: 691865bad627 ("clk: qcom: clk-alpha-pll: Add support for Fabia PLL calibration")
+Signed-off-by: Jonathan Marek <jonathan@marek.ca>
+Link: https://lore.kernel.org/r/20210609022852.4151-1-jonathan@marek.ca
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/clk-alpha-pll.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
+index c6eb99169ddc..6f8f0bbc5ab5 100644
+--- a/drivers/clk/qcom/clk-alpha-pll.c
++++ b/drivers/clk/qcom/clk-alpha-pll.c
+@@ -1234,7 +1234,7 @@ static int alpha_pll_fabia_prepare(struct clk_hw *hw)
+ return ret;
+
+ /* Setup PLL for calibration frequency */
+- regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), cal_l);
++ regmap_write(pll->clkr.regmap, PLL_CAL_L_VAL(pll), cal_l);
+
+ /* Bringup the PLL at calibration frequency */
+ ret = clk_alpha_pll_enable(hw);
+--
+2.30.2
+
--- /dev/null
+From e99add914838d1291c1105d4ed644a30dfd5abb9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 17:27:51 +0530
+Subject: clk: qcom: gcc: Add support for a new frequency for SC7280
+
+From: Taniya Das <tdas@codeaurora.org>
+
+[ Upstream commit ca1c667f4be935825fffb232a106c9d3f1c09b0b ]
+
+There is a requirement to support 52MHz for qup clocks for bluetooth
+usecase, thus update the frequency table to support the frequency.
+
+Fixes: a3cc092196ef ("clk: qcom: Add Global Clock controller (GCC) driver for SC7280")
+Signed-off-by: Taniya Das <tdas@codeaurora.org>
+Link: https://lore.kernel.org/r/1624449471-9984-1-git-send-email-tdas@codeaurora.org
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sc7280.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/qcom/gcc-sc7280.c b/drivers/clk/qcom/gcc-sc7280.c
+index ef734db316df..6cefcdc86990 100644
+--- a/drivers/clk/qcom/gcc-sc7280.c
++++ b/drivers/clk/qcom/gcc-sc7280.c
+@@ -716,6 +716,7 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s2_clk_src[] = {
+ F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625),
+ F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75),
+ F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25),
++ F(52174000, P_GCC_GPLL0_OUT_MAIN, 1, 2, 23),
+ F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75),
+ F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0),
+ F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15),
+--
+2.30.2
+
--- /dev/null
+From f5fdebd426b70d2907841ded97a9386dc2f9a050 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 May 2021 13:41:49 -0400
+Subject: clk: rockchip: fix rk3568 cpll clk gate bits
+
+From: Peter Geis <pgwipeout@gmail.com>
+
+[ Upstream commit 2f3877d609e7951ef96d24979eb9d163f1f004f8 ]
+
+The cpll clk gate bits had an ordering issue. This led to the loss of
+the boot sdmmc controller when the gmac was shut down with:
+`ip link set eth0 down`
+as the cpll_100m was shut off instead of the cpll_62p5.
+cpll_62p5, cpll_50m, cpll_25m were all off by one with cpll_100m
+misplaced.
+
+Fixes: cf911d89c4c5 ("clk: rockchip: add clock controller for rk3568")
+Signed-off-by: Peter Geis <pgwipeout@gmail.com>
+Reviewed-by: Elaine Zhang<zhangqing@rock-chips.com>
+Link: https://lore.kernel.org/r/20210519174149.3691335-1-pgwipeout@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/rockchip/clk-rk3568.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c
+index 946ea2f45bf3..75ca855e720d 100644
+--- a/drivers/clk/rockchip/clk-rk3568.c
++++ b/drivers/clk/rockchip/clk-rk3568.c
+@@ -454,17 +454,17 @@ static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = {
+ COMPOSITE_NOMUX(CPLL_125M, "cpll_125m", "cpll", CLK_IGNORE_UNUSED,
+ RK3568_CLKSEL_CON(80), 0, 5, DFLAGS,
+ RK3568_CLKGATE_CON(35), 10, GFLAGS),
++ COMPOSITE_NOMUX(CPLL_100M, "cpll_100m", "cpll", CLK_IGNORE_UNUSED,
++ RK3568_CLKSEL_CON(82), 0, 5, DFLAGS,
++ RK3568_CLKGATE_CON(35), 11, GFLAGS),
+ COMPOSITE_NOMUX(CPLL_62P5M, "cpll_62p5", "cpll", CLK_IGNORE_UNUSED,
+ RK3568_CLKSEL_CON(80), 8, 5, DFLAGS,
+- RK3568_CLKGATE_CON(35), 11, GFLAGS),
++ RK3568_CLKGATE_CON(35), 12, GFLAGS),
+ COMPOSITE_NOMUX(CPLL_50M, "cpll_50m", "cpll", CLK_IGNORE_UNUSED,
+ RK3568_CLKSEL_CON(81), 0, 5, DFLAGS,
+- RK3568_CLKGATE_CON(35), 12, GFLAGS),
++ RK3568_CLKGATE_CON(35), 13, GFLAGS),
+ COMPOSITE_NOMUX(CPLL_25M, "cpll_25m", "cpll", CLK_IGNORE_UNUSED,
+ RK3568_CLKSEL_CON(81), 8, 6, DFLAGS,
+- RK3568_CLKGATE_CON(35), 13, GFLAGS),
+- COMPOSITE_NOMUX(CPLL_100M, "cpll_100m", "cpll", CLK_IGNORE_UNUSED,
+- RK3568_CLKSEL_CON(82), 0, 5, DFLAGS,
+ RK3568_CLKGATE_CON(35), 14, GFLAGS),
+ COMPOSITE_NOMUX(0, "clk_osc0_div_750k", "xin24m", CLK_IGNORE_UNUSED,
+ RK3568_CLKSEL_CON(82), 8, 6, DFLAGS,
+--
+2.30.2
+
--- /dev/null
+From 6f136457510c0a10eb51cc8545445de7b0d7c21e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 13:26:37 -0600
+Subject: clk: si5341: Avoid divide errors due to bogus register contents
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit 78f6f406026d688868223d5dbeb197a4f7e9a9fd ]
+
+If the Si5341 is being initially programmed and has no stored NVM
+configuration, some of the register contents may contain unexpected
+values, such as zeros, which could cause divide by zero errors during
+driver initialization. Trap errors caused by zero registers or zero clock
+rates which could result in divide errors later in the code.
+
+Fixes: 3044a860fd ("clk: Add Si5341/Si5340 driver")
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Link: https://lore.kernel.org/r/20210325192643.2190069-4-robert.hancock@calian.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-si5341.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c
+index b8a960e927bc..ac1ccec2b681 100644
+--- a/drivers/clk/clk-si5341.c
++++ b/drivers/clk/clk-si5341.c
+@@ -624,6 +624,9 @@ static unsigned long si5341_synth_clk_recalc_rate(struct clk_hw *hw,
+ SI5341_SYNTH_N_NUM(synth->index), &n_num, &n_den);
+ if (err < 0)
+ return err;
++ /* Check for bogus/uninitialized settings */
++ if (!n_num || !n_den)
++ return 0;
+
+ /*
+ * n_num and n_den are shifted left as much as possible, so to prevent
+@@ -807,6 +810,9 @@ static long si5341_output_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+ {
+ unsigned long r;
+
++ if (!rate)
++ return 0;
++
+ r = *parent_rate >> 1;
+
+ /* If rate is an even divisor, no changes to parent required */
+@@ -835,11 +841,16 @@ static int si5341_output_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+ {
+ struct clk_si5341_output *output = to_clk_si5341_output(hw);
+- /* Frequency divider is (r_div + 1) * 2 */
+- u32 r_div = (parent_rate / rate) >> 1;
++ u32 r_div;
+ int err;
+ u8 r[3];
+
++ if (!rate)
++ return -EINVAL;
++
++ /* Frequency divider is (r_div + 1) * 2 */
++ r_div = (parent_rate / rate) >> 1;
++
+ if (r_div <= 1)
+ r_div = 0;
+ else if (r_div >= BIT(24))
+--
+2.30.2
+
--- /dev/null
+From e8738af8d4a126eb35e17d1c7036db20405b399c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 13:26:38 -0600
+Subject: clk: si5341: Check for input clock presence and PLL lock on startup
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit 71dcc4d1f7d2ad97ff7ab831281bc6893ff713a2 ]
+
+After initializing the device, wait for it to report that the input
+clock is present and the PLL has locked before declaring success.
+
+Fixes: 3044a860fd ("clk: Add Si5341/Si5340 driver")
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Link: https://lore.kernel.org/r/20210325192643.2190069-5-robert.hancock@calian.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-si5341.c | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c
+index ac1ccec2b681..da40b90c2aa8 100644
+--- a/drivers/clk/clk-si5341.c
++++ b/drivers/clk/clk-si5341.c
+@@ -92,6 +92,9 @@ struct clk_si5341_output_config {
+ #define SI5341_PN_BASE 0x0002
+ #define SI5341_DEVICE_REV 0x0005
+ #define SI5341_STATUS 0x000C
++#define SI5341_LOS 0x000D
++#define SI5341_STATUS_STICKY 0x0011
++#define SI5341_LOS_STICKY 0x0012
+ #define SI5341_SOFT_RST 0x001C
+ #define SI5341_IN_SEL 0x0021
+ #define SI5341_DEVICE_READY 0x00FE
+@@ -99,6 +102,12 @@ struct clk_si5341_output_config {
+ #define SI5341_IN_EN 0x0949
+ #define SI5341_INX_TO_PFD_EN 0x094A
+
++/* Status bits */
++#define SI5341_STATUS_SYSINCAL BIT(0)
++#define SI5341_STATUS_LOSXAXB BIT(1)
++#define SI5341_STATUS_LOSREF BIT(2)
++#define SI5341_STATUS_LOL BIT(3)
++
+ /* Input selection */
+ #define SI5341_IN_SEL_MASK 0x06
+ #define SI5341_IN_SEL_SHIFT 1
+@@ -1416,6 +1425,7 @@ static int si5341_probe(struct i2c_client *client,
+ unsigned int i;
+ struct clk_si5341_output_config config[SI5341_MAX_NUM_OUTPUTS];
+ bool initialization_required;
++ u32 status;
+
+ data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+@@ -1583,6 +1593,22 @@ static int si5341_probe(struct i2c_client *client,
+ return err;
+ }
+
++ /* wait for device to report input clock present and PLL lock */
++ err = regmap_read_poll_timeout(data->regmap, SI5341_STATUS, status,
++ !(status & (SI5341_STATUS_LOSREF | SI5341_STATUS_LOL)),
++ 10000, 250000);
++ if (err) {
++ dev_err(&client->dev, "Error waiting for input clock or PLL lock\n");
++ return err;
++ }
++
++ /* clear sticky alarm bits from initialization */
++ err = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0);
++ if (err) {
++ dev_err(&client->dev, "unable to clear sticky status\n");
++ return err;
++ }
++
+ /* Free the names, clk framework makes copies */
+ for (i = 0; i < data->num_synth; ++i)
+ devm_kfree(&client->dev, (void *)synth_clock_names[i]);
+--
+2.30.2
+
--- /dev/null
+From 15a418782d10ba94249ab4d24614bc4cc81b6951 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 13:26:39 -0600
+Subject: clk: si5341: Update initialization magic
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit 3c9b49b0031aefb81adfdba5ab0ddf3ca3a2cdc9 ]
+
+Update the default register settings to include the VCO_RESET_CALCODE
+settings (set by the SiLabs ClockBuilder software but not described in
+the datasheet). Also update part of the initialization sequence to match
+ClockBuilder and the datasheet.
+
+Fixes: 3044a860fd ("clk: Add Si5341/Si5340 driver")
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Link: https://lore.kernel.org/r/20210325192643.2190069-6-robert.hancock@calian.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-si5341.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c
+index da40b90c2aa8..eb22f4fdbc6b 100644
+--- a/drivers/clk/clk-si5341.c
++++ b/drivers/clk/clk-si5341.c
+@@ -350,6 +350,8 @@ static const struct si5341_reg_default si5341_reg_defaults[] = {
+ { 0x094A, 0x00 }, /* INx_TO_PFD_EN (disabled) */
+ { 0x0A02, 0x00 }, /* Not in datasheet */
+ { 0x0B44, 0x0F }, /* PDIV_ENB (datasheet does not mention what it is) */
++ { 0x0B57, 0x10 }, /* VCO_RESET_CALCODE (not described in datasheet) */
++ { 0x0B58, 0x05 }, /* VCO_RESET_CALCODE (not described in datasheet) */
+ };
+
+ /* Read and interpret a 44-bit followed by a 32-bit value in the regmap */
+@@ -1104,7 +1106,7 @@ static const struct si5341_reg_default si5341_preamble[] = {
+ { 0x0B25, 0x00 },
+ { 0x0502, 0x01 },
+ { 0x0505, 0x03 },
+- { 0x0957, 0x1F },
++ { 0x0957, 0x17 },
+ { 0x0B4E, 0x1A },
+ };
+
+--
+2.30.2
+
--- /dev/null
+From 961ce794b2d14cec3b312aef208c8a231da1cd41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 13:26:36 -0600
+Subject: clk: si5341: Wait for DEVICE_READY on startup
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit 6e7d2de1e000d36990923ed80d2e78dfcb545cee ]
+
+The Si5341 datasheet warns that before accessing any other registers,
+including the PAGE register, we need to wait for the DEVICE_READY register
+to indicate the device is ready, or the process of the device loading its
+state from NVM can be corrupted. Wait for DEVICE_READY on startup before
+continuing initialization. This is done using a raw I2C register read
+prior to setting up regmap to avoid any potential unwanted automatic PAGE
+register accesses from regmap at this stage.
+
+Fixes: 3044a860fd ("clk: Add Si5341/Si5340 driver")
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Link: https://lore.kernel.org/r/20210325192643.2190069-3-robert.hancock@calian.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-si5341.c | 32 ++++++++++++++++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+
+diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c
+index e0446e66fa64..b8a960e927bc 100644
+--- a/drivers/clk/clk-si5341.c
++++ b/drivers/clk/clk-si5341.c
+@@ -94,6 +94,7 @@ struct clk_si5341_output_config {
+ #define SI5341_STATUS 0x000C
+ #define SI5341_SOFT_RST 0x001C
+ #define SI5341_IN_SEL 0x0021
++#define SI5341_DEVICE_READY 0x00FE
+ #define SI5341_XAXB_CFG 0x090E
+ #define SI5341_IN_EN 0x0949
+ #define SI5341_INX_TO_PFD_EN 0x094A
+@@ -1189,6 +1190,32 @@ static const struct regmap_range_cfg si5341_regmap_ranges[] = {
+ },
+ };
+
++static int si5341_wait_device_ready(struct i2c_client *client)
++{
++ int count;
++
++ /* Datasheet warns: Any attempt to read or write any register other
++ * than DEVICE_READY before DEVICE_READY reads as 0x0F may corrupt the
++ * NVM programming and may corrupt the register contents, as they are
++ * read from NVM. Note that this includes accesses to the PAGE register.
++ * Also: DEVICE_READY is available on every register page, so no page
++ * change is needed to read it.
++ * Do this outside regmap to avoid automatic PAGE register access.
++ * May take up to 300ms to complete.
++ */
++ for (count = 0; count < 15; ++count) {
++ s32 result = i2c_smbus_read_byte_data(client,
++ SI5341_DEVICE_READY);
++ if (result < 0)
++ return result;
++ if (result == 0x0F)
++ return 0;
++ msleep(20);
++ }
++ dev_err(&client->dev, "timeout waiting for DEVICE_READY\n");
++ return -EIO;
++}
++
+ static const struct regmap_config si5341_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+@@ -1385,6 +1412,11 @@ static int si5341_probe(struct i2c_client *client,
+
+ data->i2c_client = client;
+
++ /* Must be done before otherwise touching hardware */
++ err = si5341_wait_device_ready(client);
++ if (err)
++ return err;
++
+ for (i = 0; i < SI5341_NUM_INPUTS; ++i) {
+ input = devm_clk_get(&client->dev, si5341_input_clock_names[i]);
+ if (IS_ERR(input)) {
+--
+2.30.2
+
--- /dev/null
+From d6036b6d1a0b37b2b6c89500c0ea155e363c8eda Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 May 2021 15:13:15 +0200
+Subject: clk: sunxi-ng: v3s: fix incorrect postdivider on pll-audio
+
+From: Tobias Schramm <t.schramm@manjaro.org>
+
+[ Upstream commit 47e4dc4e63e1dcb8eec01c4214bcefc248eb72ed ]
+
+Commit 46060be6d840 ("clk: sunxi-ng: v3s: use sigma-delta modulation for audio-pll")
+changed the audio pll on the Allwinner V3s and V3 SoCs to use
+sigma-delta modulation. In the process the declaration of fixed postdivider
+providing "pll-audio" was adjusted to provide the desired clock rates from
+the now sigma-delta modulated pll.
+However, while the divider used for calculations by the clock framework
+was adjusted the actual divider programmed into the hardware in
+sun8i_v3_v3s_ccu_init was left at "divide by four". This broke the
+"pll-audio" clock, now only providing quater the expected clock rate.
+It would in general be desirable to program the postdivider for
+"pll-audio" to four, such that a broader range of frequencies were
+available on the pll outputs. But the clock for the integrated codec
+"ac-dig" does not feature a mux that allows to select from all pll outputs
+as it is just a simple clock gate connected to "pll-audio". Thus we need
+to set the postdivider to one to be able to provide the 22.5792MHz and
+24.576MHz rates required by the internal sun4i codec.
+
+This patches fixes the incorrect clock rate by forcing the postdivider to
+one in sun8i_v3_v3s_ccu_init.
+
+Fixes: 46060be6d840 ("clk: sunxi-ng: v3s: use sigma-delta modulation for audio-pll")
+Signed-off-by: Tobias Schramm <t.schramm@manjaro.org>
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Link: https://lore.kernel.org/r/20210513131315.2059451-1-t.schramm@manjaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/sunxi-ng/ccu-sun8i-v3s.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
+index a774942cb153..f49724a22540 100644
+--- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
++++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
+@@ -817,10 +817,10 @@ static void __init sun8i_v3_v3s_ccu_init(struct device_node *node,
+ return;
+ }
+
+- /* Force the PLL-Audio-1x divider to 4 */
++ /* Force the PLL-Audio-1x divider to 1 */
+ val = readl(reg + SUN8I_V3S_PLL_AUDIO_REG);
+ val &= ~GENMASK(19, 16);
+- writel(val | (3 << 16), reg + SUN8I_V3S_PLL_AUDIO_REG);
++ writel(val, reg + SUN8I_V3S_PLL_AUDIO_REG);
+
+ sunxi_ccu_probe(node, reg, ccu_desc);
+ }
+--
+2.30.2
+
--- /dev/null
+From bd0597111bec3be9d51eb65937fa805b1c73794b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 May 2021 19:30:33 +0300
+Subject: clk: tegra30: Use 300MHz for video decoder by default
+
+From: Dmitry Osipenko <digetx@gmail.com>
+
+[ Upstream commit 56bb7c28ad00e7bcfc851c4e183c42d148d3ad4e ]
+
+The 600MHz is a too high clock rate for some SoC versions for the video
+decoder hardware and this may cause stability issues. Use 300MHz for the
+video decoder by default, which is supported by all hardware versions.
+
+Fixes: ed1a2459e20c ("clk: tegra: Add Tegra20/30 EMC clock implementation")
+Acked-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/tegra/clk-tegra30.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
+index 16dbf83d2f62..a33688b2359e 100644
+--- a/drivers/clk/tegra/clk-tegra30.c
++++ b/drivers/clk/tegra/clk-tegra30.c
+@@ -1245,7 +1245,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
+ { TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0 },
+ { TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0 },
+ { TEGRA30_CLK_PLL_U, TEGRA30_CLK_CLK_MAX, 480000000, 0 },
+- { TEGRA30_CLK_VDE, TEGRA30_CLK_PLL_C, 600000000, 0 },
++ { TEGRA30_CLK_VDE, TEGRA30_CLK_PLL_C, 300000000, 0 },
+ { TEGRA30_CLK_SPDIF_IN_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 },
+ { TEGRA30_CLK_I2S0_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 },
+ { TEGRA30_CLK_I2S1_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 },
+--
+2.30.2
+
--- /dev/null
+From c133ed4b8ee6a37d0f2d8f37b33f27f21856084d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 May 2021 23:16:47 +0200
+Subject: clk: vc5: fix output disabling when enabling a FOD
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Luca Ceresoli <luca@lucaceresoli.net>
+
+[ Upstream commit fc336ae622df0ec114dbe5551a4d2760c535ecd0 ]
+
+On 5P49V6965, when an output is enabled we enable the corresponding
+FOD. When this happens for the first time, and specifically when writing
+register VC5_OUT_DIV_CONTROL in vc5_clk_out_prepare(), all other outputs
+are stopped for a short time and then restarted.
+
+According to Renesas support this is intended: "The reason for that is VC6E
+has synced up all output function".
+
+This behaviour can be disabled at least on VersaClock 6E devices, of which
+only the 5P49V6965 is currently implemented by this driver. This requires
+writing bit 7 (bypass_sync{1..4}) in register 0x20..0x50. Those registers
+are named "Unused Factory Reserved Register", and the bits are documented
+as "Skip VDDO<N> verification", which does not clearly explain the relation
+to FOD sync. However according to Renesas support as well as my testing
+setting this bit does prevent disabling of all clock outputs when enabling
+a FOD.
+
+See "VersaClock ® 6E Family Register Descriptions and Programming Guide"
+(August 30, 2018), Table 116 "Power Up VDD check", page 58:
+https://www.renesas.com/us/en/document/mau/versaclock-6e-family-register-descriptions-and-programming-guide
+
+Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net>
+Reviewed-by: Adam Ford <aford173@gmail.com>
+Link: https://lore.kernel.org/r/20210527211647.1520720-1-luca@lucaceresoli.net
+Fixes: 2bda748e6ad8 ("clk: vc5: Add support for IDT VersaClock 5P49V6965")
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-versaclock5.c | 27 ++++++++++++++++++++++++---
+ 1 file changed, 24 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
+index 344cd6c61188..3c737742c2a9 100644
+--- a/drivers/clk/clk-versaclock5.c
++++ b/drivers/clk/clk-versaclock5.c
+@@ -69,7 +69,10 @@
+ #define VC5_FEEDBACK_FRAC_DIV(n) (0x19 + (n))
+ #define VC5_RC_CONTROL0 0x1e
+ #define VC5_RC_CONTROL1 0x1f
+-/* Register 0x20 is factory reserved */
++
++/* These registers are named "Unused Factory Reserved Registers" */
++#define VC5_RESERVED_X0(idx) (0x20 + ((idx) * 0x10))
++#define VC5_RESERVED_X0_BYPASS_SYNC BIT(7) /* bypass_sync<idx> bit */
+
+ /* Output divider control for divider 1,2,3,4 */
+ #define VC5_OUT_DIV_CONTROL(idx) (0x21 + ((idx) * 0x10))
+@@ -87,7 +90,6 @@
+ #define VC5_OUT_DIV_SKEW_INT(idx, n) (0x2b + ((idx) * 0x10) + (n))
+ #define VC5_OUT_DIV_INT(idx, n) (0x2d + ((idx) * 0x10) + (n))
+ #define VC5_OUT_DIV_SKEW_FRAC(idx) (0x2f + ((idx) * 0x10))
+-/* Registers 0x30, 0x40, 0x50 are factory reserved */
+
+ /* Clock control register for clock 1,2 */
+ #define VC5_CLK_OUTPUT_CFG(idx, n) (0x60 + ((idx) * 0x2) + (n))
+@@ -140,6 +142,8 @@
+ #define VC5_HAS_INTERNAL_XTAL BIT(0)
+ /* chip has PFD requency doubler */
+ #define VC5_HAS_PFD_FREQ_DBL BIT(1)
++/* chip has bits to disable FOD sync */
++#define VC5_HAS_BYPASS_SYNC_BIT BIT(2)
+
+ /* Supported IDT VC5 models. */
+ enum vc5_model {
+@@ -581,6 +585,23 @@ static int vc5_clk_out_prepare(struct clk_hw *hw)
+ unsigned int src;
+ int ret;
+
++ /*
++ * When enabling a FOD, all currently enabled FODs are briefly
++ * stopped in order to synchronize all of them. This causes a clock
++ * disruption to any unrelated chips that might be already using
++ * other clock outputs. Bypass the sync feature to avoid the issue,
++ * which is possible on the VersaClock 6E family via reserved
++ * registers.
++ */
++ if (vc5->chip_info->flags & VC5_HAS_BYPASS_SYNC_BIT) {
++ ret = regmap_update_bits(vc5->regmap,
++ VC5_RESERVED_X0(hwdata->num),
++ VC5_RESERVED_X0_BYPASS_SYNC,
++ VC5_RESERVED_X0_BYPASS_SYNC);
++ if (ret)
++ return ret;
++ }
++
+ /*
+ * If the input mux is disabled, enable it first and
+ * select source from matching FOD.
+@@ -1166,7 +1187,7 @@ static const struct vc5_chip_info idt_5p49v6965_info = {
+ .model = IDT_VC6_5P49V6965,
+ .clk_fod_cnt = 4,
+ .clk_out_cnt = 5,
+- .flags = 0,
++ .flags = VC5_HAS_BYPASS_SYNC_BIT,
+ };
+
+ static const struct i2c_device_id vc5_id[] = {
+--
+2.30.2
+
--- /dev/null
+From d94a877281bbc6593dc165664a8f8709d098c041 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 12:15:11 +0200
+Subject: clk: zynqmp: fix compile testing without ZYNQMP_FIRMWARE
+
+From: Michal Simek <michal.simek@xilinx.com>
+
+[ Upstream commit 6c9feabc2c6bd49abbd2130341e7cb91f42d3fa5 ]
+
+When the firmware code is disabled, the incomplete error handling
+in the clk driver causes compile-time warnings:
+
+drivers/clk/zynqmp/pll.c: In function 'zynqmp_pll_recalc_rate':
+drivers/clk/zynqmp/pll.c:147:29: error: 'fbdiv' is used uninitialized [-Werror=uninitialized]
+ 147 | rate = parent_rate * fbdiv;
+ | ~~~~~~~~~~~~^~~~~~~
+In function 'zynqmp_pll_get_mode',
+ inlined from 'zynqmp_pll_recalc_rate' at drivers/clk/zynqmp/pll.c:148:6:
+drivers/clk/zynqmp/pll.c:61:27: error: 'ret_payload' is used uninitialized [-Werror=uninitialized]
+ 61 | return ret_payload[1];
+ | ~~~~~~~~~~~^~~
+drivers/clk/zynqmp/pll.c: In function 'zynqmp_pll_recalc_rate':
+drivers/clk/zynqmp/pll.c:53:13: note: 'ret_payload' declared here
+ 53 | u32 ret_payload[PAYLOAD_ARG_CNT];
+ | ^~~~~~~~~~~
+drivers/clk/zynqmp/clk-mux-zynqmp.c: In function 'zynqmp_clk_mux_get_parent':
+drivers/clk/zynqmp/clk-mux-zynqmp.c:57:16: error: 'val' is used uninitialized [-Werror=uninitialized]
+ 57 | return val;
+ | ^~~
+
+As it was apparently intentional to support this for compile testing
+purposes, change the code to have just enough error handling for the
+compiler to not notice the remaining bugs.
+
+Fixes: 21f237534661 ("clk: zynqmp: Drop dependency on ARCH_ZYNQMP")
+Co-developed-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Michal Simek <michal.simek@xilinx.com>
+Link: https://lore.kernel.org/r/f1c4e8c903fe2d5df5413421920a56890a46387a.1624356908.git.michal.simek@xilinx.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/zynqmp/clk-mux-zynqmp.c | 10 ++++++++--
+ drivers/clk/zynqmp/pll.c | 22 ++++++++++++++++------
+ 2 files changed, 24 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c
+index 06194149be83..d576c900dee0 100644
+--- a/drivers/clk/zynqmp/clk-mux-zynqmp.c
++++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c
+@@ -38,7 +38,7 @@ struct zynqmp_clk_mux {
+ * zynqmp_clk_mux_get_parent() - Get parent of clock
+ * @hw: handle between common and hardware-specific interfaces
+ *
+- * Return: Parent index
++ * Return: Parent index on success or number of parents in case of error
+ */
+ static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw)
+ {
+@@ -50,9 +50,15 @@ static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw)
+
+ ret = zynqmp_pm_clock_getparent(clk_id, &val);
+
+- if (ret)
++ if (ret) {
+ pr_warn_once("%s() getparent failed for clock: %s, ret = %d\n",
+ __func__, clk_name, ret);
++ /*
++ * clk_core_get_parent_by_index() takes num_parents as incorrect
++ * index which is exactly what I want to return here
++ */
++ return clk_hw_get_num_parents(hw);
++ }
+
+ return val;
+ }
+diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c
+index abe6afbf3407..e025581f0d54 100644
+--- a/drivers/clk/zynqmp/pll.c
++++ b/drivers/clk/zynqmp/pll.c
+@@ -31,8 +31,9 @@ struct zynqmp_pll {
+ #define PS_PLL_VCO_MAX 3000000000UL
+
+ enum pll_mode {
+- PLL_MODE_INT,
+- PLL_MODE_FRAC,
++ PLL_MODE_INT = 0,
++ PLL_MODE_FRAC = 1,
++ PLL_MODE_ERROR = 2,
+ };
+
+ #define FRAC_OFFSET 0x8
+@@ -54,9 +55,11 @@ static inline enum pll_mode zynqmp_pll_get_mode(struct clk_hw *hw)
+ int ret;
+
+ ret = zynqmp_pm_get_pll_frac_mode(clk_id, ret_payload);
+- if (ret)
++ if (ret) {
+ pr_warn_once("%s() PLL get frac mode failed for %s, ret = %d\n",
+ __func__, clk_name, ret);
++ return PLL_MODE_ERROR;
++ }
+
+ return ret_payload[1];
+ }
+@@ -126,7 +129,7 @@ static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ * @hw: Handle between common and hardware-specific interfaces
+ * @parent_rate: Clock frequency of parent clock
+ *
+- * Return: Current clock frequency
++ * Return: Current clock frequency or 0 in case of error
+ */
+ static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+@@ -138,14 +141,21 @@ static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long rate, frac;
+ u32 ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
++ enum pll_mode mode;
+
+ ret = zynqmp_pm_clock_getdivider(clk_id, &fbdiv);
+- if (ret)
++ if (ret) {
+ pr_warn_once("%s() get divider failed for %s, ret = %d\n",
+ __func__, clk_name, ret);
++ return 0ul;
++ }
++
++ mode = zynqmp_pll_get_mode(hw);
++ if (mode == PLL_MODE_ERROR)
++ return 0ul;
+
+ rate = parent_rate * fbdiv;
+- if (zynqmp_pll_get_mode(hw) == PLL_MODE_FRAC) {
++ if (mode == PLL_MODE_FRAC) {
+ zynqmp_pm_get_pll_frac_data(clk_id, ret_payload);
+ data = ret_payload[1];
+ frac = (parent_rate * data) / FRAC_DIV;
+--
+2.30.2
+
--- /dev/null
+From c35819d9524c4f702da8e9f9896ee42797c6a556 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 May 2021 12:01:20 -0700
+Subject: clocksource: Check per-CPU clock synchronization when marked unstable
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit 7560c02bdffb7c52d1457fa551b9e745d4b9e754 ]
+
+Some sorts of per-CPU clock sources have a history of going out of
+synchronization with each other. However, this problem has purportedy been
+solved in the past ten years. Except that it is all too possible that the
+problem has instead simply been made less likely, which might mean that
+some of the occasional "Marking clocksource 'tsc' as unstable" messages
+might be due to desynchronization. How would anyone know?
+
+Therefore apply CPU-to-CPU synchronization checking to newly unstable
+clocksource that are marked with the new CLOCK_SOURCE_VERIFY_PERCPU flag.
+Lists of desynchronized CPUs are printed, with the caveat that if it
+is the reporting CPU that is itself desynchronized, it will appear that
+all the other clocks are wrong. Just like in real life.
+
+Reported-by: Chris Mason <clm@fb.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Feng Tang <feng.tang@intel.com>
+Link: https://lore.kernel.org/r/20210527190124.440372-2-paulmck@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/tsc.c | 3 +-
+ include/linux/clocksource.h | 2 +-
+ kernel/time/clocksource.c | 60 +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 63 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
+index 57ec01192180..6eb1b097e97e 100644
+--- a/arch/x86/kernel/tsc.c
++++ b/arch/x86/kernel/tsc.c
+@@ -1152,7 +1152,8 @@ static struct clocksource clocksource_tsc = {
+ .mask = CLOCKSOURCE_MASK(64),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS |
+ CLOCK_SOURCE_VALID_FOR_HRES |
+- CLOCK_SOURCE_MUST_VERIFY,
++ CLOCK_SOURCE_MUST_VERIFY |
++ CLOCK_SOURCE_VERIFY_PERCPU,
+ .vdso_clock_mode = VDSO_CLOCKMODE_TSC,
+ .enable = tsc_cs_enable,
+ .resume = tsc_resume,
+diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
+index d6ab416ee2d2..7f83d51c0fd7 100644
+--- a/include/linux/clocksource.h
++++ b/include/linux/clocksource.h
+@@ -137,7 +137,7 @@ struct clocksource {
+ #define CLOCK_SOURCE_UNSTABLE 0x40
+ #define CLOCK_SOURCE_SUSPEND_NONSTOP 0x80
+ #define CLOCK_SOURCE_RESELECT 0x100
+-
++#define CLOCK_SOURCE_VERIFY_PERCPU 0x200
+ /* simplify initialization of mask field */
+ #define CLOCKSOURCE_MASK(bits) GENMASK_ULL((bits) - 1, 0)
+
+diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
+index 43243f2be98e..cb12225bf050 100644
+--- a/kernel/time/clocksource.c
++++ b/kernel/time/clocksource.c
+@@ -224,6 +224,60 @@ static bool cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow)
+ return false;
+ }
+
++static u64 csnow_mid;
++static cpumask_t cpus_ahead;
++static cpumask_t cpus_behind;
++
++static void clocksource_verify_one_cpu(void *csin)
++{
++ struct clocksource *cs = (struct clocksource *)csin;
++
++ csnow_mid = cs->read(cs);
++}
++
++static void clocksource_verify_percpu(struct clocksource *cs)
++{
++ int64_t cs_nsec, cs_nsec_max = 0, cs_nsec_min = LLONG_MAX;
++ u64 csnow_begin, csnow_end;
++ int cpu, testcpu;
++ s64 delta;
++
++ cpumask_clear(&cpus_ahead);
++ cpumask_clear(&cpus_behind);
++ preempt_disable();
++ testcpu = smp_processor_id();
++ pr_warn("Checking clocksource %s synchronization from CPU %d.\n", cs->name, testcpu);
++ for_each_online_cpu(cpu) {
++ if (cpu == testcpu)
++ continue;
++ csnow_begin = cs->read(cs);
++ smp_call_function_single(cpu, clocksource_verify_one_cpu, cs, 1);
++ csnow_end = cs->read(cs);
++ delta = (s64)((csnow_mid - csnow_begin) & cs->mask);
++ if (delta < 0)
++ cpumask_set_cpu(cpu, &cpus_behind);
++ delta = (csnow_end - csnow_mid) & cs->mask;
++ if (delta < 0)
++ cpumask_set_cpu(cpu, &cpus_ahead);
++ delta = clocksource_delta(csnow_end, csnow_begin, cs->mask);
++ cs_nsec = clocksource_cyc2ns(delta, cs->mult, cs->shift);
++ if (cs_nsec > cs_nsec_max)
++ cs_nsec_max = cs_nsec;
++ if (cs_nsec < cs_nsec_min)
++ cs_nsec_min = cs_nsec;
++ }
++ preempt_enable();
++ if (!cpumask_empty(&cpus_ahead))
++ pr_warn(" CPUs %*pbl ahead of CPU %d for clocksource %s.\n",
++ cpumask_pr_args(&cpus_ahead), testcpu, cs->name);
++ if (!cpumask_empty(&cpus_behind))
++ pr_warn(" CPUs %*pbl behind CPU %d for clocksource %s.\n",
++ cpumask_pr_args(&cpus_behind), testcpu, cs->name);
++ if (!cpumask_empty(&cpus_ahead) || !cpumask_empty(&cpus_behind))
++ pr_warn(" CPU %d check durations %lldns - %lldns for clocksource %s.\n",
++ testcpu, cs_nsec_min, cs_nsec_max, cs->name);
++}
++
+ static void clocksource_watchdog(struct timer_list *unused)
+ {
+ u64 csnow, wdnow, cslast, wdlast, delta;
+@@ -448,6 +502,12 @@ static int __clocksource_watchdog_kthread(void)
+ unsigned long flags;
+ int select = 0;
+
++ /* Do any required per-CPU skew verification. */
++ if (curr_clocksource &&
++ curr_clocksource->flags & CLOCK_SOURCE_UNSTABLE &&
++ curr_clocksource->flags & CLOCK_SOURCE_VERIFY_PERCPU)
++ clocksource_verify_percpu(curr_clocksource);
++
+ spin_lock_irqsave(&watchdog_lock, flags);
+ list_for_each_entry_safe(cs, tmp, &watchdog_list, wd_list) {
+ if (cs->flags & CLOCK_SOURCE_UNSTABLE) {
+--
+2.30.2
+
--- /dev/null
+From bcac9df87058b95300770286737eabed117d98cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 11:55:06 +0300
+Subject: clocksource/drivers/timer-ti-dm: Save and restore timer TIOCP_CFG
+
+From: Tony Lindgren <tony@atomide.com>
+
+[ Upstream commit 9517c577f9f722270584cfb1a7b4e1354e408658 ]
+
+As we are using cpu_pm to save and restore context, we must also save and
+restore the timer sysconfig register TIOCP_CFG. This is needed because
+we are not calling PM runtime functions at all with cpu_pm.
+
+Fixes: b34677b0999a ("clocksource/drivers/timer-ti-dm: Implement cpu_pm notifier for context save and restore")
+Cc: Aaro Koskinen <aaro.koskinen@iki.fi>
+Cc: Adam Ford <aford173@gmail.com>
+Cc: Andreas Kemnade <andreas@kemnade.info>
+Cc: Lokesh Vutla <lokeshvutla@ti.com>
+Cc: Peter Ujfalusi <peter.ujfalusi@gmail.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20210415085506.56828-1-tony@atomide.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clocksource/timer-ti-dm.c | 6 ++++++
+ include/clocksource/timer-ti-dm.h | 1 +
+ 2 files changed, 7 insertions(+)
+
+diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
+index 33eeabf9c3d1..e5c631f1b5cb 100644
+--- a/drivers/clocksource/timer-ti-dm.c
++++ b/drivers/clocksource/timer-ti-dm.c
+@@ -78,6 +78,9 @@ static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
+
+ static void omap_timer_restore_context(struct omap_dm_timer *timer)
+ {
++ __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET,
++ timer->context.ocp_cfg, 0);
++
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG,
+ timer->context.twer);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG,
+@@ -95,6 +98,9 @@ static void omap_timer_restore_context(struct omap_dm_timer *timer)
+
+ static void omap_timer_save_context(struct omap_dm_timer *timer)
+ {
++ timer->context.ocp_cfg =
++ __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0);
++
+ timer->context.tclr =
+ omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+ timer->context.twer =
+diff --git a/include/clocksource/timer-ti-dm.h b/include/clocksource/timer-ti-dm.h
+index 4c61dade8835..f6da8a132639 100644
+--- a/include/clocksource/timer-ti-dm.h
++++ b/include/clocksource/timer-ti-dm.h
+@@ -74,6 +74,7 @@
+ #define OMAP_TIMER_ERRATA_I103_I767 0x80000000
+
+ struct timer_regs {
++ u32 ocp_cfg;
+ u32 tidr;
+ u32 tier;
+ u32 twer;
+--
+2.30.2
+
--- /dev/null
+From 04895b9a50ab3963209cf54771aeef1610d96752 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 May 2021 12:01:19 -0700
+Subject: clocksource: Retry clock read if long delays detected
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit db3a34e17433de2390eb80d436970edcebd0ca3e ]
+
+When the clocksource watchdog marks a clock as unstable, this might be due
+to that clock being unstable or it might be due to delays that happen to
+occur between the reads of the two clocks. Yes, interrupts are disabled
+across those two reads, but there are no shortage of things that can delay
+interrupts-disabled regions of code ranging from SMI handlers to vCPU
+preemption. It would be good to have some indication as to why the clock
+was marked unstable.
+
+Therefore, re-read the watchdog clock on either side of the read from the
+clock under test. If the watchdog clock shows an excessive time delta
+between its pair of reads, the reads are retried.
+
+The maximum number of retries is specified by a new kernel boot parameter
+clocksource.max_cswd_read_retries, which defaults to three, that is, up to
+four reads, one initial and up to three retries. If more than one retry
+was required, a message is printed on the console (the occasional single
+retry is expected behavior, especially in guest OSes). If the maximum
+number of retries is exceeded, the clock under test will be marked
+unstable. However, the probability of this happening due to various sorts
+of delays is quite small. In addition, the reason (clock-read delays) for
+the unstable marking will be apparent.
+
+Reported-by: Chris Mason <clm@fb.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Feng Tang <feng.tang@intel.com>
+Link: https://lore.kernel.org/r/20210527190124.440372-1-paulmck@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../admin-guide/kernel-parameters.txt | 6 +++
+ kernel/time/clocksource.c | 53 ++++++++++++++++---
+ 2 files changed, 53 insertions(+), 6 deletions(-)
+
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index cb89dbdedc46..995deccc28bc 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -581,6 +581,12 @@
+ loops can be debugged more effectively on production
+ systems.
+
++ clocksource.max_cswd_read_retries= [KNL]
++ Number of clocksource_watchdog() retries due to
++ external delays before the clock will be marked
++ unstable. Defaults to three retries, that is,
++ four attempts to read the clock under test.
++
+ clearcpuid=BITNUM[,BITNUM...] [X86]
+ Disable CPUID feature X for the kernel. See
+ arch/x86/include/asm/cpufeatures.h for the valid bit
+diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
+index 2cd902592fc1..43243f2be98e 100644
+--- a/kernel/time/clocksource.c
++++ b/kernel/time/clocksource.c
+@@ -124,6 +124,13 @@ static void __clocksource_change_rating(struct clocksource *cs, int rating);
+ #define WATCHDOG_INTERVAL (HZ >> 1)
+ #define WATCHDOG_THRESHOLD (NSEC_PER_SEC >> 4)
+
++/*
++ * Maximum permissible delay between two readouts of the watchdog
++ * clocksource surrounding a read of the clocksource being validated.
++ * This delay could be due to SMIs, NMIs, or to VCPU preemptions.
++ */
++#define WATCHDOG_MAX_SKEW (100 * NSEC_PER_USEC)
++
+ static void clocksource_watchdog_work(struct work_struct *work)
+ {
+ /*
+@@ -184,12 +191,45 @@ void clocksource_mark_unstable(struct clocksource *cs)
+ spin_unlock_irqrestore(&watchdog_lock, flags);
+ }
+
++static ulong max_cswd_read_retries = 3;
++module_param(max_cswd_read_retries, ulong, 0644);
++
++static bool cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow)
++{
++ unsigned int nretries;
++ u64 wd_end, wd_delta;
++ int64_t wd_delay;
++
++ for (nretries = 0; nretries <= max_cswd_read_retries; nretries++) {
++ local_irq_disable();
++ *wdnow = watchdog->read(watchdog);
++ *csnow = cs->read(cs);
++ wd_end = watchdog->read(watchdog);
++ local_irq_enable();
++
++ wd_delta = clocksource_delta(wd_end, *wdnow, watchdog->mask);
++ wd_delay = clocksource_cyc2ns(wd_delta, watchdog->mult,
++ watchdog->shift);
++ if (wd_delay <= WATCHDOG_MAX_SKEW) {
++ if (nretries > 1 || nretries >= max_cswd_read_retries) {
++ pr_warn("timekeeping watchdog on CPU%d: %s retried %d times before success\n",
++ smp_processor_id(), watchdog->name, nretries);
++ }
++ return true;
++ }
++ }
++
++ pr_warn("timekeeping watchdog on CPU%d: %s read-back delay of %lldns, attempt %d, marking unstable\n",
++ smp_processor_id(), watchdog->name, wd_delay, nretries);
++ return false;
++}
++
+ static void clocksource_watchdog(struct timer_list *unused)
+ {
+- struct clocksource *cs;
+ u64 csnow, wdnow, cslast, wdlast, delta;
+- int64_t wd_nsec, cs_nsec;
+ int next_cpu, reset_pending;
++ int64_t wd_nsec, cs_nsec;
++ struct clocksource *cs;
+
+ spin_lock(&watchdog_lock);
+ if (!watchdog_running)
+@@ -206,10 +246,11 @@ static void clocksource_watchdog(struct timer_list *unused)
+ continue;
+ }
+
+- local_irq_disable();
+- csnow = cs->read(cs);
+- wdnow = watchdog->read(watchdog);
+- local_irq_enable();
++ if (!cs_watchdog_read(cs, &csnow, &wdnow)) {
++ /* Clock readout unreliable, so give it up. */
++ __clocksource_unstable(cs);
++ continue;
++ }
+
+ /* Clocksource initialized ? */
+ if (!(cs->flags & CLOCK_SOURCE_WATCHDOG) ||
+--
+2.30.2
+
--- /dev/null
+From 846e32fbdf29c7b50a96ae289aa2f10d2fc29e98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 15:59:25 +0800
+Subject: configfs: fix memleak in configfs_release_bin_file
+
+From: Chung-Chiang Cheng <shepjeng@gmail.com>
+
+[ Upstream commit 3c252b087de08d3cb32468b54a158bd7ad0ae2f7 ]
+
+When reading binary attributes in progress, buffer->bin_buffer is setup in
+configfs_read_bin_file() but never freed.
+
+Fixes: 03607ace807b4 ("configfs: implement binary attributes")
+Signed-off-by: Chung-Chiang Cheng <cccheng@synology.com>
+[hch: move the vfree rather than duplicating it]
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/configfs/file.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/fs/configfs/file.c b/fs/configfs/file.c
+index e26060dae70a..b4b0fbabd62e 100644
+--- a/fs/configfs/file.c
++++ b/fs/configfs/file.c
+@@ -480,13 +480,13 @@ static int configfs_release_bin_file(struct inode *inode, struct file *file)
+ buffer->bin_buffer_size);
+ }
+ up_read(&frag->frag_sem);
+- /* vfree on NULL is safe */
+- vfree(buffer->bin_buffer);
+- buffer->bin_buffer = NULL;
+- buffer->bin_buffer_size = 0;
+- buffer->needs_read_fill = 1;
+ }
+
++ vfree(buffer->bin_buffer);
++ buffer->bin_buffer = NULL;
++ buffer->bin_buffer_size = 0;
++ buffer->needs_read_fill = 1;
++
+ configfs_release(inode, file);
+ return 0;
+ }
+--
+2.30.2
+
--- /dev/null
+From 7e58376f051cfa06e90ba8c868b8b37a11a4aad3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 11:58:57 -0600
+Subject: coresight: core: Fix use of uninitialized pointer
+
+From: Junhao He <hejunhao2@hisilicon.com>
+
+[ Upstream commit d777a8991847729ec4e2a13fcad58c2b00bb19dc ]
+
+Currently the pointer "sink" might be checked before initialized. Fix
+this by initializing this pointer.
+
+Link: https://lore.kernel.org/r/1620912469-52222-2-git-send-email-liuqi115@huawei.com
+Fixes: 6d578258b955 ("coresight: Make sysfs functional on topologies with per core sink")
+Signed-off-by: Junhao He <hejunhao2@hisilicon.com>
+Signed-off-by: Qi Liu <liuqi115@huawei.com>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Link: https://lore.kernel.org/r/20210614175901.532683-3-mathieu.poirier@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
+index 6c68d34d956e..4ddf3d233844 100644
+--- a/drivers/hwtracing/coresight/coresight-core.c
++++ b/drivers/hwtracing/coresight/coresight-core.c
+@@ -608,7 +608,7 @@ static struct coresight_device *
+ coresight_find_enabled_sink(struct coresight_device *csdev)
+ {
+ int i;
+- struct coresight_device *sink;
++ struct coresight_device *sink = NULL;
+
+ if ((csdev->type == CORESIGHT_DEV_TYPE_SINK ||
+ csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) &&
+--
+2.30.2
+
--- /dev/null
+From 04c67177c1ab5dce7ab14f571e9b895250031b4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 21:11:39 +0200
+Subject: cpufreq: Make cpufreq_online() call driver->offline() on errors
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 3b7180573c250eb6e2a7eec54ae91f27472332ea ]
+
+In the CPU removal path the ->offline() callback provided by the
+driver is always invoked before ->exit(), but in the cpufreq_online()
+error path it is not, so ->exit() is expected to somehow know the
+context in which it has been called and act accordingly.
+
+That is less than straightforward, so make cpufreq_online() invoke
+the driver's ->offline() callback, if present, on errors before
+->exit() too.
+
+This only potentially affects intel_pstate.
+
+Fixes: 91a12e91dc39 ("cpufreq: Allow light-weight tear down and bring up of CPUs")
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/cpufreq.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+index 802abc925b2a..cbab834c37a0 100644
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -1367,9 +1367,14 @@ static int cpufreq_online(unsigned int cpu)
+ goto out_free_policy;
+ }
+
++ /*
++ * The initialization has succeeded and the policy is online.
++ * If there is a problem with its frequency table, take it
++ * offline and drop it.
++ */
+ ret = cpufreq_table_validate_and_sort(policy);
+ if (ret)
+- goto out_exit_policy;
++ goto out_offline_policy;
+
+ /* related_cpus should at least include policy->cpus. */
+ cpumask_copy(policy->related_cpus, policy->cpus);
+@@ -1515,6 +1520,10 @@ out_destroy_policy:
+
+ up_write(&policy->rwsem);
+
++out_offline_policy:
++ if (cpufreq_driver->offline)
++ cpufreq_driver->offline(policy);
++
+ out_exit_policy:
+ if (cpufreq_driver->exit)
+ cpufreq_driver->exit(policy);
+--
+2.30.2
+
--- /dev/null
+From 62d48a7381089ea7ecb5d83c71b7434ce5d5fd35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 May 2021 08:58:04 +0200
+Subject: crypto: ccp - Fix a resource leak in an error handling path
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit a6f8e68e238a15bb15f1726b35c695136c64eaba ]
+
+If an error occurs after calling 'sp_get_irqs()', 'sp_free_irqs()' must be
+called as already done in the error handling path.
+
+Fixes: f4d18d656f88 ("crypto: ccp - Abstract interrupt registeration")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Acked-by: John Allen <john.allen@amd.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ccp/sp-pci.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/ccp/sp-pci.c b/drivers/crypto/ccp/sp-pci.c
+index f468594ef8af..6fb6ba35f89d 100644
+--- a/drivers/crypto/ccp/sp-pci.c
++++ b/drivers/crypto/ccp/sp-pci.c
+@@ -222,7 +222,7 @@ static int sp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ if (ret) {
+ dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n",
+ ret);
+- goto e_err;
++ goto free_irqs;
+ }
+ }
+
+@@ -230,10 +230,12 @@ static int sp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+
+ ret = sp_init(sp);
+ if (ret)
+- goto e_err;
++ goto free_irqs;
+
+ return 0;
+
++free_irqs:
++ sp_free_irqs(sp);
+ e_err:
+ dev_notice(dev, "initialization failed\n");
+ return ret;
+--
+2.30.2
+
--- /dev/null
+From eb914e4b73f1342bd4209e6550cc78ce158a400b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 May 2021 10:44:28 +0800
+Subject: crypto: ecdh - fix ecdh-nist-p192's entry in testmgr
+
+From: Hui Tang <tanghui20@huawei.com>
+
+[ Upstream commit 6889fc2104e5d20899b91e61daf07a7524b2010d ]
+
+Add a comment that p192 will fail to register in FIPS mode.
+
+Fix ecdh-nist-p192's entry in testmgr by removing the ifdefs
+and not setting fips_allowed.
+
+Signed-off-by: Hui Tang <tanghui20@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/ecdh.c | 1 +
+ crypto/testmgr.c | 3 ---
+ crypto/testmgr.h | 2 --
+ 3 files changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/crypto/ecdh.c b/crypto/ecdh.c
+index 04a427b8c956..4227d35f5485 100644
+--- a/crypto/ecdh.c
++++ b/crypto/ecdh.c
+@@ -179,6 +179,7 @@ static int ecdh_init(void)
+ {
+ int ret;
+
++ /* NIST p192 will fail to register in FIPS mode */
+ ret = crypto_register_kpp(&ecdh_nist_p192);
+ ecdh_nist_p192_registered = ret == 0;
+
+diff --git a/crypto/testmgr.c b/crypto/testmgr.c
+index 10c5b3b01ec4..26e40dba9ad2 100644
+--- a/crypto/testmgr.c
++++ b/crypto/testmgr.c
+@@ -4899,15 +4899,12 @@ static const struct alg_test_desc alg_test_descs[] = {
+ }
+ }, {
+ #endif
+-#ifndef CONFIG_CRYPTO_FIPS
+ .alg = "ecdh-nist-p192",
+ .test = alg_test_kpp,
+- .fips_allowed = 1,
+ .suite = {
+ .kpp = __VECS(ecdh_p192_tv_template)
+ }
+ }, {
+-#endif
+ .alg = "ecdh-nist-p256",
+ .test = alg_test_kpp,
+ .fips_allowed = 1,
+diff --git a/crypto/testmgr.h b/crypto/testmgr.h
+index 34e4a3db3991..fe1e59da59ff 100644
+--- a/crypto/testmgr.h
++++ b/crypto/testmgr.h
+@@ -2685,7 +2685,6 @@ static const struct kpp_testvec curve25519_tv_template[] = {
+ }
+ };
+
+-#ifndef CONFIG_CRYPTO_FIPS
+ static const struct kpp_testvec ecdh_p192_tv_template[] = {
+ {
+ .secret =
+@@ -2725,7 +2724,6 @@ static const struct kpp_testvec ecdh_p192_tv_template[] = {
+ .expected_ss_size = 24
+ }
+ };
+-#endif
+
+ static const struct kpp_testvec ecdh_p256_tv_template[] = {
+ {
+--
+2.30.2
+
--- /dev/null
+From ec40ac2bf7261f67e949f2c7adc9cfeb49fb8546 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 May 2021 10:44:29 +0800
+Subject: crypto: ecdh - fix 'ecdh_init'
+
+From: Hui Tang <tanghui20@huawei.com>
+
+[ Upstream commit 8fd28fa5046b377039d5bbc0ab2f625dec703980 ]
+
+NIST P192 is not unregistered if failed to register NIST P256,
+actually it need to unregister the algorithms already registered.
+
+Signed-off-by: Hui Tang <tanghui20@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/ecdh.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/crypto/ecdh.c b/crypto/ecdh.c
+index 4227d35f5485..e2c480859024 100644
+--- a/crypto/ecdh.c
++++ b/crypto/ecdh.c
+@@ -183,7 +183,16 @@ static int ecdh_init(void)
+ ret = crypto_register_kpp(&ecdh_nist_p192);
+ ecdh_nist_p192_registered = ret == 0;
+
+- return crypto_register_kpp(&ecdh_nist_p256);
++ ret = crypto_register_kpp(&ecdh_nist_p256);
++ if (ret)
++ goto nist_p256_error;
++
++ return 0;
++
++nist_p256_error:
++ if (ecdh_nist_p192_registered)
++ crypto_unregister_kpp(&ecdh_nist_p192);
++ return ret;
+ }
+
+ static void ecdh_exit(void)
+--
+2.30.2
+
--- /dev/null
+From 6026ceec4e8648ab1aed021943ad67bed710ddd8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 17:02:55 +0800
+Subject: crypto: hisilicon/hpre - fix unmapping invalid dma address
+
+From: Hui Tang <tanghui20@huawei.com>
+
+[ Upstream commit 0b0553b701f830d820ba9026e5799c24e400a4b5 ]
+
+Currently, an invalid dma address may be unmapped when calling
+'xx_data_clr_all' in error path, so check dma address of sqe in/out
+if initialized before calling 'dma_free_coherent' or 'dma_unmap_single'.
+
+Fixes: a9214b0b6ed2 ("crypto: hisilicon - fix the check on dma address")
+Signed-off-by: Hui Tang <tanghui20@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/hisilicon/hpre/hpre_crypto.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/drivers/crypto/hisilicon/hpre/hpre_crypto.c b/drivers/crypto/hisilicon/hpre/hpre_crypto.c
+index a380087c83f7..782ddffa5d90 100644
+--- a/drivers/crypto/hisilicon/hpre/hpre_crypto.c
++++ b/drivers/crypto/hisilicon/hpre/hpre_crypto.c
+@@ -298,6 +298,8 @@ static void hpre_hw_data_clr_all(struct hpre_ctx *ctx,
+ dma_addr_t tmp;
+
+ tmp = le64_to_cpu(sqe->in);
++ if (unlikely(dma_mapping_error(dev, tmp)))
++ return;
+
+ if (src) {
+ if (req->src)
+@@ -307,6 +309,8 @@ static void hpre_hw_data_clr_all(struct hpre_ctx *ctx,
+ }
+
+ tmp = le64_to_cpu(sqe->out);
++ if (unlikely(dma_mapping_error(dev, tmp)))
++ return;
+
+ if (req->dst) {
+ if (dst)
+@@ -524,6 +528,8 @@ static int hpre_msg_request_set(struct hpre_ctx *ctx, void *req, bool is_rsa)
+ msg->key = cpu_to_le64(ctx->dh.dma_xa_p);
+ }
+
++ msg->in = cpu_to_le64(DMA_MAPPING_ERROR);
++ msg->out = cpu_to_le64(DMA_MAPPING_ERROR);
+ msg->dw0 |= cpu_to_le32(0x1 << HPRE_SQE_DONE_SHIFT);
+ msg->task_len1 = (ctx->key_sz >> HPRE_BITS_2_BYTES_SHIFT) - 1;
+ h_req->ctx = ctx;
+@@ -1372,11 +1378,15 @@ static void hpre_ecdh_hw_data_clr_all(struct hpre_ctx *ctx,
+ dma_addr_t dma;
+
+ dma = le64_to_cpu(sqe->in);
++ if (unlikely(dma_mapping_error(dev, dma)))
++ return;
+
+ if (src && req->src)
+ dma_free_coherent(dev, ctx->key_sz << 2, req->src, dma);
+
+ dma = le64_to_cpu(sqe->out);
++ if (unlikely(dma_mapping_error(dev, dma)))
++ return;
+
+ if (req->dst)
+ dma_free_coherent(dev, ctx->key_sz << 1, req->dst, dma);
+@@ -1431,6 +1441,8 @@ static int hpre_ecdh_msg_request_set(struct hpre_ctx *ctx,
+ h_req->areq.ecdh = req;
+ msg = &h_req->req;
+ memset(msg, 0, sizeof(*msg));
++ msg->in = cpu_to_le64(DMA_MAPPING_ERROR);
++ msg->out = cpu_to_le64(DMA_MAPPING_ERROR);
+ msg->key = cpu_to_le64(ctx->ecdh.dma_p);
+
+ msg->dw0 |= cpu_to_le32(0x1U << HPRE_SQE_DONE_SHIFT);
+@@ -1667,11 +1679,15 @@ static void hpre_curve25519_hw_data_clr_all(struct hpre_ctx *ctx,
+ dma_addr_t dma;
+
+ dma = le64_to_cpu(sqe->in);
++ if (unlikely(dma_mapping_error(dev, dma)))
++ return;
+
+ if (src && req->src)
+ dma_free_coherent(dev, ctx->key_sz, req->src, dma);
+
+ dma = le64_to_cpu(sqe->out);
++ if (unlikely(dma_mapping_error(dev, dma)))
++ return;
+
+ if (req->dst)
+ dma_free_coherent(dev, ctx->key_sz, req->dst, dma);
+@@ -1722,6 +1738,8 @@ static int hpre_curve25519_msg_request_set(struct hpre_ctx *ctx,
+ h_req->areq.curve25519 = req;
+ msg = &h_req->req;
+ memset(msg, 0, sizeof(*msg));
++ msg->in = cpu_to_le64(DMA_MAPPING_ERROR);
++ msg->out = cpu_to_le64(DMA_MAPPING_ERROR);
+ msg->key = cpu_to_le64(ctx->curve25519.dma_p);
+
+ msg->dw0 |= cpu_to_le32(0x1U << HPRE_SQE_DONE_SHIFT);
+--
+2.30.2
+
--- /dev/null
+From 275482602df9c072127560c52a7911559e898705 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 May 2021 19:42:06 +0800
+Subject: crypto: hisilicon/sec - fixup 3des minimum key size declaration
+
+From: Kai Ye <yekai13@huawei.com>
+
+[ Upstream commit 6161f40c630bd7ced5f236cd5fbabec06e47afae ]
+
+Fixup the 3des algorithm minimum key size declaration.
+
+Signed-off-by: Kai Ye <yekai13@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/hisilicon/sec2/sec_crypto.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+index 133aede8bf07..b43fad8b9e8d 100644
+--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+@@ -1541,11 +1541,11 @@ static struct skcipher_alg sec_skciphers[] = {
+ AES_BLOCK_SIZE, AES_BLOCK_SIZE)
+
+ SEC_SKCIPHER_ALG("ecb(des3_ede)", sec_setkey_3des_ecb,
+- SEC_DES3_2KEY_SIZE, SEC_DES3_3KEY_SIZE,
++ SEC_DES3_3KEY_SIZE, SEC_DES3_3KEY_SIZE,
+ DES3_EDE_BLOCK_SIZE, 0)
+
+ SEC_SKCIPHER_ALG("cbc(des3_ede)", sec_setkey_3des_cbc,
+- SEC_DES3_2KEY_SIZE, SEC_DES3_3KEY_SIZE,
++ SEC_DES3_3KEY_SIZE, SEC_DES3_3KEY_SIZE,
+ DES3_EDE_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE)
+
+ SEC_SKCIPHER_ALG("xts(sm4)", sec_setkey_sm4_xts,
+--
+2.30.2
+
--- /dev/null
+From 07c0d52f3132b11ba9eb967da61b4881d52bf831 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 20:26:08 +0000
+Subject: crypto: ixp4xx - dma_unmap the correct address
+
+From: Corentin Labbe <clabbe@baylibre.com>
+
+[ Upstream commit 9395c58fdddd79cdd3882132cdd04e8ac7ad525f ]
+
+Testing ixp4xx_crypto with CONFIG_DMA_API_DEBUG lead to the following error:
+DMA-API: platform ixp4xx_crypto.0: device driver tries to free DMA memory it has not allocated [device address=0x0000000000000000] [size=24 bytes]
+
+This is due to dma_unmap using the wrong address.
+
+Fixes: 0d44dc59b2b4 ("crypto: ixp4xx - Fix handling of chained sg buffers")
+Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ixp4xx_crypto.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
+index 0616e369522e..ed3deaa5ed2b 100644
+--- a/drivers/crypto/ixp4xx_crypto.c
++++ b/drivers/crypto/ixp4xx_crypto.c
+@@ -330,7 +330,7 @@ static void free_buf_chain(struct device *dev, struct buffer_desc *buf,
+
+ buf1 = buf->next;
+ phys1 = buf->phys_next;
+- dma_unmap_single(dev, buf->phys_next, buf->buf_len, buf->dir);
++ dma_unmap_single(dev, buf->phys_addr, buf->buf_len, buf->dir);
+ dma_pool_free(buffer_pool, buf, phys);
+ buf = buf1;
+ phys = phys1;
+--
+2.30.2
+
--- /dev/null
+From 59288f9126818e9e29dcf7090fceed284fb8c216 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 20:26:09 +0000
+Subject: crypto: ixp4xx - update IV after requests
+
+From: Corentin Labbe <clabbe@baylibre.com>
+
+[ Upstream commit e8acf011f2e7e21a7e2fae47cbaa06598e533d40 ]
+
+Crypto selftests fail on ixp4xx since it do not update IV after skcipher
+requests.
+
+Fixes: 81bef0150074 ("crypto: ixp4xx - Hardware crypto support for IXP4xx CPUs")
+Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ixp4xx_crypto.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
+index ed3deaa5ed2b..f577ee4afd06 100644
+--- a/drivers/crypto/ixp4xx_crypto.c
++++ b/drivers/crypto/ixp4xx_crypto.c
+@@ -149,6 +149,8 @@ struct crypt_ctl {
+ struct ablk_ctx {
+ struct buffer_desc *src;
+ struct buffer_desc *dst;
++ u8 iv[MAX_IVLEN];
++ bool encrypt;
+ };
+
+ struct aead_ctx {
+@@ -381,6 +383,20 @@ static void one_packet(dma_addr_t phys)
+ case CTL_FLAG_PERFORM_ABLK: {
+ struct skcipher_request *req = crypt->data.ablk_req;
+ struct ablk_ctx *req_ctx = skcipher_request_ctx(req);
++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
++ unsigned int ivsize = crypto_skcipher_ivsize(tfm);
++ unsigned int offset;
++
++ if (ivsize > 0) {
++ offset = req->cryptlen - ivsize;
++ if (req_ctx->encrypt) {
++ scatterwalk_map_and_copy(req->iv, req->dst,
++ offset, ivsize, 0);
++ } else {
++ memcpy(req->iv, req_ctx->iv, ivsize);
++ memzero_explicit(req_ctx->iv, ivsize);
++ }
++ }
+
+ if (req_ctx->dst) {
+ free_buf_chain(dev, req_ctx->dst, crypt->dst_buf);
+@@ -876,6 +892,7 @@ static int ablk_perform(struct skcipher_request *req, int encrypt)
+ struct ablk_ctx *req_ctx = skcipher_request_ctx(req);
+ struct buffer_desc src_hook;
+ struct device *dev = &pdev->dev;
++ unsigned int offset;
+ gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
+ GFP_KERNEL : GFP_ATOMIC;
+
+@@ -885,6 +902,7 @@ static int ablk_perform(struct skcipher_request *req, int encrypt)
+ return -EAGAIN;
+
+ dir = encrypt ? &ctx->encrypt : &ctx->decrypt;
++ req_ctx->encrypt = encrypt;
+
+ crypt = get_crypt_desc();
+ if (!crypt)
+@@ -900,6 +918,10 @@ static int ablk_perform(struct skcipher_request *req, int encrypt)
+
+ BUG_ON(ivsize && !req->iv);
+ memcpy(crypt->iv, req->iv, ivsize);
++ if (ivsize > 0 && !encrypt) {
++ offset = req->cryptlen - ivsize;
++ scatterwalk_map_and_copy(req_ctx->iv, req->src, offset, ivsize, 0);
++ }
+ if (req->src != req->dst) {
+ struct buffer_desc dst_hook;
+ crypt->mode |= NPE_OP_NOT_IN_PLACE;
+--
+2.30.2
+
--- /dev/null
+From 4869956b8d4b74611d165cf5e278777090cc85d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Jun 2021 18:01:55 +0800
+Subject: crypto: nitrox - fix unchecked variable in nitrox_register_interrupts
+
+From: Tong Tiangen <tongtiangen@huawei.com>
+
+[ Upstream commit 57c126661f50b884d3812e7db6e00f2e778eccfb ]
+
+Function nitrox_register_interrupts leaves variable 'nr_vecs' unchecked, which
+would be use as kcalloc parameter later.
+
+Fixes: 5155e118dda9 ("crypto: cavium/nitrox - use pci_alloc_irq_vectors() while enabling MSI-X.")
+Signed-off-by: Tong Tiangen <tongtiangen@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/cavium/nitrox/nitrox_isr.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/crypto/cavium/nitrox/nitrox_isr.c b/drivers/crypto/cavium/nitrox/nitrox_isr.c
+index c288c4b51783..f19e520da6d0 100644
+--- a/drivers/crypto/cavium/nitrox/nitrox_isr.c
++++ b/drivers/crypto/cavium/nitrox/nitrox_isr.c
+@@ -307,6 +307,10 @@ int nitrox_register_interrupts(struct nitrox_device *ndev)
+ * Entry 192: NPS_CORE_INT_ACTIVE
+ */
+ nr_vecs = pci_msix_vec_count(pdev);
++ if (nr_vecs < 0) {
++ dev_err(DEV(ndev), "Error in getting vec count %d\n", nr_vecs);
++ return nr_vecs;
++ }
+
+ /* Enable MSI-X */
+ ret = pci_alloc_irq_vectors(pdev, nr_vecs, nr_vecs, PCI_IRQ_MSIX);
+--
+2.30.2
+
--- /dev/null
+From 82b97d1dd337b77d582fd16ce234dcc02a830d94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 May 2021 11:14:55 +0800
+Subject: crypto: nx - add missing MODULE_DEVICE_TABLE
+
+From: Bixuan Cui <cuibixuan@huawei.com>
+
+[ Upstream commit 06676aa1f455c74e3ad1624cea3acb9ed2ef71ae ]
+
+This patch adds missing MODULE_DEVICE_TABLE definition which generates
+correct modalias for automatic loading of this driver when it is built
+as an external module.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Bixuan Cui <cuibixuan@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/nx/nx-842-pseries.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/crypto/nx/nx-842-pseries.c b/drivers/crypto/nx/nx-842-pseries.c
+index cc8dd3072b8b..8ee547ee378e 100644
+--- a/drivers/crypto/nx/nx-842-pseries.c
++++ b/drivers/crypto/nx/nx-842-pseries.c
+@@ -1069,6 +1069,7 @@ static const struct vio_device_id nx842_vio_driver_ids[] = {
+ {"ibm,compression-v1", "ibm,compression"},
+ {"", ""},
+ };
++MODULE_DEVICE_TABLE(vio, nx842_vio_driver_ids);
+
+ static struct vio_driver nx842_vio_driver = {
+ .name = KBUILD_MODNAME,
+--
+2.30.2
+
--- /dev/null
+From 7d211878ab8d78e751880588404bff85db7d5454 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jun 2021 15:57:12 +0800
+Subject: crypto: nx - Fix RCU warning in nx842_OF_upd_status
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 2a96726bd0ccde4f12b9b9a9f61f7b1ac5af7e10 ]
+
+The function nx842_OF_upd_status triggers a sparse RCU warning when
+it directly dereferences the RCU-protected devdata. This appears
+to be an accident as there was another variable of the same name
+that was passed in from the caller.
+
+After it was removed (because the main purpose of using it, to
+update the status member was itself removed) the global variable
+unintenionally stood in as its replacement.
+
+This patch restores the devdata parameter.
+
+Fixes: 90fd73f912f0 ("crypto: nx - remove pSeries NX 'status' field")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/nx/nx-842-pseries.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/crypto/nx/nx-842-pseries.c b/drivers/crypto/nx/nx-842-pseries.c
+index 8ee547ee378e..9b2417ebc95a 100644
+--- a/drivers/crypto/nx/nx-842-pseries.c
++++ b/drivers/crypto/nx/nx-842-pseries.c
+@@ -538,13 +538,15 @@ static int nx842_OF_set_defaults(struct nx842_devdata *devdata)
+ * The status field indicates if the device is enabled when the status
+ * is 'okay'. Otherwise the device driver will be disabled.
+ *
+- * @prop - struct property point containing the maxsyncop for the update
++ * @devdata: struct nx842_devdata to use for dev_info
++ * @prop: struct property point containing the maxsyncop for the update
+ *
+ * Returns:
+ * 0 - Device is available
+ * -ENODEV - Device is not available
+ */
+-static int nx842_OF_upd_status(struct property *prop)
++static int nx842_OF_upd_status(struct nx842_devdata *devdata,
++ struct property *prop)
+ {
+ const char *status = (const char *)prop->value;
+
+@@ -758,7 +760,7 @@ static int nx842_OF_upd(struct property *new_prop)
+ goto out;
+
+ /* Perform property updates */
+- ret = nx842_OF_upd_status(status);
++ ret = nx842_OF_upd_status(new_devdata, status);
+ if (ret)
+ goto error_out;
+
+--
+2.30.2
+
--- /dev/null
+From 9866678d6a7d687a6288c7ad399cbcd84a8f06b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Jun 2021 22:51:18 +0800
+Subject: crypto: omap-sham - Fix PM reference leak in omap sham ops
+
+From: Zhang Qilong <zhangqilong3@huawei.com>
+
+[ Upstream commit ca323b2c61ec321eb9f2179a405b9c34cdb4f553 ]
+
+pm_runtime_get_sync will increment pm usage counter
+even it failed. Forgetting to putting operation will
+result in reference leak here. We fix it by replacing
+it with pm_runtime_resume_and_get to keep usage counter
+balanced.
+
+Fixes: 604c31039dae4 ("crypto: omap-sham - Check for return value from pm_runtime_get_sync")
+Signed-off-by: Zhang Qilong <zhangqilong3@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/omap-sham.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
+index ae0d320d3c60..dd53ad9987b0 100644
+--- a/drivers/crypto/omap-sham.c
++++ b/drivers/crypto/omap-sham.c
+@@ -372,7 +372,7 @@ static int omap_sham_hw_init(struct omap_sham_dev *dd)
+ {
+ int err;
+
+- err = pm_runtime_get_sync(dd->dev);
++ err = pm_runtime_resume_and_get(dd->dev);
+ if (err < 0) {
+ dev_err(dd->dev, "failed to get sync: %d\n", err);
+ return err;
+@@ -2244,7 +2244,7 @@ static int omap_sham_suspend(struct device *dev)
+
+ static int omap_sham_resume(struct device *dev)
+ {
+- int err = pm_runtime_get_sync(dev);
++ int err = pm_runtime_resume_and_get(dev);
+ if (err < 0) {
+ dev_err(dev, "failed to get sync: %d\n", err);
+ return err;
+--
+2.30.2
+
--- /dev/null
+From 2ce08da74ebca5f14e83f5c3ad357101d54ea8ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 May 2021 05:13:15 -0400
+Subject: crypto: qat - check return code of qat_hal_rd_rel_reg()
+
+From: Jack Xu <jack.xu@intel.com>
+
+[ Upstream commit 96b57229209490c8bca4335b01a426a96173dc56 ]
+
+Check the return code of the function qat_hal_rd_rel_reg() and return it
+to the caller.
+
+This is to fix the following warning when compiling the driver with
+clang scan-build:
+
+ drivers/crypto/qat/qat_common/qat_hal.c:1436:2: warning: 6th function call argument is an uninitialized value
+
+Signed-off-by: Jack Xu <jack.xu@intel.com>
+Co-developed-by: Zhehui Xiang <zhehui.xiang@intel.com>
+Signed-off-by: Zhehui Xiang <zhehui.xiang@intel.com>
+Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/qat/qat_common/qat_hal.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/qat/qat_common/qat_hal.c b/drivers/crypto/qat/qat_common/qat_hal.c
+index bd3028126cbe..069f51621f0e 100644
+--- a/drivers/crypto/qat/qat_common/qat_hal.c
++++ b/drivers/crypto/qat/qat_common/qat_hal.c
+@@ -1417,7 +1417,11 @@ static int qat_hal_put_rel_wr_xfer(struct icp_qat_fw_loader_handle *handle,
+ pr_err("QAT: bad xfrAddr=0x%x\n", xfr_addr);
+ return -EINVAL;
+ }
+- qat_hal_rd_rel_reg(handle, ae, ctx, ICP_GPB_REL, gprnum, &gprval);
++ status = qat_hal_rd_rel_reg(handle, ae, ctx, ICP_GPB_REL, gprnum, &gprval);
++ if (status) {
++ pr_err("QAT: failed to read register");
++ return status;
++ }
+ gpr_addr = qat_hal_get_reg_addr(ICP_GPB_REL, gprnum);
+ data16low = 0xffff & data;
+ data16hi = 0xffff & (data >> 0x10);
+--
+2.30.2
+
--- /dev/null
+From af2e6836b2fa9cc8264f7ec36a26eb6cf984d848 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 May 2021 05:13:16 -0400
+Subject: crypto: qat - remove unused macro in FW loader
+
+From: Jack Xu <jack.xu@intel.com>
+
+[ Upstream commit 9afe77cf25d9670e61b489fd52cc6f75fd7f6803 ]
+
+Remove the unused macro ICP_DH895XCC_PESRAM_BAR_SIZE in the firmware
+loader.
+
+This is to fix the following warning when compiling the driver using the
+clang compiler with CC=clang W=2:
+
+ drivers/crypto/qat/qat_common/qat_uclo.c:345:9: warning: macro is not used [-Wunused-macros]
+
+Signed-off-by: Jack Xu <jack.xu@intel.com>
+Co-developed-by: Zhehui Xiang <zhehui.xiang@intel.com>
+Signed-off-by: Zhehui Xiang <zhehui.xiang@intel.com>
+Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/qat/qat_common/qat_uclo.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/crypto/qat/qat_common/qat_uclo.c b/drivers/crypto/qat/qat_common/qat_uclo.c
+index 1fb5fc852f6b..6d95160e451e 100644
+--- a/drivers/crypto/qat/qat_common/qat_uclo.c
++++ b/drivers/crypto/qat/qat_common/qat_uclo.c
+@@ -342,7 +342,6 @@ static int qat_uclo_init_umem_seg(struct icp_qat_fw_loader_handle *handle,
+ return 0;
+ }
+
+-#define ICP_DH895XCC_PESRAM_BAR_SIZE 0x80000
+ static int qat_uclo_init_ae_memory(struct icp_qat_fw_loader_handle *handle,
+ struct icp_qat_uof_initmem *init_mem)
+ {
+--
+2.30.2
+
--- /dev/null
+From 98accef8e42a40da4739f0becf0e1d962ec23903 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 May 2021 22:20:23 -0400
+Subject: crypto: qce: skcipher: Fix incorrect sg count for dma transfers
+
+From: Thara Gopinath <thara.gopinath@linaro.org>
+
+[ Upstream commit 1339a7c3ba05137a2d2fe75f602311bbfc6fab33 ]
+
+Use the sg count returned by dma_map_sg to call into
+dmaengine_prep_slave_sg rather than using the original sg count. dma_map_sg
+can merge consecutive sglist entries, thus making the original sg count
+wrong. This is a fix for memory coruption issues observed while testing
+encryption/decryption of large messages using libkcapi framework.
+
+Patch has been tested further by running full suite of tcrypt.ko tests
+including fuzz tests.
+
+Signed-off-by: Thara Gopinath <thara.gopinath@linaro.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/qce/skcipher.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c
+index c0a0d8c4fce1..259418479227 100644
+--- a/drivers/crypto/qce/skcipher.c
++++ b/drivers/crypto/qce/skcipher.c
+@@ -72,7 +72,7 @@ qce_skcipher_async_req_handle(struct crypto_async_request *async_req)
+ struct scatterlist *sg;
+ bool diff_dst;
+ gfp_t gfp;
+- int ret;
++ int dst_nents, src_nents, ret;
+
+ rctx->iv = req->iv;
+ rctx->ivsize = crypto_skcipher_ivsize(skcipher);
+@@ -123,21 +123,22 @@ qce_skcipher_async_req_handle(struct crypto_async_request *async_req)
+ sg_mark_end(sg);
+ rctx->dst_sg = rctx->dst_tbl.sgl;
+
+- ret = dma_map_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst);
+- if (ret < 0)
++ dst_nents = dma_map_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst);
++ if (dst_nents < 0)
+ goto error_free;
+
+ if (diff_dst) {
+- ret = dma_map_sg(qce->dev, req->src, rctx->src_nents, dir_src);
+- if (ret < 0)
++ src_nents = dma_map_sg(qce->dev, req->src, rctx->src_nents, dir_src);
++ if (src_nents < 0)
+ goto error_unmap_dst;
+ rctx->src_sg = req->src;
+ } else {
+ rctx->src_sg = rctx->dst_sg;
++ src_nents = dst_nents - 1;
+ }
+
+- ret = qce_dma_prep_sgs(&qce->dma, rctx->src_sg, rctx->src_nents,
+- rctx->dst_sg, rctx->dst_nents,
++ ret = qce_dma_prep_sgs(&qce->dma, rctx->src_sg, src_nents,
++ rctx->dst_sg, dst_nents,
+ qce_skcipher_done, async_req);
+ if (ret)
+ goto error_unmap_src;
+--
+2.30.2
+
--- /dev/null
+From 435e613c37a0160bedc0b927eb1f2057d19c8c7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 May 2021 11:12:42 -0500
+Subject: crypto: sa2ul - Fix leaks on failure paths with sa_dma_init()
+
+From: Suman Anna <s-anna@ti.com>
+
+[ Upstream commit 4c0716ee1d973f6504d13f0e8d4d10350c85ad37 ]
+
+The sa_dma_init() function doesn't release the requested dma channels
+on all failure paths. Any failure in this function also ends up
+leaking the dma pool created in sa_init_mem() in the sa_ul_probe()
+function. Fix all of these issues.
+
+Fixes: 7694b6ca649f ("crypto: sa2ul - Add crypto driver")
+Signed-off-by: Suman Anna <s-anna@ti.com>
+Reviewed-by: Tero Kristo <kristo@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/sa2ul.c | 21 ++++++++++++---------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c
+index 1c6929fb3a13..3d6f0af2f938 100644
+--- a/drivers/crypto/sa2ul.c
++++ b/drivers/crypto/sa2ul.c
+@@ -2300,9 +2300,9 @@ static int sa_dma_init(struct sa_crypto_data *dd)
+
+ dd->dma_rx2 = dma_request_chan(dd->dev, "rx2");
+ if (IS_ERR(dd->dma_rx2)) {
+- dma_release_channel(dd->dma_rx1);
+- return dev_err_probe(dd->dev, PTR_ERR(dd->dma_rx2),
+- "Unable to request rx2 DMA channel\n");
++ ret = dev_err_probe(dd->dev, PTR_ERR(dd->dma_rx2),
++ "Unable to request rx2 DMA channel\n");
++ goto err_dma_rx2;
+ }
+
+ dd->dma_tx = dma_request_chan(dd->dev, "tx");
+@@ -2323,28 +2323,31 @@ static int sa_dma_init(struct sa_crypto_data *dd)
+ if (ret) {
+ dev_err(dd->dev, "can't configure IN dmaengine slave: %d\n",
+ ret);
+- return ret;
++ goto err_dma_config;
+ }
+
+ ret = dmaengine_slave_config(dd->dma_rx2, &cfg);
+ if (ret) {
+ dev_err(dd->dev, "can't configure IN dmaengine slave: %d\n",
+ ret);
+- return ret;
++ goto err_dma_config;
+ }
+
+ ret = dmaengine_slave_config(dd->dma_tx, &cfg);
+ if (ret) {
+ dev_err(dd->dev, "can't configure OUT dmaengine slave: %d\n",
+ ret);
+- return ret;
++ goto err_dma_config;
+ }
+
+ return 0;
+
++err_dma_config:
++ dma_release_channel(dd->dma_tx);
+ err_dma_tx:
+- dma_release_channel(dd->dma_rx1);
+ dma_release_channel(dd->dma_rx2);
++err_dma_rx2:
++ dma_release_channel(dd->dma_rx1);
+
+ return ret;
+ }
+@@ -2414,7 +2417,7 @@ static int sa_ul_probe(struct platform_device *pdev)
+ sa_init_mem(dev_data);
+ ret = sa_dma_init(dev_data);
+ if (ret)
+- goto disable_pm_runtime;
++ goto destroy_dma_pool;
+
+ match = of_match_node(of_match, dev->of_node);
+ if (!match) {
+@@ -2454,9 +2457,9 @@ release_dma:
+ dma_release_channel(dev_data->dma_rx1);
+ dma_release_channel(dev_data->dma_tx);
+
++destroy_dma_pool:
+ dma_pool_destroy(dev_data->sc_pool);
+
+-disable_pm_runtime:
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+
+--
+2.30.2
+
--- /dev/null
+From 4ed284eaf4513bb4566e119db1dba98401f9fd20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 May 2021 11:12:43 -0500
+Subject: crypto: sa2ul - Fix pm_runtime enable in sa_ul_probe()
+
+From: Suman Anna <s-anna@ti.com>
+
+[ Upstream commit 5c8552325e013cbdabc443cd1f1b4d03c4a2e64e ]
+
+The pm_runtime APIs added first in commit 7694b6ca649f ("crypto: sa2ul -
+Add crypto driver") are not unwound properly and was fixed up partially
+in commit 13343badae09 ("crypto: sa2ul - Fix PM reference leak in
+sa_ul_probe()"). This fixed up the pm_runtime usage count but not the
+state. Fix this properly.
+
+Fixes: 13343badae09 ("crypto: sa2ul - Fix PM reference leak in sa_ul_probe()")
+Signed-off-by: Suman Anna <s-anna@ti.com>
+Reviewed-by: Tero Kristo <kristo@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/sa2ul.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c
+index 3d6f0af2f938..a215daedf78a 100644
+--- a/drivers/crypto/sa2ul.c
++++ b/drivers/crypto/sa2ul.c
+@@ -2411,6 +2411,7 @@ static int sa_ul_probe(struct platform_device *pdev)
+ if (ret < 0) {
+ dev_err(&pdev->dev, "%s: failed to get sync: %d\n", __func__,
+ ret);
++ pm_runtime_disable(dev);
+ return ret;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 73c8883fd4e176b349e19b705a230e40bf5eb479 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 May 2021 11:12:44 -0500
+Subject: crypto: sa2ul - Use of_device_get_match_data() helper
+
+From: Suman Anna <s-anna@ti.com>
+
+[ Upstream commit d699c5d0bd811e48de72aeeb8e3872c63e957745 ]
+
+Simplify the probe function by using the of_device_get_match_data()
+helper instead of open coding. The logic is also moved up to fix the
+missing pm_runtime cleanup in case of a match failure.
+
+Fixes: 0bc42311cdff ("crypto: sa2ul - Add support for AM64")
+Signed-off-by: Suman Anna <s-anna@ti.com>
+Reviewed-by: Tero Kristo <kristo@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/sa2ul.c | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c
+index a215daedf78a..9f077ec9dbb7 100644
+--- a/drivers/crypto/sa2ul.c
++++ b/drivers/crypto/sa2ul.c
+@@ -2388,7 +2388,6 @@ MODULE_DEVICE_TABLE(of, of_match);
+
+ static int sa_ul_probe(struct platform_device *pdev)
+ {
+- const struct of_device_id *match;
+ struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
+ struct resource *res;
+@@ -2400,6 +2399,10 @@ static int sa_ul_probe(struct platform_device *pdev)
+ if (!dev_data)
+ return -ENOMEM;
+
++ dev_data->match_data = of_device_get_match_data(dev);
++ if (!dev_data->match_data)
++ return -ENODEV;
++
+ sa_k3_dev = dev;
+ dev_data->dev = dev;
+ dev_data->pdev = pdev;
+@@ -2420,13 +2423,6 @@ static int sa_ul_probe(struct platform_device *pdev)
+ if (ret)
+ goto destroy_dma_pool;
+
+- match = of_match_node(of_match, dev->of_node);
+- if (!match) {
+- dev_err(dev, "No compatible match found\n");
+- return -ENODEV;
+- }
+- dev_data->match_data = match->data;
+-
+ spin_lock_init(&dev_data->scid_lock);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ saul_base = devm_ioremap_resource(dev, res);
+--
+2.30.2
+
--- /dev/null
+From b70a4de5fb0c687303dd67cd93d19b361da5ce38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jun 2021 08:21:50 +0200
+Subject: crypto: shash - avoid comparing pointers to exported functions under
+ CFI
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+[ Upstream commit 22ca9f4aaf431a9413dcc115dd590123307f274f ]
+
+crypto_shash_alg_has_setkey() is implemented by testing whether the
+.setkey() member of a struct shash_alg points to the default version,
+called shash_no_setkey(). As crypto_shash_alg_has_setkey() is a static
+inline, this requires shash_no_setkey() to be exported to modules.
+
+Unfortunately, when building with CFI, function pointers are routed
+via CFI stubs which are private to each module (or to the kernel proper)
+and so this function pointer comparison may fail spuriously.
+
+Let's fix this by turning crypto_shash_alg_has_setkey() into an out of
+line function.
+
+Cc: Sami Tolvanen <samitolvanen@google.com>
+Cc: Eric Biggers <ebiggers@kernel.org>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Reviewed-by: Eric Biggers <ebiggers@google.com>
+Reviewed-by: Sami Tolvanen <samitolvanen@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/shash.c | 18 +++++++++++++++---
+ include/crypto/internal/hash.h | 8 +-------
+ 2 files changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/crypto/shash.c b/crypto/shash.c
+index 2e3433ad9762..0a0a50cb694f 100644
+--- a/crypto/shash.c
++++ b/crypto/shash.c
+@@ -20,12 +20,24 @@
+
+ static const struct crypto_type crypto_shash_type;
+
+-int shash_no_setkey(struct crypto_shash *tfm, const u8 *key,
+- unsigned int keylen)
++static int shash_no_setkey(struct crypto_shash *tfm, const u8 *key,
++ unsigned int keylen)
+ {
+ return -ENOSYS;
+ }
+-EXPORT_SYMBOL_GPL(shash_no_setkey);
++
++/*
++ * Check whether an shash algorithm has a setkey function.
++ *
++ * For CFI compatibility, this must not be an inline function. This is because
++ * when CFI is enabled, modules won't get the same address for shash_no_setkey
++ * (if it were exported, which inlining would require) as the core kernel will.
++ */
++bool crypto_shash_alg_has_setkey(struct shash_alg *alg)
++{
++ return alg->setkey != shash_no_setkey;
++}
++EXPORT_SYMBOL_GPL(crypto_shash_alg_has_setkey);
+
+ static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key,
+ unsigned int keylen)
+diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h
+index 0a288dddcf5b..25806141db59 100644
+--- a/include/crypto/internal/hash.h
++++ b/include/crypto/internal/hash.h
+@@ -75,13 +75,7 @@ void crypto_unregister_ahashes(struct ahash_alg *algs, int count);
+ int ahash_register_instance(struct crypto_template *tmpl,
+ struct ahash_instance *inst);
+
+-int shash_no_setkey(struct crypto_shash *tfm, const u8 *key,
+- unsigned int keylen);
+-
+-static inline bool crypto_shash_alg_has_setkey(struct shash_alg *alg)
+-{
+- return alg->setkey != shash_no_setkey;
+-}
++bool crypto_shash_alg_has_setkey(struct shash_alg *alg);
+
+ static inline bool crypto_shash_alg_needs_key(struct shash_alg *alg)
+ {
+--
+2.30.2
+
--- /dev/null
+From 976ff3d32f092afcfa95ccfd892d7f93ea75bf12 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Jun 2021 14:30:35 +0800
+Subject: crypto: sm2 - fix a memory leak in sm2
+
+From: Hongbo Li <herberthbli@tencent.com>
+
+[ Upstream commit 5cd259ca5d466f65ffd21e2e2fa00fb648a8c555 ]
+
+SM2 module alloc ec->Q in sm2_set_pub_key(), when doing alg test in
+test_akcipher_one(), it will set public key for every test vector,
+and don't free ec->Q. This will cause a memory leak.
+
+This patch alloc ec->Q in sm2_ec_ctx_init().
+
+Fixes: ea7ecb66440b ("crypto: sm2 - introduce OSCCA SM2 asymmetric cipher algorithm")
+Signed-off-by: Hongbo Li <herberthbli@tencent.com>
+Reviewed-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/sm2.c | 24 ++++++++++--------------
+ 1 file changed, 10 insertions(+), 14 deletions(-)
+
+diff --git a/crypto/sm2.c b/crypto/sm2.c
+index b21addc3ac06..db8a4a265669 100644
+--- a/crypto/sm2.c
++++ b/crypto/sm2.c
+@@ -79,10 +79,17 @@ static int sm2_ec_ctx_init(struct mpi_ec_ctx *ec)
+ goto free;
+
+ rc = -ENOMEM;
++
++ ec->Q = mpi_point_new(0);
++ if (!ec->Q)
++ goto free;
++
+ /* mpi_ec_setup_elliptic_curve */
+ ec->G = mpi_point_new(0);
+- if (!ec->G)
++ if (!ec->G) {
++ mpi_point_release(ec->Q);
+ goto free;
++ }
+
+ mpi_set(ec->G->x, x);
+ mpi_set(ec->G->y, y);
+@@ -91,6 +98,7 @@ static int sm2_ec_ctx_init(struct mpi_ec_ctx *ec)
+ rc = -EINVAL;
+ ec->n = mpi_scanval(ecp->n);
+ if (!ec->n) {
++ mpi_point_release(ec->Q);
+ mpi_point_release(ec->G);
+ goto free;
+ }
+@@ -386,27 +394,15 @@ static int sm2_set_pub_key(struct crypto_akcipher *tfm,
+ MPI a;
+ int rc;
+
+- ec->Q = mpi_point_new(0);
+- if (!ec->Q)
+- return -ENOMEM;
+-
+ /* include the uncompressed flag '0x04' */
+- rc = -ENOMEM;
+ a = mpi_read_raw_data(key, keylen);
+ if (!a)
+- goto error;
++ return -ENOMEM;
+
+ mpi_normalize(a);
+ rc = sm2_ecc_os2ec(ec->Q, a);
+ mpi_free(a);
+- if (rc)
+- goto error;
+-
+- return 0;
+
+-error:
+- mpi_point_release(ec->Q);
+- ec->Q = NULL;
+ return rc;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From a2f9922dfbb0d1ecb859608844cd5caaec4be259 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 16:54:08 +0800
+Subject: crypto: testmgr - fix initialization of 'secret_size'
+
+From: Hui Tang <tanghui20@huawei.com>
+
+[ Upstream commit 2d016672528a592ada5188e53ac746e1b8b7a978 ]
+
+Actual data length of the 'secret' is not equal to the 'secret_size'.
+
+Since the 'curve_id' has removed in the 'secret', the 'secret_size'
+should subtract the length of the 'curve_id'.
+
+Fixes: 6763f5ea2d9a ("crypto: ecdh - move curve_id of ECDH from ...")
+Signed-off-by: Hui Tang <tanghui20@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/testmgr.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/crypto/testmgr.h b/crypto/testmgr.h
+index fe1e59da59ff..b9cf5b815532 100644
+--- a/crypto/testmgr.h
++++ b/crypto/testmgr.h
+@@ -2718,7 +2718,7 @@ static const struct kpp_testvec ecdh_p192_tv_template[] = {
+ "\xf4\x57\xcc\x4f\x1f\x4e\x31\xcc"
+ "\xe3\x40\x60\xc8\x06\x93\xc6\x2e"
+ "\x99\x80\x81\x28\xaf\xc5\x51\x74",
+- .secret_size = 32,
++ .secret_size = 30,
+ .b_public_size = 48,
+ .expected_a_public_size = 48,
+ .expected_ss_size = 24
+@@ -2764,7 +2764,7 @@ static const struct kpp_testvec ecdh_p256_tv_template[] = {
+ "\x9f\x4a\x38\xcc\xc0\x2c\x49\x2f"
+ "\xb1\x32\xbb\xaf\x22\x61\xda\xcb"
+ "\x6f\xdb\xa9\xaa\xfc\x77\x81\xf3",
+- .secret_size = 40,
++ .secret_size = 38,
+ .b_public_size = 64,
+ .expected_a_public_size = 64,
+ .expected_ss_size = 32
+@@ -2802,8 +2802,8 @@ static const struct kpp_testvec ecdh_p256_tv_template[] = {
+ "\x37\x08\xcc\x40\x5e\x7a\xfd\x6a"
+ "\x6a\x02\x6e\x41\x87\x68\x38\x77"
+ "\xfa\xa9\x44\x43\x2d\xef\x09\xdf",
+- .secret_size = 8,
+- .b_secret_size = 40,
++ .secret_size = 6,
++ .b_secret_size = 38,
+ .b_public_size = 64,
+ .expected_a_public_size = 64,
+ .expected_ss_size = 32,
+--
+2.30.2
+
--- /dev/null
+From fb37daa2369d6ca39cb255943eb69d1eb89024f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 May 2021 15:00:49 +0800
+Subject: crypto: ux500 - Fix error return code in hash_hw_final()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit b01360384009ab066940b45f34880991ea7ccbfb ]
+
+Fix to return a negative error code from the error handling
+case instead of 0, as done elsewhere in this function.
+
+Fixes: 8a63b1994c50 ("crypto: ux500 - Add driver for HASH hardware")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ux500/hash/hash_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c
+index ecb7412e84e3..51a6e1a42434 100644
+--- a/drivers/crypto/ux500/hash/hash_core.c
++++ b/drivers/crypto/ux500/hash/hash_core.c
+@@ -1011,6 +1011,7 @@ static int hash_hw_final(struct ahash_request *req)
+ goto out;
+ }
+ } else if (req->nbytes == 0 && ctx->keylen > 0) {
++ ret = -EPERM;
+ dev_err(device_data->dev, "%s: Empty message with keylength > 0, NOT supported\n",
+ __func__);
+ goto out;
+--
+2.30.2
+
--- /dev/null
+From e518af7296e986424c8c402329d251925bae6f96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Jun 2021 01:53:40 -0400
+Subject: crypto: x86/curve25519 - fix cpu feature checking logic in mod_exit
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+[ Upstream commit 1b82435d17774f3eaab35dce239d354548aa9da2 ]
+
+In curve25519_mod_init() the curve25519_alg will be registered only when
+(X86_FEATURE_BMI2 && X86_FEATURE_ADX). But in curve25519_mod_exit()
+it still checks (X86_FEATURE_BMI2 || X86_FEATURE_ADX) when do crypto
+unregister. This will trigger a BUG_ON in crypto_unregister_alg() as
+alg->cra_refcnt is 0 if the cpu only supports one of X86_FEATURE_BMI2
+and X86_FEATURE_ADX.
+
+Fixes: 07b586fe0662 ("crypto: x86/curve25519 - replace with formally verified implementation")
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/crypto/curve25519-x86_64.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/crypto/curve25519-x86_64.c b/arch/x86/crypto/curve25519-x86_64.c
+index 6706b6cb1d0f..38caf61cd5b7 100644
+--- a/arch/x86/crypto/curve25519-x86_64.c
++++ b/arch/x86/crypto/curve25519-x86_64.c
+@@ -1500,7 +1500,7 @@ static int __init curve25519_mod_init(void)
+ static void __exit curve25519_mod_exit(void)
+ {
+ if (IS_REACHABLE(CONFIG_CRYPTO_KPP) &&
+- (boot_cpu_has(X86_FEATURE_BMI2) || boot_cpu_has(X86_FEATURE_ADX)))
++ static_branch_likely(&curve25519_use_bmi2_adx))
+ crypto_unregister_kpp(&curve25519_alg);
+ }
+
+--
+2.30.2
+
--- /dev/null
+From a86087600360eeb2ef796ccf002a905e2ee48245 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 14:08:44 +0800
+Subject: csky: syscache: Fixup duplicate cache flush
+
+From: Guo Ren <guoren@linux.alibaba.com>
+
+[ Upstream commit 6ea42c84f33368eb3fe1ec1bff8d7cb1a5c7b07a ]
+
+The current csky logic of sys_cacheflush is wrong, it'll cause
+icache flush call dcache flush again. Now fixup it with a
+conditional "break & fallthrough".
+
+Fixes: 997153b9a75c ("csky: Add flush_icache_mm to defer flush icache all")
+Fixes: 0679d29d3e23 ("csky: fix syscache.c fallthrough warning")
+Acked-by: Randy Dunlap <rdunlap@infradead.org>
+Co-Developed-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/csky/mm/syscache.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/arch/csky/mm/syscache.c b/arch/csky/mm/syscache.c
+index 4e51d63850c4..cd847ad62c7e 100644
+--- a/arch/csky/mm/syscache.c
++++ b/arch/csky/mm/syscache.c
+@@ -12,15 +12,17 @@ SYSCALL_DEFINE3(cacheflush,
+ int, cache)
+ {
+ switch (cache) {
+- case ICACHE:
+ case BCACHE:
+- flush_icache_mm_range(current->mm,
+- (unsigned long)addr,
+- (unsigned long)addr + bytes);
+- fallthrough;
+ case DCACHE:
+ dcache_wb_range((unsigned long)addr,
+ (unsigned long)addr + bytes);
++ if (cache != BCACHE)
++ break;
++ fallthrough;
++ case ICACHE:
++ flush_icache_mm_range(current->mm,
++ (unsigned long)addr,
++ (unsigned long)addr + bytes);
+ break;
+ default:
+ return -EINVAL;
+--
+2.30.2
+
--- /dev/null
+From 12a99b751cb7286a44034bfe2c5a286ecf7f347c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 15:32:38 -0700
+Subject: cw1200: Revert unnecessary patches that fix unreal use-after-free
+ bugs
+
+From: Hang Zhang <zh.nvgt@gmail.com>
+
+[ Upstream commit 3f60f4685699aa6006e58e424637e8e413e0a94d ]
+
+A previous commit 4f68ef64cd7f ("cw1200: Fix concurrency
+use-after-free bugs in cw1200_hw_scan()") tried to fix a seemingly
+use-after-free bug between cw1200_bss_info_changed() and
+cw1200_hw_scan(), where the former frees a sk_buff pointed
+to by frame.skb, and the latter accesses the sk_buff
+pointed to by frame.skb. However, this issue should be a
+false alarm because:
+
+(1) "frame.skb" is not a shared variable between the above
+two functions, because "frame" is a local function variable,
+each of the two functions has its own local "frame" - they
+just happen to have the same variable name.
+
+(2) the sk_buff(s) pointed to by these two "frame.skb" are
+also two different object instances, they are individually
+allocated by different dev_alloc_skb() within the two above
+functions. To free one object instance will not invalidate
+the access of another different one.
+
+Based on these facts, the previous commit should be unnecessary.
+Moreover, it also introduced a missing unlock which was
+addressed in a subsequent commit 51c8d24101c7 ("cw1200: fix missing
+unlock on error in cw1200_hw_scan()"). Now that the
+original use-after-free is unreal, these two commits should
+be reverted. This patch performs the reversion.
+
+Fixes: 4f68ef64cd7f ("cw1200: Fix concurrency use-after-free bugs in cw1200_hw_scan()")
+Fixes: 51c8d24101c7 ("cw1200: fix missing unlock on error in cw1200_hw_scan()")
+Signed-off-by: Hang Zhang <zh.nvgt@gmail.com>
+Acked-by: Jia-Ju Bai <baijiaju1990@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210521223238.25020-1-zh.nvgt@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/st/cw1200/scan.c | 17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/wireless/st/cw1200/scan.c b/drivers/net/wireless/st/cw1200/scan.c
+index 988581cc134b..1f856fbbc0ea 100644
+--- a/drivers/net/wireless/st/cw1200/scan.c
++++ b/drivers/net/wireless/st/cw1200/scan.c
+@@ -75,30 +75,27 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
+ if (req->n_ssids > WSM_SCAN_MAX_NUM_OF_SSIDS)
+ return -EINVAL;
+
+- /* will be unlocked in cw1200_scan_work() */
+- down(&priv->scan.lock);
+- mutex_lock(&priv->conf_mutex);
+-
+ frame.skb = ieee80211_probereq_get(hw, priv->vif->addr, NULL, 0,
+ req->ie_len);
+- if (!frame.skb) {
+- mutex_unlock(&priv->conf_mutex);
+- up(&priv->scan.lock);
++ if (!frame.skb)
+ return -ENOMEM;
+- }
+
+ if (req->ie_len)
+ skb_put_data(frame.skb, req->ie, req->ie_len);
+
++ /* will be unlocked in cw1200_scan_work() */
++ down(&priv->scan.lock);
++ mutex_lock(&priv->conf_mutex);
++
+ ret = wsm_set_template_frame(priv, &frame);
+ if (!ret) {
+ /* Host want to be the probe responder. */
+ ret = wsm_set_probe_responder(priv, true);
+ }
+ if (ret) {
+- dev_kfree_skb(frame.skb);
+ mutex_unlock(&priv->conf_mutex);
+ up(&priv->scan.lock);
++ dev_kfree_skb(frame.skb);
+ return ret;
+ }
+
+@@ -120,8 +117,8 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
+ ++priv->scan.n_ssids;
+ }
+
+- dev_kfree_skb(frame.skb);
+ mutex_unlock(&priv->conf_mutex);
++ dev_kfree_skb(frame.skb);
+ queue_work(priv->workqueue, &priv->scan.work);
+ return 0;
+ }
+--
+2.30.2
+
--- /dev/null
+From 69105b4ae6908fedbaddc5af51caab11fc87ae76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jun 2021 19:35:04 -0700
+Subject: dax: fix ENOMEM handling in grab_mapping_entry()
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 1a14e3779dd58c16b30e56558146e5cc850ba8b0 ]
+
+grab_mapping_entry() has a bug in handling of ENOMEM condition. Suppose
+we have a PMD entry at index i which we are downgrading to a PTE entry.
+grab_mapping_entry() will set pmd_downgrade to true, lock the entry, clear
+the entry in xarray, and decrement mapping->nrpages. The it will call:
+
+ entry = dax_make_entry(pfn_to_pfn_t(0), flags);
+ dax_lock_entry(xas, entry);
+
+which inserts new PTE entry into xarray. However this may fail allocating
+the new node. We handle this by:
+
+ if (xas_nomem(xas, mapping_gfp_mask(mapping) & ~__GFP_HIGHMEM))
+ goto retry;
+
+however pmd_downgrade stays set to true even though 'entry' returned from
+get_unlocked_entry() will be NULL now. And we will go again through the
+downgrade branch. This is mostly harmless except that mapping->nrpages is
+decremented again and we temporarily have an invalid entry stored in
+xarray. Fix the problem by setting pmd_downgrade to false each time we
+lookup the entry we work with so that it matches the entry we found.
+
+Link: https://lkml.kernel.org/r/20210622160015.18004-1-jack@suse.cz
+Fixes: b15cd800682f ("dax: Convert page fault handlers to XArray")
+Signed-off-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dax.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/dax.c b/fs/dax.c
+index 62352cbcf0f4..da41f9363568 100644
+--- a/fs/dax.c
++++ b/fs/dax.c
+@@ -488,10 +488,11 @@ static void *grab_mapping_entry(struct xa_state *xas,
+ struct address_space *mapping, unsigned int order)
+ {
+ unsigned long index = xas->xa_index;
+- bool pmd_downgrade = false; /* splitting PMD entry into PTE entries? */
++ bool pmd_downgrade; /* splitting PMD entry into PTE entries? */
+ void *entry;
+
+ retry:
++ pmd_downgrade = false;
+ xas_lock_irq(xas);
+ entry = get_unlocked_entry(xas, order);
+
+--
+2.30.2
+
--- /dev/null
+From 6ff647010438672c54fd350b61b83941f89ed327 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 18:58:41 +0800
+Subject: drivers: hv: Fix missing error code in vmbus_connect()
+
+From: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
+
+[ Upstream commit 9de6655cc5a6a1febc514465c87c24a0e96d8dba ]
+
+Eliminate the follow smatch warning:
+
+drivers/hv/connection.c:236 vmbus_connect() warn: missing error code
+'ret'.
+
+Reported-by: Abaci Robot <abaci@linux.alibaba.com>
+Signed-off-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://lore.kernel.org/r/1621940321-72353-1-git-send-email-jiapeng.chong@linux.alibaba.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/connection.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
+index 311cd005b3be..5e479d54918c 100644
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -232,8 +232,10 @@ int vmbus_connect(void)
+ */
+
+ for (i = 0; ; i++) {
+- if (i == ARRAY_SIZE(vmbus_versions))
++ if (i == ARRAY_SIZE(vmbus_versions)) {
++ ret = -EDOM;
+ goto cleanup;
++ }
+
+ version = vmbus_versions[i];
+ if (version > max_version)
+--
+2.30.2
+
--- /dev/null
+From f72464f88d732a73f2b0a8c8373177451b81a751 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jun 2021 20:26:14 +0800
+Subject: drivers/perf: fix the missed ida_simple_remove() in ddr_perf_probe()
+
+From: Jing Xiangfeng <jingxiangfeng@huawei.com>
+
+[ Upstream commit d96b1b8c9f79b6bb234a31c80972a6f422079376 ]
+
+ddr_perf_probe() misses to call ida_simple_remove() in an error path.
+Jump to cpuhp_state_err to fix it.
+
+Signed-off-by: Jing Xiangfeng <jingxiangfeng@huawei.com>
+Reviewed-by: Dong Aisheng <aisheng.dong@nxp.com>
+Link: https://lore.kernel.org/r/20210617122614.166823-1-jingxiangfeng@huawei.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/fsl_imx8_ddr_perf.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c
+index 2bbb93188064..7b87aaf267d5 100644
+--- a/drivers/perf/fsl_imx8_ddr_perf.c
++++ b/drivers/perf/fsl_imx8_ddr_perf.c
+@@ -705,8 +705,10 @@ static int ddr_perf_probe(struct platform_device *pdev)
+
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL, DDR_PERF_DEV_NAME "%d",
+ num);
+- if (!name)
+- return -ENOMEM;
++ if (!name) {
++ ret = -ENOMEM;
++ goto cpuhp_state_err;
++ }
+
+ pmu->devtype_data = of_device_get_match_data(&pdev->dev);
+
+--
+2.30.2
+
--- /dev/null
+From a615317540e60441bad9c223ee406a4de22fe3b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Jun 2021 16:34:51 +0800
+Subject: drivers/perf: hisi: Fix data source control
+
+From: Shaokun Zhang <zhangshaokun@hisilicon.com>
+
+[ Upstream commit 814be609baae62aaa6c02fa6f3ad66cff32a6d15 ]
+
+'Data source' is a new function for HHA PMU and config / clear
+interface was wrong by mistake. 'HHA_DATSRC_CTRL' register is
+mainly used for data source configuration, if we enable bit0
+as driver, it will go on count the event and we didn't check
+it carefully. So fix the issue and do as the initial purpose.
+
+Fixes: 932f6a99f9b0 ("drivers/perf: hisi: Add new functions for HHA PMU")
+Reported-by: kernel test robot <lkp@intel.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
+Link: https://lore.kernel.org/r/1622709291-37996-1-git-send-email-zhangshaokun@hisilicon.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
+index 0316fabe32f1..acc864bded2b 100644
+--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
++++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
+@@ -90,7 +90,7 @@ static void hisi_hha_pmu_config_ds(struct perf_event *event)
+
+ val = readl(hha_pmu->base + HHA_DATSRC_CTRL);
+ val |= HHA_DATSRC_SKT_EN;
+- writel(ds_skt, hha_pmu->base + HHA_DATSRC_CTRL);
++ writel(val, hha_pmu->base + HHA_DATSRC_CTRL);
+ }
+ }
+
+@@ -104,7 +104,7 @@ static void hisi_hha_pmu_clear_ds(struct perf_event *event)
+
+ val = readl(hha_pmu->base + HHA_DATSRC_CTRL);
+ val &= ~HHA_DATSRC_SKT_EN;
+- writel(ds_skt, hha_pmu->base + HHA_DATSRC_CTRL);
++ writel(val, hha_pmu->base + HHA_DATSRC_CTRL);
+ }
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 8b131433b034d2dad2b39c5231f1ded14450ec55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 17:57:20 -0700
+Subject: drm/amd/dc: Fix a missing check bug in dm_dp_mst_detect()
+
+From: Yingjie Wang <wangyingjie55@126.com>
+
+[ Upstream commit 655c0ed19772d92c9665ed08bdc5202acc096dda ]
+
+In dm_dp_mst_detect(), We should check whether or not @connector
+has been unregistered from userspace. If the connector is unregistered,
+we should return disconnected status.
+
+Fixes: 4562236b3bc0 ("drm/amd/dc: Add dc display driver (v2)")
+Signed-off-by: Yingjie Wang <wangyingjie55@126.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+index 9b221db526dc..d62460b69d95 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+@@ -278,6 +278,9 @@ dm_dp_mst_detect(struct drm_connector *connector,
+ struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
+ struct amdgpu_dm_connector *master = aconnector->mst_port;
+
++ if (drm_connector_is_unregistered(connector))
++ return connector_status_disconnected;
++
+ return drm_dp_mst_detect_port(connector, ctx, &master->mst_mgr,
+ aconnector->port);
+ }
+--
+2.30.2
+
--- /dev/null
+From 0dee4d67354c4f407ab917990268fb8848b6c91c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 May 2021 19:30:36 -0400
+Subject: drm/amd/display: Avoid HPD IRQ in GPU reset state
+
+From: Zhan Liu <zhan.liu@amd.com>
+
+[ Upstream commit 509b9a5b4865dee723296f143695a7774fc96c4a ]
+
+[Why]
+If GPU is in reset state, force enabling link will cause
+unexpected behaviour.
+
+[How]
+Avoid handling HPD IRQ when GPU is in reset state.
+
+Signed-off-by: Zhan Liu <zhan.liu@amd.com>
+Reviewed-by: Nikola Cornij <nikola.cornij@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 875fd187463e..dcb4e585c270 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -2726,15 +2726,15 @@ static void handle_hpd_rx_irq(void *param)
+ }
+ }
+
+- if (!amdgpu_in_reset(adev))
++ if (!amdgpu_in_reset(adev)) {
+ mutex_lock(&adev->dm.dc_lock);
+ #ifdef CONFIG_DRM_AMD_DC_HDCP
+ result = dc_link_handle_hpd_rx_irq(dc_link, &hpd_irq_data, NULL);
+ #else
+ result = dc_link_handle_hpd_rx_irq(dc_link, NULL, NULL);
+ #endif
+- if (!amdgpu_in_reset(adev))
+ mutex_unlock(&adev->dm.dc_lock);
++ }
+
+ out:
+ if (result && !is_mst_root_connector) {
+--
+2.30.2
+
--- /dev/null
+From 77cd0b15613bc8e6cd3df5ca6058533b760f2ded Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Apr 2021 11:47:00 -0400
+Subject: drm/amd/display: fix potential gpu reset deadlock
+
+From: Roman Li <Roman.Li@amd.com>
+
+[ Upstream commit cf8b92a75646735136053ce51107bfa8cfc23191 ]
+
+[Why]
+In gpu reset dc_lock acquired in dm_suspend().
+Asynchronously handle_hpd_rx_irq can also be called
+through amdgpu_dm_irq_suspend->flush_work, which also
+tries to acquire dc_lock. That causes a deadlock.
+
+[How]
+Check if amdgpu executing reset before acquiring dc_lock.
+
+Signed-off-by: Lang Yu <Lang.Yu@amd.com>
+Signed-off-by: Roman Li <Roman.Li@amd.com>
+Reviewed-by: Qingqing Zhuo <Qingqing.Zhuo@amd.com>
+Acked-by: Wayne Lin <Wayne.Lin@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 652cc1a0e450..875fd187463e 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -2726,13 +2726,15 @@ static void handle_hpd_rx_irq(void *param)
+ }
+ }
+
+- mutex_lock(&adev->dm.dc_lock);
++ if (!amdgpu_in_reset(adev))
++ mutex_lock(&adev->dm.dc_lock);
+ #ifdef CONFIG_DRM_AMD_DC_HDCP
+ result = dc_link_handle_hpd_rx_irq(dc_link, &hpd_irq_data, NULL);
+ #else
+ result = dc_link_handle_hpd_rx_irq(dc_link, NULL, NULL);
+ #endif
+- mutex_unlock(&adev->dm.dc_lock);
++ if (!amdgpu_in_reset(adev))
++ mutex_unlock(&adev->dm.dc_lock);
+
+ out:
+ if (result && !is_mst_root_connector) {
+--
+2.30.2
+
--- /dev/null
+From 1ba4a93d411ce48671ca7d04af274e39ac2dbb3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 May 2021 16:51:01 -0400
+Subject: drm/amd/display: take dc_lock in short pulse handler only
+
+From: Aurabindo Pillai <aurabindo.pillai@amd.com>
+
+[ Upstream commit d2aa1356834d845ffdac0d8c01b58aa60d1bdc65 ]
+
+[Why]
+Conditions that end up modifying the global dc state must be locked.
+However, during mst allocate payload sequence, lock is already taken.
+With StarTech 1.2 DP hub, we get an HPD RX interrupt for a reason other
+than to indicate down reply availability right after sending payload
+allocation. The handler again takes dc lock before calling the
+dc's HPD RX handler. Due to this contention, the DRM thread which waits
+for MST down reply never gets a chance to finish its waiting
+successfully and ends up timing out. Once the lock is released, the hpd
+rx handler fires and goes ahead to read from the MST HUB, but now its
+too late and the HUB doesnt lightup all displays since DRM lacks error
+handling when payload allocation fails.
+
+[How]
+Take lock only if there is a change in link status or if automated test
+pattern bit is set. The latter fixes the null pointer dereference when
+running certain DP Link Layer Compliance test.
+
+Fixes: c8ea79a8a276 ("drm/amd/display: NULL pointer error during compliance test")
+
+Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 19 +++++++++++++++++--
+ .../gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +-
+ .../gpu/drm/amd/display/dc/inc/dc_link_dp.h | 4 ++++
+ 3 files changed, 22 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index dcb4e585c270..2b2d7b9f26f1 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -28,6 +28,7 @@
+
+ #include "dm_services_types.h"
+ #include "dc.h"
++#include "dc_link_dp.h"
+ #include "dc/inc/core_types.h"
+ #include "dal_asic_id.h"
+ #include "dmub/dmub_srv.h"
+@@ -2696,6 +2697,7 @@ static void handle_hpd_rx_irq(void *param)
+ enum dc_connection_type new_connection_type = dc_connection_none;
+ struct amdgpu_device *adev = drm_to_adev(dev);
+ union hpd_irq_data hpd_irq_data;
++ bool lock_flag = 0;
+
+ memset(&hpd_irq_data, 0, sizeof(hpd_irq_data));
+
+@@ -2726,15 +2728,28 @@ static void handle_hpd_rx_irq(void *param)
+ }
+ }
+
+- if (!amdgpu_in_reset(adev)) {
++ /*
++ * TODO: We need the lock to avoid touching DC state while it's being
++ * modified during automated compliance testing, or when link loss
++ * happens. While this should be split into subhandlers and proper
++ * interfaces to avoid having to conditionally lock like this in the
++ * outer layer, we need this workaround temporarily to allow MST
++ * lightup in some scenarios to avoid timeout.
++ */
++ if (!amdgpu_in_reset(adev) &&
++ (hpd_rx_irq_check_link_loss_status(dc_link, &hpd_irq_data) ||
++ hpd_irq_data.bytes.device_service_irq.bits.AUTOMATED_TEST)) {
+ mutex_lock(&adev->dm.dc_lock);
++ lock_flag = 1;
++ }
++
+ #ifdef CONFIG_DRM_AMD_DC_HDCP
+ result = dc_link_handle_hpd_rx_irq(dc_link, &hpd_irq_data, NULL);
+ #else
+ result = dc_link_handle_hpd_rx_irq(dc_link, NULL, NULL);
+ #endif
++ if (!amdgpu_in_reset(adev) && lock_flag)
+ mutex_unlock(&adev->dm.dc_lock);
+- }
+
+ out:
+ if (result && !is_mst_root_connector) {
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+index 3ff3d9e90983..72bd7bc681a8 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+@@ -1976,7 +1976,7 @@ enum dc_status read_hpd_rx_irq_data(
+ return retval;
+ }
+
+-static bool hpd_rx_irq_check_link_loss_status(
++bool hpd_rx_irq_check_link_loss_status(
+ struct dc_link *link,
+ union hpd_irq_data *hpd_irq_dpcd_data)
+ {
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
+index 3ae05c96d557..a9c0c7f7a55d 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
+@@ -67,6 +67,10 @@ bool perform_link_training_with_retries(
+ struct pipe_ctx *pipe_ctx,
+ enum signal_type signal);
+
++bool hpd_rx_irq_check_link_loss_status(
++ struct dc_link *link,
++ union hpd_irq_data *hpd_irq_dpcd_data);
++
+ bool is_mst_supported(struct dc_link *link);
+
+ bool detect_dp_sink_caps(struct dc_link *link);
+--
+2.30.2
+
--- /dev/null
+From 4608fc3c731fe67e82999f4a16608ed8ff6f4a89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Apr 2021 19:04:58 +0200
+Subject: drm/ast: Fix missing conversions to managed API
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 9ea172a9a3f4a7c5e876469509fc18ddefc7d49d ]
+
+The commit 7cbb93d89838 ("drm/ast: Use managed pci functions")
+converted a few PCI accessors to the managed API and dropped the
+manual pci_iounmap() calls, but it seems to have forgotten converting
+pci_iomap() to the managed one. It resulted in the leftover resources
+after the driver unbind. Let's fix them.
+
+Fixes: 7cbb93d89838 ("drm/ast: Use managed pci functions")
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210421170458.21178-1-tiwai@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/ast/ast_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
+index 0ac3c2039c4b..c29cc7f19863 100644
+--- a/drivers/gpu/drm/ast/ast_main.c
++++ b/drivers/gpu/drm/ast/ast_main.c
+@@ -413,7 +413,7 @@ struct ast_private *ast_device_create(const struct drm_driver *drv,
+
+ pci_set_drvdata(pdev, dev);
+
+- ast->regs = pci_iomap(pdev, 1, 0);
++ ast->regs = pcim_iomap(pdev, 1, 0);
+ if (!ast->regs)
+ return ERR_PTR(-EIO);
+
+@@ -429,7 +429,7 @@ struct ast_private *ast_device_create(const struct drm_driver *drv,
+
+ /* "map" IO regs if the above hasn't done so already */
+ if (!ast->ioregs) {
+- ast->ioregs = pci_iomap(pdev, 2, 0);
++ ast->ioregs = pcim_iomap(pdev, 2, 0);
+ if (!ast->ioregs)
+ return ERR_PTR(-EIO);
+ }
+--
+2.30.2
+
--- /dev/null
+From 1baafbcd648a1fc7707430625110d071c860d7c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Apr 2021 19:51:16 +0800
+Subject: drm/bridge: anx7625: Fix power on delay
+
+From: Hsin-Yi Wang <hsinyi@chromium.org>
+
+[ Upstream commit 1fcf24fb07e254ca69001ab14adc8cf567127c44 ]
+
+>From anx7625 spec, the delay between powering on power supplies and gpio
+should be larger than 10ms.
+
+Fixes: 6c744983004e ("drm/bridge: anx7625: disable regulators when power off")
+Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
+Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210428115116.931328-1-hsinyi@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/analogix/anx7625.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
+index 23283ba0c4f9..b4e349ca38fe 100644
+--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
++++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
+@@ -893,7 +893,7 @@ static void anx7625_power_on(struct anx7625_data *ctx)
+ usleep_range(2000, 2100);
+ }
+
+- usleep_range(4000, 4100);
++ usleep_range(11000, 12000);
+
+ /* Power on pin enable */
+ gpiod_set_value(ctx->pdata.gpio_p_on, 1);
+--
+2.30.2
+
--- /dev/null
+From f999d8bc13b822fb737f21de2e8518da66a85607 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 00:02:07 +0200
+Subject: drm/bridge: fix LONTIUM_LT8912B dependencies
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Adrien Grassein <adrien.grassein@gmail.com>
+
+[ Upstream commit 660729e494b6ee64feb97b41f3092c32a41c7dae ]
+
+LONTIUM_LT8912B uses "drm_display_mode_to_videomode" from
+DRM framework that needs VIDEOMODE_HELPERS to be enabled.
+
+Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge")
+Reported-by: Michal Suchánek <msuchanek@suse.de>
+Signed-off-by: Adrien Grassein <adrien.grassein@gmail.com>
+Reviewed-by: Robert Foss <robert.foss@linaro.org>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210504220207.4004511-1-adrien.grassein@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
+index eb3eebab4f27..9ce8438fb58b 100644
+--- a/drivers/gpu/drm/bridge/Kconfig
++++ b/drivers/gpu/drm/bridge/Kconfig
+@@ -68,6 +68,7 @@ config DRM_LONTIUM_LT8912B
+ select DRM_KMS_HELPER
+ select DRM_MIPI_DSI
+ select REGMAP_I2C
++ select VIDEOMODE_HELPERS
+ help
+ Driver for Lontium LT8912B DSI to HDMI bridge
+ chip driver.
+--
+2.30.2
+
--- /dev/null
+From 89cd90c62259b7ca00ec84648a666b70842d7a47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Apr 2021 15:39:24 -0700
+Subject: drm/bridge: Fix the stop condition of drm_bridge_chain_pre_enable()
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit bab5cca7e609952b069a550e39fe4893149fb658 ]
+
+The drm_bridge_chain_pre_enable() is not the proper opposite of
+drm_bridge_chain_post_disable(). It continues along the chain to
+_before_ the starting bridge. Let's fix that.
+
+Fixes: 05193dc38197 ("drm/bridge: Make the bridge chain a double-linked list")
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210416153909.v4.1.If62a003f76a2bc4ccc6c53565becc05d2aad4430@changeid
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_bridge.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
+index 64f0effb52ac..044acd07c153 100644
+--- a/drivers/gpu/drm/drm_bridge.c
++++ b/drivers/gpu/drm/drm_bridge.c
+@@ -522,6 +522,9 @@ void drm_bridge_chain_pre_enable(struct drm_bridge *bridge)
+ list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
+ if (iter->funcs->pre_enable)
+ iter->funcs->pre_enable(iter);
++
++ if (iter == bridge)
++ break;
+ }
+ }
+ EXPORT_SYMBOL(drm_bridge_chain_pre_enable);
+--
+2.30.2
+
--- /dev/null
+From 1409f1590596ca4400932e65f6785e84df96f702 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Apr 2021 11:01:24 +0200
+Subject: drm/bridge/sii8620: fix dependency on extcon
+
+From: Robert Foss <robert.foss@linaro.org>
+
+[ Upstream commit 08319adbdde15ef7cee1970336f63461254baa2a ]
+
+The DRM_SIL_SII8620 kconfig has a weak `imply` dependency
+on EXTCON, which causes issues when sii8620 is built
+as a builtin and EXTCON is built as a module.
+
+The symptoms are 'undefined reference' errors caused
+by the symbols in EXTCON not being available
+to the sii8620 driver.
+
+Fixes: 688838442147 ("drm/bridge/sii8620: use micro-USB cable detection logic to detect MHL")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210419090124.153560-1-robert.foss@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
+index 400193e38d29..eb3eebab4f27 100644
+--- a/drivers/gpu/drm/bridge/Kconfig
++++ b/drivers/gpu/drm/bridge/Kconfig
+@@ -172,7 +172,7 @@ config DRM_SIL_SII8620
+ tristate "Silicon Image SII8620 HDMI/MHL bridge"
+ depends on OF
+ select DRM_KMS_HELPER
+- imply EXTCON
++ select EXTCON
+ depends on RC_CORE || !RC_CORE
+ help
+ Silicon Image SII8620 HDMI/MHL bridge chip driver.
+--
+2.30.2
+
--- /dev/null
+From 340b57ede3e47824a0118c485b9ff966c887d520 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Mar 2021 14:05:42 +1100
+Subject: drm/i915: Merge fix for "drm: Switch to %p4cc format modifier"
+
+From: Stephen Rothwell <sfr@canb.auug.org.au>
+
+[ Upstream commit e3c2f1870af43fc95f6fe141537f5142c5fe4717 ]
+
+Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Fixes: 92f1d09ca4ed ("drm: Switch to %p4cc format modifier")
+Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
+Cc: Petr Mladek <pmladek@suse.com>
+Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: dri-devel@lists.freedesktop.org
+Link: https://lore.kernel.org/dri-devel/20210514115307.4364aff9@canb.auug.org.au/T/#macc61d4e0b17ca0da2b26aae8fbbcbf47324da13
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/skl_universal_plane.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
+index 7ffd7b570b54..538682f882b1 100644
+--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
++++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
+@@ -1082,7 +1082,6 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
+ struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ const struct drm_framebuffer *fb = plane_state->hw.fb;
+ unsigned int rotation = plane_state->hw.rotation;
+- struct drm_format_name_buf format_name;
+
+ if (!fb)
+ return 0;
+@@ -1130,9 +1129,8 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
+ case DRM_FORMAT_XVYU12_16161616:
+ case DRM_FORMAT_XVYU16161616:
+ drm_dbg_kms(&dev_priv->drm,
+- "Unsupported pixel format %s for 90/270!\n",
+- drm_get_format_name(fb->format->format,
+- &format_name));
++ "Unsupported pixel format %p4cc for 90/270!\n",
++ &fb->format->format);
+ return -EINVAL;
+ default:
+ break;
+--
+2.30.2
+
--- /dev/null
+From 840a702c14086ce15e244cbef14ef460afe94c22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Jun 2021 08:08:38 +0200
+Subject: drm/i915/selftests: Reorder tasklet_disable vs local_bh_disable
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Chris Wilson <chris@chris-wilson.co.uk>
+
+[ Upstream commit 2328e1b35ac2bb003236c3268aabe456ffab8b56 ]
+
+Due to a change in requirements that disallows tasklet_disable() being
+called from atomic context, rearrange the selftest to avoid doing so.
+
+<3> [324.942939] BUG: sleeping function called from invalid context at kernel/softirq.c:888
+<3> [324.942952] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 5601, name: i915_selftest
+<4> [324.942960] 1 lock held by i915_selftest/5601:
+<4> [324.942963] #0: ffff888101d19240 (&dev->mutex){....}-{3:3}, at: device_driver_attach+0x18/0x50
+<3> [324.942987] Preemption disabled at:
+<3> [324.942990] [<ffffffffa026fbd2>] live_hold_reset.part.65+0xc2/0x2f0 [i915]
+<4> [324.943255] CPU: 0 PID: 5601 Comm: i915_selftest Tainted: G U 5.13.0-rc5-CI-CI_DRM_10197+ #1
+<4> [324.943259] Hardware name: Intel Corp. Geminilake/GLK RVP2 LP4SD (07), BIOS GELKRVPA.X64.0062.B30.1708222146 08/22/2017
+<4> [324.943263] Call Trace:
+<4> [324.943267] dump_stack+0x7f/0xad
+<4> [324.943276] ___might_sleep.cold.123+0xf2/0x106
+<4> [324.943286] tasklet_unlock_wait+0x2e/0xb0
+<4> [324.943291] ? ktime_get_raw+0x81/0x120
+<4> [324.943305] live_hold_reset.part.65+0x1ab/0x2f0 [i915]
+<4> [324.943500] __i915_subtests.cold.7+0x42/0x92 [i915]
+<4> [324.943723] ? __i915_live_teardown+0x50/0x50 [i915]
+<4> [324.943922] ? __intel_gt_live_setup+0x30/0x30 [i915]
+
+Fixes: da044747401fc ("tasklets: Replace spin wait in tasklet_unlock_wait()")
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Matthew Auld <matthew.auld@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210611060838.647973-1-thomas.hellstrom@linux.intel.com
+(cherry picked from commit 35c6367f516090a3086d37e7023b08608d555aba)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/selftest_execlists.c | 55 ++++++++++++--------
+ 1 file changed, 32 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/selftest_execlists.c b/drivers/gpu/drm/i915/gt/selftest_execlists.c
+index 1081cd36a2bd..1e5d59a776b8 100644
+--- a/drivers/gpu/drm/i915/gt/selftest_execlists.c
++++ b/drivers/gpu/drm/i915/gt/selftest_execlists.c
+@@ -551,6 +551,32 @@ static int live_pin_rewind(void *arg)
+ return err;
+ }
+
++static int engine_lock_reset_tasklet(struct intel_engine_cs *engine)
++{
++ tasklet_disable(&engine->execlists.tasklet);
++ local_bh_disable();
++
++ if (test_and_set_bit(I915_RESET_ENGINE + engine->id,
++ &engine->gt->reset.flags)) {
++ local_bh_enable();
++ tasklet_enable(&engine->execlists.tasklet);
++
++ intel_gt_set_wedged(engine->gt);
++ return -EBUSY;
++ }
++
++ return 0;
++}
++
++static void engine_unlock_reset_tasklet(struct intel_engine_cs *engine)
++{
++ clear_and_wake_up_bit(I915_RESET_ENGINE + engine->id,
++ &engine->gt->reset.flags);
++
++ local_bh_enable();
++ tasklet_enable(&engine->execlists.tasklet);
++}
++
+ static int live_hold_reset(void *arg)
+ {
+ struct intel_gt *gt = arg;
+@@ -598,15 +624,9 @@ static int live_hold_reset(void *arg)
+
+ /* We have our request executing, now remove it and reset */
+
+- local_bh_disable();
+- if (test_and_set_bit(I915_RESET_ENGINE + id,
+- >->reset.flags)) {
+- local_bh_enable();
+- intel_gt_set_wedged(gt);
+- err = -EBUSY;
++ err = engine_lock_reset_tasklet(engine);
++ if (err)
+ goto out;
+- }
+- tasklet_disable(&engine->execlists.tasklet);
+
+ engine->execlists.tasklet.callback(&engine->execlists.tasklet);
+ GEM_BUG_ON(execlists_active(&engine->execlists) != rq);
+@@ -618,10 +638,7 @@ static int live_hold_reset(void *arg)
+ __intel_engine_reset_bh(engine, NULL);
+ GEM_BUG_ON(rq->fence.error != -EIO);
+
+- tasklet_enable(&engine->execlists.tasklet);
+- clear_and_wake_up_bit(I915_RESET_ENGINE + id,
+- >->reset.flags);
+- local_bh_enable();
++ engine_unlock_reset_tasklet(engine);
+
+ /* Check that we do not resubmit the held request */
+ if (!i915_request_wait(rq, 0, HZ / 5)) {
+@@ -4585,15 +4602,9 @@ static int reset_virtual_engine(struct intel_gt *gt,
+ GEM_BUG_ON(engine == ve->engine);
+
+ /* Take ownership of the reset and tasklet */
+- local_bh_disable();
+- if (test_and_set_bit(I915_RESET_ENGINE + engine->id,
+- >->reset.flags)) {
+- local_bh_enable();
+- intel_gt_set_wedged(gt);
+- err = -EBUSY;
++ err = engine_lock_reset_tasklet(engine);
++ if (err)
+ goto out_heartbeat;
+- }
+- tasklet_disable(&engine->execlists.tasklet);
+
+ engine->execlists.tasklet.callback(&engine->execlists.tasklet);
+ GEM_BUG_ON(execlists_active(&engine->execlists) != rq);
+@@ -4612,9 +4623,7 @@ static int reset_virtual_engine(struct intel_gt *gt,
+ GEM_BUG_ON(rq->fence.error != -EIO);
+
+ /* Release our grasp on the engine, letting CS flow again */
+- tasklet_enable(&engine->execlists.tasklet);
+- clear_and_wake_up_bit(I915_RESET_ENGINE + engine->id, >->reset.flags);
+- local_bh_enable();
++ engine_unlock_reset_tasklet(engine);
+
+ /* Check that we do not resubmit the held request */
+ i915_request_get(rq);
+--
+2.30.2
+
--- /dev/null
+From 47ad6327344fda1414d46557540bd66df3c47d07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jan 2021 14:51:08 +0100
+Subject: drm/imx: ipuv3-plane: do not advertise YUV formats on planes without
+ CSC
+
+From: Philipp Zabel <p.zabel@pengutronix.de>
+
+[ Upstream commit 06841148c570832d4d247b0f6befc1922a84120b ]
+
+Only planes that are displayed via the Display Processor (DP) path
+support color space conversion. Limit formats on planes that are
+shown via the direct Display Controller (DC) path to RGB.
+
+Reported-by: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/imx/ipuv3-plane.c | 41 ++++++++++++++++++++++++++++---
+ 1 file changed, 37 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
+index fa5009705365..fc8f4834ed7b 100644
+--- a/drivers/gpu/drm/imx/ipuv3-plane.c
++++ b/drivers/gpu/drm/imx/ipuv3-plane.c
+@@ -35,7 +35,7 @@ static inline struct ipu_plane *to_ipu_plane(struct drm_plane *p)
+ return container_of(p, struct ipu_plane, base);
+ }
+
+-static const uint32_t ipu_plane_formats[] = {
++static const uint32_t ipu_plane_all_formats[] = {
+ DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_ABGR1555,
+@@ -72,6 +72,31 @@ static const uint32_t ipu_plane_formats[] = {
+ DRM_FORMAT_BGRX8888_A8,
+ };
+
++static const uint32_t ipu_plane_rgb_formats[] = {
++ DRM_FORMAT_ARGB1555,
++ DRM_FORMAT_XRGB1555,
++ DRM_FORMAT_ABGR1555,
++ DRM_FORMAT_XBGR1555,
++ DRM_FORMAT_RGBA5551,
++ DRM_FORMAT_BGRA5551,
++ DRM_FORMAT_ARGB4444,
++ DRM_FORMAT_ARGB8888,
++ DRM_FORMAT_XRGB8888,
++ DRM_FORMAT_ABGR8888,
++ DRM_FORMAT_XBGR8888,
++ DRM_FORMAT_RGBA8888,
++ DRM_FORMAT_RGBX8888,
++ DRM_FORMAT_BGRA8888,
++ DRM_FORMAT_BGRX8888,
++ DRM_FORMAT_RGB565,
++ DRM_FORMAT_RGB565_A8,
++ DRM_FORMAT_BGR565_A8,
++ DRM_FORMAT_RGB888_A8,
++ DRM_FORMAT_BGR888_A8,
++ DRM_FORMAT_RGBX8888_A8,
++ DRM_FORMAT_BGRX8888_A8,
++};
++
+ static const uint64_t ipu_format_modifiers[] = {
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_INVALID
+@@ -830,16 +855,24 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
+ struct ipu_plane *ipu_plane;
+ const uint64_t *modifiers = ipu_format_modifiers;
+ unsigned int zpos = (type == DRM_PLANE_TYPE_PRIMARY) ? 0 : 1;
++ unsigned int format_count;
++ const uint32_t *formats;
+ int ret;
+
+ DRM_DEBUG_KMS("channel %d, dp flow %d, possible_crtcs=0x%x\n",
+ dma, dp, possible_crtcs);
+
++ if (dp == IPU_DP_FLOW_SYNC_BG || dp == IPU_DP_FLOW_SYNC_FG) {
++ formats = ipu_plane_all_formats;
++ format_count = ARRAY_SIZE(ipu_plane_all_formats);
++ } else {
++ formats = ipu_plane_rgb_formats;
++ format_count = ARRAY_SIZE(ipu_plane_rgb_formats);
++ }
+ ipu_plane = drmm_universal_plane_alloc(dev, struct ipu_plane, base,
+ possible_crtcs, &ipu_plane_funcs,
+- ipu_plane_formats,
+- ARRAY_SIZE(ipu_plane_formats),
+- modifiers, type, NULL);
++ formats, format_count, modifiers,
++ type, NULL);
+ if (IS_ERR(ipu_plane)) {
+ DRM_ERROR("failed to allocate and initialize %s plane\n",
+ zpos ? "overlay" : "primary");
+--
+2.30.2
+
--- /dev/null
+From 3751cf0ce74954a968e1bea1d55b5be00b23f6f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 16:59:27 +0200
+Subject: drm/imx: ipuv3-plane: fix PRG modifiers after drm managed resource
+ conversion
+
+From: Lucas Stach <l.stach@pengutronix.de>
+
+[ Upstream commit 17b9a94656fe19aef3647c4f93d93be51697ceb1 ]
+
+The conversion to drm managed resources introduced two bugs: the plane is now
+always initialized with the linear-only list, while the list with the Vivante
+GPU modifiers should have been used when the PRG/PRE engines are present. This
+masked another issue, as ipu_plane_format_mod_supported() is now called before
+the private plane data is set up, so if a non-linear modifier is supplied in
+the plane modifier list, we run into a NULL pointer dereference checking for
+the PRG presence. To fix this just remove the check from this function, as we
+know that it will only be called with a non-linear modifier, if the plane init
+code has already determined that the PRG/PRE is present.
+
+Fixes: 699e7e543f1a ("drm/imx: ipuv3-plane: use drm managed resources")
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Link: https://lore.kernel.org/r/20210510145927.988661-1-l.stach@pengutronix.de
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/imx/ipuv3-plane.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
+index fc8f4834ed7b..233310712deb 100644
+--- a/drivers/gpu/drm/imx/ipuv3-plane.c
++++ b/drivers/gpu/drm/imx/ipuv3-plane.c
+@@ -345,10 +345,11 @@ static bool ipu_plane_format_mod_supported(struct drm_plane *plane,
+ if (modifier == DRM_FORMAT_MOD_LINEAR)
+ return true;
+
+- /* without a PRG there are no supported modifiers */
+- if (!ipu_prg_present(ipu))
+- return false;
+-
++ /*
++ * Without a PRG the possible modifiers list only includes the linear
++ * modifier, so we always take the early return from this function and
++ * only end up here if the PRG is present.
++ */
+ return ipu_prg_format_supported(ipu, format, modifier);
+ }
+
+@@ -869,6 +870,10 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
+ formats = ipu_plane_rgb_formats;
+ format_count = ARRAY_SIZE(ipu_plane_rgb_formats);
+ }
++
++ if (ipu_prg_present(ipu))
++ modifiers = pre_format_modifiers;
++
+ ipu_plane = drmm_universal_plane_alloc(dev, struct ipu_plane, base,
+ possible_crtcs, &ipu_plane_funcs,
+ formats, format_count, modifiers,
+@@ -883,9 +888,6 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
+ ipu_plane->dma = dma;
+ ipu_plane->dp_flow = dp;
+
+- if (ipu_prg_present(ipu))
+- modifiers = pre_format_modifiers;
+-
+ drm_plane_helper_add(&ipu_plane->base, &ipu_plane_helper_funcs);
+
+ if (dp == IPU_DP_FLOW_SYNC_BG || dp == IPU_DP_FLOW_SYNC_FG)
+--
+2.30.2
+
--- /dev/null
+From 55da3fd7884c129cc264ceb50f6c1368c541e950 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 May 2021 10:37:56 +0530
+Subject: drm/msm/disp/dpu1: avoid perf update in frame done event
+
+From: Krishna Manikandan <mkrishn@codeaurora.org>
+
+[ Upstream commit a1f2ba60eace242fd034173db3762f342a824a2e ]
+
+Crtc perf update from frame event work can result in
+wrong bandwidth and clock update from dpu if the work
+is scheduled after the swap state has happened.
+
+Avoid such issues by moving perf update to complete
+commit once the frame is accepted by the hardware.
+
+Fixes: a29c8c024165 ("drm/msm/disp/dpu1: fix display underruns during modeset")
+Signed-off-by: Krishna Manikandan <mkrishn@codeaurora.org>
+Tested-by: Douglas Anderson <dianders@chromium.org>
+Link: https://lore.kernel.org/r/1622092076-5100-1-git-send-email-mkrishn@codeaurora.org
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+index 18bc76b7f1a3..4523d6ba891b 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+@@ -407,9 +407,6 @@ static void dpu_crtc_frame_event_work(struct kthread_work *work)
+ fevent->event);
+ }
+
+- if (fevent->event & DPU_ENCODER_FRAME_EVENT_DONE)
+- dpu_core_perf_crtc_update(crtc, 0, false);
+-
+ if (fevent->event & (DPU_ENCODER_FRAME_EVENT_DONE
+ | DPU_ENCODER_FRAME_EVENT_ERROR))
+ frame_done = true;
+@@ -477,6 +474,7 @@ static void dpu_crtc_frame_event_cb(void *data, u32 event)
+ void dpu_crtc_complete_commit(struct drm_crtc *crtc)
+ {
+ trace_dpu_crtc_complete_commit(DRMID(crtc));
++ dpu_core_perf_crtc_update(crtc, 0, false);
+ _dpu_crtc_complete_flip(crtc);
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 44a9393036ff96897b8c498a6f4746cb08732c21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 15:25:30 -0700
+Subject: drm/msm/dp: handle irq_hpd with sink_count = 0 correctly
+
+From: Kuogee Hsieh <khsieh@codeaurora.org>
+
+[ Upstream commit f21c8a276c2daddddf58d483b49b01d0603f0316 ]
+
+irq_hpd interrupt should be handled after dongle plugged in and
+before dongle unplugged. Hence irq_hpd interrupt is enabled at
+the end of the plugin handle and disabled at the beginning of
+unplugged handle. Current irq_hpd with sink_count = 0 is wrongly
+handled same as the dongle unplugged which tears down the mainlink
+and disables the phy. This patch fixes this problem by only tearing
+down the mainlink but keeping phy enabled at irq_hpd with
+sink_count = 0 handle so that next irq_hpd with sink_count =1 can be
+handled by setup mainlink only. This patch also set dongle into D3
+(power off) state at end of handling irq_hpd with sink_count = 0.
+
+Changes in v2:
+-- add ctrl->phy_Power_count
+
+Changes in v3:
+-- del ctrl->phy_Power_count
+-- add phy_power_off to dp_ctrl_off_link_stream()
+
+Changes in v4:
+-- return immediately if clock disable failed at dp_ctrl_off_link_stream()
+
+Changes in v5:
+-- set dongle to D3 (power off) state at dp_ctrl_off_link_stream()
+
+Changes in v6:
+-- add Fixes tag
+
+Fixes: ea9f337ce81e ("drm/msm/dp: reset dp controller only at boot up and pm_resume")
+Signed-off-by: Kuogee Hsieh <khsieh@codeaurora.org>
+Tested-by: Stephen Boyd <swboyd@chromium.org>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Link: https://lore.kernel.org/r/1621635930-30161-1-git-send-email-khsieh@codeaurora.org
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dp/dp_catalog.c | 5 +--
+ drivers/gpu/drm/msm/dp/dp_ctrl.c | 55 ++++++++++++++++++++++++++++
+ drivers/gpu/drm/msm/dp/dp_ctrl.h | 2 +
+ drivers/gpu/drm/msm/dp/dp_display.c | 57 +++++++++++++++++++++--------
+ 4 files changed, 101 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
+index b1a9b1b98f5f..f4f53f23e331 100644
+--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
++++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
+@@ -582,10 +582,9 @@ void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog)
+
+ u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER);
+
+- /* enable HPD interrupts */
++ /* enable HPD plug and unplug interrupts */
+ dp_catalog_hpd_config_intr(dp_catalog,
+- DP_DP_HPD_PLUG_INT_MASK | DP_DP_IRQ_HPD_INT_MASK
+- | DP_DP_HPD_UNPLUG_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, true);
++ DP_DP_HPD_PLUG_INT_MASK | DP_DP_HPD_UNPLUG_INT_MASK, true);
+
+ /* Configure REFTIMER and enable it */
+ reftimer |= DP_DP_HPD_REFTIMER_ENABLE;
+diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
+index 1390f3547fde..2a8955ca70d1 100644
+--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
++++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
+@@ -1809,6 +1809,61 @@ end:
+ return ret;
+ }
+
++int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl)
++{
++ struct dp_ctrl_private *ctrl;
++ struct dp_io *dp_io;
++ struct phy *phy;
++ int ret;
++
++ ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
++ dp_io = &ctrl->parser->io;
++ phy = dp_io->phy;
++
++ /* set dongle to D3 (power off) mode */
++ dp_link_psm_config(ctrl->link, &ctrl->panel->link_info, true);
++
++ dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
++
++ ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, false);
++ if (ret) {
++ DRM_ERROR("Failed to disable pixel clocks. ret=%d\n", ret);
++ return ret;
++ }
++
++ ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false);
++ if (ret) {
++ DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret);
++ return ret;
++ }
++
++ phy_power_off(phy);
++
++ /* aux channel down, reinit phy */
++ phy_exit(phy);
++ phy_init(phy);
++
++ DRM_DEBUG_DP("DP off link/stream done\n");
++ return ret;
++}
++
++void dp_ctrl_off_phy(struct dp_ctrl *dp_ctrl)
++{
++ struct dp_ctrl_private *ctrl;
++ struct dp_io *dp_io;
++ struct phy *phy;
++
++ ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
++ dp_io = &ctrl->parser->io;
++ phy = dp_io->phy;
++
++ dp_catalog_ctrl_reset(ctrl->catalog);
++
++ phy_exit(phy);
++
++ DRM_DEBUG_DP("DP off phy done\n");
++}
++
+ int dp_ctrl_off(struct dp_ctrl *dp_ctrl)
+ {
+ struct dp_ctrl_private *ctrl;
+diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.h b/drivers/gpu/drm/msm/dp/dp_ctrl.h
+index a836bd358447..25e4f7512252 100644
+--- a/drivers/gpu/drm/msm/dp/dp_ctrl.h
++++ b/drivers/gpu/drm/msm/dp/dp_ctrl.h
+@@ -23,6 +23,8 @@ int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, bool reset);
+ void dp_ctrl_host_deinit(struct dp_ctrl *dp_ctrl);
+ int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl);
+ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl);
++int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl);
++void dp_ctrl_off_phy(struct dp_ctrl *dp_ctrl);
+ int dp_ctrl_off(struct dp_ctrl *dp_ctrl);
+ void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl);
+ void dp_ctrl_isr(struct dp_ctrl *dp_ctrl);
+diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
+index 1784e119269b..cdec0a367a2c 100644
+--- a/drivers/gpu/drm/msm/dp/dp_display.c
++++ b/drivers/gpu/drm/msm/dp/dp_display.c
+@@ -346,6 +346,12 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
+ dp->dp_display.max_pclk_khz = DP_MAX_PIXEL_CLK_KHZ;
+ dp->dp_display.max_dp_lanes = dp->parser->max_dp_lanes;
+
++ /*
++ * set sink to normal operation mode -- D0
++ * before dpcd read
++ */
++ dp_link_psm_config(dp->link, &dp->panel->link_info, false);
++
+ dp_link_reset_phy_params_vx_px(dp->link);
+ rc = dp_ctrl_on_link(dp->ctrl);
+ if (rc) {
+@@ -414,11 +420,6 @@ static int dp_display_usbpd_configure_cb(struct device *dev)
+
+ dp_display_host_init(dp, false);
+
+- /*
+- * set sink to normal operation mode -- D0
+- * before dpcd read
+- */
+- dp_link_psm_config(dp->link, &dp->panel->link_info, false);
+ rc = dp_display_process_hpd_high(dp);
+ end:
+ return rc;
+@@ -579,6 +580,10 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data)
+ dp_add_event(dp, EV_CONNECT_PENDING_TIMEOUT, 0, tout);
+ }
+
++ /* enable HDP irq_hpd/replug interrupt */
++ dp_catalog_hpd_config_intr(dp->catalog,
++ DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, true);
++
+ mutex_unlock(&dp->event_mutex);
+
+ /* uevent will complete connection part */
+@@ -628,7 +633,26 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
+ mutex_lock(&dp->event_mutex);
+
+ state = dp->hpd_state;
+- if (state == ST_DISCONNECT_PENDING || state == ST_DISCONNECTED) {
++
++ /* disable irq_hpd/replug interrupts */
++ dp_catalog_hpd_config_intr(dp->catalog,
++ DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, false);
++
++ /* unplugged, no more irq_hpd handle */
++ dp_del_event(dp, EV_IRQ_HPD_INT);
++
++ if (state == ST_DISCONNECTED) {
++ /* triggered by irq_hdp with sink_count = 0 */
++ if (dp->link->sink_count == 0) {
++ dp_ctrl_off_phy(dp->ctrl);
++ hpd->hpd_high = 0;
++ dp->core_initialized = false;
++ }
++ mutex_unlock(&dp->event_mutex);
++ return 0;
++ }
++
++ if (state == ST_DISCONNECT_PENDING) {
+ mutex_unlock(&dp->event_mutex);
+ return 0;
+ }
+@@ -642,9 +666,8 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
+
+ dp->hpd_state = ST_DISCONNECT_PENDING;
+
+- /* disable HPD plug interrupt until disconnect is done */
+- dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK
+- | DP_DP_IRQ_HPD_INT_MASK, false);
++ /* disable HPD plug interrupts */
++ dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, false);
+
+ hpd->hpd_high = 0;
+
+@@ -660,8 +683,8 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
+ /* signal the disconnect event early to ensure proper teardown */
+ dp_display_handle_plugged_change(g_dp_display, false);
+
+- dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK |
+- DP_DP_IRQ_HPD_INT_MASK, true);
++ /* enable HDP plug interrupt to prepare for next plugin */
++ dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, true);
+
+ /* uevent will complete disconnection part */
+ mutex_unlock(&dp->event_mutex);
+@@ -692,7 +715,7 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data)
+
+ /* irq_hpd can happen at either connected or disconnected state */
+ state = dp->hpd_state;
+- if (state == ST_DISPLAY_OFF) {
++ if (state == ST_DISPLAY_OFF || state == ST_SUSPENDED) {
+ mutex_unlock(&dp->event_mutex);
+ return 0;
+ }
+@@ -910,9 +933,13 @@ static int dp_display_disable(struct dp_display_private *dp, u32 data)
+
+ dp_display->audio_enabled = false;
+
+- dp_ctrl_off(dp->ctrl);
+-
+- dp->core_initialized = false;
++ /* triggered by irq_hpd with sink_count = 0 */
++ if (dp->link->sink_count == 0) {
++ dp_ctrl_off_link_stream(dp->ctrl);
++ } else {
++ dp_ctrl_off(dp->ctrl);
++ dp->core_initialized = false;
++ }
+
+ dp_display->power_on = false;
+
+--
+2.30.2
+
--- /dev/null
+From 9e290d69a0a1be1cbb4cc71a4d8ba3a194be5b4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 14:38:05 +0800
+Subject: drm/msm/dpu: Fix error return code in dpu_mdss_init()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit e020ac961ce5d038de66dc7f6ffca98899e9a3f3 ]
+
+The error code returned by platform_get_irq() is stored in 'irq', it's
+forgotten to be copied to 'ret' before being returned. As a result, the
+value 0 of 'ret' is returned incorrectly.
+
+After the above fix is completed, initializing the local variable 'ret'
+to 0 is no longer needed, remove it.
+
+In addition, when dpu_mdss_init() is successfully returned, the value of
+'ret' is always 0. Therefore, replace "return ret" with "return 0" to make
+the code clearer.
+
+Fixes: 070e64dc1bbc ("drm/msm/dpu: Convert to a chained irq chip")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Link: https://lore.kernel.org/r/20210510063805.3262-2-thunder.leizhen@huawei.com
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
+index 06b56fec04e0..6b0a7bc87eb7 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
+@@ -225,7 +225,7 @@ int dpu_mdss_init(struct drm_device *dev)
+ struct msm_drm_private *priv = dev->dev_private;
+ struct dpu_mdss *dpu_mdss;
+ struct dss_module_power *mp;
+- int ret = 0;
++ int ret;
+ int irq;
+
+ dpu_mdss = devm_kzalloc(dev->dev, sizeof(*dpu_mdss), GFP_KERNEL);
+@@ -253,8 +253,10 @@ int dpu_mdss_init(struct drm_device *dev)
+ goto irq_domain_error;
+
+ irq = platform_get_irq(pdev, 0);
+- if (irq < 0)
++ if (irq < 0) {
++ ret = irq;
+ goto irq_error;
++ }
+
+ irq_set_chained_handler_and_data(irq, dpu_mdss_irq,
+ dpu_mdss);
+@@ -263,7 +265,7 @@ int dpu_mdss_init(struct drm_device *dev)
+
+ pm_runtime_enable(dev->dev);
+
+- return ret;
++ return 0;
+
+ irq_error:
+ _dpu_mdss_irq_domain_fini(dpu_mdss);
+--
+2.30.2
+
--- /dev/null
+From c227d443f1a39fe37b2ee39dc960bc1645fc1087 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 May 2021 10:28:36 +0800
+Subject: drm/msm: Fix error return code in msm_drm_init()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit a1c9b1e3bdd6d8dc43c18699772fb6cf4497d45a ]
+
+Fix to return a negative error code from the error handling case instead
+of 0, as done elsewhere in this function.
+
+Fixes: 7f9743abaa79 ("drm/msm: validate display and event threads")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Link: https://lore.kernel.org/r/20210508022836.1777-1-thunder.leizhen@huawei.com
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_drv.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
+index fe7d17cd35ec..afd555b0c105 100644
+--- a/drivers/gpu/drm/msm/msm_drv.c
++++ b/drivers/gpu/drm/msm/msm_drv.c
+@@ -523,6 +523,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
+ priv->event_thread[i].worker = kthread_create_worker(0,
+ "crtc_event:%d", priv->event_thread[i].crtc_id);
+ if (IS_ERR(priv->event_thread[i].worker)) {
++ ret = PTR_ERR(priv->event_thread[i].worker);
+ DRM_DEV_ERROR(dev, "failed to create crtc_event kthread\n");
+ goto err_msm_uninit;
+ }
+--
+2.30.2
+
--- /dev/null
+From eb7d45f1c06a99d6bd8b00737bef32ce1518565c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Jun 2021 18:40:55 -0700
+Subject: drm/pl111: Actually fix CONFIG_VEXPRESS_CONFIG depends
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 4e566003571244f508408f59ce78f6ac2ccdba8e ]
+
+VEXPRESS_CONFIG needs to either be missing, built-in, or modular when
+pl111 is modular. Update the Kconfig to reflect the need.
+
+Fixes: 4dc7c97d04dc ("drm/pl111: depend on CONFIG_VEXPRESS_CONFIG")
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210604014055.4060521-1-keescook@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/pl111/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/pl111/Kconfig b/drivers/gpu/drm/pl111/Kconfig
+index c5210a5bef1b..3aae387a96af 100644
+--- a/drivers/gpu/drm/pl111/Kconfig
++++ b/drivers/gpu/drm/pl111/Kconfig
+@@ -2,7 +2,8 @@
+ config DRM_PL111
+ tristate "DRM Support for PL111 CLCD Controller"
+ depends on DRM
+- depends on VEXPRESS_CONFIG
++ depends on ARM || ARM64 || COMPILE_TEST
++ depends on VEXPRESS_CONFIG || VEXPRESS_CONFIG=n
+ depends on COMMON_CLK
+ select DRM_KMS_HELPER
+ select DRM_KMS_CMA_HELPER
+--
+2.30.2
+
--- /dev/null
+From 68093b938aa754f8f1a0745a2e5ee48f286afb38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Jun 2021 14:52:52 -0700
+Subject: drm/pl111: depend on CONFIG_VEXPRESS_CONFIG
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 4dc7c97d04dcaa9f19482f70dcfdbeb52cc7193f ]
+
+Avoid randconfig build failures by requiring VEXPRESS_CONFIG:
+
+aarch64-linux-gnu-ld: drivers/gpu/drm/pl111/pl111_versatile.o: in function `pl111_vexpress_clcd_init':
+pl111_versatile.c:(.text+0x220): undefined reference to `devm_regmap_init_vexpress_config'
+
+Fixes: 826fc86b5903 ("drm: pl111: Move VExpress setup into versatile init")
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210602215252.695994-4-keescook@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/pl111/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/pl111/Kconfig b/drivers/gpu/drm/pl111/Kconfig
+index 80f6748055e3..c5210a5bef1b 100644
+--- a/drivers/gpu/drm/pl111/Kconfig
++++ b/drivers/gpu/drm/pl111/Kconfig
+@@ -2,7 +2,7 @@
+ config DRM_PL111
+ tristate "DRM Support for PL111 CLCD Controller"
+ depends on DRM
+- depends on ARM || ARM64 || COMPILE_TEST
++ depends on VEXPRESS_CONFIG
+ depends on COMMON_CLK
+ select DRM_KMS_HELPER
+ select DRM_KMS_CMA_HELPER
+--
+2.30.2
+
--- /dev/null
+From 59dca4bd2b861a264e44db7fbd01221f69d4f2ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Jun 2021 17:13:13 +0100
+Subject: drm: qxl: ensure surf.data is ininitialized
+
+From: Colin Ian King <colin.king@canonical.com>
+
+[ Upstream commit fbbf23ddb2a1cc0c12c9f78237d1561c24006f50 ]
+
+The object surf is not fully initialized and the uninitialized
+field surf.data is being copied by the call to qxl_bo_create
+via the call to qxl_gem_object_create. Set surf.data to zero
+to ensure garbage data from the stack is not being copied.
+
+Addresses-Coverity: ("Uninitialized scalar variable")
+Fixes: f64122c1f6ad ("drm: add new QXL driver. (v1.4)")
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20210608161313.161922-1-colin.king@canonical.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/qxl/qxl_dumb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c
+index 48a58ba1db96..686485b19d0f 100644
+--- a/drivers/gpu/drm/qxl/qxl_dumb.c
++++ b/drivers/gpu/drm/qxl/qxl_dumb.c
+@@ -58,6 +58,8 @@ int qxl_mode_dumb_create(struct drm_file *file_priv,
+ surf.height = args->height;
+ surf.stride = pitch;
+ surf.format = format;
++ surf.data = 0;
++
+ r = qxl_gem_object_create_with_handle(qdev, file_priv,
+ QXL_GEM_DOMAIN_CPU,
+ args->size, &surf, &qobj,
+--
+2.30.2
+
--- /dev/null
+From 612b1f760428725b7eb15413a9af6bb92ded2d53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 May 2021 21:49:28 +0800
+Subject: drm/rockchip: cdn-dp-core: add missing clk_disable_unprepare() on
+ error in cdn_dp_grf_write()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit ae41d925c75b53798f289c69ee8d9f7d36432f6d ]
+
+After calling clk_prepare_enable(), clk_disable_unprepare() need
+be called when calling regmap_write() failed.
+
+Fixes: 1a0f7ed3abe2 ("drm/rockchip: cdn-dp: add cdn DP support for rk3399")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210519134928.2696617-1-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/cdn-dp-core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
+index a4a45daf93f2..6802d9b65f82 100644
+--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
++++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
+@@ -73,6 +73,7 @@ static int cdn_dp_grf_write(struct cdn_dp_device *dp,
+ ret = regmap_write(dp->grf, reg, val);
+ if (ret) {
+ DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret);
++ clk_disable_unprepare(dp->grf_clk);
+ return ret;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From d8be4abd947274489879454bd063a0daa5017e71 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Sep 2020 17:20:49 +0100
+Subject: drm/rockchip: cdn-dp: fix sign extension on an int multiply for a u64
+ result
+
+From: Colin Ian King <colin.king@canonical.com>
+
+[ Upstream commit ce0cb93a5adb283f577cd4661f511047b5e39028 ]
+
+The variable bit_per_pix is a u8 and is promoted in the multiplication
+to an int type and then sign extended to a u64. If the result of the
+int multiplication is greater than 0x7fffffff then the upper 32 bits will
+be set to 1 as a result of the sign extension. Avoid this by casting
+tu_size_reg to u64 to avoid sign extension and also a potential overflow.
+
+Fixes: 1a0f7ed3abe2 ("drm/rockchip: cdn-dp: add cdn DP support for rk3399")
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Reviewed-by: Guenter Roeck <groeck@chromium.org>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20200915162049.36434-1-colin.king@canonical.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/cdn-dp-reg.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
+index 9d2163ef4d6e..33fb4d05c506 100644
+--- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c
++++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
+@@ -658,7 +658,7 @@ int cdn_dp_config_video(struct cdn_dp_device *dp)
+ */
+ do {
+ tu_size_reg += 2;
+- symbol = tu_size_reg * mode->clock * bit_per_pix;
++ symbol = (u64)tu_size_reg * mode->clock * bit_per_pix;
+ do_div(symbol, dp->max_lanes * link_rate * 8);
+ rem = do_div(symbol, 1000);
+ if (tu_size_reg > 64) {
+--
+2.30.2
+
--- /dev/null
+From 4b8183caaaa47547865d433e44c1dd754876ad4b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Apr 2021 19:04:10 -0700
+Subject: drm/rockchip: dsi: move all lane config except LCDC mux to bind()
+
+From: Thomas Hebb <tommyhebb@gmail.com>
+
+[ Upstream commit 43c2de1002d2b70fb5941fa14e97a34e3dc214d4 ]
+
+When we first enable the DSI encoder, we currently program some per-chip
+configuration that we look up in rk3399_chip_data based on the device
+tree compatible we match. This data configures various parameters of the
+MIPI lanes, including on RK3399 whether DSI1 is slaved to DSI0 in a
+dual-mode configuration. It also selects which LCDC (i.e. VOP) to scan
+out from.
+
+This causes a problem in RK3399 dual-mode configurations, though: panel
+prepare() callbacks run before the encoder gets enabled and expect to be
+able to write commands to the DSI bus, but the bus isn't fully
+functional until the lane and master/slave configuration have been
+programmed. As a result, dual-mode panels (and possibly others too) fail
+to turn on when the rockchipdrm driver is initially loaded.
+
+Because the LCDC mux is the only thing we don't know until enable time
+(and is the only thing that can ever change), we can actually move most
+of the initialization to bind() and get it out of the way early. That's
+what this change does. (Rockchip's 4.4 BSP kernel does it in mode_set(),
+which also avoids the issue, but bind() seems like the more correct
+place to me.)
+
+Tested on a Google Scarlet board (Acer Chromebook Tab 10), which has a
+Kingdisplay KD097D04 dual-mode panel. Prior to this change, the panel's
+backlight would turn on but no image would appear when initially loading
+rockchipdrm. If I kept rockchipdrm loaded and reloaded the panel driver,
+it would come on. With this change, the panel successfully turns on
+during initial rockchipdrm load as expected.
+
+Fixes: 2d4f7bdafd70 ("drm/rockchip: dsi: migrate to use dw-mipi-dsi bridge driver")
+Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
+Tested-by: Jonathan Liu <net147@gmail.com>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/55fe7f3454d8c91dc3837ba5aa741d4a0e67378f.1618797813.git.tommyhebb@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 36 ++++++++++++++-----
+ 1 file changed, 28 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+index 24a71091759c..d8c47ee3cad3 100644
+--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
++++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+@@ -692,13 +692,8 @@ static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_rockchip_phy_ops = {
+ .get_timing = dw_mipi_dsi_phy_get_timing,
+ };
+
+-static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi,
+- int mux)
++static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi)
+ {
+- if (dsi->cdata->lcdsel_grf_reg)
+- regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg,
+- mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big);
+-
+ if (dsi->cdata->lanecfg1_grf_reg)
+ regmap_write(dsi->grf_regmap, dsi->cdata->lanecfg1_grf_reg,
+ dsi->cdata->lanecfg1);
+@@ -712,6 +707,13 @@ static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi,
+ dsi->cdata->enable);
+ }
+
++static void dw_mipi_dsi_rockchip_set_lcdsel(struct dw_mipi_dsi_rockchip *dsi,
++ int mux)
++{
++ regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg,
++ mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big);
++}
++
+ static int
+ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
+ struct drm_crtc_state *crtc_state,
+@@ -767,9 +769,9 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
+ return;
+ }
+
+- dw_mipi_dsi_rockchip_config(dsi, mux);
++ dw_mipi_dsi_rockchip_set_lcdsel(dsi, mux);
+ if (dsi->slave)
+- dw_mipi_dsi_rockchip_config(dsi->slave, mux);
++ dw_mipi_dsi_rockchip_set_lcdsel(dsi->slave, mux);
+
+ clk_disable_unprepare(dsi->grf_clk);
+ }
+@@ -923,6 +925,24 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
+ return ret;
+ }
+
++ /*
++ * With the GRF clock running, write lane and dual-mode configurations
++ * that won't change immediately. If we waited until enable() to do
++ * this, things like panel preparation would not be able to send
++ * commands over DSI.
++ */
++ ret = clk_prepare_enable(dsi->grf_clk);
++ if (ret) {
++ DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret);
++ return ret;
++ }
++
++ dw_mipi_dsi_rockchip_config(dsi);
++ if (dsi->slave)
++ dw_mipi_dsi_rockchip_config(dsi->slave);
++
++ clk_disable_unprepare(dsi->grf_clk);
++
+ ret = rockchip_dsi_drm_create_encoder(dsi, drm_dev);
+ if (ret) {
+ DRM_DEV_ERROR(dev, "Failed to create drm encoder\n");
+--
+2.30.2
+
--- /dev/null
+From dabf099a9bbd52e9c70691e7e5ad53e8e55176df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 17:13:16 +0200
+Subject: drm/rockchip: lvds: Fix an error handling path
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 3dfa159f6b0c054eb63673fbf643a5f2cc862e63 ]
+
+'ret' is know to be 0 a this point. Checking the return value of
+'phy_init()' and 'phy_set_mode()' was intended instead.
+
+So add the missing assignments.
+
+Fixes: cca1705c3d89 ("drm/rockchip: lvds: Add PX30 support")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/248220d4815dc8c8088cebfab7d6df5f70518438.1619881852.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/rockchip_lvds.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c
+index bd5ba10822c2..489d63c05c0d 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c
++++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c
+@@ -499,11 +499,11 @@ static int px30_lvds_probe(struct platform_device *pdev,
+ if (IS_ERR(lvds->dphy))
+ return PTR_ERR(lvds->dphy);
+
+- phy_init(lvds->dphy);
++ ret = phy_init(lvds->dphy);
+ if (ret)
+ return ret;
+
+- phy_set_mode(lvds->dphy, PHY_MODE_LVDS);
++ ret = phy_set_mode(lvds->dphy, PHY_MODE_LVDS);
+ if (ret)
+ return ret;
+
+--
+2.30.2
+
--- /dev/null
+From d61fa53ba5032e75c8bb673a490f0a3fc60f5ae9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 May 2021 15:05:54 +0200
+Subject: drm: rockchip: set alpha_en to 0 if it is not used
+
+From: Alex Bee <knaerzche@gmail.com>
+
+[ Upstream commit 046e0db975695540c9d9898cdbf0b60533d28afb ]
+
+alpha_en should be set to 0 if it is not used, i.e. to disable alpha
+blending if it was enabled before and should be disabled now.
+
+Fixes: 2aae8ed1f390 ("drm/rockchip: Add per-pixel alpha support for the PX30 VOP")
+Signed-off-by: Alex Bee <knaerzche@gmail.com>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210528130554.72191-6-knaerzche@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+index 64469439ddf2..f5b9028a16a3 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+@@ -1022,6 +1022,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
+ VOP_WIN_SET(vop, win, alpha_en, 1);
+ } else {
+ VOP_WIN_SET(vop, win, src_alpha_ctl, SRC_ALPHA_EN(0));
++ VOP_WIN_SET(vop, win, alpha_en, 0);
+ }
+
+ VOP_WIN_SET(vop, win, enable, 1);
+--
+2.30.2
+
--- /dev/null
+From 709333ece3876e73b422a8cda9e5df0d40480edd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 May 2021 17:05:07 +0200
+Subject: drm/vc4: crtc: Fix vc4_get_crtc_encoder logic
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+[ Upstream commit 5a184d959d5a5a66b377cb5cd4c95a80388e0c88 ]
+
+The vc4_get_crtc_encoder function currently only works when the
+connector->state->crtc pointer is set, which is only true when the
+connector is currently enabled.
+
+However, we use it as part of the disable path as well, and our lookup
+will fail in that case, resulting in it returning a null pointer we
+can't act on.
+
+We can access the connector that used to be connected to that crtc
+though using the old connector state in the disable path.
+
+Since we want to support both the enable and disable path, we can
+support it by passing the state accessor variant as a function pointer,
+together with the atomic state.
+
+Fixes: 792c3132bc1b ("drm/vc4: encoder: Add finer-grained encoder callbacks")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210507150515.257424-5-maxime@cerno.tech
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
+index d079303cc426..1733add20498 100644
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -279,14 +279,22 @@ static u32 vc4_crtc_get_fifo_full_level_bits(struct vc4_crtc *vc4_crtc,
+ * allows drivers to push pixels to more than one encoder from the
+ * same CRTC.
+ */
+-static struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc)
++static struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc,
++ struct drm_atomic_state *state,
++ struct drm_connector_state *(*get_state)(struct drm_atomic_state *state,
++ struct drm_connector *connector))
+ {
+ struct drm_connector *connector;
+ struct drm_connector_list_iter conn_iter;
+
+ drm_connector_list_iter_begin(crtc->dev, &conn_iter);
+ drm_for_each_connector_iter(connector, &conn_iter) {
+- if (connector->state->crtc == crtc) {
++ struct drm_connector_state *conn_state = get_state(state, connector);
++
++ if (!conn_state)
++ continue;
++
++ if (conn_state->crtc == crtc) {
+ drm_connector_list_iter_end(&conn_iter);
+ return connector->encoder;
+ }
+@@ -309,7 +317,8 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_atomic_state *s
+ {
+ struct drm_device *dev = crtc->dev;
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+- struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
++ struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, state,
++ drm_atomic_get_new_connector_state);
+ struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+ const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
+@@ -424,7 +433,8 @@ static int vc4_crtc_disable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state,
+ unsigned int channel)
+ {
+- struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
++ struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, state,
++ drm_atomic_get_old_connector_state);
+ struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+@@ -524,7 +534,8 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
+ {
+ struct drm_device *dev = crtc->dev;
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+- struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
++ struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, state,
++ drm_atomic_get_new_connector_state);
+ struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
+
+ require_hvs_enabled(dev);
+--
+2.30.2
+
--- /dev/null
+From cbed82080806b040f4be4106a6221432f7cc5ade Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 May 2021 17:05:08 +0200
+Subject: drm/vc4: crtc: Lookup the encoder from the register at boot
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+[ Upstream commit b601c16b7ba8f3bb7a7e773b238da6b63657fa1d ]
+
+At boot, we can't rely on the vc4_get_crtc_encoder since we don't have a
+state yet and thus will not be able to figure out which connector is
+attached to our CRTC.
+
+However, we have a muxing bit in the CRTC register we can use to get the
+encoder currently connected to the pixelvalve. We can thus read that
+register, lookup the associated register through the vc4_pv_data
+structure, and then pass it to vc4_crtc_disable so that we can perform
+the proper operations.
+
+Fixes: 875a4d536842 ("drm/vc4: drv: Disable the CRTC at boot time")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210507150515.257424-6-maxime@cerno.tech
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 38 ++++++++++++++++++++++++++++++----
+ 1 file changed, 34 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
+index 1733add20498..1f36b67cd6ce 100644
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -430,11 +430,10 @@ static void require_hvs_enabled(struct drm_device *dev)
+ }
+
+ static int vc4_crtc_disable(struct drm_crtc *crtc,
++ struct drm_encoder *encoder,
+ struct drm_atomic_state *state,
+ unsigned int channel)
+ {
+- struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, state,
+- drm_atomic_get_old_connector_state);
+ struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+@@ -475,10 +474,29 @@ static int vc4_crtc_disable(struct drm_crtc *crtc,
+ return 0;
+ }
+
++static struct drm_encoder *vc4_crtc_get_encoder_by_type(struct drm_crtc *crtc,
++ enum vc4_encoder_type type)
++{
++ struct drm_encoder *encoder;
++
++ drm_for_each_encoder(encoder, crtc->dev) {
++ struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
++
++ if (vc4_encoder->type == type)
++ return encoder;
++ }
++
++ return NULL;
++}
++
+ int vc4_crtc_disable_at_boot(struct drm_crtc *crtc)
+ {
+ struct drm_device *drm = crtc->dev;
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
++ enum vc4_encoder_type encoder_type;
++ const struct vc4_pv_data *pv_data;
++ struct drm_encoder *encoder;
++ unsigned encoder_sel;
+ int channel;
+
+ if (!(of_device_is_compatible(vc4_crtc->pdev->dev.of_node,
+@@ -497,7 +515,17 @@ int vc4_crtc_disable_at_boot(struct drm_crtc *crtc)
+ if (channel < 0)
+ return 0;
+
+- return vc4_crtc_disable(crtc, NULL, channel);
++ encoder_sel = VC4_GET_FIELD(CRTC_READ(PV_CONTROL), PV_CONTROL_CLK_SELECT);
++ if (WARN_ON(encoder_sel != 0))
++ return 0;
++
++ pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
++ encoder_type = pv_data->encoder_types[encoder_sel];
++ encoder = vc4_crtc_get_encoder_by_type(crtc, encoder_type);
++ if (WARN_ON(!encoder))
++ return 0;
++
++ return vc4_crtc_disable(crtc, encoder, NULL, channel);
+ }
+
+ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
+@@ -506,6 +534,8 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state,
+ crtc);
+ struct vc4_crtc_state *old_vc4_state = to_vc4_crtc_state(old_state);
++ struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, state,
++ drm_atomic_get_old_connector_state);
+ struct drm_device *dev = crtc->dev;
+
+ require_hvs_enabled(dev);
+@@ -513,7 +543,7 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
+ /* Disable vblank irq handling before crtc is disabled. */
+ drm_crtc_vblank_off(crtc);
+
+- vc4_crtc_disable(crtc, state, old_vc4_state->assigned_channel);
++ vc4_crtc_disable(crtc, encoder, state, old_vc4_state->assigned_channel);
+
+ /*
+ * Make sure we issue a vblank event after disabling the CRTC if
+--
+2.30.2
+
--- /dev/null
+From 6eaeaa8ac2b34a3a6e1957f6ab0576d0f9d60752 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 May 2021 17:05:06 +0200
+Subject: drm/vc4: crtc: Pass the drm_atomic_state to config_pv
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+[ Upstream commit c6883985d46319e0d4f159de8932b09ff93e877d ]
+
+The vc4_crtc_config_pv will need to access the drm_atomic_state
+structure and its only parent function, vc4_crtc_atomic_enable already
+has access to it. Let's pass it as a parameter.
+
+Fixes: 792c3132bc1b ("drm/vc4: encoder: Add finer-grained encoder callbacks")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210507150515.257424-4-maxime@cerno.tech
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
+index 76657dcdf9b0..d079303cc426 100644
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -305,7 +305,7 @@ static void vc4_crtc_pixelvalve_reset(struct drm_crtc *crtc)
+ CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_FIFO_CLR);
+ }
+
+-static void vc4_crtc_config_pv(struct drm_crtc *crtc)
++static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_atomic_state *state)
+ {
+ struct drm_device *dev = crtc->dev;
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+@@ -313,8 +313,8 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
+ struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+ const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
+- struct drm_crtc_state *state = crtc->state;
+- struct drm_display_mode *mode = &state->adjusted_mode;
++ struct drm_crtc_state *crtc_state = crtc->state;
++ struct drm_display_mode *mode = &crtc_state->adjusted_mode;
+ bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
+ u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
+ bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
+@@ -539,7 +539,7 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
+ if (vc4_encoder->pre_crtc_configure)
+ vc4_encoder->pre_crtc_configure(encoder, state);
+
+- vc4_crtc_config_pv(crtc);
++ vc4_crtc_config_pv(crtc, state);
+
+ CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
+
+--
+2.30.2
+
--- /dev/null
+From bd927103e61c30ac11efee5e5641ab87045f4ae0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 May 2021 15:18:51 +0200
+Subject: drm/vc4: hdmi: Fix error path of hpd-gpios
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+[ Upstream commit e075a7811977ff51c917a65ed1896e08231d2615 ]
+
+If the of_get_named_gpio_flags call fails in vc4_hdmi_bind, we jump to
+the err_unprepare_hsm label. That label will then call
+pm_runtime_disable and put_device on the DDC device.
+
+We just retrieved the DDC device, so the latter is definitely justified.
+However at that point we still haven't called pm_runtime_enable, so the
+call to pm_runtime_disable is not supposed to be there.
+
+Fixes: 10ee275cb12f ("drm/vc4: prepare for CEC support")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210524131852.263883-1-maxime@cerno.tech
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 8106b5634fe1..e94730beb15b 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -2000,7 +2000,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
+ &hpd_gpio_flags);
+ if (vc4_hdmi->hpd_gpio < 0) {
+ ret = vc4_hdmi->hpd_gpio;
+- goto err_unprepare_hsm;
++ goto err_put_ddc;
+ }
+
+ vc4_hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW;
+@@ -2041,8 +2041,8 @@ err_destroy_conn:
+ vc4_hdmi_connector_destroy(&vc4_hdmi->connector);
+ err_destroy_encoder:
+ drm_encoder_cleanup(encoder);
+-err_unprepare_hsm:
+ pm_runtime_disable(dev);
++err_put_ddc:
+ put_device(&vc4_hdmi->ddc->dev);
+
+ return ret;
+--
+2.30.2
+
--- /dev/null
+From 4efd78b0a379bc7bf6626d4f3eb1d2fa1dec93ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 23:57:37 -0400
+Subject: drm/vmwgfx: Fix cpu updates of coherent multisample surfaces
+
+From: Thomas Hellstrom <thellstrom@vmware.com>
+
+[ Upstream commit 88509f698c4e38e287e016e86a0445547824135c ]
+
+In cases where the dirty linear memory range spans multiple sample sheets
+in a surface, the dirty surface region is incorrectly computed.
+To do this correctly and in an optimized fashion we would have to compute
+the dirty region of each sample sheet and compute the union of those
+regions.
+
+But assuming that cpu writing to a multisample surface is rather a corner
+case than a common case, just set the dirty region to the full surface.
+
+This fixes OpenGL piglit errors with SVGA_FORCE_COHERENT=1
+and the piglit test:
+
+fbo-depthstencil blit default_fb -samples=2 -auto
+
+Fixes: 9ca7d19ff8ba ("drm/vmwgfx: Add surface dirty-tracking callbacks")
+Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
+Reviewed-by: Charmaine Lee <charmainel@vmware.com>
+Reviewed-by: Roland Scheidegger <sroland@vmware.com>
+Signed-off-by: Zack Rusin <zackr@vmware.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210505035740.286923-4-zackr@vmware.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/vmwgfx/device_include/svga3d_surfacedefs.h | 8 ++++++--
+ drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 13 +++++++++++++
+ 2 files changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h
+index 4db25bd9fa22..127eaf0a0a58 100644
+--- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h
++++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h
+@@ -1467,6 +1467,7 @@ struct svga3dsurface_cache {
+
+ /**
+ * struct svga3dsurface_loc - Surface location
++ * @sheet: The multisample sheet.
+ * @sub_resource: Surface subresource. Defined as layer * num_mip_levels +
+ * mip_level.
+ * @x: X coordinate.
+@@ -1474,6 +1475,7 @@ struct svga3dsurface_cache {
+ * @z: Z coordinate.
+ */
+ struct svga3dsurface_loc {
++ u32 sheet;
+ u32 sub_resource;
+ u32 x, y, z;
+ };
+@@ -1566,8 +1568,8 @@ svga3dsurface_get_loc(const struct svga3dsurface_cache *cache,
+ u32 layer;
+ int i;
+
+- if (offset >= cache->sheet_bytes)
+- offset %= cache->sheet_bytes;
++ loc->sheet = offset / cache->sheet_bytes;
++ offset -= loc->sheet * cache->sheet_bytes;
+
+ layer = offset / cache->mip_chain_bytes;
+ offset -= layer * cache->mip_chain_bytes;
+@@ -1631,6 +1633,7 @@ svga3dsurface_min_loc(const struct svga3dsurface_cache *cache,
+ u32 sub_resource,
+ struct svga3dsurface_loc *loc)
+ {
++ loc->sheet = 0;
+ loc->sub_resource = sub_resource;
+ loc->x = loc->y = loc->z = 0;
+ }
+@@ -1652,6 +1655,7 @@ svga3dsurface_max_loc(const struct svga3dsurface_cache *cache,
+ const struct drm_vmw_size *size;
+ u32 mip;
+
++ loc->sheet = 0;
+ loc->sub_resource = sub_resource + 1;
+ mip = sub_resource % cache->num_mip_levels;
+ size = &cache->mip[mip].size;
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+index c3e55c1376eb..beab3e19d8e2 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+@@ -1804,6 +1804,19 @@ static void vmw_surface_tex_dirty_range_add(struct vmw_resource *res,
+ svga3dsurface_get_loc(cache, &loc2, end - 1);
+ svga3dsurface_inc_loc(cache, &loc2);
+
++ if (loc1.sheet != loc2.sheet) {
++ u32 sub_res;
++
++ /*
++ * Multiple multisample sheets. To do this in an optimized
++ * fashion, compute the dirty region for each sheet and the
++ * resulting union. Since this is not a common case, just dirty
++ * the whole surface.
++ */
++ for (sub_res = 0; sub_res < dirty->num_subres; ++sub_res)
++ vmw_subres_dirty_full(dirty, sub_res);
++ return;
++ }
+ if (loc1.sub_resource + 1 == loc2.sub_resource) {
+ /* Dirty range covers a single sub-resource */
+ vmw_subres_dirty_add(dirty, &loc1, &loc2);
+--
+2.30.2
+
--- /dev/null
+From a7d1bfa8bd0e3ff62ee3db57e733cf2e13239e13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 23:57:36 -0400
+Subject: drm/vmwgfx: Mark a surface gpu-dirty after the SVGA3dCmdDXGenMips
+ command
+
+From: Thomas Hellstrom <thellstrom@vmware.com>
+
+[ Upstream commit 75156a887b6cea6e09d83ec19f4ebfd7c86265f0 ]
+
+The SVGA3dCmdDXGenMips command uses a shader-resource view to access
+the underlying surface. Normally accesses using that view-type are not
+dirtying the underlying surface, but that particular command is an
+exception.
+Mark the surface gpu-dirty after a SVGA3dCmdDXGenMips command has been
+submitted.
+
+This fixes the piglit getteximage-formats test run with
+SVGA_FORCE_COHERENT=1
+
+Fixes: a9f58c456e9d ("drm/vmwgfx: Be more restrictive when dirtying resources")
+Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
+Reviewed-by: Charmaine Lee <charmainel@vmware.com>
+Reviewed-by: Roland Scheidegger <sroland@vmware.com>
+Signed-off-by: Zack Rusin <zackr@vmware.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210505035740.286923-3-zackr@vmware.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+index 7a24196f92c3..d6a6d8a3387a 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+@@ -2763,12 +2763,24 @@ static int vmw_cmd_dx_genmips(struct vmw_private *dev_priv,
+ {
+ VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXGenMips) =
+ container_of(header, typeof(*cmd), header);
+- struct vmw_resource *ret;
++ struct vmw_resource *view;
++ struct vmw_res_cache_entry *rcache;
+
+- ret = vmw_view_id_val_add(sw_context, vmw_view_sr,
+- cmd->body.shaderResourceViewId);
++ view = vmw_view_id_val_add(sw_context, vmw_view_sr,
++ cmd->body.shaderResourceViewId);
++ if (IS_ERR(view))
++ return PTR_ERR(view);
+
+- return PTR_ERR_OR_ZERO(ret);
++ /*
++ * Normally the shader-resource view is not gpu-dirtying, but for
++ * this particular command it is...
++ * So mark the last looked-up surface, which is the surface
++ * the view points to, gpu-dirty.
++ */
++ rcache = &sw_context->res_cache[vmw_res_surface];
++ vmw_validation_res_set_dirty(sw_context->ctx, rcache->private,
++ VMW_RES_DIRTY_SET);
++ return 0;
+ }
+
+ /**
+--
+2.30.2
+
--- /dev/null
+From 9b5a32d9b5acbb74721e287c7d4beadd3e56df64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Jun 2021 12:02:48 -0700
+Subject: e1000e: Check the PCIm state
+
+From: Sasha Neftin <sasha.neftin@intel.com>
+
+[ Upstream commit 2e7256f12cdb16eaa2515b6231d665044a07c51a ]
+
+Complete to commit def4ec6dce393e ("e1000e: PCIm function state support")
+Check the PCIm state only on CSME systems. There is no point to do this
+check on non CSME systems.
+This patch fixes a generation a false-positive warning:
+"Error in exiting dmoff"
+
+Fixes: def4ec6dce39 ("e1000e: PCIm function state support")
+Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
+Tested-by: Dvora Fuxbrumer <dvorax.fuxbrumer@linux.intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/e1000e/netdev.c | 24 ++++++++++++----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
+index 88e9035b75cf..dc0ded7e5e61 100644
+--- a/drivers/net/ethernet/intel/e1000e/netdev.c
++++ b/drivers/net/ethernet/intel/e1000e/netdev.c
+@@ -5223,18 +5223,20 @@ static void e1000_watchdog_task(struct work_struct *work)
+ pm_runtime_resume(netdev->dev.parent);
+
+ /* Checking if MAC is in DMoff state*/
+- pcim_state = er32(STATUS);
+- while (pcim_state & E1000_STATUS_PCIM_STATE) {
+- if (tries++ == dmoff_exit_timeout) {
+- e_dbg("Error in exiting dmoff\n");
+- break;
+- }
+- usleep_range(10000, 20000);
++ if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) {
+ pcim_state = er32(STATUS);
+-
+- /* Checking if MAC exited DMoff state */
+- if (!(pcim_state & E1000_STATUS_PCIM_STATE))
+- e1000_phy_hw_reset(&adapter->hw);
++ while (pcim_state & E1000_STATUS_PCIM_STATE) {
++ if (tries++ == dmoff_exit_timeout) {
++ e_dbg("Error in exiting dmoff\n");
++ break;
++ }
++ usleep_range(10000, 20000);
++ pcim_state = er32(STATUS);
++
++ /* Checking if MAC exited DMoff state */
++ if (!(pcim_state & E1000_STATUS_PCIM_STATE))
++ e1000_phy_hw_reset(&adapter->hw);
++ }
+ }
+
+ /* update snapshot of PHY registers on LSC */
+--
+2.30.2
+
--- /dev/null
+From c22ce9821d263d23fa0f84270008db8462f4be67 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Apr 2021 15:54:53 +0200
+Subject: EDAC/aspeed: Use proper format string for printing resource
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 2e2f16d5cdb33e5f6fc53b7ad66c9f456d5f2950 ]
+
+On ARMv7, resource_size_t can be 64-bit, which breaks printing
+it as %x:
+
+ drivers/edac/aspeed_edac.c: In function 'init_csrows':
+ drivers/edac/aspeed_edac.c:257:28: error: format '%x' expects argument of \
+ type 'unsigned int', but argument 4 has type 'resource_size_t' {aka 'long \
+ long unsigned int'} [-Werror=format=]
+ 257 | dev_dbg(mci->pdev, "dt: /memory node resources: first page \
+ r.start=0x%x, resource_size=0x%x, PAGE_SHIFT macro=0x%x\n",
+
+Use the special %pR format string to pretty-print the entire resource
+instead.
+
+Fixes: edfc2d73ca45 ("EDAC/aspeed: Add support for AST2400 and AST2600")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
+Link: https://lkml.kernel.org/r/20210421135500.3518661-1-arnd@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/aspeed_edac.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/edac/aspeed_edac.c b/drivers/edac/aspeed_edac.c
+index a46da56d6d54..6bd5f8815919 100644
+--- a/drivers/edac/aspeed_edac.c
++++ b/drivers/edac/aspeed_edac.c
+@@ -254,8 +254,8 @@ static int init_csrows(struct mem_ctl_info *mci)
+ return rc;
+ }
+
+- dev_dbg(mci->pdev, "dt: /memory node resources: first page r.start=0x%x, resource_size=0x%x, PAGE_SHIFT macro=0x%x\n",
+- r.start, resource_size(&r), PAGE_SHIFT);
++ dev_dbg(mci->pdev, "dt: /memory node resources: first page %pR, PAGE_SHIFT macro=0x%x\n",
++ &r, PAGE_SHIFT);
+
+ csrow->first_page = r.start >> PAGE_SHIFT;
+ nr_pages = resource_size(&r) >> PAGE_SHIFT;
+--
+2.30.2
+
--- /dev/null
+From 9f8d3b1cb00aa2c115c29b711c3897297113604f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Jun 2021 09:02:03 -0700
+Subject: EDAC/igen6: fix core dependency
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 0a9ece9ba154dd6205709108180952c55e630833 ]
+
+igen6_edac needs mce_register()/unregister() functions,
+so it should depend on X86_MCE (or X86_MCE_INTEL).
+
+That change prevents these build errors:
+
+ld: drivers/edac/igen6_edac.o: in function `igen6_remove':
+igen6_edac.c:(.text+0x494): undefined reference to `mce_unregister_decode_chain'
+ld: drivers/edac/igen6_edac.o: in function `igen6_probe':
+igen6_edac.c:(.text+0xf5b): undefined reference to `mce_register_decode_chain'
+
+Fixes: 10590a9d4f23e ("EDAC/igen6: Add EDAC driver for Intel client SoCs using IBECC")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Link: https://lore.kernel.org/r/20210619160203.2026-1-rdunlap@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
+index 1e836e320edd..91164c5f0757 100644
+--- a/drivers/edac/Kconfig
++++ b/drivers/edac/Kconfig
+@@ -270,7 +270,8 @@ config EDAC_PND2
+
+ config EDAC_IGEN6
+ tristate "Intel client SoC Integrated MC"
+- depends on PCI && X86_64 && PCI_MMCONFIG && ARCH_HAVE_NMI_SAFE_CMPXCHG
++ depends on PCI && PCI_MMCONFIG && ARCH_HAVE_NMI_SAFE_CMPXCHG
++ depends on X64_64 && X86_MCE_INTEL
+ help
+ Support for error detection and correction on the Intel
+ client SoC Integrated Memory Controller using In-Band ECC IP.
+--
+2.30.2
+
--- /dev/null
+From 634724e4c90720b9afd3ef2ee3c0b3d834e65810 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jun 2021 10:44:19 -0700
+Subject: EDAC/Intel: Do not load EDAC driver when running as a guest
+
+From: Luck, Tony <tony.luck@intel.com>
+
+[ Upstream commit f0a029fff4a50eb01648810a77ba1873e829fdd4 ]
+
+There's little to no point in loading an EDAC driver running in a guest:
+1) The CPU model reported by CPUID may not represent actual h/w
+2) The hypervisor likely does not pass in access to memory controller devices
+3) Hypervisors generally do not pass corrected error details to guests
+
+Add a check in each of the Intel EDAC drivers for X86_FEATURE_HYPERVISOR
+and simply return -ENODEV in the init routine.
+
+Acked-by: Borislav Petkov <bp@suse.de>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Link: https://lore.kernel.org/r/20210615174419.GA1087688@agluck-desk2.amr.corp.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/i10nm_base.c | 3 +++
+ drivers/edac/pnd2_edac.c | 3 +++
+ drivers/edac/sb_edac.c | 3 +++
+ drivers/edac/skx_base.c | 3 +++
+ 4 files changed, 12 insertions(+)
+
+diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c
+index 238a4ad1e526..37b4e875420e 100644
+--- a/drivers/edac/i10nm_base.c
++++ b/drivers/edac/i10nm_base.c
+@@ -278,6 +278,9 @@ static int __init i10nm_init(void)
+ if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR)))
+ return -EBUSY;
+
++ if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
++ return -ENODEV;
++
+ id = x86_match_cpu(i10nm_cpuids);
+ if (!id)
+ return -ENODEV;
+diff --git a/drivers/edac/pnd2_edac.c b/drivers/edac/pnd2_edac.c
+index 928f63a374c7..c94ca1f790c4 100644
+--- a/drivers/edac/pnd2_edac.c
++++ b/drivers/edac/pnd2_edac.c
+@@ -1554,6 +1554,9 @@ static int __init pnd2_init(void)
+ if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR)))
+ return -EBUSY;
+
++ if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
++ return -ENODEV;
++
+ id = x86_match_cpu(pnd2_cpuids);
+ if (!id)
+ return -ENODEV;
+diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
+index 93daa4297f2e..4c626fcd4dcb 100644
+--- a/drivers/edac/sb_edac.c
++++ b/drivers/edac/sb_edac.c
+@@ -3510,6 +3510,9 @@ static int __init sbridge_init(void)
+ if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR)))
+ return -EBUSY;
+
++ if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
++ return -ENODEV;
++
+ id = x86_match_cpu(sbridge_cpuids);
+ if (!id)
+ return -ENODEV;
+diff --git a/drivers/edac/skx_base.c b/drivers/edac/skx_base.c
+index 6a4f0b27c654..4dbd46575bfb 100644
+--- a/drivers/edac/skx_base.c
++++ b/drivers/edac/skx_base.c
+@@ -656,6 +656,9 @@ static int __init skx_init(void)
+ if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR)))
+ return -EBUSY;
+
++ if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
++ return -ENODEV;
++
+ id = x86_match_cpu(skx_cpuids);
+ if (!id)
+ return -ENODEV;
+--
+2.30.2
+
--- /dev/null
+From 577d073a3ca68f90e756c2fe23f6fe5268de68c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 May 2021 11:37:27 +0800
+Subject: EDAC/ti: Add missing MODULE_DEVICE_TABLE
+
+From: Bixuan Cui <cuibixuan@huawei.com>
+
+[ Upstream commit 0a37f32ba5272b2d4ec8c8d0f6b212b81b578f7e ]
+
+The module misses MODULE_DEVICE_TABLE() for of_device_id tables and thus
+never autoloads on ID matches.
+
+Add the missing declaration.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Bixuan Cui <cuibixuan@huawei.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: Tero Kristo <kristo@kernel.org>
+Link: https://lkml.kernel.org/r/20210512033727.26701-1-cuibixuan@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/ti_edac.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/edac/ti_edac.c b/drivers/edac/ti_edac.c
+index e7eae20f83d1..169f96e51c29 100644
+--- a/drivers/edac/ti_edac.c
++++ b/drivers/edac/ti_edac.c
+@@ -197,6 +197,7 @@ static const struct of_device_id ti_edac_of_match[] = {
+ { .compatible = "ti,emif-dra7xx", .data = (void *)EMIF_TYPE_DRA7 },
+ {},
+ };
++MODULE_DEVICE_TABLE(of, ti_edac_of_match);
+
+ static int _emif_get_id(struct device_node *node)
+ {
+--
+2.30.2
+
--- /dev/null
+From 26a5bbe36d16d2e3c18eeedbcfd0ca82653582db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Jun 2021 01:17:55 +0300
+Subject: eeprom: idt_89hpesx: Put fwnode in matching case during ->probe()
+
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+
+[ Upstream commit 3f6ee1c095156a74ab2df605af13020f1ce3e600 ]
+
+device_get_next_child_node() bumps a reference counting of a returned variable.
+We have to balance it whenever we return to the caller.
+
+Fixes: db15d73e5f0e ("eeprom: idt_89hpesx: Support both ACPI and OF probing")
+Cc: Huy Duong <qhuyduong@hotmail.com>
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210607221757.81465-1-andy.shevchenko@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/eeprom/idt_89hpesx.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/misc/eeprom/idt_89hpesx.c b/drivers/misc/eeprom/idt_89hpesx.c
+index 81c70e5bc168..45a61a1f9e98 100644
+--- a/drivers/misc/eeprom/idt_89hpesx.c
++++ b/drivers/misc/eeprom/idt_89hpesx.c
+@@ -1161,6 +1161,7 @@ static void idt_get_fw_data(struct idt_89hpesx_dev *pdev)
+ else /* if (!fwnode_property_read_bool(node, "read-only")) */
+ pdev->eero = false;
+
++ fwnode_handle_put(fwnode);
+ dev_info(dev, "EEPROM of %d bytes found by 0x%x",
+ pdev->eesize, pdev->eeaddr);
+ }
+--
+2.30.2
+
--- /dev/null
+From 2b08e6d51c6a738fba4977f100643f468ddd27db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Jun 2021 01:17:56 +0300
+Subject: eeprom: idt_89hpesx: Restore printing the unsupported fwnode name
+
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+
+[ Upstream commit e0db3deea73ba418bf5dc21f5a4e32ca87d16dde ]
+
+When iterating over child firmware nodes restore printing the name of ones
+that are not supported.
+
+While at it, refactor loop body to clearly show that we stop at the first match.
+
+Fixes: db15d73e5f0e ("eeprom: idt_89hpesx: Support both ACPI and OF probing")
+Cc: Huy Duong <qhuyduong@hotmail.com>
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210607221757.81465-2-andy.shevchenko@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/eeprom/idt_89hpesx.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/misc/eeprom/idt_89hpesx.c b/drivers/misc/eeprom/idt_89hpesx.c
+index 45a61a1f9e98..3e4a594c110b 100644
+--- a/drivers/misc/eeprom/idt_89hpesx.c
++++ b/drivers/misc/eeprom/idt_89hpesx.c
+@@ -1126,11 +1126,10 @@ static void idt_get_fw_data(struct idt_89hpesx_dev *pdev)
+
+ device_for_each_child_node(dev, fwnode) {
+ ee_id = idt_ee_match_id(fwnode);
+- if (!ee_id) {
+- dev_warn(dev, "Skip unsupported EEPROM device");
+- continue;
+- } else
++ if (ee_id)
+ break;
++
++ dev_warn(dev, "Skip unsupported EEPROM device %pfw\n", fwnode);
+ }
+
+ /* If there is no fwnode EEPROM device, then set zero size */
+--
+2.30.2
+
--- /dev/null
+From 5db11e08fd0c8e4c7a211eb246fe75d4aea767c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 May 2021 16:55:55 +0800
+Subject: ehea: fix error return code in ehea_restart_qps()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit 015dbf5662fd689d581c0bc980711b073ca09a1a ]
+
+Fix to return -EFAULT from the error handling case instead of 0, as done
+elsewhere in this function.
+
+By the way, when get_zeroed_page() fails, directly return -ENOMEM to
+simplify code.
+
+Fixes: 2c69448bbced ("ehea: DLPAR memory add fix")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Link: https://lore.kernel.org/r/20210528085555.9390-1-thunder.leizhen@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ehea/ehea_main.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c
+index ea55314b209d..d105bfbc7c1c 100644
+--- a/drivers/net/ethernet/ibm/ehea/ehea_main.c
++++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c
+@@ -2618,10 +2618,8 @@ static int ehea_restart_qps(struct net_device *dev)
+ u16 dummy16 = 0;
+
+ cb0 = (void *)get_zeroed_page(GFP_KERNEL);
+- if (!cb0) {
+- ret = -ENOMEM;
+- goto out;
+- }
++ if (!cb0)
++ return -ENOMEM;
+
+ for (i = 0; i < (port->num_def_qps); i++) {
+ struct ehea_port_res *pr = &port->port_res[i];
+@@ -2641,6 +2639,7 @@ static int ehea_restart_qps(struct net_device *dev)
+ cb0);
+ if (hret != H_SUCCESS) {
+ netdev_err(dev, "query_ehea_qp failed (1)\n");
++ ret = -EFAULT;
+ goto out;
+ }
+
+@@ -2653,6 +2652,7 @@ static int ehea_restart_qps(struct net_device *dev)
+ &dummy64, &dummy16, &dummy16);
+ if (hret != H_SUCCESS) {
+ netdev_err(dev, "modify_ehea_qp failed (1)\n");
++ ret = -EFAULT;
+ goto out;
+ }
+
+@@ -2661,6 +2661,7 @@ static int ehea_restart_qps(struct net_device *dev)
+ cb0);
+ if (hret != H_SUCCESS) {
+ netdev_err(dev, "query_ehea_qp failed (2)\n");
++ ret = -EFAULT;
+ goto out;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 9e147dad80383f56982c2f45a3eec15ea67573f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Apr 2021 18:13:45 -0400
+Subject: evm: fix writing <securityfs>/evm overflow
+
+From: Mimi Zohar <zohar@linux.ibm.com>
+
+[ Upstream commit 49219d9b8785ba712575c40e48ce0f7461254626 ]
+
+EVM_SETUP_COMPLETE is defined as 0x80000000, which is larger than INT_MAX.
+The "-fno-strict-overflow" compiler option properly prevents signaling
+EVM that the EVM policy setup is complete. Define and read an unsigned
+int.
+
+Fixes: f00d79750712 ("EVM: Allow userspace to signal an RSA key has been loaded")
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/evm/evm_secfs.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
+index c175e2b659e4..5f0da41bccd0 100644
+--- a/security/integrity/evm/evm_secfs.c
++++ b/security/integrity/evm/evm_secfs.c
+@@ -66,12 +66,13 @@ static ssize_t evm_read_key(struct file *filp, char __user *buf,
+ static ssize_t evm_write_key(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+ {
+- int i, ret;
++ unsigned int i;
++ int ret;
+
+ if (!capable(CAP_SYS_ADMIN) || (evm_initialized & EVM_SETUP_COMPLETE))
+ return -EPERM;
+
+- ret = kstrtoint_from_user(buf, count, 0, &i);
++ ret = kstrtouint_from_user(buf, count, 0, &i);
+
+ if (ret)
+ return ret;
+--
+2.30.2
+
--- /dev/null
+From 3480cb2832445e900f56b3a5d49b0eac09bce6cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Jun 2021 13:10:31 +0300
+Subject: extcon: extcon-max8997: Fix IRQ freeing at error path
+
+From: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
+
+[ Upstream commit 610bdc04830a864115e6928fc944f1171dfff6f3 ]
+
+If reading MAX8997_MUIC_REG_STATUS1 fails at probe the driver exits
+without freeing the requested IRQs.
+
+Free the IRQs prior returning if reading the status fails.
+
+Fixes: 3e34c8198960 ("extcon: max8997: Avoid forcing UART path on drive probe")
+Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
+Link: https://lore.kernel.org/r/27ee4a48ee775c3f8c9d90459c18b6f2b15edc76.1623146580.git.matti.vaittinen@fi.rohmeurope.com
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/extcon/extcon-max8997.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c
+index e1408075ef7d..c15a612067af 100644
+--- a/drivers/extcon/extcon-max8997.c
++++ b/drivers/extcon/extcon-max8997.c
+@@ -733,7 +733,7 @@ static int max8997_muic_probe(struct platform_device *pdev)
+ 2, info->status);
+ if (ret) {
+ dev_err(info->dev, "failed to read MUIC register\n");
+- return ret;
++ goto err_irq;
+ }
+ cable_type = max8997_muic_get_cable_type(info,
+ MAX8997_CABLE_GROUP_ADC, &attached);
+--
+2.30.2
+
--- /dev/null
+From eea2cec28c35f3460c7162076559e226bd20a7ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 22:46:24 +0200
+Subject: extcon: max8997: Add missing modalias string
+
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+
+[ Upstream commit dc11fc2991e9efbceef93912b83e333d2835fb19 ]
+
+The platform device driver name is "max8997-muic", so advertise it
+properly in the modalias string. This fixes automated module loading when
+this driver is compiled as a module.
+
+Fixes: b76668ba8a77 ("Extcon: add MAX8997 extcon driver")
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/extcon/extcon-max8997.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c
+index c15a612067af..5c3cdb725514 100644
+--- a/drivers/extcon/extcon-max8997.c
++++ b/drivers/extcon/extcon-max8997.c
+@@ -788,3 +788,4 @@ module_platform_driver(max8997_muic_driver);
+ MODULE_DESCRIPTION("Maxim MAX8997 Extcon driver");
+ MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:max8997-muic");
+--
+2.30.2
+
--- /dev/null
+From 562ef701e8b76d2f95502d516f7abd69bc29b0b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 May 2021 15:34:35 +0200
+Subject: extcon: sm5502: Drop invalid register write in sm5502_reg_data
+
+From: Stephan Gerhold <stephan@gerhold.net>
+
+[ Upstream commit d25b224f8e5507879b36a769a6d1324cf163466c ]
+
+When sm5502_init_dev_type() iterates over sm5502_reg_data to
+initialize the registers it is limited by ARRAY_SIZE(sm5502_reg_data).
+There is no need to add another empty element to sm5502_reg_data.
+
+Having the additional empty element in sm5502_reg_data will just
+result in writing 0xff to register 0x00, which does not really
+make sense.
+
+Fixes: 914b881f9452 ("extcon: sm5502: Add support new SM5502 extcon device driver")
+Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/extcon/extcon-sm5502.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c
+index db41d1c58efd..c3e4b220e66f 100644
+--- a/drivers/extcon/extcon-sm5502.c
++++ b/drivers/extcon/extcon-sm5502.c
+@@ -88,7 +88,6 @@ static struct reg_data sm5502_reg_data[] = {
+ | SM5502_REG_INTM2_MHL_MASK,
+ .invert = true,
+ },
+- { }
+ };
+
+ /* List of detectable cables */
+--
+2.30.2
+
--- /dev/null
+From fca8809bcf6085513a42de09ac7112fa265fbecb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 20:22:15 +0200
+Subject: firmware: stratix10-svc: Fix a resource leak in an error handling
+ path
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit d99247f9b542533ddbf87a3481a05473b8e48194 ]
+
+If an error occurs after a successful 'kfifo_alloc()' call, it must be
+undone by a corresponding 'kfifo_free()' call, as already done in the
+remove function.
+
+While at it, move the 'platform_device_put()' call to this new error
+handling path and explicitly return 0 in the success path.
+
+Fixes: b5dc75c915cd ("firmware: stratix10-svc: extend svc to support new RSU features")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/0ca3f3ab139c53e846804455a1e7599ee8ae896a.1621621271.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/stratix10-svc.c | 22 +++++++++++++++-------
+ 1 file changed, 15 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c
+index 3aa489dba30a..2a7687911c09 100644
+--- a/drivers/firmware/stratix10-svc.c
++++ b/drivers/firmware/stratix10-svc.c
+@@ -1034,24 +1034,32 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)
+
+ /* add svc client device(s) */
+ svc = devm_kzalloc(dev, sizeof(*svc), GFP_KERNEL);
+- if (!svc)
+- return -ENOMEM;
++ if (!svc) {
++ ret = -ENOMEM;
++ goto err_free_kfifo;
++ }
+
+ svc->stratix10_svc_rsu = platform_device_alloc(STRATIX10_RSU, 0);
+ if (!svc->stratix10_svc_rsu) {
+ dev_err(dev, "failed to allocate %s device\n", STRATIX10_RSU);
+- return -ENOMEM;
++ ret = -ENOMEM;
++ goto err_free_kfifo;
+ }
+
+ ret = platform_device_add(svc->stratix10_svc_rsu);
+- if (ret) {
+- platform_device_put(svc->stratix10_svc_rsu);
+- return ret;
+- }
++ if (ret)
++ goto err_put_device;
++
+ dev_set_drvdata(dev, svc);
+
+ pr_info("Intel Service Layer Driver Initialized\n");
+
++ return 0;
++
++err_put_device:
++ platform_device_put(svc->stratix10_svc_rsu);
++err_free_kfifo:
++ kfifo_free(&controller->svc_fifo);
+ return ret;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 6a7225b567ad429b4cdd17007cf4d381e5a7e6ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 15:08:38 -0400
+Subject: fs: dlm: cancel work sync othercon
+
+From: Alexander Aring <aahringo@redhat.com>
+
+[ Upstream commit c6aa00e3d20c2767ba3f57b64eb862572b9744b3 ]
+
+These rx tx flags arguments are for signaling close_connection() from
+which worker they are called. Obviously the receive worker cannot cancel
+itself and vice versa for swork. For the othercon the receive worker
+should only be used, however to avoid deadlocks we should pass the same
+flags as the original close_connection() was called.
+
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dlm/lowcomms.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
+index cdc50e9a5ab0..138e8236ff6e 100644
+--- a/fs/dlm/lowcomms.c
++++ b/fs/dlm/lowcomms.c
+@@ -715,7 +715,7 @@ static void close_connection(struct connection *con, bool and_other,
+
+ if (con->othercon && and_other) {
+ /* Will only re-enter once. */
+- close_connection(con->othercon, false, true, true);
++ close_connection(con->othercon, false, tx, rx);
+ }
+
+ con->rx_leftover = 0;
+--
+2.30.2
+
--- /dev/null
+From eaa6975a2050e7a2ea985bb51579ba0e45f29ffc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 15:08:39 -0400
+Subject: fs: dlm: fix connection tcp EOF handling
+
+From: Alexander Aring <aahringo@redhat.com>
+
+[ Upstream commit 8aa31cbf20ad168c35dd83476629402aacbf5a44 ]
+
+This patch fixes the EOF handling for TCP that if and EOF is received we
+will close the socket next time the writequeue runs empty. This is a
+half-closed socket functionality which doesn't exists in SCTP. The
+midcomms layer will do a half closed socket functionality on DLM side to
+solve this problem for the SCTP case. However there is still the last ack
+flying around but other reset functionality will take care of it if it got
+lost.
+
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dlm/lowcomms.c | 48 ++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 43 insertions(+), 5 deletions(-)
+
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
+index 138e8236ff6e..b1dd850a4699 100644
+--- a/fs/dlm/lowcomms.c
++++ b/fs/dlm/lowcomms.c
+@@ -81,10 +81,13 @@ struct connection {
+ #define CF_CONNECTED 10
+ #define CF_RECONNECT 11
+ #define CF_DELAY_CONNECT 12
++#define CF_EOF 13
+ struct list_head writequeue; /* List of outgoing writequeue_entries */
+ spinlock_t writequeue_lock;
++ atomic_t writequeue_cnt;
+ void (*connect_action) (struct connection *); /* What to do to connect */
+ void (*shutdown_action)(struct connection *con); /* What to do to shutdown */
++ bool (*eof_condition)(struct connection *con); /* What to do to eof check */
+ int retries;
+ #define MAX_CONNECT_RETRIES 3
+ struct hlist_node list;
+@@ -179,6 +182,11 @@ static struct connection *__find_con(int nodeid, int r)
+ return NULL;
+ }
+
++static bool tcp_eof_condition(struct connection *con)
++{
++ return atomic_read(&con->writequeue_cnt);
++}
++
+ static int dlm_con_init(struct connection *con, int nodeid)
+ {
+ con->rx_buflen = dlm_config.ci_buffer_size;
+@@ -190,6 +198,7 @@ static int dlm_con_init(struct connection *con, int nodeid)
+ mutex_init(&con->sock_mutex);
+ INIT_LIST_HEAD(&con->writequeue);
+ spin_lock_init(&con->writequeue_lock);
++ atomic_set(&con->writequeue_cnt, 0);
+ INIT_WORK(&con->swork, process_send_sockets);
+ INIT_WORK(&con->rwork, process_recv_sockets);
+ init_waitqueue_head(&con->shutdown_wait);
+@@ -197,6 +206,7 @@ static int dlm_con_init(struct connection *con, int nodeid)
+ if (dlm_config.ci_protocol == 0) {
+ con->connect_action = tcp_connect_to_sock;
+ con->shutdown_action = dlm_tcp_shutdown;
++ con->eof_condition = tcp_eof_condition;
+ } else {
+ con->connect_action = sctp_connect_to_sock;
+ }
+@@ -723,6 +733,7 @@ static void close_connection(struct connection *con, bool and_other,
+ clear_bit(CF_CONNECTED, &con->flags);
+ clear_bit(CF_DELAY_CONNECT, &con->flags);
+ clear_bit(CF_RECONNECT, &con->flags);
++ clear_bit(CF_EOF, &con->flags);
+ mutex_unlock(&con->sock_mutex);
+ clear_bit(CF_CLOSING, &con->flags);
+ }
+@@ -860,16 +871,26 @@ out_resched:
+ return -EAGAIN;
+
+ out_close:
+- mutex_unlock(&con->sock_mutex);
+ if (ret == 0) {
+- close_connection(con, false, true, false);
+ log_print("connection %p got EOF from %d",
+ con, con->nodeid);
+- /* handling for tcp shutdown */
+- clear_bit(CF_SHUTDOWN, &con->flags);
+- wake_up(&con->shutdown_wait);
++
++ if (con->eof_condition && con->eof_condition(con)) {
++ set_bit(CF_EOF, &con->flags);
++ mutex_unlock(&con->sock_mutex);
++ } else {
++ mutex_unlock(&con->sock_mutex);
++ close_connection(con, false, true, false);
++
++ /* handling for tcp shutdown */
++ clear_bit(CF_SHUTDOWN, &con->flags);
++ wake_up(&con->shutdown_wait);
++ }
++
+ /* signal to breaking receive worker */
+ ret = -1;
++ } else {
++ mutex_unlock(&con->sock_mutex);
+ }
+ return ret;
+ }
+@@ -1020,6 +1041,7 @@ static void writequeue_entry_complete(struct writequeue_entry *e, int completed)
+
+ if (e->len == 0 && e->users == 0) {
+ list_del(&e->list);
++ atomic_dec(&e->con->writequeue_cnt);
+ free_entry(e);
+ }
+ }
+@@ -1416,6 +1438,7 @@ static struct writequeue_entry *new_wq_entry(struct connection *con, int len,
+
+ *ppc = page_address(e->page);
+ e->end += len;
++ atomic_inc(&con->writequeue_cnt);
+
+ spin_lock(&con->writequeue_lock);
+ list_add_tail(&e->list, &con->writequeue);
+@@ -1535,6 +1558,21 @@ static void send_to_sock(struct connection *con)
+ writequeue_entry_complete(e, ret);
+ }
+ spin_unlock(&con->writequeue_lock);
++
++ /* close if we got EOF */
++ if (test_and_clear_bit(CF_EOF, &con->flags)) {
++ mutex_unlock(&con->sock_mutex);
++ close_connection(con, false, false, true);
++
++ /* handling for tcp shutdown */
++ clear_bit(CF_SHUTDOWN, &con->flags);
++ wake_up(&con->shutdown_wait);
++ } else {
++ mutex_unlock(&con->sock_mutex);
++ }
++
++ return;
++
+ out:
+ mutex_unlock(&con->sock_mutex);
+ return;
+--
+2.30.2
+
--- /dev/null
+From 25c77a8b39e6f45476a3ca7101cf30fd9474e23d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Jun 2021 09:45:15 -0400
+Subject: fs: dlm: fix lowcomms_start error case
+
+From: Alexander Aring <aahringo@redhat.com>
+
+[ Upstream commit fcef0e6c27ce109d2c617aa12f0bfd9f7ff47d38 ]
+
+This patch fixes the error path handling in lowcomms_start(). We need to
+cleanup some static allocated data structure and cleanup possible
+workqueue if these have started.
+
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dlm/lowcomms.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
+index b1dd850a4699..9bf920bee292 100644
+--- a/fs/dlm/lowcomms.c
++++ b/fs/dlm/lowcomms.c
+@@ -1666,10 +1666,15 @@ static void process_send_sockets(struct work_struct *work)
+
+ static void work_stop(void)
+ {
+- if (recv_workqueue)
++ if (recv_workqueue) {
+ destroy_workqueue(recv_workqueue);
+- if (send_workqueue)
++ recv_workqueue = NULL;
++ }
++
++ if (send_workqueue) {
+ destroy_workqueue(send_workqueue);
++ send_workqueue = NULL;
++ }
+ }
+
+ static int work_start(void)
+@@ -1686,6 +1691,7 @@ static int work_start(void)
+ if (!send_workqueue) {
+ log_print("can't start dlm_send");
+ destroy_workqueue(recv_workqueue);
++ recv_workqueue = NULL;
+ return -ENOMEM;
+ }
+
+@@ -1823,7 +1829,7 @@ int dlm_lowcomms_start(void)
+
+ error = work_start();
+ if (error)
+- goto fail;
++ goto fail_local;
+
+ dlm_allow_conn = 1;
+
+@@ -1840,6 +1846,9 @@ int dlm_lowcomms_start(void)
+ fail_unlisten:
+ dlm_allow_conn = 0;
+ dlm_close_sock(&listen_con.sock);
++ work_stop();
++fail_local:
++ deinit_local();
+ fail:
+ return error;
+ }
+--
+2.30.2
+
--- /dev/null
+From 851eee4c1dffde1bc11a76411615a569c3157edf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Jun 2021 09:45:16 -0400
+Subject: fs: dlm: fix memory leak when fenced
+
+From: Alexander Aring <aahringo@redhat.com>
+
+[ Upstream commit 700ab1c363c7b54c9ea3222379b33fc00ab02f7b ]
+
+I got some kmemleak report when a node was fenced. The user space tool
+dlm_controld will therefore run some rmdir() in dlm configfs which was
+triggering some memleaks. This patch stores the sps and cms attributes
+which stores some handling for subdirectories of the configfs cluster
+entry and free them if they get released as the parent directory gets
+freed.
+
+unreferenced object 0xffff88810d9e3e00 (size 192):
+ comm "dlm_controld", pid 342, jiffies 4294698126 (age 55438.801s)
+ hex dump (first 32 bytes):
+ 00 00 00 00 00 00 00 00 73 70 61 63 65 73 00 00 ........spaces..
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ backtrace:
+ [<00000000db8b640b>] make_cluster+0x5d/0x360
+ [<000000006a571db4>] configfs_mkdir+0x274/0x730
+ [<00000000b094501c>] vfs_mkdir+0x27e/0x340
+ [<0000000058b0adaf>] do_mkdirat+0xff/0x1b0
+ [<00000000d1ffd156>] do_syscall_64+0x40/0x80
+ [<00000000ab1408c8>] entry_SYSCALL_64_after_hwframe+0x44/0xae
+unreferenced object 0xffff88810d9e3a00 (size 192):
+ comm "dlm_controld", pid 342, jiffies 4294698126 (age 55438.801s)
+ hex dump (first 32 bytes):
+ 00 00 00 00 00 00 00 00 63 6f 6d 6d 73 00 00 00 ........comms...
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ backtrace:
+ [<00000000a7ef6ad2>] make_cluster+0x82/0x360
+ [<000000006a571db4>] configfs_mkdir+0x274/0x730
+ [<00000000b094501c>] vfs_mkdir+0x27e/0x340
+ [<0000000058b0adaf>] do_mkdirat+0xff/0x1b0
+ [<00000000d1ffd156>] do_syscall_64+0x40/0x80
+ [<00000000ab1408c8>] entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dlm/config.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/fs/dlm/config.c b/fs/dlm/config.c
+index 88d95d96e36c..52bcda64172a 100644
+--- a/fs/dlm/config.c
++++ b/fs/dlm/config.c
+@@ -79,6 +79,9 @@ struct dlm_cluster {
+ unsigned int cl_new_rsb_count;
+ unsigned int cl_recover_callbacks;
+ char cl_cluster_name[DLM_LOCKSPACE_LEN];
++
++ struct dlm_spaces *sps;
++ struct dlm_comms *cms;
+ };
+
+ static struct dlm_cluster *config_item_to_cluster(struct config_item *i)
+@@ -409,6 +412,9 @@ static struct config_group *make_cluster(struct config_group *g,
+ if (!cl || !sps || !cms)
+ goto fail;
+
++ cl->sps = sps;
++ cl->cms = cms;
++
+ config_group_init_type_name(&cl->group, name, &cluster_type);
+ config_group_init_type_name(&sps->ss_group, "spaces", &spaces_type);
+ config_group_init_type_name(&cms->cs_group, "comms", &comms_type);
+@@ -458,6 +464,9 @@ static void drop_cluster(struct config_group *g, struct config_item *i)
+ static void release_cluster(struct config_item *i)
+ {
+ struct dlm_cluster *cl = config_item_to_cluster(i);
++
++ kfree(cl->sps);
++ kfree(cl->cms);
+ kfree(cl);
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 39c2367e6375517cc9ee754fa208a833047cd103 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 15:08:35 -0400
+Subject: fs: dlm: fix srcu read lock usage
+
+From: Alexander Aring <aahringo@redhat.com>
+
+[ Upstream commit b38bc9c2b3171f4411d80015ecb876bc6f9bcd26 ]
+
+This patch holds the srcu connection read lock in cases where we lookup
+the connections and accessing it. We don't hold the srcu lock in workers
+function where the scheduled worker is part of the connection itself.
+The connection should not be freed if any worker is scheduled or
+pending.
+
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dlm/lowcomms.c | 75 ++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 52 insertions(+), 23 deletions(-)
+
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
+index 166e36fcf3e4..47bf99373f3e 100644
+--- a/fs/dlm/lowcomms.c
++++ b/fs/dlm/lowcomms.c
+@@ -113,6 +113,7 @@ struct writequeue_entry {
+ int len;
+ int end;
+ int users;
++ int idx; /* get()/commit() idx exchange */
+ struct connection *con;
+ };
+
+@@ -163,21 +164,14 @@ static inline int nodeid_hash(int nodeid)
+ return nodeid & (CONN_HASH_SIZE-1);
+ }
+
+-static struct connection *__find_con(int nodeid)
++static struct connection *__find_con(int nodeid, int r)
+ {
+- int r, idx;
+ struct connection *con;
+
+- r = nodeid_hash(nodeid);
+-
+- idx = srcu_read_lock(&connections_srcu);
+ hlist_for_each_entry_rcu(con, &connection_hash[r], list) {
+- if (con->nodeid == nodeid) {
+- srcu_read_unlock(&connections_srcu, idx);
++ if (con->nodeid == nodeid)
+ return con;
+- }
+ }
+- srcu_read_unlock(&connections_srcu, idx);
+
+ return NULL;
+ }
+@@ -216,7 +210,8 @@ static struct connection *nodeid2con(int nodeid, gfp_t alloc)
+ struct connection *con, *tmp;
+ int r, ret;
+
+- con = __find_con(nodeid);
++ r = nodeid_hash(nodeid);
++ con = __find_con(nodeid, r);
+ if (con || !alloc)
+ return con;
+
+@@ -230,8 +225,6 @@ static struct connection *nodeid2con(int nodeid, gfp_t alloc)
+ return NULL;
+ }
+
+- r = nodeid_hash(nodeid);
+-
+ spin_lock(&connections_lock);
+ /* Because multiple workqueues/threads calls this function it can
+ * race on multiple cpu's. Instead of locking hot path __find_con()
+@@ -239,7 +232,7 @@ static struct connection *nodeid2con(int nodeid, gfp_t alloc)
+ * under protection of connections_lock. If this is the case we
+ * abort our connection creation and return the existing connection.
+ */
+- tmp = __find_con(nodeid);
++ tmp = __find_con(nodeid, r);
+ if (tmp) {
+ spin_unlock(&connections_lock);
+ kfree(con->rx_buf);
+@@ -256,15 +249,13 @@ static struct connection *nodeid2con(int nodeid, gfp_t alloc)
+ /* Loop round all connections */
+ static void foreach_conn(void (*conn_func)(struct connection *c))
+ {
+- int i, idx;
++ int i;
+ struct connection *con;
+
+- idx = srcu_read_lock(&connections_srcu);
+ for (i = 0; i < CONN_HASH_SIZE; i++) {
+ hlist_for_each_entry_rcu(con, &connection_hash[i], list)
+ conn_func(con);
+ }
+- srcu_read_unlock(&connections_srcu, idx);
+ }
+
+ static struct dlm_node_addr *find_node_addr(int nodeid)
+@@ -518,14 +509,21 @@ static void lowcomms_state_change(struct sock *sk)
+ int dlm_lowcomms_connect_node(int nodeid)
+ {
+ struct connection *con;
++ int idx;
+
+ if (nodeid == dlm_our_nodeid())
+ return 0;
+
++ idx = srcu_read_lock(&connections_srcu);
+ con = nodeid2con(nodeid, GFP_NOFS);
+- if (!con)
++ if (!con) {
++ srcu_read_unlock(&connections_srcu, idx);
+ return -ENOMEM;
++ }
++
+ lowcomms_connect_sock(con);
++ srcu_read_unlock(&connections_srcu, idx);
++
+ return 0;
+ }
+
+@@ -864,7 +862,7 @@ static int accept_from_sock(struct listen_connection *con)
+ int result;
+ struct sockaddr_storage peeraddr;
+ struct socket *newsock;
+- int len;
++ int len, idx;
+ int nodeid;
+ struct connection *newcon;
+ struct connection *addcon;
+@@ -907,8 +905,10 @@ static int accept_from_sock(struct listen_connection *con)
+ * the same time and the connections cross on the wire.
+ * In this case we store the incoming one in "othercon"
+ */
++ idx = srcu_read_lock(&connections_srcu);
+ newcon = nodeid2con(nodeid, GFP_NOFS);
+ if (!newcon) {
++ srcu_read_unlock(&connections_srcu, idx);
+ result = -ENOMEM;
+ goto accept_err;
+ }
+@@ -924,6 +924,7 @@ static int accept_from_sock(struct listen_connection *con)
+ if (!othercon) {
+ log_print("failed to allocate incoming socket");
+ mutex_unlock(&newcon->sock_mutex);
++ srcu_read_unlock(&connections_srcu, idx);
+ result = -ENOMEM;
+ goto accept_err;
+ }
+@@ -932,6 +933,7 @@ static int accept_from_sock(struct listen_connection *con)
+ if (result < 0) {
+ kfree(othercon);
+ mutex_unlock(&newcon->sock_mutex);
++ srcu_read_unlock(&connections_srcu, idx);
+ goto accept_err;
+ }
+
+@@ -966,6 +968,8 @@ static int accept_from_sock(struct listen_connection *con)
+ if (!test_and_set_bit(CF_READ_PENDING, &addcon->flags))
+ queue_work(recv_workqueue, &addcon->rwork);
+
++ srcu_read_unlock(&connections_srcu, idx);
++
+ return 0;
+
+ accept_err:
+@@ -1403,7 +1407,9 @@ static struct writequeue_entry *new_wq_entry(struct connection *con, int len,
+
+ void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc)
+ {
++ struct writequeue_entry *e;
+ struct connection *con;
++ int idx;
+
+ if (len > DEFAULT_BUFFER_SIZE ||
+ len < sizeof(struct dlm_header)) {
+@@ -1413,11 +1419,23 @@ void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc)
+ return NULL;
+ }
+
++ idx = srcu_read_lock(&connections_srcu);
+ con = nodeid2con(nodeid, allocation);
+- if (!con)
++ if (!con) {
++ srcu_read_unlock(&connections_srcu, idx);
+ return NULL;
++ }
++
++ e = new_wq_entry(con, len, allocation, ppc);
++ if (!e) {
++ srcu_read_unlock(&connections_srcu, idx);
++ return NULL;
++ }
++
++ /* we assume if successful commit must called */
++ e->idx = idx;
+
+- return new_wq_entry(con, len, allocation, ppc);
++ return e;
+ }
+
+ void dlm_lowcomms_commit_buffer(void *mh)
+@@ -1435,10 +1453,12 @@ void dlm_lowcomms_commit_buffer(void *mh)
+ spin_unlock(&con->writequeue_lock);
+
+ queue_work(send_workqueue, &con->swork);
++ srcu_read_unlock(&connections_srcu, e->idx);
+ return;
+
+ out:
+ spin_unlock(&con->writequeue_lock);
++ srcu_read_unlock(&connections_srcu, e->idx);
+ return;
+ }
+
+@@ -1532,8 +1552,10 @@ int dlm_lowcomms_close(int nodeid)
+ {
+ struct connection *con;
+ struct dlm_node_addr *na;
++ int idx;
+
+ log_print("closing connection to node %d", nodeid);
++ idx = srcu_read_lock(&connections_srcu);
+ con = nodeid2con(nodeid, 0);
+ if (con) {
+ set_bit(CF_CLOSE, &con->flags);
+@@ -1542,6 +1564,7 @@ int dlm_lowcomms_close(int nodeid)
+ if (con->othercon)
+ clean_one_writequeue(con->othercon);
+ }
++ srcu_read_unlock(&connections_srcu, idx);
+
+ spin_lock(&dlm_node_addrs_spin);
+ na = find_node_addr(nodeid);
+@@ -1621,6 +1644,8 @@ static void shutdown_conn(struct connection *con)
+
+ void dlm_lowcomms_shutdown(void)
+ {
++ int idx;
++
+ /* Set all the flags to prevent any
+ * socket activity.
+ */
+@@ -1633,7 +1658,9 @@ void dlm_lowcomms_shutdown(void)
+
+ dlm_close_sock(&listen_con.sock);
+
++ idx = srcu_read_lock(&connections_srcu);
+ foreach_conn(shutdown_conn);
++ srcu_read_unlock(&connections_srcu, idx);
+ }
+
+ static void _stop_conn(struct connection *con, bool and_other)
+@@ -1682,7 +1709,7 @@ static void free_conn(struct connection *con)
+
+ static void work_flush(void)
+ {
+- int ok, idx;
++ int ok;
+ int i;
+ struct connection *con;
+
+@@ -1693,7 +1720,6 @@ static void work_flush(void)
+ flush_workqueue(recv_workqueue);
+ if (send_workqueue)
+ flush_workqueue(send_workqueue);
+- idx = srcu_read_lock(&connections_srcu);
+ for (i = 0; i < CONN_HASH_SIZE && ok; i++) {
+ hlist_for_each_entry_rcu(con, &connection_hash[i],
+ list) {
+@@ -1707,14 +1733,17 @@ static void work_flush(void)
+ }
+ }
+ }
+- srcu_read_unlock(&connections_srcu, idx);
+ } while (!ok);
+ }
+
+ void dlm_lowcomms_stop(void)
+ {
++ int idx;
++
++ idx = srcu_read_lock(&connections_srcu);
+ work_flush();
+ foreach_conn(free_conn);
++ srcu_read_unlock(&connections_srcu, idx);
+ work_stop();
+ deinit_local();
+ }
+--
+2.30.2
+
--- /dev/null
+From 733c416a8d19888ab9352366a4d202c72f93f7f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 15:08:37 -0400
+Subject: fs: dlm: reconnect if socket error report occurs
+
+From: Alexander Aring <aahringo@redhat.com>
+
+[ Upstream commit ba868d9deaab2bb1c09e50650127823925154802 ]
+
+This patch will change the reconnect handling that if an error occurs
+if a socket error callback is occurred. This will also handle reconnects
+in a non blocking connecting case which is currently missing. If error
+ECONNREFUSED is reported we delay the reconnect by one second.
+
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dlm/lowcomms.c | 60 ++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 39 insertions(+), 21 deletions(-)
+
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
+index 47bf99373f3e..cdc50e9a5ab0 100644
+--- a/fs/dlm/lowcomms.c
++++ b/fs/dlm/lowcomms.c
+@@ -79,6 +79,8 @@ struct connection {
+ #define CF_CLOSING 8
+ #define CF_SHUTDOWN 9
+ #define CF_CONNECTED 10
++#define CF_RECONNECT 11
++#define CF_DELAY_CONNECT 12
+ struct list_head writequeue; /* List of outgoing writequeue_entries */
+ spinlock_t writequeue_lock;
+ void (*connect_action) (struct connection *); /* What to do to connect */
+@@ -87,6 +89,7 @@ struct connection {
+ #define MAX_CONNECT_RETRIES 3
+ struct hlist_node list;
+ struct connection *othercon;
++ struct connection *sendcon;
+ struct work_struct rwork; /* Receive workqueue */
+ struct work_struct swork; /* Send workqueue */
+ wait_queue_head_t shutdown_wait; /* wait for graceful shutdown */
+@@ -585,6 +588,22 @@ static void lowcomms_error_report(struct sock *sk)
+ dlm_config.ci_tcp_port, sk->sk_err,
+ sk->sk_err_soft);
+ }
++
++ /* below sendcon only handling */
++ if (test_bit(CF_IS_OTHERCON, &con->flags))
++ con = con->sendcon;
++
++ switch (sk->sk_err) {
++ case ECONNREFUSED:
++ set_bit(CF_DELAY_CONNECT, &con->flags);
++ break;
++ default:
++ break;
++ }
++
++ if (!test_and_set_bit(CF_RECONNECT, &con->flags))
++ queue_work(send_workqueue, &con->swork);
++
+ out:
+ read_unlock_bh(&sk->sk_callback_lock);
+ if (orig_report)
+@@ -702,6 +721,8 @@ static void close_connection(struct connection *con, bool and_other,
+ con->rx_leftover = 0;
+ con->retries = 0;
+ clear_bit(CF_CONNECTED, &con->flags);
++ clear_bit(CF_DELAY_CONNECT, &con->flags);
++ clear_bit(CF_RECONNECT, &con->flags);
+ mutex_unlock(&con->sock_mutex);
+ clear_bit(CF_CLOSING, &con->flags);
+ }
+@@ -840,18 +861,15 @@ out_resched:
+
+ out_close:
+ mutex_unlock(&con->sock_mutex);
+- if (ret != -EAGAIN) {
+- /* Reconnect when there is something to send */
++ if (ret == 0) {
+ close_connection(con, false, true, false);
+- if (ret == 0) {
+- log_print("connection %p got EOF from %d",
+- con, con->nodeid);
+- /* handling for tcp shutdown */
+- clear_bit(CF_SHUTDOWN, &con->flags);
+- wake_up(&con->shutdown_wait);
+- /* signal to breaking receive worker */
+- ret = -1;
+- }
++ log_print("connection %p got EOF from %d",
++ con, con->nodeid);
++ /* handling for tcp shutdown */
++ clear_bit(CF_SHUTDOWN, &con->flags);
++ wake_up(&con->shutdown_wait);
++ /* signal to breaking receive worker */
++ ret = -1;
+ }
+ return ret;
+ }
+@@ -939,6 +957,7 @@ static int accept_from_sock(struct listen_connection *con)
+
+ lockdep_set_subclass(&othercon->sock_mutex, 1);
+ newcon->othercon = othercon;
++ othercon->sendcon = newcon;
+ } else {
+ /* close other sock con if we have something new */
+ close_connection(othercon, false, true, false);
+@@ -1503,7 +1522,7 @@ static void send_to_sock(struct connection *con)
+ cond_resched();
+ goto out;
+ } else if (ret < 0)
+- goto send_error;
++ goto out;
+ }
+
+ /* Don't starve people filling buffers */
+@@ -1520,14 +1539,6 @@ out:
+ mutex_unlock(&con->sock_mutex);
+ return;
+
+-send_error:
+- mutex_unlock(&con->sock_mutex);
+- close_connection(con, false, false, true);
+- /* Requeue the send work. When the work daemon runs again, it will try
+- a new connection, then call this function again. */
+- queue_work(send_workqueue, &con->swork);
+- return;
+-
+ out_connect:
+ mutex_unlock(&con->sock_mutex);
+ queue_work(send_workqueue, &con->swork);
+@@ -1602,8 +1613,15 @@ static void process_send_sockets(struct work_struct *work)
+ struct connection *con = container_of(work, struct connection, swork);
+
+ clear_bit(CF_WRITE_PENDING, &con->flags);
+- if (con->sock == NULL) /* not mutex protected so check it inside too */
++
++ if (test_and_clear_bit(CF_RECONNECT, &con->flags))
++ close_connection(con, false, false, true);
++
++ if (con->sock == NULL) { /* not mutex protected so check it inside too */
++ if (test_and_clear_bit(CF_DELAY_CONNECT, &con->flags))
++ msleep(1000);
+ con->connect_action(con);
++ }
+ if (!list_empty(&con->writequeue))
+ send_to_sock(con);
+ }
+--
+2.30.2
+
--- /dev/null
+From 442bde6f604ad47238e10bc998a24ea6deebbe17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Jun 2021 13:28:12 +0100
+Subject: fsi: core: Fix return of error values on failures
+
+From: Colin Ian King <colin.king@canonical.com>
+
+[ Upstream commit 910810945707fe9877ca86a0dca4e585fd05e37b ]
+
+Currently the cfam_read and cfam_write functions return the provided
+number of bytes given in the count parameter and not the error return
+code in variable rc, hence all failures of read/writes are being
+silently ignored. Fix this by returning the error code in rc.
+
+Addresses-Coverity: ("Unused value")
+Fixes: d1dcd6782576 ("fsi: Add cfam char devices")
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Reviewed-by: Jeremy Kerr <jk@ozlabs.org>
+Link: https://lore.kernel.org/r/20210603122812.83587-1-colin.king@canonical.com
+Signed-off-by: Joel Stanley <joel@jms.id.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/fsi/fsi-core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
+index 4e60e84cd17a..59ddc9fd5bca 100644
+--- a/drivers/fsi/fsi-core.c
++++ b/drivers/fsi/fsi-core.c
+@@ -724,7 +724,7 @@ static ssize_t cfam_read(struct file *filep, char __user *buf, size_t count,
+ rc = count;
+ fail:
+ *offset = off;
+- return count;
++ return rc;
+ }
+
+ static ssize_t cfam_write(struct file *filep, const char __user *buf,
+@@ -761,7 +761,7 @@ static ssize_t cfam_write(struct file *filep, const char __user *buf,
+ rc = count;
+ fail:
+ *offset = off;
+- return count;
++ return rc;
+ }
+
+ static loff_t cfam_llseek(struct file *file, loff_t offset, int whence)
+--
+2.30.2
+
--- /dev/null
+From 008d03ca3b5e32b09eb7aaebad190f582b44486c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Feb 2021 11:12:32 -0600
+Subject: fsi: occ: Don't accept response from un-initialized OCC
+
+From: Eddie James <eajames@linux.ibm.com>
+
+[ Upstream commit 8a4659be08576141f47d47d94130eb148cb5f0df ]
+
+If the OCC is not initialized and responds as such, the driver
+should continue waiting for a valid response until the timeout
+expires.
+
+Signed-off-by: Eddie James <eajames@linux.ibm.com>
+Reviewed-by: Joel Stanley <joel@jms.id.au>
+Fixes: 7ed98dddb764 ("fsi: Add On-Chip Controller (OCC) driver")
+Link: https://lore.kernel.org/r/20210209171235.20624-2-eajames@linux.ibm.com
+Signed-off-by: Joel Stanley <joel@jms.id.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/fsi/fsi-occ.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/fsi/fsi-occ.c b/drivers/fsi/fsi-occ.c
+index 10ca2e290655..cb05b6dacc9d 100644
+--- a/drivers/fsi/fsi-occ.c
++++ b/drivers/fsi/fsi-occ.c
+@@ -495,6 +495,7 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len,
+ goto done;
+
+ if (resp->return_status == OCC_RESP_CMD_IN_PRG ||
++ resp->return_status == OCC_RESP_CRIT_INIT ||
+ resp->seq_no != seq_no) {
+ rc = -ETIMEDOUT;
+
+--
+2.30.2
+
--- /dev/null
+From 7de19eca2237ecc101d2beaeebcb0d5456af3f08 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jul 2020 16:45:17 +0930
+Subject: fsi/sbefifo: Clean up correct FIFO when receiving reset request from
+ SBE
+
+From: Joachim Fenkes <FENKES@de.ibm.com>
+
+[ Upstream commit 95152433e46fdb36652ebdbea442356a16ae1fa6 ]
+
+When the SBE requests a reset via the down FIFO, that is also the
+FIFO we should go and reset ;)
+
+Fixes: 9f4a8a2d7f9d ("fsi/sbefifo: Add driver for the SBE FIFO")
+Signed-off-by: Joachim Fenkes <FENKES@de.ibm.com>
+Signed-off-by: Joel Stanley <joel@jms.id.au>
+Link: https://lore.kernel.org/r/20200724071518.430515-2-joel@jms.id.au
+Signed-off-by: Joel Stanley <joel@jms.id.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/fsi/fsi-sbefifo.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c
+index bfd5e5da8020..de27c435d706 100644
+--- a/drivers/fsi/fsi-sbefifo.c
++++ b/drivers/fsi/fsi-sbefifo.c
+@@ -400,7 +400,7 @@ static int sbefifo_cleanup_hw(struct sbefifo *sbefifo)
+ /* The FIFO already contains a reset request from the SBE ? */
+ if (down_status & SBEFIFO_STS_RESET_REQ) {
+ dev_info(dev, "Cleanup: FIFO reset request set, resetting\n");
+- rc = sbefifo_regw(sbefifo, SBEFIFO_UP, SBEFIFO_PERFORM_RESET);
++ rc = sbefifo_regw(sbefifo, SBEFIFO_DOWN, SBEFIFO_PERFORM_RESET);
+ if (rc) {
+ sbefifo->broken = true;
+ dev_err(dev, "Cleanup: Reset reg write failed, rc=%d\n", rc);
+--
+2.30.2
+
--- /dev/null
+From 6640da0170a1db4d4599b6dcd1eef570ea288628 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jul 2020 16:45:18 +0930
+Subject: fsi/sbefifo: Fix reset timeout
+
+From: Joachim Fenkes <FENKES@de.ibm.com>
+
+[ Upstream commit 9ab1428dfe2c66b51e0b41337cd0164da0ab6080 ]
+
+On BMCs with lower timer resolution than 1ms, msleep(1) will take
+way longer than 1ms, so looping 10k times won't wait for 10s but
+significantly longer.
+
+Fix this by using jiffies like the rest of the code.
+
+Fixes: 9f4a8a2d7f9d ("fsi/sbefifo: Add driver for the SBE FIFO")
+Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
+Link: https://lore.kernel.org/r/20200724071518.430515-3-joel@jms.id.au
+Signed-off-by: Joel Stanley <joel@jms.id.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/fsi/fsi-sbefifo.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c
+index de27c435d706..84cb965bfed5 100644
+--- a/drivers/fsi/fsi-sbefifo.c
++++ b/drivers/fsi/fsi-sbefifo.c
+@@ -325,7 +325,8 @@ static int sbefifo_up_write(struct sbefifo *sbefifo, __be32 word)
+ static int sbefifo_request_reset(struct sbefifo *sbefifo)
+ {
+ struct device *dev = &sbefifo->fsi_dev->dev;
+- u32 status, timeout;
++ unsigned long end_time;
++ u32 status;
+ int rc;
+
+ dev_dbg(dev, "Requesting FIFO reset\n");
+@@ -341,7 +342,8 @@ static int sbefifo_request_reset(struct sbefifo *sbefifo)
+ }
+
+ /* Wait for it to complete */
+- for (timeout = 0; timeout < SBEFIFO_RESET_TIMEOUT; timeout++) {
++ end_time = jiffies + msecs_to_jiffies(SBEFIFO_RESET_TIMEOUT);
++ while (!time_after(jiffies, end_time)) {
+ rc = sbefifo_regr(sbefifo, SBEFIFO_UP | SBEFIFO_STS, &status);
+ if (rc) {
+ dev_err(dev, "Failed to read UP fifo status during reset"
+@@ -355,7 +357,7 @@ static int sbefifo_request_reset(struct sbefifo *sbefifo)
+ return 0;
+ }
+
+- msleep(1);
++ cond_resched();
+ }
+ dev_err(dev, "FIFO reset timed out\n");
+
+--
+2.30.2
+
--- /dev/null
+From 1d6ef7b31a7a759624d7b415e6e7b0aa995ad2a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Mar 2021 10:13:44 -0500
+Subject: fsi: scom: Reset the FSI2PIB engine for any error
+
+From: Eddie James <eajames@linux.ibm.com>
+
+[ Upstream commit a5c317dac5567206ca7b6bc9d008dd6890c8bced ]
+
+The error bits in the FSI2PIB status are only cleared by a reset. So
+the driver needs to perform a reset after seeing any of the FSI2PIB
+errors, otherwise subsequent operations will also look like failures.
+
+Fixes: 6b293258cded ("fsi: scom: Major overhaul")
+Signed-off-by: Eddie James <eajames@linux.ibm.com>
+Reviewed-by: Joel Stanley <joel@jms.id.au>
+Link: https://lore.kernel.org/r/20210329151344.14246-1-eajames@linux.ibm.com
+Signed-off-by: Joel Stanley <joel@jms.id.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/fsi/fsi-scom.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c
+index b45bfab7b7f5..75d1389e2626 100644
+--- a/drivers/fsi/fsi-scom.c
++++ b/drivers/fsi/fsi-scom.c
+@@ -38,9 +38,10 @@
+ #define SCOM_STATUS_PIB_RESP_MASK 0x00007000
+ #define SCOM_STATUS_PIB_RESP_SHIFT 12
+
+-#define SCOM_STATUS_ANY_ERR (SCOM_STATUS_PROTECTION | \
+- SCOM_STATUS_PARITY | \
+- SCOM_STATUS_PIB_ABORT | \
++#define SCOM_STATUS_FSI2PIB_ERROR (SCOM_STATUS_PROTECTION | \
++ SCOM_STATUS_PARITY | \
++ SCOM_STATUS_PIB_ABORT)
++#define SCOM_STATUS_ANY_ERR (SCOM_STATUS_FSI2PIB_ERROR | \
+ SCOM_STATUS_PIB_RESP_MASK)
+ /* SCOM address encodings */
+ #define XSCOM_ADDR_IND_FLAG BIT_ULL(63)
+@@ -240,13 +241,14 @@ static int handle_fsi2pib_status(struct scom_device *scom, uint32_t status)
+ {
+ uint32_t dummy = -1;
+
+- if (status & SCOM_STATUS_PROTECTION)
+- return -EPERM;
+- if (status & SCOM_STATUS_PARITY) {
++ if (status & SCOM_STATUS_FSI2PIB_ERROR)
+ fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG, &dummy,
+ sizeof(uint32_t));
++
++ if (status & SCOM_STATUS_PROTECTION)
++ return -EPERM;
++ if (status & SCOM_STATUS_PARITY)
+ return -EIO;
+- }
+ /* Return -EBUSY on PIB abort to force a retry */
+ if (status & SCOM_STATUS_PIB_ABORT)
+ return -EBUSY;
+--
+2.30.2
+
--- /dev/null
+From c53ed857b60d652fb458dcb4dc66aca5db542d40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Jun 2021 19:55:41 -0700
+Subject: gve: Fix swapped vars when fetching max queues
+
+From: Bailey Forrest <bcf@google.com>
+
+[ Upstream commit 1db1a862a08f85edc36aad091236ac9b818e949e ]
+
+Fixes: 893ce44df565 ("gve: Add basic driver framework for Compute Engine Virtual NIC")
+Signed-off-by: Bailey Forrest <bcf@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/google/gve/gve_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
+index bbc423e93122..79cefe85a799 100644
+--- a/drivers/net/ethernet/google/gve/gve_main.c
++++ b/drivers/net/ethernet/google/gve/gve_main.c
+@@ -1295,8 +1295,8 @@ static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+
+ gve_write_version(®_bar->driver_version);
+ /* Get max queues to alloc etherdev */
+- max_rx_queues = ioread32be(®_bar->max_tx_queues);
+- max_tx_queues = ioread32be(®_bar->max_rx_queues);
++ max_tx_queues = ioread32be(®_bar->max_tx_queues);
++ max_rx_queues = ioread32be(®_bar->max_rx_queues);
+ /* Alloc and setup the netdev and priv */
+ dev = alloc_etherdev_mqs(sizeof(*priv), max_tx_queues, max_rx_queues);
+ if (!dev) {
+--
+2.30.2
+
--- /dev/null
+From ad46fb194b5962eedbdb3796d05b1a4cd16fa475 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Jun 2021 07:39:51 +0200
+Subject: habanalabs: Fix an error handling path in 'hl_pci_probe()'
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 3002f467a0b0a70aec01d9f446da4ac8c6fda10b ]
+
+If an error occurs after a 'pci_enable_pcie_error_reporting()' call, it
+must be undone by a corresponding 'pci_disable_pcie_error_reporting()'
+call, as already done in the remove function.
+
+Fixes: 2e5eda4681f9 ("habanalabs: PCIe Advanced Error Reporting support")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
+Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/habanalabs/common/habanalabs_drv.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/misc/habanalabs/common/habanalabs_drv.c b/drivers/misc/habanalabs/common/habanalabs_drv.c
+index 64d1530db985..d15b912a347b 100644
+--- a/drivers/misc/habanalabs/common/habanalabs_drv.c
++++ b/drivers/misc/habanalabs/common/habanalabs_drv.c
+@@ -464,6 +464,7 @@ static int hl_pci_probe(struct pci_dev *pdev,
+ return 0;
+
+ disable_device:
++ pci_disable_pcie_error_reporting(pdev);
+ pci_set_drvdata(pdev, NULL);
+ destroy_hdev(hdev);
+
+--
+2.30.2
+
--- /dev/null
+From 939b3d75d7dd5516f4126cc7a8d12085bcdbf997 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Mar 2021 17:27:16 -0700
+Subject: HID: do not use down_interruptible() when unbinding devices
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+[ Upstream commit f2145f8dc566c4f3b5a8deb58dcd12bed4e20194 ]
+
+Action of unbinding driver from a device is not cancellable and should not
+fail, and driver core does not pay attention to the result of "remove"
+method, therefore using down_interruptible() in hid_device_remove() does
+not make sense.
+
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-core.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index 0de2788b9814..7db332139f7d 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -2306,12 +2306,8 @@ static int hid_device_remove(struct device *dev)
+ {
+ struct hid_device *hdev = to_hid_device(dev);
+ struct hid_driver *hdrv;
+- int ret = 0;
+
+- if (down_interruptible(&hdev->driver_input_lock)) {
+- ret = -EINTR;
+- goto end;
+- }
++ down(&hdev->driver_input_lock);
+ hdev->io_started = false;
+
+ hdrv = hdev->driver;
+@@ -2326,8 +2322,8 @@ static int hid_device_remove(struct device *dev)
+
+ if (!hdev->io_started)
+ up(&hdev->driver_input_lock);
+-end:
+- return ret;
++
++ return 0;
+ }
+
+ static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
+--
+2.30.2
+
--- /dev/null
+From f8c3b46da7f5daea3f5fe06440fef79faf27dc2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Jun 2021 20:58:14 +0200
+Subject: HID: hid-input: add Surface Go battery quirk
+
+From: Zoltan Tamas Vajda <zoltan.tamas.vajda@gmail.com>
+
+[ Upstream commit b5539722eb832441f309642fe5102cc3536f92b8 ]
+
+The Elantech touchscreen/digitizer in the Surface Go mistakenly reports
+having a battery. This results in a low battery message every time you
+try to use the pen.
+
+This patch adds a quirk to ignore the non-existent battery and
+gets rid of the false low battery messages.
+
+Signed-off-by: Zoltan Tamas Vajda <zoltan.tamas.vajda@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-ids.h | 1 +
+ drivers/hid/hid-input.c | 2 ++
+ 2 files changed, 3 insertions(+)
+
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index b84a0a11e05b..63ca5959dc67 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -396,6 +396,7 @@
+ #define USB_DEVICE_ID_HP_X2_10_COVER 0x0755
+ #define I2C_DEVICE_ID_HP_SPECTRE_X360_15 0x2817
+ #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706
++#define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A
+
+ #define USB_VENDOR_ID_ELECOM 0x056e
+ #define USB_DEVICE_ID_ELECOM_BM084 0x0061
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index abbfa91e73e4..68c8644234a4 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -326,6 +326,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
+ HID_BATTERY_QUIRK_IGNORE },
+ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_15),
+ HID_BATTERY_QUIRK_IGNORE },
++ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN),
++ HID_BATTERY_QUIRK_IGNORE },
+ {}
+ };
+
+--
+2.30.2
+
--- /dev/null
+From 4237402977caf9f60cbaa00cffaa14514a84fc26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Jun 2021 12:10:23 -0400
+Subject: HID: sony: fix freeze when inserting ghlive ps3/wii dongles
+
+From: Pascal Giard <pascal.giard@etsmtl.ca>
+
+[ Upstream commit fb1a79a6b6e1223ddb18f12aa35e36f832da2290 ]
+
+This commit fixes a freeze on insertion of a Guitar Hero Live PS3/WiiU
+USB dongle. Indeed, with the current implementation, inserting one of
+those USB dongles will lead to a hard freeze. I apologize for not
+catching this earlier, it didn't occur on my old laptop.
+
+While the issue was isolated to memory alloc/free, I could not figure
+out why it causes a freeze. So this patch fixes this issue by
+simplifying memory allocation and usage.
+
+We remind that for the dongle to work properly, a control URB needs to
+be sent periodically. We used to alloc/free the URB each time this URB
+needed to be sent.
+
+With this patch, the memory for the URB is allocated on the probe, reused
+for as long as the dongle is plugged in, and freed once the dongle is
+unplugged.
+
+Signed-off-by: Pascal Giard <pascal.giard@etsmtl.ca>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-sony.c | 98 +++++++++++++++++++++---------------------
+ 1 file changed, 49 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
+index 8319b0ce385a..b3722c51ec78 100644
+--- a/drivers/hid/hid-sony.c
++++ b/drivers/hid/hid-sony.c
+@@ -597,9 +597,8 @@ struct sony_sc {
+ /* DS4 calibration data */
+ struct ds4_calibration_data ds4_calib_data[6];
+ /* GH Live */
++ struct urb *ghl_urb;
+ struct timer_list ghl_poke_timer;
+- struct usb_ctrlrequest *ghl_cr;
+- u8 *ghl_databuf;
+ };
+
+ static void sony_set_leds(struct sony_sc *sc);
+@@ -625,66 +624,54 @@ static inline void sony_schedule_work(struct sony_sc *sc,
+
+ static void ghl_magic_poke_cb(struct urb *urb)
+ {
+- if (urb) {
+- /* Free sc->ghl_cr and sc->ghl_databuf allocated in
+- * ghl_magic_poke()
+- */
+- kfree(urb->setup_packet);
+- kfree(urb->transfer_buffer);
+- }
++ struct sony_sc *sc = urb->context;
++
++ if (urb->status < 0)
++ hid_err(sc->hdev, "URB transfer failed : %d", urb->status);
++
++ mod_timer(&sc->ghl_poke_timer, jiffies + GHL_GUITAR_POKE_INTERVAL*HZ);
+ }
+
+ static void ghl_magic_poke(struct timer_list *t)
+ {
++ int ret;
+ struct sony_sc *sc = from_timer(sc, t, ghl_poke_timer);
+
+- int ret;
++ ret = usb_submit_urb(sc->ghl_urb, GFP_ATOMIC);
++ if (ret < 0)
++ hid_err(sc->hdev, "usb_submit_urb failed: %d", ret);
++}
++
++static int ghl_init_urb(struct sony_sc *sc, struct usb_device *usbdev)
++{
++ struct usb_ctrlrequest *cr;
++ u16 poke_size;
++ u8 *databuf;
+ unsigned int pipe;
+- struct urb *urb;
+- struct usb_device *usbdev = to_usb_device(sc->hdev->dev.parent->parent);
+- const u16 poke_size =
+- ARRAY_SIZE(ghl_ps3wiiu_magic_data);
+
++ poke_size = ARRAY_SIZE(ghl_ps3wiiu_magic_data);
+ pipe = usb_sndctrlpipe(usbdev, 0);
+
+- if (!sc->ghl_cr) {
+- sc->ghl_cr = kzalloc(sizeof(*sc->ghl_cr), GFP_ATOMIC);
+- if (!sc->ghl_cr)
+- goto resched;
+- }
+-
+- if (!sc->ghl_databuf) {
+- sc->ghl_databuf = kzalloc(poke_size, GFP_ATOMIC);
+- if (!sc->ghl_databuf)
+- goto resched;
+- }
++ cr = devm_kzalloc(&sc->hdev->dev, sizeof(*cr), GFP_ATOMIC);
++ if (cr == NULL)
++ return -ENOMEM;
+
+- urb = usb_alloc_urb(0, GFP_ATOMIC);
+- if (!urb)
+- goto resched;
++ databuf = devm_kzalloc(&sc->hdev->dev, poke_size, GFP_ATOMIC);
++ if (databuf == NULL)
++ return -ENOMEM;
+
+- sc->ghl_cr->bRequestType =
++ cr->bRequestType =
+ USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT;
+- sc->ghl_cr->bRequest = USB_REQ_SET_CONFIGURATION;
+- sc->ghl_cr->wValue = cpu_to_le16(ghl_ps3wiiu_magic_value);
+- sc->ghl_cr->wIndex = 0;
+- sc->ghl_cr->wLength = cpu_to_le16(poke_size);
+- memcpy(sc->ghl_databuf, ghl_ps3wiiu_magic_data, poke_size);
+-
++ cr->bRequest = USB_REQ_SET_CONFIGURATION;
++ cr->wValue = cpu_to_le16(ghl_ps3wiiu_magic_value);
++ cr->wIndex = 0;
++ cr->wLength = cpu_to_le16(poke_size);
++ memcpy(databuf, ghl_ps3wiiu_magic_data, poke_size);
+ usb_fill_control_urb(
+- urb, usbdev, pipe,
+- (unsigned char *) sc->ghl_cr, sc->ghl_databuf,
+- poke_size, ghl_magic_poke_cb, NULL);
+- ret = usb_submit_urb(urb, GFP_ATOMIC);
+- if (ret < 0) {
+- kfree(sc->ghl_databuf);
+- kfree(sc->ghl_cr);
+- }
+- usb_free_urb(urb);
+-
+-resched:
+- /* Reschedule for next time */
+- mod_timer(&sc->ghl_poke_timer, jiffies + GHL_GUITAR_POKE_INTERVAL*HZ);
++ sc->ghl_urb, usbdev, pipe,
++ (unsigned char *) cr, databuf, poke_size,
++ ghl_magic_poke_cb, sc);
++ return 0;
+ }
+
+ static int guitar_mapping(struct hid_device *hdev, struct hid_input *hi,
+@@ -2981,6 +2968,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
+ int ret;
+ unsigned long quirks = id->driver_data;
+ struct sony_sc *sc;
++ struct usb_device *usbdev;
+ unsigned int connect_mask = HID_CONNECT_DEFAULT;
+
+ if (!strcmp(hdev->name, "FutureMax Dance Mat"))
+@@ -3000,6 +2988,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
+ sc->quirks = quirks;
+ hid_set_drvdata(hdev, sc);
+ sc->hdev = hdev;
++ usbdev = to_usb_device(sc->hdev->dev.parent->parent);
+
+ ret = hid_parse(hdev);
+ if (ret) {
+@@ -3042,6 +3031,15 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
+ }
+
+ if (sc->quirks & GHL_GUITAR_PS3WIIU) {
++ sc->ghl_urb = usb_alloc_urb(0, GFP_ATOMIC);
++ if (!sc->ghl_urb)
++ return -ENOMEM;
++ ret = ghl_init_urb(sc, usbdev);
++ if (ret) {
++ hid_err(hdev, "error preparing URB\n");
++ return ret;
++ }
++
+ timer_setup(&sc->ghl_poke_timer, ghl_magic_poke, 0);
+ mod_timer(&sc->ghl_poke_timer,
+ jiffies + GHL_GUITAR_POKE_INTERVAL*HZ);
+@@ -3054,8 +3052,10 @@ static void sony_remove(struct hid_device *hdev)
+ {
+ struct sony_sc *sc = hid_get_drvdata(hdev);
+
+- if (sc->quirks & GHL_GUITAR_PS3WIIU)
++ if (sc->quirks & GHL_GUITAR_PS3WIIU) {
+ del_timer_sync(&sc->ghl_poke_timer);
++ usb_free_urb(sc->ghl_urb);
++ }
+
+ hid_hw_close(hdev);
+
+--
+2.30.2
+
--- /dev/null
+From 0a11d0095d715242ae8800d854fe2d9558c01359 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Jun 2021 15:29:51 +0200
+Subject: HID: surface-hid: Fix get-report request
+
+From: Maximilian Luz <luzmaximilian@gmail.com>
+
+[ Upstream commit 2b2bcc76e2ffbaff7e6ec1c62cb9c10881dc70cd ]
+
+Getting a report (e.g. feature report) from a device requires us to send
+a request indicating which report we want to retrieve and then waiting
+for the corresponding response containing that report. We already
+provide the response structure to the request call, but the request
+isn't marked as a request that expects a response. Thus the request
+returns before we receive the response and the response buffer indicates
+a zero length response due to that.
+
+This essentially means that the get-report calls are broken and will
+always indicate that a report of length zero has been read.
+
+Fix this by appropriately marking the request.
+
+Fixes: b05ff1002a5c ("HID: Add support for Surface Aggregator Module HID transport")
+Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/surface-hid/surface_hid.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hid/surface-hid/surface_hid.c b/drivers/hid/surface-hid/surface_hid.c
+index 3477b31611ae..a3a70e4f3f6c 100644
+--- a/drivers/hid/surface-hid/surface_hid.c
++++ b/drivers/hid/surface-hid/surface_hid.c
+@@ -143,7 +143,7 @@ static int ssam_hid_get_raw_report(struct surface_hid_device *shid, u8 rprt_id,
+ rqst.target_id = shid->uid.target;
+ rqst.instance_id = shid->uid.instance;
+ rqst.command_id = SURFACE_HID_CID_GET_FEATURE_REPORT;
+- rqst.flags = 0;
++ rqst.flags = SSAM_REQUEST_HAS_RESPONSE;
+ rqst.length = sizeof(rprt_id);
+ rqst.payload = &rprt_id;
+
+--
+2.30.2
+
--- /dev/null
+From 30299a92348cba0acb53fc84ddeeec41328ff3d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 09:58:09 -0700
+Subject: HID: wacom: Correct base usage for capacitive ExpressKey status bits
+
+From: Jason Gerecke <killertofu@gmail.com>
+
+[ Upstream commit 424d8237945c6c448c8b3f23885d464fb5685c97 ]
+
+The capacitive status of ExpressKeys is reported with usages beginning
+at 0x940, not 0x950. Bring our driver into alignment with reality.
+
+Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/wacom_wac.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
+index 71c886245dbf..8f16654eca09 100644
+--- a/drivers/hid/wacom_wac.h
++++ b/drivers/hid/wacom_wac.h
+@@ -122,7 +122,7 @@
+ #define WACOM_HID_WD_TOUCHONOFF (WACOM_HID_UP_WACOMDIGITIZER | 0x0454)
+ #define WACOM_HID_WD_BATTERY_LEVEL (WACOM_HID_UP_WACOMDIGITIZER | 0x043b)
+ #define WACOM_HID_WD_EXPRESSKEY00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0910)
+-#define WACOM_HID_WD_EXPRESSKEYCAP00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0950)
++#define WACOM_HID_WD_EXPRESSKEYCAP00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0940)
+ #define WACOM_HID_WD_MODE_CHANGE (WACOM_HID_UP_WACOMDIGITIZER | 0x0980)
+ #define WACOM_HID_WD_MUTE_DEVICE (WACOM_HID_UP_WACOMDIGITIZER | 0x0981)
+ #define WACOM_HID_WD_CONTROLPANEL (WACOM_HID_UP_WACOMDIGITIZER | 0x0982)
+--
+2.30.2
+
--- /dev/null
+From 6c1b8faa3987afc10ad52ead018d30d909233562 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 18:48:34 -0700
+Subject: hugetlb: address ref count racing in prep_compound_gigantic_page
+
+From: Mike Kravetz <mike.kravetz@oracle.com>
+
+[ Upstream commit 7118fc2906e2925d7edb5ed9c8a57f2a5f23b849 ]
+
+In [1], Jann Horn points out a possible race between
+prep_compound_gigantic_page and __page_cache_add_speculative. The root
+cause of the possible race is prep_compound_gigantic_page uncondittionally
+setting the ref count of pages to zero. It does this because
+prep_compound_gigantic_page is handed a 'group' of pages from an allocator
+and needs to convert that group of pages to a compound page. The ref
+count of each page in this 'group' is one as set by the allocator.
+However, the ref count of compound page tail pages must be zero.
+
+The potential race comes about when ref counted pages are returned from
+the allocator. When this happens, other mm code could also take a
+reference on the page. __page_cache_add_speculative is one such example.
+Therefore, prep_compound_gigantic_page can not just set the ref count of
+pages to zero as it does today. Doing so would lose the reference taken
+by any other code. This would lead to BUGs in code checking ref counts
+and could possibly even lead to memory corruption.
+
+There are two possible ways to address this issue.
+
+1) Make all allocators of gigantic groups of pages be able to return a
+ properly constructed compound page.
+
+2) Make prep_compound_gigantic_page be more careful when constructing a
+ compound page.
+
+This patch takes approach 2.
+
+In prep_compound_gigantic_page, use cmpxchg to only set ref count to zero
+if it is one. If the cmpxchg fails, call synchronize_rcu() in the hope
+that the extra ref count will be driopped during a rcu grace period. This
+is not a performance critical code path and the wait should be
+accceptable. If the ref count is still inflated after the grace period,
+then undo any modifications made and return an error.
+
+Currently prep_compound_gigantic_page is type void and does not return
+errors. Modify the two callers to check for and handle error returns. On
+error, the caller must free the 'group' of pages as they can not be used
+to form a gigantic page. After freeing pages, the runtime caller
+(alloc_fresh_huge_page) will retry the allocation once. Boot time
+allocations can not be retried.
+
+The routine prep_compound_page also unconditionally sets the ref count of
+compound page tail pages to zero. However, in this case the buddy
+allocator is constructing a compound page from freshly allocated pages.
+The ref count on those freshly allocated pages is already zero, so the
+set_page_count(p, 0) is unnecessary and could lead to confusion. Just
+remove it.
+
+[1] https://lore.kernel.org/linux-mm/CAG48ez23q0Jy9cuVnwAe7t_fdhMk2S7N5Hdi-GLcCeq5bsfLxw@mail.gmail.com/
+
+Link: https://lkml.kernel.org/r/20210622021423.154662-3-mike.kravetz@oracle.com
+Fixes: 58a84aa92723 ("thp: set compound tail page _count to zero")
+Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
+Reported-by: Jann Horn <jannh@google.com>
+Cc: Youquan Song <youquan.song@intel.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Jan Kara <jack@suse.cz>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: "Kirill A . Shutemov" <kirill@shutemov.name>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Muchun Song <songmuchun@bytedance.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/hugetlb.c | 72 +++++++++++++++++++++++++++++++++++++++++++------
+ mm/page_alloc.c | 1 -
+ 2 files changed, 64 insertions(+), 9 deletions(-)
+
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 65e0e8642ded..c68201078267 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -1508,9 +1508,9 @@ static void prep_new_huge_page(struct hstate *h, struct page *page, int nid)
+ spin_unlock_irq(&hugetlb_lock);
+ }
+
+-static void prep_compound_gigantic_page(struct page *page, unsigned int order)
++static bool prep_compound_gigantic_page(struct page *page, unsigned int order)
+ {
+- int i;
++ int i, j;
+ int nr_pages = 1 << order;
+ struct page *p = page + 1;
+
+@@ -1532,11 +1532,48 @@ static void prep_compound_gigantic_page(struct page *page, unsigned int order)
+ * after get_user_pages().
+ */
+ __ClearPageReserved(p);
++ /*
++ * Subtle and very unlikely
++ *
++ * Gigantic 'page allocators' such as memblock or cma will
++ * return a set of pages with each page ref counted. We need
++ * to turn this set of pages into a compound page with tail
++ * page ref counts set to zero. Code such as speculative page
++ * cache adding could take a ref on a 'to be' tail page.
++ * We need to respect any increased ref count, and only set
++ * the ref count to zero if count is currently 1. If count
++ * is not 1, we call synchronize_rcu in the hope that a rcu
++ * grace period will cause ref count to drop and then retry.
++ * If count is still inflated on retry we return an error and
++ * must discard the pages.
++ */
++ if (!page_ref_freeze(p, 1)) {
++ pr_info("HugeTLB unexpected inflated ref count on freshly allocated page\n");
++ synchronize_rcu();
++ if (!page_ref_freeze(p, 1))
++ goto out_error;
++ }
+ set_page_count(p, 0);
+ set_compound_head(p, page);
+ }
+ atomic_set(compound_mapcount_ptr(page), -1);
+ atomic_set(compound_pincount_ptr(page), 0);
++ return true;
++
++out_error:
++ /* undo tail page modifications made above */
++ p = page + 1;
++ for (j = 1; j < i; j++, p = mem_map_next(p, page, j)) {
++ clear_compound_head(p);
++ set_page_refcounted(p);
++ }
++ /* need to clear PG_reserved on remaining tail pages */
++ for (; j < nr_pages; j++, p = mem_map_next(p, page, j))
++ __ClearPageReserved(p);
++ set_compound_order(page, 0);
++ page[1].compound_nr = 0;
++ __ClearPageHead(page);
++ return false;
+ }
+
+ /*
+@@ -1656,7 +1693,9 @@ static struct page *alloc_fresh_huge_page(struct hstate *h,
+ nodemask_t *node_alloc_noretry)
+ {
+ struct page *page;
++ bool retry = false;
+
++retry:
+ if (hstate_is_gigantic(h))
+ page = alloc_gigantic_page(h, gfp_mask, nid, nmask);
+ else
+@@ -1665,8 +1704,21 @@ static struct page *alloc_fresh_huge_page(struct hstate *h,
+ if (!page)
+ return NULL;
+
+- if (hstate_is_gigantic(h))
+- prep_compound_gigantic_page(page, huge_page_order(h));
++ if (hstate_is_gigantic(h)) {
++ if (!prep_compound_gigantic_page(page, huge_page_order(h))) {
++ /*
++ * Rare failure to convert pages to compound page.
++ * Free pages and try again - ONCE!
++ */
++ free_gigantic_page(page, huge_page_order(h));
++ if (!retry) {
++ retry = true;
++ goto retry;
++ }
++ pr_warn("HugeTLB page can not be used due to unexpected inflated ref count\n");
++ return NULL;
++ }
++ }
+ prep_new_huge_page(h, page, page_to_nid(page));
+
+ return page;
+@@ -2637,10 +2689,14 @@ static void __init gather_bootmem_prealloc(void)
+
+ VM_BUG_ON(!hstate_is_gigantic(h));
+ WARN_ON(page_count(page) != 1);
+- prep_compound_gigantic_page(page, huge_page_order(h));
+- WARN_ON(PageReserved(page));
+- prep_new_huge_page(h, page, page_to_nid(page));
+- put_page(page); /* free it into the hugepage allocator */
++ if (prep_compound_gigantic_page(page, huge_page_order(h))) {
++ WARN_ON(PageReserved(page));
++ prep_new_huge_page(h, page, page_to_nid(page));
++ put_page(page); /* add to the hugepage allocator */
++ } else {
++ free_gigantic_page(page, huge_page_order(h));
++ pr_warn("HugeTLB page can not be used due to unexpected inflated ref count\n");
++ }
+
+ /*
+ * We need to restore the 'stolen' pages to totalram_pages
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index fc5beebf6988..dcd6bbd46584 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -698,7 +698,6 @@ void prep_compound_page(struct page *page, unsigned int order)
+ __SetPageHead(page);
+ for (i = 1; i < nr_pages; i++) {
+ struct page *p = page + i;
+- set_page_count(p, 0);
+ p->mapping = TAIL_MAPPING;
+ set_compound_head(p, page);
+ }
+--
+2.30.2
+
--- /dev/null
+From 8767a52e65600e156f8b4b08a1c33e8997bbe083 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 18:48:31 -0700
+Subject: hugetlb: remove prep_compound_huge_page cleanup
+
+From: Mike Kravetz <mike.kravetz@oracle.com>
+
+[ Upstream commit 48b8d744ea841b8adf8d07bfe7a2d55f22e4d179 ]
+
+Patch series "Fix prep_compound_gigantic_page ref count adjustment".
+
+These patches address the possible race between
+prep_compound_gigantic_page and __page_cache_add_speculative as described
+by Jann Horn in [1].
+
+The first patch simply removes the unnecessary/obsolete helper routine
+prep_compound_huge_page to make the actual fix a little simpler.
+
+The second patch is the actual fix and has a detailed explanation in the
+commit message.
+
+This potential issue has existed for almost 10 years and I am unaware of
+anyone actually hitting the race. I did not cc stable, but would be happy
+to squash the patches and send to stable if anyone thinks that is a good
+idea.
+
+[1] https://lore.kernel.org/linux-mm/CAG48ez23q0Jy9cuVnwAe7t_fdhMk2S7N5Hdi-GLcCeq5bsfLxw@mail.gmail.com/
+
+This patch (of 2):
+
+I could not think of a reliable way to recreate the issue for testing.
+Rather, I 'simulated errors' to exercise all the error paths.
+
+The routine prep_compound_huge_page is a simple wrapper to call either
+prep_compound_gigantic_page or prep_compound_page. However, it is only
+called from gather_bootmem_prealloc which only processes gigantic pages.
+Eliminate the routine and call prep_compound_gigantic_page directly.
+
+Link: https://lkml.kernel.org/r/20210622021423.154662-1-mike.kravetz@oracle.com
+Link: https://lkml.kernel.org/r/20210622021423.154662-2-mike.kravetz@oracle.com
+Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Jan Kara <jack@suse.cz>
+Cc: Jann Horn <jannh@google.com>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: "Kirill A . Shutemov" <kirill@shutemov.name>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Youquan Song <youquan.song@intel.com>
+Cc: Muchun Song <songmuchun@bytedance.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/hugetlb.c | 29 ++++++++++-------------------
+ 1 file changed, 10 insertions(+), 19 deletions(-)
+
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 5ba5a0da6d57..65e0e8642ded 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -1318,8 +1318,6 @@ static struct page *alloc_gigantic_page(struct hstate *h, gfp_t gfp_mask,
+ return alloc_contig_pages(nr_pages, gfp_mask, nid, nodemask);
+ }
+
+-static void prep_new_huge_page(struct hstate *h, struct page *page, int nid);
+-static void prep_compound_gigantic_page(struct page *page, unsigned int order);
+ #else /* !CONFIG_CONTIG_ALLOC */
+ static struct page *alloc_gigantic_page(struct hstate *h, gfp_t gfp_mask,
+ int nid, nodemask_t *nodemask)
+@@ -2625,16 +2623,10 @@ found:
+ return 1;
+ }
+
+-static void __init prep_compound_huge_page(struct page *page,
+- unsigned int order)
+-{
+- if (unlikely(order > (MAX_ORDER - 1)))
+- prep_compound_gigantic_page(page, order);
+- else
+- prep_compound_page(page, order);
+-}
+-
+-/* Put bootmem huge pages into the standard lists after mem_map is up */
++/*
++ * Put bootmem huge pages into the standard lists after mem_map is up.
++ * Note: This only applies to gigantic (order > MAX_ORDER) pages.
++ */
+ static void __init gather_bootmem_prealloc(void)
+ {
+ struct huge_bootmem_page *m;
+@@ -2643,20 +2635,19 @@ static void __init gather_bootmem_prealloc(void)
+ struct page *page = virt_to_page(m);
+ struct hstate *h = m->hstate;
+
++ VM_BUG_ON(!hstate_is_gigantic(h));
+ WARN_ON(page_count(page) != 1);
+- prep_compound_huge_page(page, huge_page_order(h));
++ prep_compound_gigantic_page(page, huge_page_order(h));
+ WARN_ON(PageReserved(page));
+ prep_new_huge_page(h, page, page_to_nid(page));
+ put_page(page); /* free it into the hugepage allocator */
+
+ /*
+- * If we had gigantic hugepages allocated at boot time, we need
+- * to restore the 'stolen' pages to totalram_pages in order to
+- * fix confusing memory reports from free(1) and another
+- * side-effects, like CommitLimit going negative.
++ * We need to restore the 'stolen' pages to totalram_pages
++ * in order to fix confusing memory reports from free(1) and
++ * other side-effects, like CommitLimit going negative.
+ */
+- if (hstate_is_gigantic(h))
+- adjust_managed_page_count(page, pages_per_huge_page(h));
++ adjust_managed_page_count(page, pages_per_huge_page(h));
+ cond_resched();
+ }
+ }
+--
+2.30.2
+
--- /dev/null
+From f57414bef96d20f4f1a6a879012177aea2c3479b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 May 2021 15:01:16 +0800
+Subject: hv_utils: Fix passing zero to 'PTR_ERR' warning
+
+From: YueHaibing <yuehaibing@huawei.com>
+
+[ Upstream commit c6a8625fa4c6b0a97860d053271660ccedc3d1b3 ]
+
+Sparse warn this:
+
+drivers/hv/hv_util.c:753 hv_timesync_init() warn:
+ passing zero to 'PTR_ERR'
+
+Use PTR_ERR_OR_ZERO instead of PTR_ERR to fix this.
+
+Signed-off-by: YueHaibing <yuehaibing@huawei.com>
+Link: https://lore.kernel.org/r/20210514070116.16800-1-yuehaibing@huawei.com
+[ wei: change %ld to %d ]
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/hv_util.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
+index e4aefeb330da..136576cba26f 100644
+--- a/drivers/hv/hv_util.c
++++ b/drivers/hv/hv_util.c
+@@ -750,8 +750,8 @@ static int hv_timesync_init(struct hv_util_service *srv)
+ */
+ hv_ptp_clock = ptp_clock_register(&ptp_hyperv_info, NULL);
+ if (IS_ERR_OR_NULL(hv_ptp_clock)) {
+- pr_err("cannot register PTP clock: %ld\n",
+- PTR_ERR(hv_ptp_clock));
++ pr_err("cannot register PTP clock: %d\n",
++ PTR_ERR_OR_ZERO(hv_ptp_clock));
+ hv_ptp_clock = NULL;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 715986614427989e75b45c0381ea3f68a47b22c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 May 2021 09:44:50 -0700
+Subject: hwmon: (lm70) Revert "hwmon: (lm70) Add support for ACPI"
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit ac61c8aae446b9c0fe18981fe721d4a43e283ad6 ]
+
+This reverts commit b58bd4c6dfe709646ed9efcbba2a70643f9bc873.
+
+None of the ACPI IDs introduced with the reverted patch is a valid ACPI
+device ID. Any ACPI users of this driver are advised to use PRP0001 and
+a devicetree-compatible device identification.
+
+Fixes: b58bd4c6dfe7 ("hwmon: (lm70) Add support for ACPI")
+Cc: Andrej Picej <andpicej@gmail.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/lm70.c | 26 +-------------------------
+ 1 file changed, 1 insertion(+), 25 deletions(-)
+
+diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c
+index 40eab3349904..6b884ea00987 100644
+--- a/drivers/hwmon/lm70.c
++++ b/drivers/hwmon/lm70.c
+@@ -22,10 +22,10 @@
+ #include <linux/hwmon.h>
+ #include <linux/mutex.h>
+ #include <linux/mod_devicetable.h>
++#include <linux/of.h>
+ #include <linux/property.h>
+ #include <linux/spi/spi.h>
+ #include <linux/slab.h>
+-#include <linux/acpi.h>
+
+ #define DRVNAME "lm70"
+
+@@ -148,29 +148,6 @@ static const struct of_device_id lm70_of_ids[] = {
+ MODULE_DEVICE_TABLE(of, lm70_of_ids);
+ #endif
+
+-#ifdef CONFIG_ACPI
+-static const struct acpi_device_id lm70_acpi_ids[] = {
+- {
+- .id = "LM000070",
+- .driver_data = LM70_CHIP_LM70,
+- },
+- {
+- .id = "TMP00121",
+- .driver_data = LM70_CHIP_TMP121,
+- },
+- {
+- .id = "LM000071",
+- .driver_data = LM70_CHIP_LM71,
+- },
+- {
+- .id = "LM000074",
+- .driver_data = LM70_CHIP_LM74,
+- },
+- {},
+-};
+-MODULE_DEVICE_TABLE(acpi, lm70_acpi_ids);
+-#endif
+-
+ static int lm70_probe(struct spi_device *spi)
+ {
+ struct device *hwmon_dev;
+@@ -217,7 +194,6 @@ static struct spi_driver lm70_driver = {
+ .driver = {
+ .name = "lm70",
+ .of_match_table = of_match_ptr(lm70_of_ids),
+- .acpi_match_table = ACPI_PTR(lm70_acpi_ids),
+ },
+ .id_table = lm70_ids,
+ .probe = lm70_probe,
+--
+2.30.2
+
--- /dev/null
+From 56496a2062cd2b1ce66ee7c95c1f0878cf9a9fb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 May 2021 09:50:25 -0700
+Subject: hwmon: (max31722) Remove non-standard ACPI device IDs
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 97387c2f06bcfd79d04a848d35517b32ee6dca7c ]
+
+Valid Maxim Integrated ACPI device IDs would start with MXIM,
+not with MAX1. On top of that, ACPI device IDs reflecting chip names
+are almost always invalid.
+
+Remove the invalid ACPI IDs.
+
+Fixes: 04e1e70afec6 ("hwmon: (max31722) Add support for MAX31722/MAX31723 temperature sensors")
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/max31722.c | 9 ---------
+ 1 file changed, 9 deletions(-)
+
+diff --git a/drivers/hwmon/max31722.c b/drivers/hwmon/max31722.c
+index 062eceb7be0d..613338cbcb17 100644
+--- a/drivers/hwmon/max31722.c
++++ b/drivers/hwmon/max31722.c
+@@ -6,7 +6,6 @@
+ * Copyright (c) 2016, Intel Corporation.
+ */
+
+-#include <linux/acpi.h>
+ #include <linux/hwmon.h>
+ #include <linux/hwmon-sysfs.h>
+ #include <linux/kernel.h>
+@@ -133,20 +132,12 @@ static const struct spi_device_id max31722_spi_id[] = {
+ {"max31723", 0},
+ {}
+ };
+-
+-static const struct acpi_device_id __maybe_unused max31722_acpi_id[] = {
+- {"MAX31722", 0},
+- {"MAX31723", 0},
+- {}
+-};
+-
+ MODULE_DEVICE_TABLE(spi, max31722_spi_id);
+
+ static struct spi_driver max31722_driver = {
+ .driver = {
+ .name = "max31722",
+ .pm = &max31722_pm_ops,
+- .acpi_match_table = ACPI_PTR(max31722_acpi_id),
+ },
+ .probe = max31722_probe,
+ .remove = max31722_remove,
+--
+2.30.2
+
--- /dev/null
+From 17dfddce18ac7c34ae1e6c18162cd3837997490a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 May 2021 08:40:16 -0700
+Subject: hwmon: (max31790) Fix fan speed reporting for fan7..12
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit cbbf244f0515af3472084f22b6213121b4a63835 ]
+
+Fans 7..12 do not have their own set of configuration registers.
+So far the code ignored that and read beyond the end of the configuration
+register range to get the tachometer period. This resulted in more or less
+random fan speed values for those fans.
+
+The datasheet is quite vague when it comes to defining the tachometer
+period for fans 7..12. Experiments confirm that the period is the same
+for both fans associated with a given set of configuration registers.
+
+Fixes: 54187ff9d766 ("hwmon: (max31790) Convert to use new hwmon registration API")
+Fixes: 195a4b4298a7 ("hwmon: Driver for Maxim MAX31790")
+Cc: Jan Kundrát <jan.kundrat@cesnet.cz>
+Reviewed-by: Jan Kundrát <jan.kundrat@cesnet.cz>
+Cc: Václav Kubernát <kubernat@cesnet.cz>
+Reviewed-by: Jan Kundrát <jan.kundrat@cesnet.cz>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20210526154022.3223012-2-linux@roeck-us.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/max31790.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hwmon/max31790.c b/drivers/hwmon/max31790.c
+index 76aa96f5b984..67677c437768 100644
+--- a/drivers/hwmon/max31790.c
++++ b/drivers/hwmon/max31790.c
+@@ -171,7 +171,7 @@ static int max31790_read_fan(struct device *dev, u32 attr, int channel,
+
+ switch (attr) {
+ case hwmon_fan_input:
+- sr = get_tach_period(data->fan_dynamics[channel]);
++ sr = get_tach_period(data->fan_dynamics[channel % NR_CHANNEL]);
+ rpm = RPM_FROM_REG(data->tach[channel], sr);
+ *val = rpm;
+ return 0;
+--
+2.30.2
+
--- /dev/null
+From 7f7faef72f60e71e499a4ba3dc0da7ba7078104f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 May 2021 08:40:18 -0700
+Subject: hwmon: (max31790) Fix pwmX_enable attributes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 148c847c9e5a54b99850617bf9c143af9a344f92 ]
+
+pwmX_enable supports three possible values:
+
+0: Fan control disabled. Duty cycle is fixed to 0%
+1: Fan control enabled, pwm mode. Duty cycle is determined by
+ values written into Target Duty Cycle registers.
+2: Fan control enabled, rpm mode
+ Duty cycle is adjusted such that fan speed matches
+ the values in Target Count registers
+
+The current code does not do this; instead, it mixes pwm control
+configuration with fan speed monitoring configuration. Worse, it
+reports that pwm control would be disabled (pwmX_enable==0) when
+it is in fact enabled in pwm mode. Part of the problem may be that
+the chip sets the "TACH input enable" bit on its own whenever the
+mode bit is set to RPM mode, but that doesn't mean that "TACH input
+enable" accurately reflects the pwm mode.
+
+Fix it up and only handle pwm control with the pwmX_enable attributes.
+In the documentation, clarify that disabling pwm control (pwmX_enable=0)
+sets the pwm duty cycle to 0%. In the code, explain why TACH_INPUT_EN
+is set together with RPM_MODE.
+
+While at it, only update the configuration register if the configuration
+has changed, and only update the cached configuration if updating the
+chip configuration was successful.
+
+Cc: Jan Kundrát <jan.kundrat@cesnet.cz>
+Cc: Václav Kubernát <kubernat@cesnet.cz>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Tested-by: Václav Kubernát <kubernat@cesnet.cz>
+Reviewed-by: Jan Kundrát <jan.kundrat@cesnet.cz>
+Link: https://lore.kernel.org/r/20210526154022.3223012-4-linux@roeck-us.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/hwmon/max31790.rst | 2 +-
+ drivers/hwmon/max31790.c | 41 ++++++++++++++++++++------------
+ 2 files changed, 27 insertions(+), 16 deletions(-)
+
+diff --git a/Documentation/hwmon/max31790.rst b/Documentation/hwmon/max31790.rst
+index 54ff0f49e28f..7b097c3b9b90 100644
+--- a/Documentation/hwmon/max31790.rst
++++ b/Documentation/hwmon/max31790.rst
+@@ -38,7 +38,7 @@ Sysfs entries
+ fan[1-12]_input RO fan tachometer speed in RPM
+ fan[1-12]_fault RO fan experienced fault
+ fan[1-6]_target RW desired fan speed in RPM
+-pwm[1-6]_enable RW regulator mode, 0=disabled, 1=manual mode, 2=rpm mode
++pwm[1-6]_enable RW regulator mode, 0=disabled (duty cycle=0%), 1=manual mode, 2=rpm mode
+ pwm[1-6] RW read: current pwm duty cycle,
+ write: target pwm duty cycle (0-255)
+ ================== === =======================================================
+diff --git a/drivers/hwmon/max31790.c b/drivers/hwmon/max31790.c
+index 8ad7a45bfe68..76aa96f5b984 100644
+--- a/drivers/hwmon/max31790.c
++++ b/drivers/hwmon/max31790.c
+@@ -27,6 +27,7 @@
+
+ /* Fan Config register bits */
+ #define MAX31790_FAN_CFG_RPM_MODE 0x80
++#define MAX31790_FAN_CFG_CTRL_MON 0x10
+ #define MAX31790_FAN_CFG_TACH_INPUT_EN 0x08
+ #define MAX31790_FAN_CFG_TACH_INPUT 0x01
+
+@@ -271,12 +272,12 @@ static int max31790_read_pwm(struct device *dev, u32 attr, int channel,
+ *val = data->pwm[channel] >> 8;
+ return 0;
+ case hwmon_pwm_enable:
+- if (fan_config & MAX31790_FAN_CFG_RPM_MODE)
++ if (fan_config & MAX31790_FAN_CFG_CTRL_MON)
++ *val = 0;
++ else if (fan_config & MAX31790_FAN_CFG_RPM_MODE)
+ *val = 2;
+- else if (fan_config & MAX31790_FAN_CFG_TACH_INPUT_EN)
+- *val = 1;
+ else
+- *val = 0;
++ *val = 1;
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+@@ -307,23 +308,33 @@ static int max31790_write_pwm(struct device *dev, u32 attr, int channel,
+ case hwmon_pwm_enable:
+ fan_config = data->fan_config[channel];
+ if (val == 0) {
+- fan_config &= ~(MAX31790_FAN_CFG_TACH_INPUT_EN |
+- MAX31790_FAN_CFG_RPM_MODE);
++ fan_config |= MAX31790_FAN_CFG_CTRL_MON;
++ /*
++ * Disable RPM mode; otherwise disabling fan speed
++ * monitoring is not possible.
++ */
++ fan_config &= ~MAX31790_FAN_CFG_RPM_MODE;
+ } else if (val == 1) {
+- fan_config = (fan_config |
+- MAX31790_FAN_CFG_TACH_INPUT_EN) &
+- ~MAX31790_FAN_CFG_RPM_MODE;
++ fan_config &= ~(MAX31790_FAN_CFG_CTRL_MON | MAX31790_FAN_CFG_RPM_MODE);
+ } else if (val == 2) {
+- fan_config |= MAX31790_FAN_CFG_TACH_INPUT_EN |
+- MAX31790_FAN_CFG_RPM_MODE;
++ fan_config &= ~MAX31790_FAN_CFG_CTRL_MON;
++ /*
++ * The chip sets MAX31790_FAN_CFG_TACH_INPUT_EN on its
++ * own if MAX31790_FAN_CFG_RPM_MODE is set.
++ * Do it here as well to reflect the actual register
++ * value in the cache.
++ */
++ fan_config |= (MAX31790_FAN_CFG_RPM_MODE | MAX31790_FAN_CFG_TACH_INPUT_EN);
+ } else {
+ err = -EINVAL;
+ break;
+ }
+- data->fan_config[channel] = fan_config;
+- err = i2c_smbus_write_byte_data(client,
+- MAX31790_REG_FAN_CONFIG(channel),
+- fan_config);
++ if (fan_config != data->fan_config[channel]) {
++ err = i2c_smbus_write_byte_data(client, MAX31790_REG_FAN_CONFIG(channel),
++ fan_config);
++ if (!err)
++ data->fan_config[channel] = fan_config;
++ }
+ break;
+ default:
+ err = -EOPNOTSUPP;
+--
+2.30.2
+
--- /dev/null
+From a711a56321f125cca360392e5dd697b0444104dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 May 2021 08:40:17 -0700
+Subject: hwmon: (max31790) Report correct current pwm duty cycles
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 897f6339893b741a5d68ae8e2475df65946041c2 ]
+
+The MAX31790 has two sets of registers for pwm duty cycles, one to request
+a duty cycle and one to read the actual current duty cycle. Both do not
+have to be the same.
+
+When reporting the pwm duty cycle to the user, the actual pwm duty cycle
+from pwm duty cycle registers needs to be reported. When setting it, the
+pwm target duty cycle needs to be written. Since we don't know the actual
+pwm duty cycle after a target pwm duty cycle has been written, set the
+valid flag to false to indicate that actual pwm duty cycle should be read
+from the chip instead of using cached values.
+
+Cc: Jan Kundrát <jan.kundrat@cesnet.cz>
+Cc: Václav Kubernát <kubernat@cesnet.cz>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Tested-by: Václav Kubernát <kubernat@ceesnet.cz>
+Reviewed-by: Jan Kundrát <jan.kundrat@cesnet.cz>
+Link: https://lore.kernel.org/r/20210526154022.3223012-3-linux@roeck-us.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/hwmon/max31790.rst | 3 ++-
+ drivers/hwmon/max31790.c | 6 +++---
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/Documentation/hwmon/max31790.rst b/Documentation/hwmon/max31790.rst
+index f301385d8cef..54ff0f49e28f 100644
+--- a/Documentation/hwmon/max31790.rst
++++ b/Documentation/hwmon/max31790.rst
+@@ -39,5 +39,6 @@ fan[1-12]_input RO fan tachometer speed in RPM
+ fan[1-12]_fault RO fan experienced fault
+ fan[1-6]_target RW desired fan speed in RPM
+ pwm[1-6]_enable RW regulator mode, 0=disabled, 1=manual mode, 2=rpm mode
+-pwm[1-6] RW fan target duty cycle (0-255)
++pwm[1-6] RW read: current pwm duty cycle,
++ write: target pwm duty cycle (0-255)
+ ================== === =======================================================
+diff --git a/drivers/hwmon/max31790.c b/drivers/hwmon/max31790.c
+index 86e6c71db685..8ad7a45bfe68 100644
+--- a/drivers/hwmon/max31790.c
++++ b/drivers/hwmon/max31790.c
+@@ -104,7 +104,7 @@ static struct max31790_data *max31790_update_device(struct device *dev)
+ data->tach[NR_CHANNEL + i] = rv;
+ } else {
+ rv = i2c_smbus_read_word_swapped(client,
+- MAX31790_REG_PWMOUT(i));
++ MAX31790_REG_PWM_DUTY_CYCLE(i));
+ if (rv < 0)
+ goto abort;
+ data->pwm[i] = rv;
+@@ -299,10 +299,10 @@ static int max31790_write_pwm(struct device *dev, u32 attr, int channel,
+ err = -EINVAL;
+ break;
+ }
+- data->pwm[channel] = val << 8;
++ data->valid = false;
+ err = i2c_smbus_write_word_swapped(client,
+ MAX31790_REG_PWMOUT(channel),
+- data->pwm[channel]);
++ val << 8);
+ break;
+ case hwmon_pwm_enable:
+ fan_config = data->fan_config[channel];
+--
+2.30.2
+
--- /dev/null
+From 263a3509f9914a02c158f8e5dd947d0166dd9f55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jun 2021 15:42:18 +1200
+Subject: hwmon: (pmbus/bpa-rs600) Handle Vin readings >= 256V
+
+From: Chris Packham <chris.packham@alliedtelesis.co.nz>
+
+[ Upstream commit 6e9ef8ca687e69e9d4cc89033d98e06350b0f3e0 ]
+
+The BPA-RS600 doesn't follow the PMBus spec for linear data.
+Specifically it treats the mantissa as an unsigned 11-bit value instead
+of a two's complement 11-bit value. At this point it's unclear whether
+this only affects Vin or if Pin/Pout1 are affected as well. Erring on
+the side of caution only Vin is dealt with here.
+
+Fixes: 15b2703e5e02 ("hwmon: (pmbus) Add driver for BluTek BPA-RS600")
+Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
+Link: https://lore.kernel.org/r/20210616034218.25821-1-chris.packham@alliedtelesis.co.nz
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/pmbus/bpa-rs600.c | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/drivers/hwmon/pmbus/bpa-rs600.c b/drivers/hwmon/pmbus/bpa-rs600.c
+index f6558ee9dec3..2be69fedfa36 100644
+--- a/drivers/hwmon/pmbus/bpa-rs600.c
++++ b/drivers/hwmon/pmbus/bpa-rs600.c
+@@ -46,6 +46,32 @@ static int bpa_rs600_read_byte_data(struct i2c_client *client, int page, int reg
+ return ret;
+ }
+
++/*
++ * The BPA-RS600 violates the PMBus spec. Specifically it treats the
++ * mantissa as unsigned. Deal with this here to allow the PMBus core
++ * to work with correctly encoded data.
++ */
++static int bpa_rs600_read_vin(struct i2c_client *client)
++{
++ int ret, exponent, mantissa;
++
++ ret = pmbus_read_word_data(client, 0, 0xff, PMBUS_READ_VIN);
++ if (ret < 0)
++ return ret;
++
++ if (ret & BIT(10)) {
++ exponent = ret >> 11;
++ mantissa = ret & 0x7ff;
++
++ exponent++;
++ mantissa >>= 1;
++
++ ret = (exponent << 11) | mantissa;
++ }
++
++ return ret;
++}
++
+ static int bpa_rs600_read_word_data(struct i2c_client *client, int page, int phase, int reg)
+ {
+ int ret;
+@@ -85,6 +111,9 @@ static int bpa_rs600_read_word_data(struct i2c_client *client, int page, int pha
+ /* These commands return data but it is invalid/un-documented */
+ ret = -ENXIO;
+ break;
++ case PMBUS_READ_VIN:
++ ret = bpa_rs600_read_vin(client);
++ break;
+ default:
+ if (reg >= PMBUS_VIRT_BASE)
+ ret = -ENXIO;
+--
+2.30.2
+
--- /dev/null
+From 8ba6c78db3b5c779925772f71688628d803ac835 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 20:29:14 +0200
+Subject: hwrng: exynos - Fix runtime PM imbalance on error
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Łukasz Stelmach <l.stelmach@samsung.com>
+
+[ Upstream commit 0cdbabf8bb7a6147f5adf37dbc251e92a1bbc2c7 ]
+
+pm_runtime_resume_and_get() wraps around pm_runtime_get_sync() and
+decrements the runtime PM usage counter in case the latter function
+fails and keeps the counter balanced.
+
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/hw_random/exynos-trng.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/char/hw_random/exynos-trng.c b/drivers/char/hw_random/exynos-trng.c
+index 8e1fe3f8dd2d..c8db62bc5ff7 100644
+--- a/drivers/char/hw_random/exynos-trng.c
++++ b/drivers/char/hw_random/exynos-trng.c
+@@ -132,7 +132,7 @@ static int exynos_trng_probe(struct platform_device *pdev)
+ return PTR_ERR(trng->mem);
+
+ pm_runtime_enable(&pdev->dev);
+- ret = pm_runtime_get_sync(&pdev->dev);
++ ret = pm_runtime_resume_and_get(&pdev->dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Could not get runtime PM.\n");
+ goto err_pm_get;
+@@ -165,7 +165,7 @@ err_register:
+ clk_disable_unprepare(trng->clk);
+
+ err_clock:
+- pm_runtime_put_sync(&pdev->dev);
++ pm_runtime_put_noidle(&pdev->dev);
+
+ err_pm_get:
+ pm_runtime_disable(&pdev->dev);
+--
+2.30.2
+
--- /dev/null
+From 1df5ad62286cb1a2cb8b180a29a62f70e2fb49f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jul 2021 15:27:24 +1200
+Subject: i2c: mpc: Restore reread of I2C status register
+
+From: Chris Packham <chris.packham@alliedtelesis.co.nz>
+
+[ Upstream commit 763778cd79267dadf0ec7e044caf7563df0ab597 ]
+
+Prior to commit 1538d82f4647 ("i2c: mpc: Interrupt driven transfer") the
+old interrupt handler would reread MPC_I2C_SR after checking the CSR_MIF
+bit. When the driver was re-written this was removed as it seemed
+unnecessary. However as it turns out this is necessary for i2c devices
+which do clock stretching otherwise we end up thinking the bus is still
+busy when processing the interrupt.
+
+Fixes: 1538d82f4647 ("i2c: mpc: Interrupt driven transfer")
+Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-mpc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
+index dcca9c2396db..6d5014ebaab5 100644
+--- a/drivers/i2c/busses/i2c-mpc.c
++++ b/drivers/i2c/busses/i2c-mpc.c
+@@ -635,6 +635,8 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
+
+ status = readb(i2c->base + MPC_I2C_SR);
+ if (status & CSR_MIF) {
++ /* Read again to allow register to stabilise */
++ status = readb(i2c->base + MPC_I2C_SR);
+ writeb(0, i2c->base + MPC_I2C_SR);
+ mpc_i2c_do_intr(i2c, status);
+ return IRQ_HANDLED;
+--
+2.30.2
+
--- /dev/null
+From 06566c8ce13d4f3555522153e6dc79ed693b2a50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Mar 2021 11:12:54 +0000
+Subject: i40e: Fix autoneg disabling for non-10GBaseT links
+
+From: Mateusz Palczewski <mateusz.palczewski@intel.com>
+
+[ Upstream commit 9262793e59f0423437166a879a73d056b1fe6f9a ]
+
+Disabling autonegotiation was allowed only for 10GBaseT PHY.
+The condition was changed to check if link media type is BaseT.
+
+Fixes: 3ce12ee9d8f9 ("i40e: Fix order of checks when enabling/disabling autoneg in ethtool")
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Reviewed-by: Karen Sornek <karen.sornek@intel.com>
+Signed-off-by: Dawid Lukwinski <dawid.lukwinski@intel.com>
+Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
+Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+index ccd5b9486ea9..3e822bad4851 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+@@ -1262,8 +1262,7 @@ static int i40e_set_link_ksettings(struct net_device *netdev,
+ if (ethtool_link_ksettings_test_link_mode(&safe_ks,
+ supported,
+ Autoneg) &&
+- hw->phy.link_info.phy_type !=
+- I40E_PHY_TYPE_10GBASE_T) {
++ hw->phy.media_type != I40E_MEDIA_TYPE_BASET) {
+ netdev_info(netdev, "Autoneg cannot be disabled on this phy\n");
+ err = -EINVAL;
+ goto done;
+--
+2.30.2
+
--- /dev/null
+From 1e7a60d3da85865f5565fffbd37ee6bf56a43437 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Feb 2021 19:50:58 +0800
+Subject: i40e: Fix error handling in i40e_vsi_open
+
+From: Dinghao Liu <dinghao.liu@zju.edu.cn>
+
+[ Upstream commit 9c04cfcd4aad232e36306cdc5c74cd9fc9148a7e ]
+
+When vsi->type == I40E_VSI_FDIR, we have caught the return value of
+i40e_vsi_request_irq() but without further handling. Check and execute
+memory clean on failure just like the other i40e_vsi_request_irq().
+
+Fixes: 8a9eb7d3cbcab ("i40e: rework fdir setup and teardown")
+Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
+Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index 704e474879c5..526fa0a791ea 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -8703,6 +8703,8 @@ int i40e_vsi_open(struct i40e_vsi *vsi)
+ dev_driver_string(&pf->pdev->dev),
+ dev_name(&pf->pdev->dev));
+ err = i40e_vsi_request_irq(vsi, int_name);
++ if (err)
++ goto err_setup_rx;
+
+ } else {
+ err = -EINVAL;
+--
+2.30.2
+
--- /dev/null
+From b0495268821126a5070e2977bc4d54c3dc99485c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Jun 2021 12:01:41 +0200
+Subject: i40e: Fix missing rtnl locking when setting up pf switch
+
+From: Jan Sokolowski <jan.sokolowski@intel.com>
+
+[ Upstream commit 956e759d5f8e0859e86b951a8779c60af633aafd ]
+
+A recent change that made i40e use new udp_tunnel infrastructure
+uses a method that expects to be called under rtnl lock.
+
+However, not all codepaths do the lock prior to calling
+i40e_setup_pf_switch.
+
+Fix that by adding additional rtnl locking and unlocking.
+
+Fixes: 40a98cb6f01f ("i40e: convert to new udp_tunnel infrastructure")
+Signed-off-by: Jan Sokolowski <jan.sokolowski@intel.com>
+Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
+Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_main.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index 526fa0a791ea..f9fe500d4ec4 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -32,7 +32,7 @@ static void i40e_vsi_reinit_locked(struct i40e_vsi *vsi);
+ static void i40e_handle_reset_warning(struct i40e_pf *pf, bool lock_acquired);
+ static int i40e_add_vsi(struct i40e_vsi *vsi);
+ static int i40e_add_veb(struct i40e_veb *veb, struct i40e_vsi *vsi);
+-static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit);
++static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit, bool lock_acquired);
+ static int i40e_setup_misc_vector(struct i40e_pf *pf);
+ static void i40e_determine_queue_usage(struct i40e_pf *pf);
+ static int i40e_setup_pf_filter_control(struct i40e_pf *pf);
+@@ -10571,7 +10571,7 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
+ #endif /* CONFIG_I40E_DCB */
+ if (!lock_acquired)
+ rtnl_lock();
+- ret = i40e_setup_pf_switch(pf, reinit);
++ ret = i40e_setup_pf_switch(pf, reinit, true);
+ if (ret)
+ goto end_unlock;
+
+@@ -14629,10 +14629,11 @@ int i40e_fetch_switch_configuration(struct i40e_pf *pf, bool printconfig)
+ * i40e_setup_pf_switch - Setup the HW switch on startup or after reset
+ * @pf: board private structure
+ * @reinit: if the Main VSI needs to re-initialized.
++ * @lock_acquired: indicates whether or not the lock has been acquired
+ *
+ * Returns 0 on success, negative value on failure
+ **/
+-static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit)
++static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit, bool lock_acquired)
+ {
+ u16 flags = 0;
+ int ret;
+@@ -14734,9 +14735,15 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit)
+
+ i40e_ptp_init(pf);
+
++ if (!lock_acquired)
++ rtnl_lock();
++
+ /* repopulate tunnel port filters */
+ udp_tunnel_nic_reset_ntf(pf->vsi[pf->lan_vsi]->netdev);
+
++ if (!lock_acquired)
++ rtnl_unlock();
++
+ return ret;
+ }
+
+@@ -15530,7 +15537,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ pf->flags |= I40E_FLAG_VEB_MODE_ENABLED;
+ }
+ #endif
+- err = i40e_setup_pf_switch(pf, false);
++ err = i40e_setup_pf_switch(pf, false, false);
+ if (err) {
+ dev_info(&pdev->dev, "setup_pf_switch failed: %d\n", err);
+ goto err_vsis;
+--
+2.30.2
+
--- /dev/null
+From a7b0145bbf4b346853b95266653c70b88a77e0f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jun 2021 19:33:41 -0700
+Subject: ia64: mca_drv: fix incorrect array size calculation
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit c5f320ff8a79501bb59338278336ec43acb9d7e2 ]
+
+gcc points out a mistake in the mca driver that goes back to before the
+git history:
+
+arch/ia64/kernel/mca_drv.c: In function 'init_record_index_pools':
+arch/ia64/kernel/mca_drv.c:346:54: error: expression does not compute the number of elements in this array; element typ
+e is 'int', not 'size_t' {aka 'long unsigned int'} [-Werror=sizeof-array-div]
+ 346 | for (i = 1; i < sizeof sal_log_sect_min_sizes/sizeof(size_t); i++)
+ | ^
+
+This is the same as sizeof(size_t), which is two shorter than the actual
+array. Use the ARRAY_SIZE() macro to get the correct calculation instead.
+
+Link: https://lkml.kernel.org/r/20210514214123.875971-1-arnd@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Cc: Masahiro Yamada <masahiroy@kernel.org>
+Cc: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/ia64/kernel/mca_drv.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
+index 36a69b4e6169..5bfc79be4cef 100644
+--- a/arch/ia64/kernel/mca_drv.c
++++ b/arch/ia64/kernel/mca_drv.c
+@@ -343,7 +343,7 @@ init_record_index_pools(void)
+
+ /* - 2 - */
+ sect_min_size = sal_log_sect_min_sizes[0];
+- for (i = 1; i < sizeof sal_log_sect_min_sizes/sizeof(size_t); i++)
++ for (i = 1; i < ARRAY_SIZE(sal_log_sect_min_sizes); i++)
+ if (sect_min_size > sal_log_sect_min_sizes[i])
+ sect_min_size = sal_log_sect_min_sizes[i];
+
+--
+2.30.2
+
--- /dev/null
+From 680506afa8d0bdf5b8a2dd39f4fe5be9c96dbd98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Jun 2021 13:27:07 +0300
+Subject: IB/cm: Improve the calling of cm_init_av_for_lap and
+ cm_init_av_by_path
+
+From: Mark Zhang <markzhang@nvidia.com>
+
+[ Upstream commit 7345201c39633fc4c82dae7315da7154efaf2459 ]
+
+The cm_init_av_for_lap() and cm_init_av_by_path() function calls have the
+following issues:
+
+1. Both of them might sleep and should not be called under spinlock.
+2. The access of cm_id_priv->av should be under cm_id_priv->lock, which
+ means it can't be initialized directly.
+
+This patch splits the calling of 2 functions into two parts: first one
+initializes an AV outside of the spinlock, the second one copies AV to
+cm_id_priv->av under spinlock.
+
+Fixes: e1444b5a163e ("IB/cm: Fix automatic path migration support")
+Link: https://lore.kernel.org/r/038fb8ad932869b4548b0c7708cab7f76af06f18.1622629024.git.leonro@nvidia.com
+Signed-off-by: Mark Zhang <markzhang@nvidia.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cm.c | 105 +++++++++++++++++++----------------
+ 1 file changed, 58 insertions(+), 47 deletions(-)
+
+diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
+index 162261fd16d6..81d832646d27 100644
+--- a/drivers/infiniband/core/cm.c
++++ b/drivers/infiniband/core/cm.c
+@@ -439,30 +439,12 @@ static void cm_set_private_data(struct cm_id_private *cm_id_priv,
+ cm_id_priv->private_data_len = private_data_len;
+ }
+
+-static int cm_init_av_for_lap(struct cm_port *port, struct ib_wc *wc,
+- struct ib_grh *grh, struct cm_av *av)
++static void cm_init_av_for_lap(struct cm_port *port, struct ib_wc *wc,
++ struct rdma_ah_attr *ah_attr, struct cm_av *av)
+ {
+- struct rdma_ah_attr new_ah_attr;
+- int ret;
+-
+ av->port = port;
+ av->pkey_index = wc->pkey_index;
+-
+- /*
+- * av->ah_attr might be initialized based on past wc during incoming
+- * connect request or while sending out connect request. So initialize
+- * a new ah_attr on stack. If initialization fails, old ah_attr is
+- * used for sending any responses. If initialization is successful,
+- * than new ah_attr is used by overwriting old one.
+- */
+- ret = ib_init_ah_attr_from_wc(port->cm_dev->ib_device,
+- port->port_num, wc,
+- grh, &new_ah_attr);
+- if (ret)
+- return ret;
+-
+- rdma_move_ah_attr(&av->ah_attr, &new_ah_attr);
+- return 0;
++ rdma_move_ah_attr(&av->ah_attr, ah_attr);
+ }
+
+ static int cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc,
+@@ -556,6 +538,20 @@ static int cm_init_av_by_path(struct sa_path_rec *path,
+ return 0;
+ }
+
++/* Move av created by cm_init_av_by_path(), so av.dgid is not moved */
++static void cm_move_av_from_path(struct cm_av *dest, struct cm_av *src)
++{
++ dest->port = src->port;
++ dest->pkey_index = src->pkey_index;
++ rdma_move_ah_attr(&dest->ah_attr, &src->ah_attr);
++ dest->timeout = src->timeout;
++}
++
++static void cm_destroy_av(struct cm_av *av)
++{
++ rdma_destroy_ah_attr(&av->ah_attr);
++}
++
+ static u32 cm_local_id(__be32 local_id)
+ {
+ return (__force u32) (local_id ^ cm.random_id_operand);
+@@ -1145,8 +1141,8 @@ retest:
+ while ((work = cm_dequeue_work(cm_id_priv)) != NULL)
+ cm_free_work(work);
+
+- rdma_destroy_ah_attr(&cm_id_priv->av.ah_attr);
+- rdma_destroy_ah_attr(&cm_id_priv->alt_av.ah_attr);
++ cm_destroy_av(&cm_id_priv->av);
++ cm_destroy_av(&cm_id_priv->alt_av);
+ kfree(cm_id_priv->private_data);
+ kfree_rcu(cm_id_priv, rcu);
+ }
+@@ -1470,6 +1466,7 @@ static int cm_validate_req_param(struct ib_cm_req_param *param)
+ int ib_send_cm_req(struct ib_cm_id *cm_id,
+ struct ib_cm_req_param *param)
+ {
++ struct cm_av av = {}, alt_av = {};
+ struct cm_id_private *cm_id_priv;
+ struct ib_mad_send_buf *msg;
+ struct cm_req_msg *req_msg;
+@@ -1485,8 +1482,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
+ spin_lock_irqsave(&cm_id_priv->lock, flags);
+ if (cm_id->state != IB_CM_IDLE || WARN_ON(cm_id_priv->timewait_info)) {
+ spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+- ret = -EINVAL;
+- goto out;
++ return -EINVAL;
+ }
+ spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+@@ -1495,18 +1491,20 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
+ if (IS_ERR(cm_id_priv->timewait_info)) {
+ ret = PTR_ERR(cm_id_priv->timewait_info);
+ cm_id_priv->timewait_info = NULL;
+- goto out;
++ return ret;
+ }
+
+ ret = cm_init_av_by_path(param->primary_path,
+- param->ppath_sgid_attr, &cm_id_priv->av);
++ param->ppath_sgid_attr, &av);
+ if (ret)
+- goto out;
++ return ret;
+ if (param->alternate_path) {
+ ret = cm_init_av_by_path(param->alternate_path, NULL,
+- &cm_id_priv->alt_av);
+- if (ret)
+- goto out;
++ &alt_av);
++ if (ret) {
++ cm_destroy_av(&av);
++ return ret;
++ }
+ }
+ cm_id->service_id = param->service_id;
+ cm_id->service_mask = ~cpu_to_be64(0);
+@@ -1523,6 +1521,11 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
+ cm_id_priv->qp_type = param->qp_type;
+
+ spin_lock_irqsave(&cm_id_priv->lock, flags);
++
++ cm_move_av_from_path(&cm_id_priv->av, &av);
++ if (param->alternate_path)
++ cm_move_av_from_path(&cm_id_priv->alt_av, &alt_av);
++
+ msg = cm_alloc_priv_msg(cm_id_priv);
+ if (IS_ERR(msg)) {
+ ret = PTR_ERR(msg);
+@@ -1550,7 +1553,6 @@ out_free:
+ cm_free_priv_msg(msg);
+ out_unlock:
+ spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+-out:
+ return ret;
+ }
+ EXPORT_SYMBOL(ib_send_cm_req);
+@@ -3267,6 +3269,8 @@ static int cm_lap_handler(struct cm_work *work)
+ struct cm_lap_msg *lap_msg;
+ struct ib_cm_lap_event_param *param;
+ struct ib_mad_send_buf *msg = NULL;
++ struct rdma_ah_attr ah_attr;
++ struct cm_av alt_av = {};
+ int ret;
+
+ /* Currently Alternate path messages are not supported for
+@@ -3295,7 +3299,25 @@ static int cm_lap_handler(struct cm_work *work)
+ work->cm_event.private_data =
+ IBA_GET_MEM_PTR(CM_LAP_PRIVATE_DATA, lap_msg);
+
++ ret = ib_init_ah_attr_from_wc(work->port->cm_dev->ib_device,
++ work->port->port_num,
++ work->mad_recv_wc->wc,
++ work->mad_recv_wc->recv_buf.grh,
++ &ah_attr);
++ if (ret)
++ goto deref;
++
++ ret = cm_init_av_by_path(param->alternate_path, NULL, &alt_av);
++ if (ret) {
++ rdma_destroy_ah_attr(&ah_attr);
++ return -EINVAL;
++ }
++
+ spin_lock_irq(&cm_id_priv->lock);
++ cm_init_av_for_lap(work->port, work->mad_recv_wc->wc,
++ &ah_attr, &cm_id_priv->av);
++ cm_move_av_from_path(&cm_id_priv->alt_av, &alt_av);
++
+ if (cm_id_priv->id.state != IB_CM_ESTABLISHED)
+ goto unlock;
+
+@@ -3329,17 +3351,6 @@ static int cm_lap_handler(struct cm_work *work)
+ goto unlock;
+ }
+
+- ret = cm_init_av_for_lap(work->port, work->mad_recv_wc->wc,
+- work->mad_recv_wc->recv_buf.grh,
+- &cm_id_priv->av);
+- if (ret)
+- goto unlock;
+-
+- ret = cm_init_av_by_path(param->alternate_path, NULL,
+- &cm_id_priv->alt_av);
+- if (ret)
+- goto unlock;
+-
+ cm_id_priv->id.lap_state = IB_CM_LAP_RCVD;
+ cm_id_priv->tid = lap_msg->hdr.tid;
+ cm_queue_work_unlock(cm_id_priv, work);
+@@ -3447,6 +3458,7 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id,
+ {
+ struct cm_id_private *cm_id_priv;
+ struct ib_mad_send_buf *msg;
++ struct cm_av av = {};
+ unsigned long flags;
+ int ret;
+
+@@ -3455,17 +3467,16 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id,
+ return -EINVAL;
+
+ cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+- ret = cm_init_av_by_path(param->path, param->sgid_attr,
+- &cm_id_priv->av);
++ ret = cm_init_av_by_path(param->path, param->sgid_attr, &av);
+ if (ret)
+ return ret;
+
++ spin_lock_irqsave(&cm_id_priv->lock, flags);
++ cm_move_av_from_path(&cm_id_priv->av, &av);
+ cm_id->service_id = param->service_id;
+ cm_id->service_mask = ~cpu_to_be64(0);
+ cm_id_priv->timeout_ms = param->timeout_ms;
+ cm_id_priv->max_cm_retries = param->max_cm_retries;
+-
+- spin_lock_irqsave(&cm_id_priv->lock, flags);
+ if (cm_id->state != IB_CM_IDLE) {
+ ret = -EINVAL;
+ goto out_unlock;
+--
+2.30.2
+
--- /dev/null
+From 749834253fb8e226a341c09079c260a6726f4dc8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Jun 2021 13:27:01 +0300
+Subject: IB/cm: Pair cm_alloc_response_msg() with a cm_free_response_msg()
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit 96376a40959e32502208210c62e68a6c60acfb48 ]
+
+This is not a functional change, but it helps make the purpose of all the
+cm_free_msg() calls clearer. In this case a response msg has a NULL
+context[0], and is never placed in cm_id_priv->msg.
+
+Link: https://lore.kernel.org/r/5cd53163be7df0a94f0d4ef7294546bc674fb74a.1622629024.git.leonro@nvidia.com
+Signed-off-by: Mark Zhang <markzhang@nvidia.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cm.c | 29 ++++++++++++++++++-----------
+ 1 file changed, 18 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
+index 0ead0d223154..6e20ba5d32e1 100644
+--- a/drivers/infiniband/core/cm.c
++++ b/drivers/infiniband/core/cm.c
+@@ -413,7 +413,7 @@ static int cm_alloc_response_msg(struct cm_port *port,
+
+ ret = cm_create_response_msg_ah(port, mad_recv_wc, m);
+ if (ret) {
+- cm_free_msg(m);
++ ib_free_send_mad(m);
+ return ret;
+ }
+
+@@ -421,6 +421,13 @@ static int cm_alloc_response_msg(struct cm_port *port,
+ return 0;
+ }
+
++static void cm_free_response_msg(struct ib_mad_send_buf *msg)
++{
++ if (msg->ah)
++ rdma_destroy_ah(msg->ah, 0);
++ ib_free_send_mad(msg);
++}
++
+ static void *cm_copy_private_data(const void *private_data, u8 private_data_len)
+ {
+ void *data;
+@@ -1569,16 +1576,16 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
+ spin_lock_irqsave(&cm_id_priv->lock, flags);
+ ret = ib_post_send_mad(cm_id_priv->msg, NULL);
+ if (ret) {
++ cm_free_msg(cm_id_priv->msg);
+ spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+- goto error2;
++ goto out;
+ }
+ BUG_ON(cm_id->state != IB_CM_IDLE);
+ cm_id->state = IB_CM_REQ_SENT;
+ spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ return 0;
+-
+-error2: cm_free_msg(cm_id_priv->msg);
+-out: return ret;
++out:
++ return ret;
+ }
+ EXPORT_SYMBOL(ib_send_cm_req);
+
+@@ -1618,7 +1625,7 @@ static int cm_issue_rej(struct cm_port *port,
+ IBA_GET(CM_REJ_REMOTE_COMM_ID, rcv_msg));
+ ret = ib_post_send_mad(msg, NULL);
+ if (ret)
+- cm_free_msg(msg);
++ cm_free_response_msg(msg);
+
+ return ret;
+ }
+@@ -1974,7 +1981,7 @@ static void cm_dup_req_handler(struct cm_work *work,
+ return;
+
+ unlock: spin_unlock_irq(&cm_id_priv->lock);
+-free: cm_free_msg(msg);
++free: cm_free_response_msg(msg);
+ }
+
+ static struct cm_id_private *cm_match_req(struct cm_work *work,
+@@ -2453,7 +2460,7 @@ static void cm_dup_rep_handler(struct cm_work *work)
+ goto deref;
+
+ unlock: spin_unlock_irq(&cm_id_priv->lock);
+-free: cm_free_msg(msg);
++free: cm_free_response_msg(msg);
+ deref: cm_deref_id(cm_id_priv);
+ }
+
+@@ -2794,7 +2801,7 @@ static int cm_issue_drep(struct cm_port *port,
+ IBA_GET(CM_DREQ_REMOTE_COMM_ID, dreq_msg));
+ ret = ib_post_send_mad(msg, NULL);
+ if (ret)
+- cm_free_msg(msg);
++ cm_free_response_msg(msg);
+
+ return ret;
+ }
+@@ -2853,7 +2860,7 @@ static int cm_dreq_handler(struct cm_work *work)
+
+ if (cm_create_response_msg_ah(work->port, work->mad_recv_wc, msg) ||
+ ib_post_send_mad(msg, NULL))
+- cm_free_msg(msg);
++ cm_free_response_msg(msg);
+ goto deref;
+ case IB_CM_DREQ_RCVD:
+ atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
+@@ -3343,7 +3350,7 @@ static int cm_lap_handler(struct cm_work *work)
+
+ if (cm_create_response_msg_ah(work->port, work->mad_recv_wc, msg) ||
+ ib_post_send_mad(msg, NULL))
+- cm_free_msg(msg);
++ cm_free_response_msg(msg);
+ goto deref;
+ case IB_CM_LAP_RCVD:
+ atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES].
+--
+2.30.2
+
--- /dev/null
+From 3bb4a685e326d72e3da71f5ea36467f2c6f47b37 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Jun 2021 13:27:02 +0300
+Subject: IB/cm: Split cm_alloc_msg()
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit 4b4e586ebe37c8c7e2a4bf46dc4b742756fd788d ]
+
+This is being used with two quite different flows, one attaches the
+message to the priv and the other does not.
+
+Ensure the message attach is consistently done under the spinlock and
+ensure that the free on error always detaches the message from the
+cm_id_priv, also always under lock.
+
+This makes read/write to the cm_id_priv->msg consistently locked and
+consistently NULL'd when the message is freed, even in all error paths.
+
+Link: https://lore.kernel.org/r/f692b8c89eecb34fd82244f317e478bea6c97688.1622629024.git.leonro@nvidia.com
+Signed-off-by: Mark Zhang <markzhang@nvidia.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cm.c | 190 +++++++++++++++++++++--------------
+ 1 file changed, 115 insertions(+), 75 deletions(-)
+
+diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
+index 6e20ba5d32e1..94613275edcc 100644
+--- a/drivers/infiniband/core/cm.c
++++ b/drivers/infiniband/core/cm.c
+@@ -305,8 +305,7 @@ static inline void cm_deref_id(struct cm_id_private *cm_id_priv)
+ complete(&cm_id_priv->comp);
+ }
+
+-static int cm_alloc_msg(struct cm_id_private *cm_id_priv,
+- struct ib_mad_send_buf **msg)
++static struct ib_mad_send_buf *cm_alloc_msg(struct cm_id_private *cm_id_priv)
+ {
+ struct ib_mad_agent *mad_agent;
+ struct ib_mad_send_buf *m;
+@@ -359,12 +358,42 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv,
+ m->retries = cm_id_priv->max_cm_retries;
+
+ refcount_inc(&cm_id_priv->refcount);
++ spin_unlock_irqrestore(&cm.state_lock, flags2);
+ m->context[0] = cm_id_priv;
+- *msg = m;
++ return m;
+
+ out:
+ spin_unlock_irqrestore(&cm.state_lock, flags2);
+- return ret;
++ return ERR_PTR(ret);
++}
++
++static struct ib_mad_send_buf *
++cm_alloc_priv_msg(struct cm_id_private *cm_id_priv)
++{
++ struct ib_mad_send_buf *msg;
++
++ lockdep_assert_held(&cm_id_priv->lock);
++
++ msg = cm_alloc_msg(cm_id_priv);
++ if (IS_ERR(msg))
++ return msg;
++ cm_id_priv->msg = msg;
++ return msg;
++}
++
++static void cm_free_priv_msg(struct ib_mad_send_buf *msg)
++{
++ struct cm_id_private *cm_id_priv = msg->context[0];
++
++ lockdep_assert_held(&cm_id_priv->lock);
++
++ if (!WARN_ON(cm_id_priv->msg != msg))
++ cm_id_priv->msg = NULL;
++
++ if (msg->ah)
++ rdma_destroy_ah(msg->ah, 0);
++ cm_deref_id(cm_id_priv);
++ ib_free_send_mad(msg);
+ }
+
+ static struct ib_mad_send_buf *cm_alloc_response_msg_no_ah(struct cm_port *port,
+@@ -1508,6 +1537,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
+ struct ib_cm_req_param *param)
+ {
+ struct cm_id_private *cm_id_priv;
++ struct ib_mad_send_buf *msg;
+ struct cm_req_msg *req_msg;
+ unsigned long flags;
+ int ret;
+@@ -1559,31 +1589,34 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
+ cm_id_priv->pkey = param->primary_path->pkey;
+ cm_id_priv->qp_type = param->qp_type;
+
+- ret = cm_alloc_msg(cm_id_priv, &cm_id_priv->msg);
+- if (ret)
+- goto out;
++ spin_lock_irqsave(&cm_id_priv->lock, flags);
++ msg = cm_alloc_priv_msg(cm_id_priv);
++ if (IS_ERR(msg)) {
++ ret = PTR_ERR(msg);
++ goto out_unlock;
++ }
+
+- req_msg = (struct cm_req_msg *) cm_id_priv->msg->mad;
++ req_msg = (struct cm_req_msg *)msg->mad;
+ cm_format_req(req_msg, cm_id_priv, param);
+ cm_id_priv->tid = req_msg->hdr.tid;
+- cm_id_priv->msg->timeout_ms = cm_id_priv->timeout_ms;
+- cm_id_priv->msg->context[1] = (void *) (unsigned long) IB_CM_REQ_SENT;
++ msg->timeout_ms = cm_id_priv->timeout_ms;
++ msg->context[1] = (void *)(unsigned long)IB_CM_REQ_SENT;
+
+ cm_id_priv->local_qpn = cpu_to_be32(IBA_GET(CM_REQ_LOCAL_QPN, req_msg));
+ cm_id_priv->rq_psn = cpu_to_be32(IBA_GET(CM_REQ_STARTING_PSN, req_msg));
+
+ trace_icm_send_req(&cm_id_priv->id);
+- spin_lock_irqsave(&cm_id_priv->lock, flags);
+- ret = ib_post_send_mad(cm_id_priv->msg, NULL);
+- if (ret) {
+- cm_free_msg(cm_id_priv->msg);
+- spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+- goto out;
+- }
++ ret = ib_post_send_mad(msg, NULL);
++ if (ret)
++ goto out_free;
+ BUG_ON(cm_id->state != IB_CM_IDLE);
+ cm_id->state = IB_CM_REQ_SENT;
+ spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ return 0;
++out_free:
++ cm_free_priv_msg(msg);
++out_unlock:
++ spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ out:
+ return ret;
+ }
+@@ -2290,9 +2323,11 @@ int ib_send_cm_rep(struct ib_cm_id *cm_id,
+ goto out;
+ }
+
+- ret = cm_alloc_msg(cm_id_priv, &msg);
+- if (ret)
++ msg = cm_alloc_priv_msg(cm_id_priv);
++ if (IS_ERR(msg)) {
++ ret = PTR_ERR(msg);
+ goto out;
++ }
+
+ rep_msg = (struct cm_rep_msg *) msg->mad;
+ cm_format_rep(rep_msg, cm_id_priv, param);
+@@ -2301,14 +2336,10 @@ int ib_send_cm_rep(struct ib_cm_id *cm_id,
+
+ trace_icm_send_rep(cm_id);
+ ret = ib_post_send_mad(msg, NULL);
+- if (ret) {
+- spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+- cm_free_msg(msg);
+- return ret;
+- }
++ if (ret)
++ goto out_free;
+
+ cm_id->state = IB_CM_REP_SENT;
+- cm_id_priv->msg = msg;
+ cm_id_priv->initiator_depth = param->initiator_depth;
+ cm_id_priv->responder_resources = param->responder_resources;
+ cm_id_priv->rq_psn = cpu_to_be32(IBA_GET(CM_REP_STARTING_PSN, rep_msg));
+@@ -2316,8 +2347,13 @@ int ib_send_cm_rep(struct ib_cm_id *cm_id,
+ "IBTA declares QPN to be 24 bits, but it is 0x%X\n",
+ param->qp_num);
+ cm_id_priv->local_qpn = cpu_to_be32(param->qp_num & 0xFFFFFF);
++ spin_unlock_irqrestore(&cm_id_priv->lock, flags);
++ return 0;
+
+-out: spin_unlock_irqrestore(&cm_id_priv->lock, flags);
++out_free:
++ cm_free_priv_msg(msg);
++out:
++ spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ return ret;
+ }
+ EXPORT_SYMBOL(ib_send_cm_rep);
+@@ -2364,9 +2400,11 @@ int ib_send_cm_rtu(struct ib_cm_id *cm_id,
+ goto error;
+ }
+
+- ret = cm_alloc_msg(cm_id_priv, &msg);
+- if (ret)
++ msg = cm_alloc_msg(cm_id_priv);
++ if (IS_ERR(msg)) {
++ ret = PTR_ERR(msg);
+ goto error;
++ }
+
+ cm_format_rtu((struct cm_rtu_msg *) msg->mad, cm_id_priv,
+ private_data, private_data_len);
+@@ -2664,10 +2702,10 @@ static int cm_send_dreq_locked(struct cm_id_private *cm_id_priv,
+ cm_id_priv->id.lap_state == IB_CM_MRA_LAP_RCVD)
+ ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
+
+- ret = cm_alloc_msg(cm_id_priv, &msg);
+- if (ret) {
++ msg = cm_alloc_priv_msg(cm_id_priv);
++ if (IS_ERR(msg)) {
+ cm_enter_timewait(cm_id_priv);
+- return ret;
++ return PTR_ERR(msg);
+ }
+
+ cm_format_dreq((struct cm_dreq_msg *) msg->mad, cm_id_priv,
+@@ -2679,12 +2717,11 @@ static int cm_send_dreq_locked(struct cm_id_private *cm_id_priv,
+ ret = ib_post_send_mad(msg, NULL);
+ if (ret) {
+ cm_enter_timewait(cm_id_priv);
+- cm_free_msg(msg);
++ cm_free_priv_msg(msg);
+ return ret;
+ }
+
+ cm_id_priv->id.state = IB_CM_DREQ_SENT;
+- cm_id_priv->msg = msg;
+ return 0;
+ }
+
+@@ -2739,9 +2776,9 @@ static int cm_send_drep_locked(struct cm_id_private *cm_id_priv,
+ cm_set_private_data(cm_id_priv, private_data, private_data_len);
+ cm_enter_timewait(cm_id_priv);
+
+- ret = cm_alloc_msg(cm_id_priv, &msg);
+- if (ret)
+- return ret;
++ msg = cm_alloc_msg(cm_id_priv);
++ if (IS_ERR(msg))
++ return PTR_ERR(msg);
+
+ cm_format_drep((struct cm_drep_msg *) msg->mad, cm_id_priv,
+ private_data, private_data_len);
+@@ -2934,9 +2971,9 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv,
+ case IB_CM_REP_RCVD:
+ case IB_CM_MRA_REP_SENT:
+ cm_reset_to_idle(cm_id_priv);
+- ret = cm_alloc_msg(cm_id_priv, &msg);
+- if (ret)
+- return ret;
++ msg = cm_alloc_msg(cm_id_priv);
++ if (IS_ERR(msg))
++ return PTR_ERR(msg);
+ cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, reason,
+ ari, ari_length, private_data, private_data_len,
+ state);
+@@ -2944,9 +2981,9 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv,
+ case IB_CM_REP_SENT:
+ case IB_CM_MRA_REP_RCVD:
+ cm_enter_timewait(cm_id_priv);
+- ret = cm_alloc_msg(cm_id_priv, &msg);
+- if (ret)
+- return ret;
++ msg = cm_alloc_msg(cm_id_priv);
++ if (IS_ERR(msg))
++ return PTR_ERR(msg);
+ cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, reason,
+ ari, ari_length, private_data, private_data_len,
+ state);
+@@ -3124,13 +3161,15 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id,
+ default:
+ trace_icm_send_mra_unknown_err(&cm_id_priv->id);
+ ret = -EINVAL;
+- goto error1;
++ goto error_unlock;
+ }
+
+ if (!(service_timeout & IB_CM_MRA_FLAG_DELAY)) {
+- ret = cm_alloc_msg(cm_id_priv, &msg);
+- if (ret)
+- goto error1;
++ msg = cm_alloc_msg(cm_id_priv);
++ if (IS_ERR(msg)) {
++ ret = PTR_ERR(msg);
++ goto error_unlock;
++ }
+
+ cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv,
+ msg_response, service_timeout,
+@@ -3138,7 +3177,7 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id,
+ trace_icm_send_mra(cm_id);
+ ret = ib_post_send_mad(msg, NULL);
+ if (ret)
+- goto error2;
++ goto error_free_msg;
+ }
+
+ cm_id->state = cm_state;
+@@ -3148,13 +3187,11 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id,
+ spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ return 0;
+
+-error1: spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+- kfree(data);
+- return ret;
+-
+-error2: spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+- kfree(data);
++error_free_msg:
+ cm_free_msg(msg);
++error_unlock:
++ spin_unlock_irqrestore(&cm_id_priv->lock, flags);
++ kfree(data);
+ return ret;
+ }
+ EXPORT_SYMBOL(ib_send_cm_mra);
+@@ -3490,38 +3527,41 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id,
+ &cm_id_priv->av,
+ cm_id_priv);
+ if (ret)
+- goto out;
++ return ret;
+
+ cm_id->service_id = param->service_id;
+ cm_id->service_mask = ~cpu_to_be64(0);
+ cm_id_priv->timeout_ms = param->timeout_ms;
+ cm_id_priv->max_cm_retries = param->max_cm_retries;
+- ret = cm_alloc_msg(cm_id_priv, &msg);
+- if (ret)
+- goto out;
+-
+- cm_format_sidr_req((struct cm_sidr_req_msg *) msg->mad, cm_id_priv,
+- param);
+- msg->timeout_ms = cm_id_priv->timeout_ms;
+- msg->context[1] = (void *) (unsigned long) IB_CM_SIDR_REQ_SENT;
+
+ spin_lock_irqsave(&cm_id_priv->lock, flags);
+- if (cm_id->state == IB_CM_IDLE) {
+- trace_icm_send_sidr_req(&cm_id_priv->id);
+- ret = ib_post_send_mad(msg, NULL);
+- } else {
++ if (cm_id->state != IB_CM_IDLE) {
+ ret = -EINVAL;
++ goto out_unlock;
+ }
+
+- if (ret) {
+- spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+- cm_free_msg(msg);
+- goto out;
++ msg = cm_alloc_priv_msg(cm_id_priv);
++ if (IS_ERR(msg)) {
++ ret = PTR_ERR(msg);
++ goto out_unlock;
+ }
++
++ cm_format_sidr_req((struct cm_sidr_req_msg *)msg->mad, cm_id_priv,
++ param);
++ msg->timeout_ms = cm_id_priv->timeout_ms;
++ msg->context[1] = (void *)(unsigned long)IB_CM_SIDR_REQ_SENT;
++
++ trace_icm_send_sidr_req(&cm_id_priv->id);
++ ret = ib_post_send_mad(msg, NULL);
++ if (ret)
++ goto out_free;
+ cm_id->state = IB_CM_SIDR_REQ_SENT;
+- cm_id_priv->msg = msg;
+ spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+-out:
++ return 0;
++out_free:
++ cm_free_priv_msg(msg);
++out_unlock:
++ spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+ return ret;
+ }
+ EXPORT_SYMBOL(ib_send_cm_sidr_req);
+@@ -3668,9 +3708,9 @@ static int cm_send_sidr_rep_locked(struct cm_id_private *cm_id_priv,
+ if (cm_id_priv->id.state != IB_CM_SIDR_REQ_RCVD)
+ return -EINVAL;
+
+- ret = cm_alloc_msg(cm_id_priv, &msg);
+- if (ret)
+- return ret;
++ msg = cm_alloc_msg(cm_id_priv);
++ if (IS_ERR(msg))
++ return PTR_ERR(msg);
+
+ cm_format_sidr_rep((struct cm_sidr_rep_msg *) msg->mad, cm_id_priv,
+ param);
+--
+2.30.2
+
--- /dev/null
+From 8822da67f2d669c1e3ce5fd111a98a59d4e97dbc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 21:13:13 -0700
+Subject: ibmvnic: account for bufs already saved in indir_buf
+
+From: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+
+[ Upstream commit 72368f8b2b9e4106072a2728bed3367d54641c22 ]
+
+This fixes a crash in replenish_rx_pool() when called from ibmvnic_poll()
+after a previous call to replenish_rx_pool() encountered an error when
+allocating a socket buffer.
+
+Thanks to Rick Lindsley and Dany Madden for helping debug the crash.
+
+Fixes: 4f0b6812e9b9 ("ibmvnic: Introduce batched RX buffer descriptor transmission")
+Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 2d15b446ceb3..779de81a54a6 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -328,7 +328,14 @@ static void replenish_rx_pool(struct ibmvnic_adapter *adapter,
+
+ rx_scrq = adapter->rx_scrq[pool->index];
+ ind_bufp = &rx_scrq->ind_buf;
+- for (i = 0; i < count; ++i) {
++
++ /* netdev_skb_alloc() could have failed after we saved a few skbs
++ * in the indir_buf and we would not have sent them to VIOS yet.
++ * To account for them, start the loop at ind_bufp->index rather
++ * than 0. If we pushed all the skbs to VIOS, ind_bufp->index will
++ * be 0.
++ */
++ for (i = ind_bufp->index; i < count; ++i) {
+ skb = netdev_alloc_skb(adapter->netdev, pool->buff_size);
+ if (!skb) {
+ dev_err(dev, "Couldn't replenish rx buff\n");
+--
+2.30.2
+
--- /dev/null
+From da994a9ea062260657b51988cada1979c1c75109 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 21:13:12 -0700
+Subject: ibmvnic: clean pending indirect buffs during reset
+
+From: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+
+[ Upstream commit 65d6470d139a6c1655fccb5cbacbeaba8e8ad2f8 ]
+
+We batch subordinate command response queue (scrq) descriptors that we
+need to send to the VIOS using an "indirect" buffer. If after we queue
+one or more scrqs in the indirect buffer encounter an error (say fail
+to allocate an skb), we leave the queued scrq descriptors in the
+indirect buffer until the next call to ibmvnic_xmit().
+
+On the next call to ibmvnic_xmit(), it is possible that the adapter is
+going through a reset and it is possible that the long term buffers
+have been unmapped on the VIOS side. If we proceed to flush (send) the
+packets that are in the indirect buffer, we will end up using the old
+map ids and this can cause the VIOS to trigger an unnecessary FATAL
+error reset.
+
+Instead of flushing packets remaining on the indirect_buff, discard
+(clean) them instead.
+
+Fixes: 0d973388185d4 ("ibmvnic: Introduce xmit_more support using batched subCRQ hcalls")
+Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 8b2f6eb8eb21..2d15b446ceb3 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -106,6 +106,8 @@ static void release_crq_queue(struct ibmvnic_adapter *);
+ static int __ibmvnic_set_mac(struct net_device *, u8 *);
+ static int init_crq_queue(struct ibmvnic_adapter *adapter);
+ static int send_query_phys_parms(struct ibmvnic_adapter *adapter);
++static void ibmvnic_tx_scrq_clean_buffer(struct ibmvnic_adapter *adapter,
++ struct ibmvnic_sub_crq_queue *tx_scrq);
+
+ struct ibmvnic_stat {
+ char name[ETH_GSTRING_LEN];
+@@ -668,6 +670,7 @@ static int reset_tx_pools(struct ibmvnic_adapter *adapter)
+
+ tx_scrqs = adapter->num_active_tx_pools;
+ for (i = 0; i < tx_scrqs; i++) {
++ ibmvnic_tx_scrq_clean_buffer(adapter, adapter->tx_scrq[i]);
+ rc = reset_one_tx_pool(adapter, &adapter->tso_pool[i]);
+ if (rc)
+ return rc;
+@@ -1618,7 +1621,8 @@ static void ibmvnic_tx_scrq_clean_buffer(struct ibmvnic_adapter *adapter,
+ ind_bufp->index = 0;
+ if (atomic_sub_return(entries, &tx_scrq->used) <=
+ (adapter->req_tx_entries_per_subcrq / 2) &&
+- __netif_subqueue_stopped(adapter->netdev, queue_num)) {
++ __netif_subqueue_stopped(adapter->netdev, queue_num) &&
++ !test_bit(0, &adapter->resetting)) {
+ netif_wake_subqueue(adapter->netdev, queue_num);
+ netdev_dbg(adapter->netdev, "Started queue %d\n",
+ queue_num);
+@@ -1711,7 +1715,6 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
+ tx_send_failed++;
+ tx_dropped++;
+ ret = NETDEV_TX_OK;
+- ibmvnic_tx_scrq_flush(adapter, tx_scrq);
+ goto out;
+ }
+
+@@ -3175,6 +3178,7 @@ static void release_sub_crqs(struct ibmvnic_adapter *adapter, bool do_h_free)
+
+ netdev_dbg(adapter->netdev, "Releasing tx_scrq[%d]\n",
+ i);
++ ibmvnic_tx_scrq_clean_buffer(adapter, adapter->tx_scrq[i]);
+ if (adapter->tx_scrq[i]->irq) {
+ free_irq(adapter->tx_scrq[i]->irq,
+ adapter->tx_scrq[i]);
+--
+2.30.2
+
--- /dev/null
+From fc61fedc73a740bf92fab3999ca1bd13a287b862 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 21:13:15 -0700
+Subject: ibmvnic: free tx_pool if tso_pool alloc fails
+
+From: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+
+[ Upstream commit f6ebca8efa52e4ae770f0325d618e7bcf08ada0c ]
+
+Free tx_pool and clear it, if allocation of tso_pool fails.
+
+release_tx_pools() assumes we have both tx and tso_pools if ->tx_pool is
+non-NULL. If allocation of tso_pool fails in init_tx_pools(), the assumption
+will not be true and we would end up dereferencing ->tx_buff, ->free_map
+fields from a NULL pointer.
+
+Fixes: 3205306c6b8d ("ibmvnic: Update TX pool initialization routine")
+Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index b8bdab0b2701..ede65b32f821 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -778,8 +778,11 @@ static int init_tx_pools(struct net_device *netdev)
+
+ adapter->tso_pool = kcalloc(tx_subcrqs,
+ sizeof(struct ibmvnic_tx_pool), GFP_KERNEL);
+- if (!adapter->tso_pool)
++ if (!adapter->tso_pool) {
++ kfree(adapter->tx_pool);
++ adapter->tx_pool = NULL;
+ return -1;
++ }
+
+ adapter->num_active_tx_pools = tx_subcrqs;
+
+--
+2.30.2
+
--- /dev/null
+From 12915ba6e6aeb385f42fcef3205a7983fa64cb08 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 21:13:14 -0700
+Subject: ibmvnic: set ltb->buff to NULL after freeing
+
+From: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+
+[ Upstream commit 552a33729f1a7cc5115d0752064fe9abd6e3e336 ]
+
+free_long_term_buff() checks ltb->buff to decide whether we have a long
+term buffer to free. So set ltb->buff to NULL afer freeing. While here,
+also clear ->map_id, fix up some coding style and log an error.
+
+Fixes: 9c4eaabd1bb39 ("Check CRQ command return codes")
+Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 779de81a54a6..b8bdab0b2701 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -211,12 +211,11 @@ static int alloc_long_term_buff(struct ibmvnic_adapter *adapter,
+ mutex_lock(&adapter->fw_lock);
+ adapter->fw_done_rc = 0;
+ reinit_completion(&adapter->fw_done);
+- rc = send_request_map(adapter, ltb->addr,
+- ltb->size, ltb->map_id);
++
++ rc = send_request_map(adapter, ltb->addr, ltb->size, ltb->map_id);
+ if (rc) {
+- dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr);
+- mutex_unlock(&adapter->fw_lock);
+- return rc;
++ dev_err(dev, "send_request_map failed, rc = %d\n", rc);
++ goto out;
+ }
+
+ rc = ibmvnic_wait_for_completion(adapter, &adapter->fw_done, 10000);
+@@ -224,20 +223,23 @@ static int alloc_long_term_buff(struct ibmvnic_adapter *adapter,
+ dev_err(dev,
+ "Long term map request aborted or timed out,rc = %d\n",
+ rc);
+- dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr);
+- mutex_unlock(&adapter->fw_lock);
+- return rc;
++ goto out;
+ }
+
+ if (adapter->fw_done_rc) {
+ dev_err(dev, "Couldn't map long term buffer,rc = %d\n",
+ adapter->fw_done_rc);
++ rc = -1;
++ goto out;
++ }
++ rc = 0;
++out:
++ if (rc) {
+ dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr);
+- mutex_unlock(&adapter->fw_lock);
+- return -1;
++ ltb->buff = NULL;
+ }
+ mutex_unlock(&adapter->fw_lock);
+- return 0;
++ return rc;
+ }
+
+ static void free_long_term_buff(struct ibmvnic_adapter *adapter,
+@@ -257,6 +259,8 @@ static void free_long_term_buff(struct ibmvnic_adapter *adapter,
+ adapter->reset_reason != VNIC_RESET_TIMEOUT)
+ send_request_unmap(adapter, ltb->map_id);
+ dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr);
++ ltb->buff = NULL;
++ ltb->map_id = 0;
+ }
+
+ static int reset_long_term_buff(struct ibmvnic_adapter *adapter,
+--
+2.30.2
+
--- /dev/null
+From 62961fc4ba0143096b15fb5f7d8b05a4e1e5f3e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Jun 2021 11:02:44 -0700
+Subject: ieee802154: hwsim: avoid possible crash in hwsim_del_edge_nl()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0303b30375dff5351a79cc2c3c87dfa4fda29bed ]
+
+Both MAC802154_HWSIM_ATTR_RADIO_ID and MAC802154_HWSIM_ATTR_RADIO_EDGE
+must be present to avoid a crash.
+
+Fixes: f25da51fdc38 ("ieee802154: hwsim: add replacement for fakelb")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Alexander Aring <alex.aring@gmail.com>
+Cc: Stefan Schmidt <stefan@datenfreihafen.org>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Acked-by: Alexander Aring <aahringo@redhat.com>
+Link: https://lore.kernel.org/r/20210621180244.882076-1-eric.dumazet@gmail.com
+Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ieee802154/mac802154_hwsim.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c
+index baa7e21b7f4f..ebc976b7fcc2 100644
+--- a/drivers/net/ieee802154/mac802154_hwsim.c
++++ b/drivers/net/ieee802154/mac802154_hwsim.c
+@@ -480,7 +480,7 @@ static int hwsim_del_edge_nl(struct sk_buff *msg, struct genl_info *info)
+ struct hwsim_edge *e;
+ u32 v0, v1;
+
+- if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] &&
++ if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] ||
+ !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE])
+ return -EINVAL;
+
+--
+2.30.2
+
--- /dev/null
+From 6f7bc5601359d58e2a4097c8d3f0d20297b4e422 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jun 2021 10:09:01 +0800
+Subject: ieee802154: hwsim: Fix memory leak in hwsim_add_one
+
+From: Dongliang Mu <mudongliangabcd@gmail.com>
+
+[ Upstream commit 28a5501c3383f0e6643012c187b7c2027ef42aea ]
+
+No matter from hwsim_remove or hwsim_del_radio_nl, hwsim_del fails to
+remove the entry in the edges list. Take the example below, phy0, phy1
+and e0 will be deleted, resulting in e1 not freed and accessed in the
+future.
+
+ hwsim_phys
+ |
+ ------------------------------
+ | |
+phy0 (edges) phy1 (edges)
+ ----> e1 (idx = 1) ----> e0 (idx = 0)
+
+Fix this by deleting and freeing all the entries in the edges list
+between hwsim_edge_unsubscribe_me and list_del(&phy->list).
+
+Reported-by: syzbot+b80c9959009a9325cdff@syzkaller.appspotmail.com
+Fixes: 1c9f4a3fce77 ("ieee802154: hwsim: fix rcu handling")
+Signed-off-by: Dongliang Mu <mudongliangabcd@gmail.com>
+Acked-by: Alexander Aring <aahringo@redhat.com>
+Link: https://lore.kernel.org/r/20210616020901.2759466-1-mudongliangabcd@gmail.com
+Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ieee802154/mac802154_hwsim.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c
+index 366eaae3550a..baa7e21b7f4f 100644
+--- a/drivers/net/ieee802154/mac802154_hwsim.c
++++ b/drivers/net/ieee802154/mac802154_hwsim.c
+@@ -824,12 +824,17 @@ err_pib:
+ static void hwsim_del(struct hwsim_phy *phy)
+ {
+ struct hwsim_pib *pib;
++ struct hwsim_edge *e;
+
+ hwsim_edge_unsubscribe_me(phy);
+
+ list_del(&phy->list);
+
+ rcu_read_lock();
++ list_for_each_entry_rcu(e, &phy->edges, list) {
++ list_del_rcu(&e->list);
++ hwsim_free_edge(e);
++ }
+ pib = rcu_dereference(phy->pib);
+ rcu_read_unlock();
+
+--
+2.30.2
+
--- /dev/null
+From 757f2c74ec724545477fba40fd4ad2d8dfc1f5ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Jun 2021 09:58:12 +0800
+Subject: ieee802154: hwsim: Fix possible memory leak in
+ hwsim_subscribe_all_others
+
+From: Dongliang Mu <mudongliangabcd@gmail.com>
+
+[ Upstream commit ab372c2293f5d0b279f31c8d768566ea37602dc9 ]
+
+In hwsim_subscribe_all_others, the error handling code performs
+incorrectly if the second hwsim_alloc_edge fails. When this issue occurs,
+it goes to sub_fail, without cleaning the edges allocated before.
+
+Fixes: f25da51fdc38 ("ieee802154: hwsim: add replacement for fakelb")
+Signed-off-by: Dongliang Mu <mudongliangabcd@gmail.com>
+Acked-by: Alexander Aring <aahringo@redhat.com>
+Link: https://lore.kernel.org/r/20210611015812.1626999-1-mudongliangabcd@gmail.com
+Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ieee802154/mac802154_hwsim.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c
+index da9135231c07..366eaae3550a 100644
+--- a/drivers/net/ieee802154/mac802154_hwsim.c
++++ b/drivers/net/ieee802154/mac802154_hwsim.c
+@@ -715,6 +715,8 @@ static int hwsim_subscribe_all_others(struct hwsim_phy *phy)
+
+ return 0;
+
++sub_fail:
++ hwsim_edge_unsubscribe_me(phy);
+ me_fail:
+ rcu_read_lock();
+ list_for_each_entry_rcu(e, &phy->edges, list) {
+@@ -722,8 +724,6 @@ me_fail:
+ hwsim_free_edge(e);
+ }
+ rcu_read_unlock();
+-sub_fail:
+- hwsim_edge_unsubscribe_me(phy);
+ return -ENOMEM;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 22a50443f01037f39a2f9d2652b9d4359326dce2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:03 +0100
+Subject: iio: accel: bma180: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit fc36da3131a747a9367a05caf06de19be1bcc972 ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of this function.
+
+Fixes: b9a6a237ffc9 ("iio:bma180: Drop _update_scan_mode()")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Peter Meerwald <pmeerw@pmeerw.net>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-2-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/bma180.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
+index a4456ab4fb9d..b8cea42fca1a 100644
+--- a/drivers/iio/accel/bma180.c
++++ b/drivers/iio/accel/bma180.c
+@@ -164,7 +164,11 @@ struct bma180_data {
+ int scale;
+ int bw;
+ bool pmode;
+- u8 buff[16]; /* 3x 16-bit + 8-bit + padding + timestamp */
++ /* Ensure timestamp is naturally aligned */
++ struct {
++ s16 chan[4];
++ s64 timestamp __aligned(8);
++ } scan;
+ };
+
+ enum bma180_chan {
+@@ -943,12 +947,12 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p)
+ mutex_unlock(&data->mutex);
+ goto err;
+ }
+- ((s16 *)data->buff)[i++] = ret;
++ data->scan.chan[i++] = ret;
+ }
+
+ mutex_unlock(&data->mutex);
+
+- iio_push_to_buffers_with_timestamp(indio_dev, data->buff, time_ns);
++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, time_ns);
+ err:
+ iio_trigger_notify_done(indio_dev->trig);
+
+--
+2.30.2
+
--- /dev/null
+From e0d62fa9517ce2444532a33a1a17a56457039a57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:04 +0100
+Subject: iio: accel: bma220: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 151dbf0078da98206817ee0b87d499035479ef11 ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of this function.
+
+Fixes: 194dc4c71413 ("iio: accel: Add triggered buffer support for BMA220")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-3-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/bma220_spi.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/accel/bma220_spi.c b/drivers/iio/accel/bma220_spi.c
+index 36fc9876dbca..0622c7936499 100644
+--- a/drivers/iio/accel/bma220_spi.c
++++ b/drivers/iio/accel/bma220_spi.c
+@@ -63,7 +63,11 @@ static const int bma220_scale_table[][2] = {
+ struct bma220_data {
+ struct spi_device *spi_device;
+ struct mutex lock;
+- s8 buffer[16]; /* 3x8-bit channels + 5x8 padding + 8x8 timestamp */
++ struct {
++ s8 chans[3];
++ /* Ensure timestamp is naturally aligned. */
++ s64 timestamp __aligned(8);
++ } scan;
+ u8 tx_buf[2] ____cacheline_aligned;
+ };
+
+@@ -94,12 +98,12 @@ static irqreturn_t bma220_trigger_handler(int irq, void *p)
+
+ mutex_lock(&data->lock);
+ data->tx_buf[0] = BMA220_REG_ACCEL_X | BMA220_READ_MASK;
+- ret = spi_write_then_read(spi, data->tx_buf, 1, data->buffer,
++ ret = spi_write_then_read(spi, data->tx_buf, 1, &data->scan.chans,
+ ARRAY_SIZE(bma220_channels) - 1);
+ if (ret < 0)
+ goto err;
+
+- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+ pf->timestamp);
+ err:
+ mutex_unlock(&data->lock);
+--
+2.30.2
+
--- /dev/null
+From d8f8806d203540259ed93cd6e1bdb86756db205b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:05 +0100
+Subject: iio: accel: hid: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit c6559bf796ccdb3a0c79db846af96c8f7046880b ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+Note this matches what was done in all the other hid sensor drivers.
+This one was missed previously due to an extra level of indirection.
+
+Found during an audit of all calls of this function.
+
+Fixes: a96cd0f901ee ("iio: accel: hid-sensor-accel-3d: Add timestamp")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-4-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/hid-sensor-accel-3d.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
+index 2f9465cb382f..27f47e1c251e 100644
+--- a/drivers/iio/accel/hid-sensor-accel-3d.c
++++ b/drivers/iio/accel/hid-sensor-accel-3d.c
+@@ -28,8 +28,11 @@ struct accel_3d_state {
+ struct hid_sensor_hub_callbacks callbacks;
+ struct hid_sensor_common common_attributes;
+ struct hid_sensor_hub_attribute_info accel[ACCEL_3D_CHANNEL_MAX];
+- /* Reserve for 3 channels + padding + timestamp */
+- u32 accel_val[ACCEL_3D_CHANNEL_MAX + 3];
++ /* Ensure timestamp is naturally aligned */
++ struct {
++ u32 accel_val[3];
++ s64 timestamp __aligned(8);
++ } scan;
+ int scale_pre_decml;
+ int scale_post_decml;
+ int scale_precision;
+@@ -245,8 +248,8 @@ static int accel_3d_proc_event(struct hid_sensor_hub_device *hsdev,
+ accel_state->timestamp = iio_get_time_ns(indio_dev);
+
+ hid_sensor_push_data(indio_dev,
+- accel_state->accel_val,
+- sizeof(accel_state->accel_val),
++ &accel_state->scan,
++ sizeof(accel_state->scan),
+ accel_state->timestamp);
+
+ accel_state->timestamp = 0;
+@@ -271,7 +274,7 @@ static int accel_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
+ case HID_USAGE_SENSOR_ACCEL_Y_AXIS:
+ case HID_USAGE_SENSOR_ACCEL_Z_AXIS:
+ offset = usage_id - HID_USAGE_SENSOR_ACCEL_X_AXIS;
+- accel_state->accel_val[CHANNEL_SCAN_INDEX_X + offset] =
++ accel_state->scan.accel_val[CHANNEL_SCAN_INDEX_X + offset] =
+ *(u32 *)raw_data;
+ ret = 0;
+ break;
+--
+2.30.2
+
--- /dev/null
+From 21bfe212c6bcb5142832312704e3bb92033dcc3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:06 +0100
+Subject: iio: accel: kxcjk-1013: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 3ab3aa2e7bd57497f9a7c6275c00dce237d2c9ba ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of this function.
+
+Fixes: 1a4fbf6a9286 ("iio: accel: kxcjk1013 3-axis accelerometer driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-5-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/kxcjk-1013.c | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
+index ff724bc17a45..f6720dbba0aa 100644
+--- a/drivers/iio/accel/kxcjk-1013.c
++++ b/drivers/iio/accel/kxcjk-1013.c
+@@ -133,6 +133,13 @@ enum kx_acpi_type {
+ ACPI_KIOX010A,
+ };
+
++enum kxcjk1013_axis {
++ AXIS_X,
++ AXIS_Y,
++ AXIS_Z,
++ AXIS_MAX
++};
++
+ struct kxcjk1013_data {
+ struct regulator_bulk_data regulators[2];
+ struct i2c_client *client;
+@@ -140,7 +147,11 @@ struct kxcjk1013_data {
+ struct iio_trigger *motion_trig;
+ struct iio_mount_matrix orientation;
+ struct mutex mutex;
+- s16 buffer[8];
++ /* Ensure timestamp naturally aligned */
++ struct {
++ s16 chans[AXIS_MAX];
++ s64 timestamp __aligned(8);
++ } scan;
+ u8 odr_bits;
+ u8 range;
+ int wake_thres;
+@@ -154,13 +165,6 @@ struct kxcjk1013_data {
+ enum kx_acpi_type acpi_type;
+ };
+
+-enum kxcjk1013_axis {
+- AXIS_X,
+- AXIS_Y,
+- AXIS_Z,
+- AXIS_MAX,
+-};
+-
+ enum kxcjk1013_mode {
+ STANDBY,
+ OPERATION,
+@@ -1094,12 +1098,12 @@ static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p)
+ ret = i2c_smbus_read_i2c_block_data_or_emulated(data->client,
+ KXCJK1013_REG_XOUT_L,
+ AXIS_MAX * 2,
+- (u8 *)data->buffer);
++ (u8 *)data->scan.chans);
+ mutex_unlock(&data->mutex);
+ if (ret < 0)
+ goto err;
+
+- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+ data->timestamp);
+ err:
+ iio_trigger_notify_done(indio_dev->trig);
+--
+2.30.2
+
--- /dev/null
+From 2e799928bccc928df730dc07e9aac5e64769b705 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:07 +0100
+Subject: iio: accel: mxc4005: Fix overread of data and alignment issue.
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit f65802284a3a337510d7f8f916c97d66c74f2e71 ]
+
+The bulk read size is based on the size of an array that also has
+space for the timestamp alongside the channels.
+Fix that and also fix alignment of the buffer passed
+to iio_push_to_buffers_with_timestamp.
+
+Found during an audit of all calls to this function.
+
+Fixes: 1ce0eda0f757 ("iio: mxc4005: add triggered buffer mode for mxc4005")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-6-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/mxc4005.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c
+index fb3cbaa62bd8..0f90e6ec01e1 100644
+--- a/drivers/iio/accel/mxc4005.c
++++ b/drivers/iio/accel/mxc4005.c
+@@ -56,7 +56,11 @@ struct mxc4005_data {
+ struct mutex mutex;
+ struct regmap *regmap;
+ struct iio_trigger *dready_trig;
+- __be16 buffer[8];
++ /* Ensure timestamp is naturally aligned */
++ struct {
++ __be16 chans[3];
++ s64 timestamp __aligned(8);
++ } scan;
+ bool trigger_enabled;
+ };
+
+@@ -135,7 +139,7 @@ static int mxc4005_read_xyz(struct mxc4005_data *data)
+ int ret;
+
+ ret = regmap_bulk_read(data->regmap, MXC4005_REG_XOUT_UPPER,
+- data->buffer, sizeof(data->buffer));
++ data->scan.chans, sizeof(data->scan.chans));
+ if (ret < 0) {
+ dev_err(data->dev, "failed to read axes\n");
+ return ret;
+@@ -301,7 +305,7 @@ static irqreturn_t mxc4005_trigger_handler(int irq, void *private)
+ if (ret < 0)
+ goto err;
+
+- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+ pf->timestamp);
+
+ err:
+--
+2.30.2
+
--- /dev/null
+From 4455c7f3cf5a36c2d9e34da6d441a9e5c15474d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:08 +0100
+Subject: iio: accel: stk8312: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit f40a71ffec808e7e51848f63f0c0d3c32d65081b ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of this function.
+
+Fixes: 95c12bba51c3 ("iio: accel: Add buffer mode for Sensortek STK8312")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-7-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/stk8312.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/iio/accel/stk8312.c b/drivers/iio/accel/stk8312.c
+index 157d8faefb9e..ba571f0f5c98 100644
+--- a/drivers/iio/accel/stk8312.c
++++ b/drivers/iio/accel/stk8312.c
+@@ -103,7 +103,11 @@ struct stk8312_data {
+ u8 mode;
+ struct iio_trigger *dready_trig;
+ bool dready_trigger_on;
+- s8 buffer[16]; /* 3x8-bit channels + 5x8 padding + 64-bit timestamp */
++ /* Ensure timestamp is naturally aligned */
++ struct {
++ s8 chans[3];
++ s64 timestamp __aligned(8);
++ } scan;
+ };
+
+ static IIO_CONST_ATTR(in_accel_scale_available, STK8312_SCALE_AVAIL);
+@@ -438,7 +442,7 @@ static irqreturn_t stk8312_trigger_handler(int irq, void *p)
+ ret = i2c_smbus_read_i2c_block_data(data->client,
+ STK8312_REG_XOUT,
+ STK8312_ALL_CHANNEL_SIZE,
+- data->buffer);
++ data->scan.chans);
+ if (ret < STK8312_ALL_CHANNEL_SIZE) {
+ dev_err(&data->client->dev, "register read failed\n");
+ mutex_unlock(&data->lock);
+@@ -452,12 +456,12 @@ static irqreturn_t stk8312_trigger_handler(int irq, void *p)
+ mutex_unlock(&data->lock);
+ goto err;
+ }
+- data->buffer[i++] = ret;
++ data->scan.chans[i++] = ret;
+ }
+ }
+ mutex_unlock(&data->lock);
+
+- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+ pf->timestamp);
+ err:
+ iio_trigger_notify_done(indio_dev->trig);
+--
+2.30.2
+
--- /dev/null
+From bfa29bb2459a1e1f04b2ac0bbd51e5300c6f6bde Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:09 +0100
+Subject: iio: accel: stk8ba50: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 334883894bc1e145a1e0f5de1b0d1b6a1133f0e6 ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of this function.
+
+Fixes: db6a19b8251f ("iio: accel: Add trigger support for STK8BA50")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-8-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/stk8ba50.c | 17 ++++++++---------
+ 1 file changed, 8 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/iio/accel/stk8ba50.c b/drivers/iio/accel/stk8ba50.c
+index 7cf9cb7e8666..eb9daa4e623a 100644
+--- a/drivers/iio/accel/stk8ba50.c
++++ b/drivers/iio/accel/stk8ba50.c
+@@ -91,12 +91,11 @@ struct stk8ba50_data {
+ u8 sample_rate_idx;
+ struct iio_trigger *dready_trig;
+ bool dready_trigger_on;
+- /*
+- * 3 x 16-bit channels (10-bit data, 6-bit padding) +
+- * 1 x 16 padding +
+- * 4 x 16 64-bit timestamp
+- */
+- s16 buffer[8];
++ /* Ensure timestamp is naturally aligned */
++ struct {
++ s16 chans[3];
++ s64 timetamp __aligned(8);
++ } scan;
+ };
+
+ #define STK8BA50_ACCEL_CHANNEL(index, reg, axis) { \
+@@ -324,7 +323,7 @@ static irqreturn_t stk8ba50_trigger_handler(int irq, void *p)
+ ret = i2c_smbus_read_i2c_block_data(data->client,
+ STK8BA50_REG_XOUT,
+ STK8BA50_ALL_CHANNEL_SIZE,
+- (u8 *)data->buffer);
++ (u8 *)data->scan.chans);
+ if (ret < STK8BA50_ALL_CHANNEL_SIZE) {
+ dev_err(&data->client->dev, "register read failed\n");
+ goto err;
+@@ -337,10 +336,10 @@ static irqreturn_t stk8ba50_trigger_handler(int irq, void *p)
+ if (ret < 0)
+ goto err;
+
+- data->buffer[i++] = ret;
++ data->scan.chans[i++] = ret;
+ }
+ }
+- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+ pf->timestamp);
+ err:
+ mutex_unlock(&data->lock);
+--
+2.30.2
+
--- /dev/null
+From b2759f3224939aa483c3ef3ad8a77f76375bd79d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Jun 2021 16:22:54 +0100
+Subject: iio: adc: at91-sama5d2: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 8f884758966259fa8c50c137ac6d4ce9bb7859db ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of this function.
+
+Fixes: 5e1a1da0f8c9 ("iio: adc: at91-sama5d2_adc: add hw trigger and buffer support")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Eugen Hristev <eugen.hristev@microchip.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20210613152301.571002-2-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/at91-sama5d2_adc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
+index a7826f097b95..d356b515df09 100644
+--- a/drivers/iio/adc/at91-sama5d2_adc.c
++++ b/drivers/iio/adc/at91-sama5d2_adc.c
+@@ -403,7 +403,8 @@ struct at91_adc_state {
+ struct at91_adc_dma dma_st;
+ struct at91_adc_touch touch_st;
+ struct iio_dev *indio_dev;
+- u16 buffer[AT91_BUFFER_MAX_HWORDS];
++ /* Ensure naturally aligned timestamp */
++ u16 buffer[AT91_BUFFER_MAX_HWORDS] __aligned(8);
+ /*
+ * lock to prevent concurrent 'single conversion' requests through
+ * sysfs.
+--
+2.30.2
+
--- /dev/null
+From c3bbd075cad8b6c0f477483ccdc0525fb4404386 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Jun 2021 16:22:55 +0100
+Subject: iio: adc: hx711: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit afe2a789fbf7acd1a05407fc7839cc08d23825e3 ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of this function.
+
+Fixes: d3bf60450d47 ("iio: hx711: add triggered buffer support")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Andreas Klinger <ak@it-klinger.de>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20210613152301.571002-3-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/hx711.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
+index 6a173531d355..f7ee856a6b8b 100644
+--- a/drivers/iio/adc/hx711.c
++++ b/drivers/iio/adc/hx711.c
+@@ -86,9 +86,9 @@ struct hx711_data {
+ struct mutex lock;
+ /*
+ * triggered buffer
+- * 2x32-bit channel + 64-bit timestamp
++ * 2x32-bit channel + 64-bit naturally aligned timestamp
+ */
+- u32 buffer[4];
++ u32 buffer[4] __aligned(8);
+ /*
+ * delay after a rising edge on SCK until the data is ready DOUT
+ * this is dependent on the hx711 where the datasheet tells a
+--
+2.30.2
+
--- /dev/null
+From d2f31d1b290f32336437fb051571bd8cb181a7ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Jun 2021 16:22:56 +0100
+Subject: iio: adc: mxs-lradc: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 6a6be221b8bd561b053f0701ec752a5ed9007f69 ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+Add a comment on why the buffer is the size it is as not immediately
+obvious.
+
+Found during an audit of all calls of this function.
+
+Fixes: 6dd112b9f85e ("iio: adc: mxs-lradc: Add support for ADC driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Andreas Klinger <ak@it-klinger.de>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20210613152301.571002-4-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/mxs-lradc-adc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/mxs-lradc-adc.c b/drivers/iio/adc/mxs-lradc-adc.c
+index 30e29f44ebd2..c480cb489c1a 100644
+--- a/drivers/iio/adc/mxs-lradc-adc.c
++++ b/drivers/iio/adc/mxs-lradc-adc.c
+@@ -115,7 +115,8 @@ struct mxs_lradc_adc {
+ struct device *dev;
+
+ void __iomem *base;
+- u32 buffer[10];
++ /* Maximum of 8 channels + 8 byte ts */
++ u32 buffer[10] __aligned(8);
+ struct iio_trigger *trig;
+ struct completion completion;
+ spinlock_t lock;
+--
+2.30.2
+
--- /dev/null
+From 328522384255e4cf38b1172cd6223dd67b5ef80b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:10 +0100
+Subject: iio: adc: ti-ads1015: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit d85d71dd1ab67eaa7351f69fec512d8f09d164e1 ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of this function.
+
+Fixes: ecc24e72f437 ("iio: adc: Add TI ADS1015 ADC driver support")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Daniel Baluta <daniel.baluta@nxp.com>
+Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-9-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ti-ads1015.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c
+index 9fef39bcf997..5b828428be77 100644
+--- a/drivers/iio/adc/ti-ads1015.c
++++ b/drivers/iio/adc/ti-ads1015.c
+@@ -395,10 +395,14 @@ static irqreturn_t ads1015_trigger_handler(int irq, void *p)
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct ads1015_data *data = iio_priv(indio_dev);
+- s16 buf[8]; /* 1x s16 ADC val + 3x s16 padding + 4x s16 timestamp */
++ /* Ensure natural alignment of timestamp */
++ struct {
++ s16 chan;
++ s64 timestamp __aligned(8);
++ } scan;
+ int chan, ret, res;
+
+- memset(buf, 0, sizeof(buf));
++ memset(&scan, 0, sizeof(scan));
+
+ mutex_lock(&data->lock);
+ chan = find_first_bit(indio_dev->active_scan_mask,
+@@ -409,10 +413,10 @@ static irqreturn_t ads1015_trigger_handler(int irq, void *p)
+ goto err;
+ }
+
+- buf[0] = res;
++ scan.chan = res;
+ mutex_unlock(&data->lock);
+
+- iio_push_to_buffers_with_timestamp(indio_dev, buf,
++ iio_push_to_buffers_with_timestamp(indio_dev, &scan,
+ iio_get_time_ns(indio_dev));
+
+ err:
+--
+2.30.2
+
--- /dev/null
+From 3798ff99a60661b7a947adcefd36c2043add8d46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Jun 2021 16:22:57 +0100
+Subject: iio: adc: ti-ads8688: Fix alignment of buffer in
+ iio_push_to_buffers_with_timestamp()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 61fa5dfa5f52806f5ce37a0ba5712c271eb22f98 ]
+
+Add __aligned(8) to ensure the buffer passed to
+iio_push_to_buffers_with_timestamp() is suitable for the naturally
+aligned timestamp that will be inserted.
+
+Fixes: f214ff521fb1 ("iio: ti-ads8688: Update buffer allocation for timestamps")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20210613152301.571002-5-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ti-ads8688.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c
+index 16bcb37eebb7..79c803537dc4 100644
+--- a/drivers/iio/adc/ti-ads8688.c
++++ b/drivers/iio/adc/ti-ads8688.c
+@@ -383,7 +383,8 @@ static irqreturn_t ads8688_trigger_handler(int irq, void *p)
+ {
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+- u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)];
++ /* Ensure naturally aligned timestamp */
++ u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)] __aligned(8);
+ int i, j = 0;
+
+ for (i = 0; i < indio_dev->masklength; i++) {
+--
+2.30.2
+
--- /dev/null
+From 7b24c2f82cb8b0e808bcf3de850758f2350b94f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:11 +0100
+Subject: iio: adc: vf610: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 7765dfaa22ea08abf0c175e7553826ba2a939632 ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of uses of
+iio_push_to_buffers_with_timestamp()
+
+Fixes: 0010d6b44406 ("iio: adc: vf610: Add IIO buffer support for Vybrid ADC")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Stefan-Gabriel Mirea <stefan-gabriel.mirea@nxp.com>
+Cc: Sanchayan Maity <maitysanchayan@gmail.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-10-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/vf610_adc.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
+index 1d794cf3e3f1..fd57fc43e8e5 100644
+--- a/drivers/iio/adc/vf610_adc.c
++++ b/drivers/iio/adc/vf610_adc.c
+@@ -167,7 +167,11 @@ struct vf610_adc {
+ u32 sample_freq_avail[5];
+
+ struct completion completion;
+- u16 buffer[8];
++ /* Ensure the timestamp is naturally aligned */
++ struct {
++ u16 chan;
++ s64 timestamp __aligned(8);
++ } scan;
+ };
+
+ static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
+@@ -579,9 +583,9 @@ static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
+ if (coco & VF610_ADC_HS_COCO0) {
+ info->value = vf610_adc_read_data(info);
+ if (iio_buffer_enabled(indio_dev)) {
+- info->buffer[0] = info->value;
++ info->scan.chan = info->value;
+ iio_push_to_buffers_with_timestamp(indio_dev,
+- info->buffer,
++ &info->scan,
+ iio_get_time_ns(indio_dev));
+ iio_trigger_notify_done(indio_dev->trig);
+ } else
+--
+2.30.2
+
--- /dev/null
+From 3c03efb5858516b827cc4d3be7e5cf6045decb0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Apr 2021 12:19:04 +0200
+Subject: iio: adis16400: do not return ints in irq handlers
+
+From: Nuno Sa <nuno.sa@analog.com>
+
+[ Upstream commit ab3df79782e7d8a27a58576c9b4e8c6c4879ad79 ]
+
+On an IRQ handler we should not return normal error codes as 'irqreturn_t'
+is expected.
+
+Not necessary to apply to stable as the original check cannot fail and
+as such the bug cannot actually occur.
+
+Fixes: 5eda3550a3cc1 ("staging:iio:adis16400: Preallocate transfer message")
+Reviewed-by: Alexandru Ardelean <ardeleanalex@gmail.com>
+Signed-off-by: Nuno Sa <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20210422101911.135630-3-nuno.sa@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/adis16400.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c
+index 768aa493a1a6..b2f92b55b910 100644
+--- a/drivers/iio/imu/adis16400.c
++++ b/drivers/iio/imu/adis16400.c
+@@ -645,9 +645,6 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
+ void *buffer;
+ int ret;
+
+- if (!adis->buffer)
+- return -ENOMEM;
+-
+ if (!(st->variant->flags & ADIS16400_NO_BURST) &&
+ st->adis.spi->max_speed_hz > ADIS16400_SPI_BURST) {
+ st->adis.spi->max_speed_hz = ADIS16400_SPI_BURST;
+--
+2.30.2
+
--- /dev/null
+From e60f892b4b719f9859999330cf2ee2717d1e5f89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Apr 2021 10:54:49 +0200
+Subject: iio: adis16475: do not return ints in irq handlers
+
+From: Nuno Sa <nuno.sa@analog.com>
+
+[ Upstream commit 00a72db718fa198da3946286dcad222399ccd4fb ]
+
+On an IRQ handler we should not return normal error codes as 'irqreturn_t'
+is expected.
+
+This is done by jumping to the 'check_burst32' label where we return
+'IRQ_HANDLED'. Note that it is fine to do the burst32 check in this
+error path. If we have proper settings to apply burst32, we might just
+do the setup now so that the next sample already uses it.
+
+Fixes: fff7352bf7a3c ("iio: imu: Add support for adis16475")
+Reviewed-by: Alexandru Ardelean <ardeleanalex@gmail.com>
+Signed-off-by: Nuno Sa <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20210427085454.30616-2-nuno.sa@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/adis16475.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/imu/adis16475.c b/drivers/iio/imu/adis16475.c
+index 1de62fc79e0f..51b76444db0b 100644
+--- a/drivers/iio/imu/adis16475.c
++++ b/drivers/iio/imu/adis16475.c
+@@ -1068,7 +1068,7 @@ static irqreturn_t adis16475_trigger_handler(int irq, void *p)
+
+ ret = spi_sync(adis->spi, &adis->msg);
+ if (ret)
+- return ret;
++ goto check_burst32;
+
+ adis->spi->max_speed_hz = cached_spi_speed_hz;
+ buffer = adis->buffer;
+--
+2.30.2
+
--- /dev/null
+From 8cdfd4fe1e525cabc36d0ed61163421e4774c241 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Apr 2021 12:19:03 +0200
+Subject: iio: adis_buffer: do not return ints in irq handlers
+
+From: Nuno Sa <nuno.sa@analog.com>
+
+[ Upstream commit d877539ad8e8fdde9af69887055fec6402be1a13 ]
+
+On an IRQ handler we should not return normal error codes as 'irqreturn_t'
+is expected.
+
+Not necessarily stable material as the old check cannot fail, so it's a bug
+we can not hit.
+
+Fixes: ccd2b52f4ac69 ("staging:iio: Add common ADIS library")
+Reviewed-by: Alexandru Ardelean <ardeleanalex@gmail.com>
+Signed-off-by: Nuno Sa <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20210422101911.135630-2-nuno.sa@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/adis_buffer.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c
+index ac354321f63a..175af154e443 100644
+--- a/drivers/iio/imu/adis_buffer.c
++++ b/drivers/iio/imu/adis_buffer.c
+@@ -129,9 +129,6 @@ static irqreturn_t adis_trigger_handler(int irq, void *p)
+ struct adis *adis = iio_device_get_drvdata(indio_dev);
+ int ret;
+
+- if (!adis->buffer)
+- return -ENOMEM;
+-
+ if (adis->data->has_paging) {
+ mutex_lock(&adis->state_lock);
+ if (adis->current_page != 0) {
+--
+2.30.2
+
--- /dev/null
+From f1af1744aab3a03c7d09843f1bf697d4d1dd8fa2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:13:46 +0100
+Subject: iio: chemical: atlas: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit b0f5d8db7348a6ce5cdd79fba46ebc91eebc8fd9 ]
+
+Variable location for the timestamp, so just use __aligned(8)
+to ensure it is always possible to naturally align it.
+
+Found during an audit of all calls of uses of
+iio_push_to_buffers_with_timestamp()
+
+Fixes tag is not accurate, but it will need manual backporting beyond
+that point if anyone cares.
+
+Fixes: 0d15190f53b4 ("iio: chemical: atlas-ph-sensor: rename atlas-ph-sensor to atlas-sensor")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Matt Ranostay <matt.ranostay@konsulko.com>
+Acked-by: Matt Ranostay <matt.ranostay@konsulko.com>
+Link: https://lore.kernel.org/r/20210501171352.512953-6-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/chemical/atlas-sensor.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/chemical/atlas-sensor.c b/drivers/iio/chemical/atlas-sensor.c
+index 56ba6c82b501..6795722c68b2 100644
+--- a/drivers/iio/chemical/atlas-sensor.c
++++ b/drivers/iio/chemical/atlas-sensor.c
+@@ -91,8 +91,8 @@ struct atlas_data {
+ struct regmap *regmap;
+ struct irq_work work;
+ unsigned int interrupt_enabled;
+-
+- __be32 buffer[6]; /* 96-bit data + 32-bit pad + 64-bit timestamp */
++ /* 96-bit data + 32-bit pad + 64-bit timestamp */
++ __be32 buffer[6] __aligned(8);
+ };
+
+ static const struct regmap_config atlas_regmap_config = {
+--
+2.30.2
+
--- /dev/null
+From e4289d5b413f152e5b5468b5e84c7a2138538511 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:13:47 +0100
+Subject: iio: cros_ec_sensors: Fix alignment of buffer in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 8dea228b174ac9637b567e5ef54f4c40db4b3c41 ]
+
+The samples buffer is passed to iio_push_to_buffers_with_timestamp()
+which requires a buffer aligned to 8 bytes as it is assumed that
+the timestamp will be naturally aligned if present.
+
+Fixes tag is inaccurate but prior to that likely manual backporting needed
+(for anything before 4.18) Earlier than that the include file to fix is
+drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.h:
+commit 974e6f02e27 ("iio: cros_ec_sensors_core: Add common functions
+for the ChromeOS EC Sensor Hub.") present since kernel stable 4.10.
+(Thanks to Gwendal for tracking this down)
+
+Fixes: 5a0b8cb46624c ("iio: cros_ec: Move cros_ec_sensors_core.h in /include")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Gwendal Grignou <gwendal@chromium.org
+Link: https://lore.kernel.org/r/20210501171352.512953-7-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/iio/common/cros_ec_sensors_core.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/iio/common/cros_ec_sensors_core.h b/include/linux/iio/common/cros_ec_sensors_core.h
+index 7ce8a8adad58..c582e1a14232 100644
+--- a/include/linux/iio/common/cros_ec_sensors_core.h
++++ b/include/linux/iio/common/cros_ec_sensors_core.h
+@@ -77,7 +77,7 @@ struct cros_ec_sensors_core_state {
+ u16 scale;
+ } calib[CROS_EC_SENSOR_MAX_AXIS];
+ s8 sign[CROS_EC_SENSOR_MAX_AXIS];
+- u8 samples[CROS_EC_SAMPLE_SIZE];
++ u8 samples[CROS_EC_SAMPLE_SIZE] __aligned(8);
+
+ int (*read_ec_sensors_data)(struct iio_dev *indio_dev,
+ unsigned long scan_mask, s16 *data);
+--
+2.30.2
+
--- /dev/null
+From c1a207835761ea858c8b31eb08c32a171c94384b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 May 2021 14:05:36 +0000
+Subject: iio: dummy: Fix build error when CONFIG_IIO_TRIGGERED_BUFFER is not
+ set
+
+From: Wei Yongjun <weiyongjun1@huawei.com>
+
+[ Upstream commit 94588c1bf1c8701392e1dc105c670d0d2fc7676a ]
+
+Gcc reports build error when CONFIG_IIO_TRIGGERED_BUFFER is not set:
+
+riscv64-linux-gnu-ld: drivers/iio/dummy/iio_simple_dummy_buffer.o: in function `iio_simple_dummy_configure_buffer':
+iio_simple_dummy_buffer.c:(.text+0x2b0): undefined reference to `iio_triggered_buffer_setup_ext'
+riscv64-linux-gnu-ld: drivers/iio/dummy/iio_simple_dummy_buffer.o: in function `.L0 ':
+iio_simple_dummy_buffer.c:(.text+0x2fc): undefined reference to `iio_triggered_buffer_cleanup'
+
+Fix it by select IIO_TRIGGERED_BUFFER for config IIO_SIMPLE_DUMMY_BUFFER.
+
+Fixes: 738f6ba11800 ("iio: dummy: iio_simple_dummy_buffer: use triggered buffer core calls")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dummy/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/iio/dummy/Kconfig b/drivers/iio/dummy/Kconfig
+index 5c5c2f8c55f3..1f46cb9e51b7 100644
+--- a/drivers/iio/dummy/Kconfig
++++ b/drivers/iio/dummy/Kconfig
+@@ -34,6 +34,7 @@ config IIO_SIMPLE_DUMMY_BUFFER
+ select IIO_BUFFER
+ select IIO_TRIGGER
+ select IIO_KFIFO_BUF
++ select IIO_TRIGGERED_BUFFER
+ help
+ Add buffered data capture to the simple dummy driver.
+
+--
+2.30.2
+
--- /dev/null
+From a728206d9753026c181306aa5edee387542e1912 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:12 +0100
+Subject: iio: gyro: bmg160: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 06778d881f3798ce93ffbbbf801234292250b598 ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of uses of
+iio_push_to_buffers_with_timestamp()
+
+Fixes: 13426454b649 ("iio: bmg160: Separate i2c and core driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Stephan Gerhold <stephan@gerhold.net>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-11-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/gyro/bmg160_core.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c
+index b11ebd9bb7a4..7bc13ff2c3ac 100644
+--- a/drivers/iio/gyro/bmg160_core.c
++++ b/drivers/iio/gyro/bmg160_core.c
+@@ -98,7 +98,11 @@ struct bmg160_data {
+ struct iio_trigger *motion_trig;
+ struct iio_mount_matrix orientation;
+ struct mutex mutex;
+- s16 buffer[8];
++ /* Ensure naturally aligned timestamp */
++ struct {
++ s16 chans[3];
++ s64 timestamp __aligned(8);
++ } scan;
+ u32 dps_range;
+ int ev_enable_state;
+ int slope_thres;
+@@ -882,12 +886,12 @@ static irqreturn_t bmg160_trigger_handler(int irq, void *p)
+
+ mutex_lock(&data->mutex);
+ ret = regmap_bulk_read(data->regmap, BMG160_REG_XOUT_L,
+- data->buffer, AXIS_MAX * 2);
++ data->scan.chans, AXIS_MAX * 2);
+ mutex_unlock(&data->mutex);
+ if (ret < 0)
+ goto err;
+
+- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+ pf->timestamp);
+ err:
+ iio_trigger_notify_done(indio_dev->trig);
+--
+2.30.2
+
--- /dev/null
+From 485b816cce5e7da64eafb73900f4ff859b39d7a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:13 +0100
+Subject: iio: humidity: am2315: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit f4ca2e2595d9fee65d5ce0d218b22ce00e5b2915 ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of uses of
+iio_push_to_buffers_with_timestamp()
+
+Fixes: 0d96d5ead3f7 ("iio: humidity: Add triggered buffer support for AM2315")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-12-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/humidity/am2315.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/iio/humidity/am2315.c b/drivers/iio/humidity/am2315.c
+index 23bc9c784ef4..248d0f262d60 100644
+--- a/drivers/iio/humidity/am2315.c
++++ b/drivers/iio/humidity/am2315.c
+@@ -33,7 +33,11 @@
+ struct am2315_data {
+ struct i2c_client *client;
+ struct mutex lock;
+- s16 buffer[8]; /* 2x16-bit channels + 2x16 padding + 4x16 timestamp */
++ /* Ensure timestamp is naturally aligned */
++ struct {
++ s16 chans[2];
++ s64 timestamp __aligned(8);
++ } scan;
+ };
+
+ struct am2315_sensor_data {
+@@ -167,20 +171,20 @@ static irqreturn_t am2315_trigger_handler(int irq, void *p)
+
+ mutex_lock(&data->lock);
+ if (*(indio_dev->active_scan_mask) == AM2315_ALL_CHANNEL_MASK) {
+- data->buffer[0] = sensor_data.hum_data;
+- data->buffer[1] = sensor_data.temp_data;
++ data->scan.chans[0] = sensor_data.hum_data;
++ data->scan.chans[1] = sensor_data.temp_data;
+ } else {
+ i = 0;
+ for_each_set_bit(bit, indio_dev->active_scan_mask,
+ indio_dev->masklength) {
+- data->buffer[i] = (bit ? sensor_data.temp_data :
+- sensor_data.hum_data);
++ data->scan.chans[i] = (bit ? sensor_data.temp_data :
++ sensor_data.hum_data);
+ i++;
+ }
+ }
+ mutex_unlock(&data->lock);
+
+- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+ pf->timestamp);
+ err:
+ iio_trigger_notify_done(indio_dev->trig);
+--
+2.30.2
+
--- /dev/null
+From a42f6ff282eda90f525abb474db1e6435986962a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:19 +0100
+Subject: iio: light: isl29125: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 3d4725194de6935dba2ad7c9cc075c885008f747 ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of uses of
+iio_push_to_buffers_with_timestamp()
+
+Fixes: 6c25539cbc46 ("iio: Add Intersil isl29125 digital color light sensor driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-18-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/light/isl29125.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/light/isl29125.c b/drivers/iio/light/isl29125.c
+index b93b85dbc3a6..ba53b50d711a 100644
+--- a/drivers/iio/light/isl29125.c
++++ b/drivers/iio/light/isl29125.c
+@@ -51,7 +51,11 @@
+ struct isl29125_data {
+ struct i2c_client *client;
+ u8 conf1;
+- u16 buffer[8]; /* 3x 16-bit, padding, 8 bytes timestamp */
++ /* Ensure timestamp is naturally aligned */
++ struct {
++ u16 chans[3];
++ s64 timestamp __aligned(8);
++ } scan;
+ };
+
+ #define ISL29125_CHANNEL(_color, _si) { \
+@@ -184,10 +188,10 @@ static irqreturn_t isl29125_trigger_handler(int irq, void *p)
+ if (ret < 0)
+ goto done;
+
+- data->buffer[j++] = ret;
++ data->scan.chans[j++] = ret;
+ }
+
+- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+ iio_get_time_ns(indio_dev));
+
+ done:
+--
+2.30.2
+
--- /dev/null
+From 1aab3f53d7ca9031252aa03aed9173aed25a73c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:20 +0100
+Subject: iio: light: tcs3414: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit ff08fbc22ab32ccc6690c21b0e5e1d402dcc076f ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of uses of
+iio_push_to_buffers_with_timestamp()
+
+Fixes: a244e7b57f0f ("iio: Add driver for AMS/TAOS tcs3414 digital color sensor")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-19-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/light/tcs3414.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/light/tcs3414.c b/drivers/iio/light/tcs3414.c
+index 6fe5d46f80d4..0593abd600ec 100644
+--- a/drivers/iio/light/tcs3414.c
++++ b/drivers/iio/light/tcs3414.c
+@@ -53,7 +53,11 @@ struct tcs3414_data {
+ u8 control;
+ u8 gain;
+ u8 timing;
+- u16 buffer[8]; /* 4x 16-bit + 8 bytes timestamp */
++ /* Ensure timestamp is naturally aligned */
++ struct {
++ u16 chans[4];
++ s64 timestamp __aligned(8);
++ } scan;
+ };
+
+ #define TCS3414_CHANNEL(_color, _si, _addr) { \
+@@ -209,10 +213,10 @@ static irqreturn_t tcs3414_trigger_handler(int irq, void *p)
+ if (ret < 0)
+ goto done;
+
+- data->buffer[j++] = ret;
++ data->scan.chans[j++] = ret;
+ }
+
+- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+ iio_get_time_ns(indio_dev));
+
+ done:
+--
+2.30.2
+
--- /dev/null
+From f520bc0c0df515e4006f750e5a3024644d677603 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:21 +0100
+Subject: iio: light: tcs3472: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit df2f37cffd6ed486d613e7ee22aadc8e49ae2dd3 ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of uses of
+iio_push_to_buffers_with_timestamp().
+
+Fixes tag is not strictly accurate as prior to that patch there was
+potentially an unaligned write. However, any backport past there will
+need to be done manually.
+
+Fixes: 0624bf847dd0 ("iio:tcs3472: Use iio_push_to_buffers_with_timestamp()")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-20-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/light/tcs3472.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c
+index b41068492338..371c6a39a165 100644
+--- a/drivers/iio/light/tcs3472.c
++++ b/drivers/iio/light/tcs3472.c
+@@ -64,7 +64,11 @@ struct tcs3472_data {
+ u8 control;
+ u8 atime;
+ u8 apers;
+- u16 buffer[8]; /* 4 16-bit channels + 64-bit timestamp */
++ /* Ensure timestamp is naturally aligned */
++ struct {
++ u16 chans[4];
++ s64 timestamp __aligned(8);
++ } scan;
+ };
+
+ static const struct iio_event_spec tcs3472_events[] = {
+@@ -386,10 +390,10 @@ static irqreturn_t tcs3472_trigger_handler(int irq, void *p)
+ if (ret < 0)
+ goto done;
+
+- data->buffer[j++] = ret;
++ data->scan.chans[j++] = ret;
+ }
+
+- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+ iio_get_time_ns(indio_dev));
+
+ done:
+--
+2.30.2
+
--- /dev/null
+From 27a169b7b5db5aeab2b7d84a0ad8d024a19161e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Jun 2021 16:22:59 +0100
+Subject: iio: light: vcnl4000: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit dce793c0ab00c35039028fdcd5ce123805a01361 ]
+
+Add __aligned(8) to ensure the buffer passed to
+iio_push_to_buffers_with_timestamp() is suitable for the naturally
+aligned timestamp that will be inserted.
+
+Here an explicit structure is not used, because the holes would
+necessitate the addition of an explict memset(), to avoid a kernel
+data leak, making for a less minimal fix.
+
+Found during an audit of all callers of iio_push_to_buffers_with_timestamp()
+
+Fixes: 8fe78d5261e7 ("iio: vcnl4000: Add buffer support for VCNL4010/20.")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Mathieu Othacehe <m.othacehe@gmail.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20210613152301.571002-7-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/light/vcnl4000.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c
+index 2f7916f95689..3b5e27053ef2 100644
+--- a/drivers/iio/light/vcnl4000.c
++++ b/drivers/iio/light/vcnl4000.c
+@@ -910,7 +910,7 @@ static irqreturn_t vcnl4010_trigger_handler(int irq, void *p)
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct vcnl4000_data *data = iio_priv(indio_dev);
+ const unsigned long *active_scan_mask = indio_dev->active_scan_mask;
+- u16 buffer[8] = {0}; /* 1x16-bit + ts */
++ u16 buffer[8] __aligned(8) = {0}; /* 1x16-bit + naturally aligned ts */
+ bool data_read = false;
+ unsigned long isr;
+ int val = 0;
+--
+2.30.2
+
--- /dev/null
+From fdcfd51cd7b1c6e2f35644e66294ee36ff898719 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Jun 2021 16:23:00 +0100
+Subject: iio: light: vcnl4035: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit ec90b52c07c0403a6db60d752484ec08d605ead0 ]
+
+Add __aligned(8) to ensure the buffer passed to
+iio_push_to_buffers_with_timestamp() is suitable for the naturally
+aligned timestamp that will be inserted.
+
+Here an explicit structure is not used, because the holes would
+necessitate the addition of an explict memset(), to avoid a potential
+kernel data leak, making for a less minimal fix.
+
+Fixes: 55707294c4eb ("iio: light: Add support for vishay vcnl4035")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Parthiban Nallathambi <pn@denx.de>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20210613152301.571002-8-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/light/vcnl4035.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iio/light/vcnl4035.c b/drivers/iio/light/vcnl4035.c
+index ae87740d9cef..bc0777411712 100644
+--- a/drivers/iio/light/vcnl4035.c
++++ b/drivers/iio/light/vcnl4035.c
+@@ -102,7 +102,8 @@ static irqreturn_t vcnl4035_trigger_consumer_handler(int irq, void *p)
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct vcnl4035_data *data = iio_priv(indio_dev);
+- u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)];
++ /* Ensure naturally aligned timestamp */
++ u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)] __aligned(8);
+ int ret;
+
+ ret = regmap_read(data->regmap, VCNL4035_ALS_DATA, (int *)buffer);
+--
+2.30.2
+
--- /dev/null
+From 1e49e6473b96a2d0153b062aaf594b52a7d5a54c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:18 +0100
+Subject: iio: magn: bmc150: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 7692088f72865c41b6b531fd09486ee99a5da930 ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of uses of
+iio_push_to_buffers_with_timestamp()
+
+Fixes: c91746a2361d ("iio: magn: Add support for BMC150 magnetometer")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Stephan Gerhold <stephan@gerhold.net>
+Cc: Linus Walleij <linus.walleij@linaro.org>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-17-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/magnetometer/bmc150_magn.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/iio/magnetometer/bmc150_magn.c b/drivers/iio/magnetometer/bmc150_magn.c
+index 00f9766bad5c..d534f4f3909e 100644
+--- a/drivers/iio/magnetometer/bmc150_magn.c
++++ b/drivers/iio/magnetometer/bmc150_magn.c
+@@ -138,8 +138,11 @@ struct bmc150_magn_data {
+ struct regmap *regmap;
+ struct regulator_bulk_data regulators[2];
+ struct iio_mount_matrix orientation;
+- /* 4 x 32 bits for x, y z, 4 bytes align, 64 bits timestamp */
+- s32 buffer[6];
++ /* Ensure timestamp is naturally aligned */
++ struct {
++ s32 chans[3];
++ s64 timestamp __aligned(8);
++ } scan;
+ struct iio_trigger *dready_trig;
+ bool dready_trigger_on;
+ int max_odr;
+@@ -675,11 +678,11 @@ static irqreturn_t bmc150_magn_trigger_handler(int irq, void *p)
+ int ret;
+
+ mutex_lock(&data->mutex);
+- ret = bmc150_magn_read_xyz(data, data->buffer);
++ ret = bmc150_magn_read_xyz(data, data->scan.chans);
+ if (ret < 0)
+ goto err;
+
+- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+ pf->timestamp);
+
+ err:
+--
+2.30.2
+
--- /dev/null
+From d498772e05051afd0aa8e14005b5092ed21fbcda Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:17 +0100
+Subject: iio: magn: hmc5843: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 1ef2f51e9fe424ccecca5bb0373d71b900c2cd41 ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of uses of
+iio_push_to_buffers_with_timestamp()
+
+Fixes: 7247645f6865 ("iio: hmc5843: Move hmc5843 out of staging")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-16-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/magnetometer/hmc5843.h | 8 ++++++--
+ drivers/iio/magnetometer/hmc5843_core.c | 4 ++--
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/iio/magnetometer/hmc5843.h b/drivers/iio/magnetometer/hmc5843.h
+index 3f6c0b662941..242f742f2643 100644
+--- a/drivers/iio/magnetometer/hmc5843.h
++++ b/drivers/iio/magnetometer/hmc5843.h
+@@ -33,7 +33,8 @@ enum hmc5843_ids {
+ * @lock: update and read regmap data
+ * @regmap: hardware access register maps
+ * @variant: describe chip variants
+- * @buffer: 3x 16-bit channels + padding + 64-bit timestamp
++ * @scan: buffer to pack data for passing to
++ * iio_push_to_buffers_with_timestamp()
+ */
+ struct hmc5843_data {
+ struct device *dev;
+@@ -41,7 +42,10 @@ struct hmc5843_data {
+ struct regmap *regmap;
+ const struct hmc5843_chip_info *variant;
+ struct iio_mount_matrix orientation;
+- __be16 buffer[8];
++ struct {
++ __be16 chans[3];
++ s64 timestamp __aligned(8);
++ } scan;
+ };
+
+ int hmc5843_common_probe(struct device *dev, struct regmap *regmap,
+diff --git a/drivers/iio/magnetometer/hmc5843_core.c b/drivers/iio/magnetometer/hmc5843_core.c
+index 780faea61d82..221563e0c18f 100644
+--- a/drivers/iio/magnetometer/hmc5843_core.c
++++ b/drivers/iio/magnetometer/hmc5843_core.c
+@@ -446,13 +446,13 @@ static irqreturn_t hmc5843_trigger_handler(int irq, void *p)
+ }
+
+ ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS,
+- data->buffer, 3 * sizeof(__be16));
++ data->scan.chans, sizeof(data->scan.chans));
+
+ mutex_unlock(&data->lock);
+ if (ret < 0)
+ goto done;
+
+- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+ iio_get_time_ns(indio_dev));
+
+ done:
+--
+2.30.2
+
--- /dev/null
+From 422c39a2fc017a5898f2c77981cf135ee59b5622 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Jun 2021 16:22:58 +0100
+Subject: iio: magn: rm3100: Fix alignment of buffer in
+ iio_push_to_buffers_with_timestamp()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit b8f939fd20690623cb24845a563e7bc1e4a21482 ]
+
+Add __aligned(8) to ensure the buffer passed to
+iio_push_to_buffers_with_timestamp() is suitable for the naturally
+aligned timestamp that will be inserted.
+
+Here an explicit structure is not used, because this buffer is used in
+a non-trivial way for data repacking.
+
+Fixes: 121354b2eceb ("iio: magnetometer: Add driver support for PNI RM3100")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Song Qiang <songqiang1304521@gmail.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20210613152301.571002-6-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/magnetometer/rm3100-core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iio/magnetometer/rm3100-core.c b/drivers/iio/magnetometer/rm3100-core.c
+index dd811da9cb6d..934da20781bb 100644
+--- a/drivers/iio/magnetometer/rm3100-core.c
++++ b/drivers/iio/magnetometer/rm3100-core.c
+@@ -78,7 +78,8 @@ struct rm3100_data {
+ bool use_interrupt;
+ int conversion_time;
+ int scale;
+- u8 buffer[RM3100_SCAN_BYTES];
++ /* Ensure naturally aligned timestamp */
++ u8 buffer[RM3100_SCAN_BYTES] __aligned(8);
+ struct iio_trigger *drdy_trig;
+
+ /*
+--
+2.30.2
+
--- /dev/null
+From 486dde891f54724b08380ecff309abfc78e92973 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:13:48 +0100
+Subject: iio: potentiostat: lmp91000: Fix alignment of buffer in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 8979b67ec61abc232636400ee8c758a16a73c95f ]
+
+Add __aligned(8) to ensure the buffer passed to
+iio_push_to_buffers_with_timestamp() is suitable for the naturally
+aligned timestamp that will be inserted.
+
+Here structure is not used, because this buffer is also used
+elsewhere in the driver.
+
+Fixes: 67e17300dc1d ("iio: potentiostat: add LMP91000 support")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Matt Ranostay <matt.ranostay@konsulko.com>
+Acked-by: Matt Ranostay <matt.ranostay@konsulko.com>
+Link: https://lore.kernel.org/r/20210501171352.512953-8-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/potentiostat/lmp91000.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/potentiostat/lmp91000.c b/drivers/iio/potentiostat/lmp91000.c
+index 8a9c576616ee..ff39ba975da7 100644
+--- a/drivers/iio/potentiostat/lmp91000.c
++++ b/drivers/iio/potentiostat/lmp91000.c
+@@ -71,8 +71,8 @@ struct lmp91000_data {
+
+ struct completion completion;
+ u8 chan_select;
+-
+- u32 buffer[4]; /* 64-bit data + 64-bit timestamp */
++ /* 64-bit data + 64-bit naturally aligned timestamp */
++ u32 buffer[4] __aligned(8);
+ };
+
+ static const struct iio_chan_spec lmp91000_channels[] = {
+--
+2.30.2
+
--- /dev/null
+From 11e51910541a5ac2915f8421a0a17a1a81b7647e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:16 +0100
+Subject: iio: prox: as3935: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 37eb8d8c64f2ecb3a5521ba1cc1fad973adfae41 ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of uses of
+iio_push_to_buffers_with_timestamp()
+
+Fixes: 37b1ba2c68cf ("iio: proximity: as3935: fix buffer stack trashing")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Matt Ranostay <matt.ranostay@konsulko.com>
+Acked-by: Matt Ranostay <matt.ranostay@konsulko.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-15-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/proximity/as3935.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c
+index edc4a35ae66d..1d5ace2bde44 100644
+--- a/drivers/iio/proximity/as3935.c
++++ b/drivers/iio/proximity/as3935.c
+@@ -59,7 +59,11 @@ struct as3935_state {
+ unsigned long noise_tripped;
+ u32 tune_cap;
+ u32 nflwdth_reg;
+- u8 buffer[16]; /* 8-bit data + 56-bit padding + 64-bit timestamp */
++ /* Ensure timestamp is naturally aligned */
++ struct {
++ u8 chan;
++ s64 timestamp __aligned(8);
++ } scan;
+ u8 buf[2] ____cacheline_aligned;
+ };
+
+@@ -225,8 +229,8 @@ static irqreturn_t as3935_trigger_handler(int irq, void *private)
+ if (ret)
+ goto err_read;
+
+- st->buffer[0] = val & AS3935_DATA_MASK;
+- iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer,
++ st->scan.chan = val & AS3935_DATA_MASK;
++ iio_push_to_buffers_with_timestamp(indio_dev, &st->scan,
+ iio_get_time_ns(indio_dev));
+ err_read:
+ iio_trigger_notify_done(indio_dev->trig);
+--
+2.30.2
+
--- /dev/null
+From cca5648cde01aebcd57e9d66240fb514028a950d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Jun 2021 16:23:01 +0100
+Subject: iio: prox: isl29501: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 92babc9938ebbf4050f2fba774836f7edc16a570 ]
+
+Add __aligned(8) to ensure the buffer passed to
+iio_push_to_buffers_with_timestamp() is suitable for the naturally
+aligned timestamp that will be inserted.
+
+Here an explicit structure is not used, because the holes would
+necessitate the addition of an explict memset(), to avoid a kernel
+data leak, making for a less minimal fix.
+
+Fixes: 1c28799257bc ("iio: light: isl29501: Add support for the ISL29501 ToF sensor.")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Mathieu Othacehe <m.othacehe@gmail.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20210613152301.571002-9-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/proximity/isl29501.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/proximity/isl29501.c b/drivers/iio/proximity/isl29501.c
+index 90e76451c972..5b6ea783795d 100644
+--- a/drivers/iio/proximity/isl29501.c
++++ b/drivers/iio/proximity/isl29501.c
+@@ -938,7 +938,7 @@ static irqreturn_t isl29501_trigger_handler(int irq, void *p)
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct isl29501_private *isl29501 = iio_priv(indio_dev);
+ const unsigned long *active_mask = indio_dev->active_scan_mask;
+- u32 buffer[4] = {}; /* 1x16-bit + ts */
++ u32 buffer[4] __aligned(8) = {}; /* 1x16-bit + naturally aligned ts */
+
+ if (test_bit(ISL29501_DISTANCE_SCAN_INDEX, active_mask))
+ isl29501_register_read(isl29501, REG_DISTANCE, buffer);
+--
+2.30.2
+
--- /dev/null
+From 0954d584c22da4250dc32d568eb08206f963b59d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:15 +0100
+Subject: iio: prox: pulsed-light: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 679cc377a03ff1944491eafc7355c1eb1fad4109 ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of uses of
+iio_push_to_buffers_with_timestamp()
+
+Fixes: cb119d535083 ("iio: proximity: add support for PulsedLight LIDAR")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Matt Ranostay <matt.ranostay@konsulko.com>
+Acked-by: Matt Ranostay <matt.ranostay@konsulko.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-14-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/proximity/pulsedlight-lidar-lite-v2.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
+index cc206bfa09c7..d854b8d5fbba 100644
+--- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
++++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
+@@ -44,7 +44,11 @@ struct lidar_data {
+ int (*xfer)(struct lidar_data *data, u8 reg, u8 *val, int len);
+ int i2c_enabled;
+
+- u16 buffer[8]; /* 2 byte distance + 8 byte timestamp */
++ /* Ensure timestamp is naturally aligned */
++ struct {
++ u16 chan;
++ s64 timestamp __aligned(8);
++ } scan;
+ };
+
+ static const struct iio_chan_spec lidar_channels[] = {
+@@ -230,9 +234,9 @@ static irqreturn_t lidar_trigger_handler(int irq, void *private)
+ struct lidar_data *data = iio_priv(indio_dev);
+ int ret;
+
+- ret = lidar_get_measurement(data, data->buffer);
++ ret = lidar_get_measurement(data, &data->scan.chan);
+ if (!ret) {
+- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
++ iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+ iio_get_time_ns(indio_dev));
+ } else if (ret != -EINVAL) {
+ dev_err(&data->client->dev, "cannot read LIDAR measurement");
+--
+2.30.2
+
--- /dev/null
+From 17257345056276f86f1c14bd10124e64030d2408 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 May 2021 18:01:14 +0100
+Subject: iio: prox: srf08: Fix buffer alignment in
+ iio_push_to_buffers_with_timestamp()
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 19f1a254fe4949fff1e67db386409f48cf438bd7 ]
+
+To make code more readable, use a structure to express the channel
+layout and ensure the timestamp is 8 byte aligned.
+
+Found during an audit of all calls of uses of
+iio_push_to_buffers_with_timestamp()
+
+Fixes: 78f839029e1d ("iio: distance: srf08: add IIO driver for us ranger")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Andreas Klinger <ak@it-klinger.de>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210501170121.512209-13-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/proximity/srf08.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/iio/proximity/srf08.c b/drivers/iio/proximity/srf08.c
+index 70beac5c9c1d..9b0886760f76 100644
+--- a/drivers/iio/proximity/srf08.c
++++ b/drivers/iio/proximity/srf08.c
+@@ -63,11 +63,11 @@ struct srf08_data {
+ int range_mm;
+ struct mutex lock;
+
+- /*
+- * triggered buffer
+- * 1x16-bit channel + 3x16 padding + 4x16 timestamp
+- */
+- s16 buffer[8];
++ /* Ensure timestamp is naturally aligned */
++ struct {
++ s16 chan;
++ s64 timestamp __aligned(8);
++ } scan;
+
+ /* Sensor-Type */
+ enum srf08_sensor_type sensor_type;
+@@ -190,9 +190,9 @@ static irqreturn_t srf08_trigger_handler(int irq, void *p)
+
+ mutex_lock(&data->lock);
+
+- data->buffer[0] = sensor_data;
++ data->scan.chan = sensor_data;
+ iio_push_to_buffers_with_timestamp(indio_dev,
+- data->buffer, pf->timestamp);
++ &data->scan, pf->timestamp);
+
+ mutex_unlock(&data->lock);
+ err:
+--
+2.30.2
+
--- /dev/null
+From 69524de56f1676ffb991070a1d0eb1d5627e151a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 May 2021 17:27:53 +0200
+Subject: ima: Don't remove security.ima if file must not be appraised
+
+From: Roberto Sassu <roberto.sassu@huawei.com>
+
+[ Upstream commit ed1b472fc15aeaa20ddeeb93fd25190014e50d17 ]
+
+Files might come from a remote source and might have xattrs, including
+security.ima. It should not be IMA task to decide whether security.ima
+should be kept or not. This patch removes the removexattr() system
+call in ima_inode_post_setattr().
+
+Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/ima/ima_appraise.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
+index 4e5eb0236278..55dac618f2a1 100644
+--- a/security/integrity/ima/ima_appraise.c
++++ b/security/integrity/ima/ima_appraise.c
+@@ -522,8 +522,6 @@ void ima_inode_post_setattr(struct user_namespace *mnt_userns,
+ return;
+
+ action = ima_must_appraise(mnt_userns, inode, MAY_ACCESS, POST_SETATTR);
+- if (!action)
+- __vfs_removexattr(&init_user_ns, dentry, XATTR_NAME_IMA);
+ iint = integrity_iint_find(inode);
+ if (iint) {
+ set_bit(IMA_CHANGE_ATTR, &iint->atomic_flags);
+--
+2.30.2
+
--- /dev/null
+From 3b0cecbc6aa0024fbb2b74f4eb2cac3759f184f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 20:57:42 +0200
+Subject: Input: goodix - platform/x86: touchscreen_dmi - Move upside down
+ quirks to touchscreen_dmi.c
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 5a6f0dbe621a5c20dc912ac474debf9f11129e03 ]
+
+Move the DMI quirks for upside-down mounted Goodix touchscreens from
+drivers/input/touchscreen/goodix.c to
+drivers/platform/x86/touchscreen_dmi.c,
+where all the other x86 touchscreen quirks live.
+
+Note the touchscreen_dmi.c code attaches standard touchscreen
+device-properties to an i2c-client device based on a combination of a
+DMI match + a device-name match. I've verified that the: Teclast X98 Pro,
+WinBook TW100 and WinBook TW700 uses an ACPI devicename of "GDIX1001:00"
+based on acpidumps and/or dmesg output available on the web.
+
+This patch was tested on a Teclast X89 tablet.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20210504185746.175461-2-hdegoede@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/touchscreen/goodix.c | 52 ------------------------
+ drivers/platform/x86/touchscreen_dmi.c | 56 ++++++++++++++++++++++++++
+ 2 files changed, 56 insertions(+), 52 deletions(-)
+
+diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
+index c682b028f0a2..4f53d3c57e69 100644
+--- a/drivers/input/touchscreen/goodix.c
++++ b/drivers/input/touchscreen/goodix.c
+@@ -178,51 +178,6 @@ static const unsigned long goodix_irq_flags[] = {
+ IRQ_TYPE_LEVEL_HIGH,
+ };
+
+-/*
+- * Those tablets have their coordinates origin at the bottom right
+- * of the tablet, as if rotated 180 degrees
+- */
+-static const struct dmi_system_id rotated_screen[] = {
+-#if defined(CONFIG_DMI) && defined(CONFIG_X86)
+- {
+- .ident = "Teclast X89",
+- .matches = {
+- /* tPAD is too generic, also match on bios date */
+- DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
+- DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
+- DMI_MATCH(DMI_BIOS_DATE, "12/19/2014"),
+- },
+- },
+- {
+- .ident = "Teclast X98 Pro",
+- .matches = {
+- /*
+- * Only match BIOS date, because the manufacturers
+- * BIOS does not report the board name at all
+- * (sometimes)...
+- */
+- DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
+- DMI_MATCH(DMI_BIOS_DATE, "10/28/2015"),
+- },
+- },
+- {
+- .ident = "WinBook TW100",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "WinBook"),
+- DMI_MATCH(DMI_PRODUCT_NAME, "TW100")
+- }
+- },
+- {
+- .ident = "WinBook TW700",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "WinBook"),
+- DMI_MATCH(DMI_PRODUCT_NAME, "TW700")
+- },
+- },
+-#endif
+- {}
+-};
+-
+ static const struct dmi_system_id nine_bytes_report[] = {
+ #if defined(CONFIG_DMI) && defined(CONFIG_X86)
+ {
+@@ -1123,13 +1078,6 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
+ ABS_MT_POSITION_Y, ts->prop.max_y);
+ }
+
+- if (dmi_check_system(rotated_screen)) {
+- ts->prop.invert_x = true;
+- ts->prop.invert_y = true;
+- dev_dbg(&ts->client->dev,
+- "Applying '180 degrees rotated screen' quirk\n");
+- }
+-
+ if (dmi_check_system(nine_bytes_report)) {
+ ts->contact_size = 9;
+
+diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c
+index bde740d6120e..b452865da2a1 100644
+--- a/drivers/platform/x86/touchscreen_dmi.c
++++ b/drivers/platform/x86/touchscreen_dmi.c
+@@ -299,6 +299,23 @@ static const struct ts_dmi_data estar_beauty_hd_data = {
+ .properties = estar_beauty_hd_props,
+ };
+
++/* Generic props + data for upside-down mounted GDIX1001 touchscreens */
++static const struct property_entry gdix1001_upside_down_props[] = {
++ PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
++ PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
++ { }
++};
++
++static const struct ts_dmi_data gdix1001_00_upside_down_data = {
++ .acpi_name = "GDIX1001:00",
++ .properties = gdix1001_upside_down_props,
++};
++
++static const struct ts_dmi_data gdix1001_01_upside_down_data = {
++ .acpi_name = "GDIX1001:01",
++ .properties = gdix1001_upside_down_props,
++};
++
+ static const struct property_entry gp_electronic_t701_props[] = {
+ PROPERTY_ENTRY_U32("touchscreen-size-x", 960),
+ PROPERTY_ENTRY_U32("touchscreen-size-y", 640),
+@@ -1330,6 +1347,16 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
+ DMI_MATCH(DMI_BOARD_NAME, "X3 Plus"),
+ },
+ },
++ {
++ /* Teclast X89 (Windows version / BIOS) */
++ .driver_data = (void *)&gdix1001_01_upside_down_data,
++ .matches = {
++ /* tPAD is too generic, also match on bios date */
++ DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
++ DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
++ DMI_MATCH(DMI_BIOS_DATE, "12/19/2014"),
++ },
++ },
+ {
+ /* Teclast X98 Plus II */
+ .driver_data = (void *)&teclast_x98plus2_data,
+@@ -1338,6 +1365,19 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "X98 Plus II"),
+ },
+ },
++ {
++ /* Teclast X98 Pro */
++ .driver_data = (void *)&gdix1001_00_upside_down_data,
++ .matches = {
++ /*
++ * Only match BIOS date, because the manufacturers
++ * BIOS does not report the board name at all
++ * (sometimes)...
++ */
++ DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
++ DMI_MATCH(DMI_BIOS_DATE, "10/28/2015"),
++ },
++ },
+ {
+ /* Trekstor Primebook C11 */
+ .driver_data = (void *)&trekstor_primebook_c11_data,
+@@ -1413,6 +1453,22 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "VINGA Twizzle J116"),
+ },
+ },
++ {
++ /* "WinBook TW100" */
++ .driver_data = (void *)&gdix1001_00_upside_down_data,
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "WinBook"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "TW100")
++ }
++ },
++ {
++ /* WinBook TW700 */
++ .driver_data = (void *)&gdix1001_00_upside_down_data,
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "WinBook"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "TW700")
++ },
++ },
+ {
+ /* Yours Y8W81, same case and touchscreen as Chuwi Vi8 */
+ .driver_data = (void *)&chuwi_vi8_data,
+--
+2.30.2
+
--- /dev/null
+From 9fcc523cd7bbe369ad4b0f8a7e34628dd5ad9e45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 May 2021 11:52:42 -0700
+Subject: Input: hil_kbd - fix error return code in hil_dev_connect()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit d9b576917a1d0efa293801a264150a1b37691617 ]
+
+Return error code -EINVAL rather than '0' when the combo devices are not
+supported.
+
+Fixes: fa71c605c2bb ("Input: combine hil_kbd and hil_ptr drivers")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Link: https://lore.kernel.org/r/20210515030053.6824-1-thunder.leizhen@huawei.com
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/keyboard/hil_kbd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c
+index bb29a7c9a1c0..54afb38601b9 100644
+--- a/drivers/input/keyboard/hil_kbd.c
++++ b/drivers/input/keyboard/hil_kbd.c
+@@ -512,6 +512,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
+ HIL_IDD_NUM_AXES_PER_SET(*idd)) {
+ printk(KERN_INFO PREFIX
+ "combo devices are not supported.\n");
++ error = -EINVAL;
+ goto bail1;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 3678066dbe7ddd8f941231d88ebeafce540309ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 13:22:20 +0300
+Subject: iommu/amd: Fix extended features logging
+
+From: Alexander Monakov <amonakov@ispras.ru>
+
+[ Upstream commit 4b21a503adf597773e4b37db05db0e9b16a81d53 ]
+
+print_iommu_info prints the EFR register and then the decoded list of
+features on a separate line:
+
+pci 0000:00:00.2: AMD-Vi: Extended features (0x206d73ef22254ade):
+ PPR X2APIC NX GT IA GA PC GA_vAPIC
+
+The second line is emitted via 'pr_cont', which causes it to have a
+different ('warn') loglevel compared to the previous line ('info').
+
+Commit 9a295ff0ffc9 attempted to rectify this by removing the newline
+from the pci_info format string, but this doesn't work, as pci_info
+calls implicitly append a newline anyway.
+
+Printing the decoded features on the same line would make it quite long.
+Instead, change pci_info() to pr_info() to omit PCI bus location info,
+which is also shown in the preceding message. This results in:
+
+pci 0000:00:00.2: AMD-Vi: Found IOMMU cap 0x40
+AMD-Vi: Extended features (0x206d73ef22254ade): PPR X2APIC NX GT IA GA PC GA_vAPIC
+AMD-Vi: Interrupt remapping enabled
+
+Fixes: 9a295ff0ffc9 ("iommu/amd: Print extended features in one line to fix divergent log levels")
+Link: https://lore.kernel.org/lkml/alpine.LNX.2.20.13.2104112326460.11104@monopod.intra.ispras.ru
+Signed-off-by: Alexander Monakov <amonakov@ispras.ru>
+Cc: Paul Menzel <pmenzel@molgen.mpg.de>
+Cc: Joerg Roedel <jroedel@suse.de>
+Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+Cc: iommu@lists.linux-foundation.org
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Link: https://lore.kernel.org/r/20210504102220.1793-1-amonakov@ispras.ru
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/amd/init.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
+index d006724f4dc2..1ded8a69c246 100644
+--- a/drivers/iommu/amd/init.c
++++ b/drivers/iommu/amd/init.c
+@@ -1908,8 +1908,8 @@ static void print_iommu_info(void)
+ pci_info(pdev, "Found IOMMU cap 0x%x\n", iommu->cap_ptr);
+
+ if (iommu->cap & (1 << IOMMU_CAP_EFR)) {
+- pci_info(pdev, "Extended features (%#llx):",
+- iommu->features);
++ pr_info("Extended features (%#llx):", iommu->features);
++
+ for (i = 0; i < ARRAY_SIZE(feat_str); ++i) {
+ if (iommu_feature(iommu, (1ULL << i)))
+ pr_cont(" %s", feat_str[i]);
+--
+2.30.2
+
--- /dev/null
+From b603dc696ed123e25fa58ab81a36d36e0db21895 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Jun 2021 14:48:21 +0100
+Subject: iommu/amd: Tidy up DMA ops init
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+[ Upstream commit be227f8e99a663d097536e9f9bc935fb26bdbc41 ]
+
+Now that DMA ops are part of the core API via iommu-dma, fold the
+vestigial remains of the IOMMU_DMA_OPS init state into the IOMMU API
+phase, and clean up a few other leftovers. This should also close the
+race window wherein bus_set_iommu() effectively makes the DMA ops state
+visible before its nominal initialisation - it seems this was previously
+fairly benign, but since commit a250c23f15c2 ("iommu: remove
+DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE") it can now lead to the strict flush
+queue policy inadvertently being picked for default domains allocated
+during that window, with a corresponding unexpected perfomance impact.
+
+Reported-by: Jussi Maki <joamaki@gmail.com>
+Tested-by: Jussi Maki <joamaki@gmail.com>
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Fixes: a250c23f15c2 ("iommu: remove DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE")
+Link: https://lore.kernel.org/r/665db61e23ff8d54ac5eb391bef520b3a803fcb9.1622727974.git.robin.murphy@arm.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/amd/amd_iommu.h | 2 --
+ drivers/iommu/amd/init.c | 5 -----
+ drivers/iommu/amd/iommu.c | 31 +++++++++++++------------------
+ 3 files changed, 13 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h
+index 55dd38d814d9..416815a525d6 100644
+--- a/drivers/iommu/amd/amd_iommu.h
++++ b/drivers/iommu/amd/amd_iommu.h
+@@ -11,8 +11,6 @@
+
+ #include "amd_iommu_types.h"
+
+-extern int amd_iommu_init_dma_ops(void);
+-extern int amd_iommu_init_passthrough(void);
+ extern irqreturn_t amd_iommu_int_thread(int irq, void *data);
+ extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
+ extern void amd_iommu_apply_erratum_63(u16 devid);
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
+index 1ded8a69c246..5ff7e5364ef4 100644
+--- a/drivers/iommu/amd/init.c
++++ b/drivers/iommu/amd/init.c
+@@ -231,7 +231,6 @@ enum iommu_init_state {
+ IOMMU_ENABLED,
+ IOMMU_PCI_INIT,
+ IOMMU_INTERRUPTS_EN,
+- IOMMU_DMA_OPS,
+ IOMMU_INITIALIZED,
+ IOMMU_NOT_FOUND,
+ IOMMU_INIT_ERROR,
+@@ -2895,10 +2894,6 @@ static int __init state_next(void)
+ init_state = ret ? IOMMU_INIT_ERROR : IOMMU_INTERRUPTS_EN;
+ break;
+ case IOMMU_INTERRUPTS_EN:
+- ret = amd_iommu_init_dma_ops();
+- init_state = ret ? IOMMU_INIT_ERROR : IOMMU_DMA_OPS;
+- break;
+- case IOMMU_DMA_OPS:
+ init_state = IOMMU_INITIALIZED;
+ break;
+ case IOMMU_INITIALIZED:
+diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
+index 3ac42bbdefc6..c46dde88a132 100644
+--- a/drivers/iommu/amd/iommu.c
++++ b/drivers/iommu/amd/iommu.c
+@@ -30,7 +30,6 @@
+ #include <linux/msi.h>
+ #include <linux/irqdomain.h>
+ #include <linux/percpu.h>
+-#include <linux/iova.h>
+ #include <linux/io-pgtable.h>
+ #include <asm/irq_remapping.h>
+ #include <asm/io_apic.h>
+@@ -1773,13 +1772,22 @@ void amd_iommu_domain_update(struct protection_domain *domain)
+ amd_iommu_domain_flush_complete(domain);
+ }
+
++static void __init amd_iommu_init_dma_ops(void)
++{
++ swiotlb = (iommu_default_passthrough() || sme_me_mask) ? 1 : 0;
++
++ if (amd_iommu_unmap_flush)
++ pr_info("IO/TLB flush on unmap enabled\n");
++ else
++ pr_info("Lazy IO/TLB flushing enabled\n");
++ iommu_set_dma_strict(amd_iommu_unmap_flush);
++}
++
+ int __init amd_iommu_init_api(void)
+ {
+- int ret, err = 0;
++ int err = 0;
+
+- ret = iova_cache_get();
+- if (ret)
+- return ret;
++ amd_iommu_init_dma_ops();
+
+ err = bus_set_iommu(&pci_bus_type, &amd_iommu_ops);
+ if (err)
+@@ -1796,19 +1804,6 @@ int __init amd_iommu_init_api(void)
+ return 0;
+ }
+
+-int __init amd_iommu_init_dma_ops(void)
+-{
+- swiotlb = (iommu_default_passthrough() || sme_me_mask) ? 1 : 0;
+-
+- if (amd_iommu_unmap_flush)
+- pr_info("IO/TLB flush on unmap enabled\n");
+- else
+- pr_info("Lazy IO/TLB flushing enabled\n");
+- iommu_set_dma_strict(amd_iommu_unmap_flush);
+- return 0;
+-
+-}
+-
+ /*****************************************************************************
+ *
+ * The following functions belong to the exported interface of AMD IOMMU
+--
+2.30.2
+
--- /dev/null
+From a6188518ffef369524cbb4aef99bd9e61757e71d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Sep 2020 12:53:19 +0530
+Subject: iommu/dma: Fix IOVA reserve dma ranges
+
+From: Srinath Mannam <srinath.mannam@broadcom.com>
+
+[ Upstream commit 571f316074a203e979ea90211d9acf423dfe5f46 ]
+
+Fix IOVA reserve failure in the case when address of first memory region
+listed in dma-ranges is equal to 0x0.
+
+Fixes: aadad097cd46f ("iommu/dma: Reserve IOVA for PCIe inaccessible DMA address")
+Signed-off-by: Srinath Mannam <srinath.mannam@broadcom.com>
+Reviewed-by: Robin Murphy <robin.murphy@arm.com>
+Tested-by: Sven Peter <sven@svenpeter.dev>
+Link: https://lore.kernel.org/r/20200914072319.6091-1-srinath.mannam@broadcom.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/dma-iommu.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
+index 7bcdd1205535..95e7349ac3f1 100644
+--- a/drivers/iommu/dma-iommu.c
++++ b/drivers/iommu/dma-iommu.c
+@@ -243,9 +243,11 @@ resv_iova:
+ lo = iova_pfn(iovad, start);
+ hi = iova_pfn(iovad, end);
+ reserve_iova(iovad, lo, hi);
+- } else {
++ } else if (end < start) {
+ /* dma_ranges list should be sorted */
+- dev_err(&dev->dev, "Failed to reserve IOVA\n");
++ dev_err(&dev->dev,
++ "Failed to reserve IOVA [%#010llx-%#010llx]\n",
++ start, end);
+ return -EINVAL;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 1ee684add750fe7c76bb47c4bda17f3fea2d6b94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Jun 2021 18:52:54 -0700
+Subject: ip6_tunnel: fix GRE6 segmentation
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit a6e3f2985a80ef6a45a17d2d9d9151f17ea3ce07 ]
+
+Commit 6c11fbf97e69 ("ip6_tunnel: add MPLS transmit support")
+moved assiging inner_ipproto down from ipxip6_tnl_xmit() to
+its callee ip6_tnl_xmit(). The latter is also used by GRE.
+
+Since commit 38720352412a ("gre: Use inner_proto to obtain inner
+header protocol") GRE had been depending on skb->inner_protocol
+during segmentation. It sets it in gre_build_header() and reads
+it in gre_gso_segment(). Changes to ip6_tnl_xmit() overwrite
+the protocol, resulting in GSO skbs getting dropped.
+
+Note that inner_protocol is a union with inner_ipproto,
+GRE uses the former while the change switched it to the latter
+(always setting it to just IPPROTO_GRE).
+
+Restore the original location of skb_set_inner_ipproto(),
+it is unclear why it was moved in the first place.
+
+Fixes: 6c11fbf97e69 ("ip6_tunnel: add MPLS transmit support")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Tested-by: Vadim Fedorenko <vfedorenko@novek.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_tunnel.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
+index 288bafded998..28ca70af014a 100644
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -1239,8 +1239,6 @@ route_lookup:
+ if (max_headroom > dev->needed_headroom)
+ dev->needed_headroom = max_headroom;
+
+- skb_set_inner_ipproto(skb, proto);
+-
+ err = ip6_tnl_encap(skb, t, &proto, fl6);
+ if (err)
+ return err;
+@@ -1377,6 +1375,8 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev,
+ if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6))
+ return -1;
+
++ skb_set_inner_ipproto(skb, protocol);
++
+ err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu,
+ protocol);
+ if (err != 0) {
+--
+2.30.2
+
--- /dev/null
+From 3f10e3fc3e62352ffb6a0e1016176efe480cd1ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 08:27:00 -0700
+Subject: ipv6: exthdrs: do not blindly use init_net
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit bcc3f2a829b9edbe3da5fb117ee5a63686d31834 ]
+
+I see no reason why max_dst_opts_cnt and max_hbh_opts_cnt
+are fetched from the initial net namespace.
+
+The other sysctls (max_dst_opts_len & max_hbh_opts_len)
+are in fact already using the current ns.
+
+Note: it is not clear why ipv6_destopt_rcv() use two ways to
+get to the netns :
+
+ 1) dev_net(dst->dev)
+ Originally used to increment IPSTATS_MIB_INHDRERRORS
+
+ 2) dev_net(skb->dev)
+ Tom used this variant in his patch.
+
+Maybe this calls to use ipv6_skb_net() instead ?
+
+Fixes: 47d3d7ac656a ("ipv6: Implement limits on Hop-by-Hop and Destination options")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Tom Herbert <tom@quantonium.net>
+Cc: Coco Li <lixiaoyan@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/exthdrs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index 56e479d158b7..6f7da8f3e2e5 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -306,7 +306,7 @@ fail_and_free:
+ #endif
+
+ if (ip6_parse_tlv(tlvprocdestopt_lst, skb,
+- init_net.ipv6.sysctl.max_dst_opts_cnt)) {
++ net->ipv6.sysctl.max_dst_opts_cnt)) {
+ skb->transport_header += extlen;
+ opt = IP6CB(skb);
+ #if IS_ENABLED(CONFIG_IPV6_MIP6)
+@@ -1037,7 +1037,7 @@ fail_and_free:
+
+ opt->flags |= IP6SKB_HOPBYHOP;
+ if (ip6_parse_tlv(tlvprochopopt_lst, skb,
+- init_net.ipv6.sysctl.max_hbh_opts_cnt)) {
++ net->ipv6.sysctl.max_hbh_opts_cnt)) {
+ skb->transport_header += extlen;
+ opt = IP6CB(skb);
+ opt->nhoff = sizeof(struct ipv6hdr);
+--
+2.30.2
+
--- /dev/null
+From 197ed9c236e6dcf7454f62f54a8c2847d4b516f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Jun 2021 03:07:20 -0700
+Subject: ipv6: fix out-of-bound access in ip6_parse_tlv()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 624085a31c1ad6a80b1e53f686bf6ee92abbf6e8 ]
+
+First problem is that optlen is fetched without checking
+there is more than one byte to parse.
+
+Fix this by taking care of IPV6_TLV_PAD1 before
+fetching optlen (under appropriate sanity checks against len)
+
+Second problem is that IPV6_TLV_PADN checks of zero
+padding are performed before the check of remaining length.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Fixes: c1412fce7ecc ("net/ipv6/exthdrs.c: Strict PadN option checking")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Paolo Abeni <pabeni@redhat.com>
+Cc: Tom Herbert <tom@herbertland.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/exthdrs.c | 27 +++++++++++++--------------
+ 1 file changed, 13 insertions(+), 14 deletions(-)
+
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index 6f7da8f3e2e5..26882e165c9e 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -135,18 +135,23 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
+ len -= 2;
+
+ while (len > 0) {
+- int optlen = nh[off + 1] + 2;
+- int i;
++ int optlen, i;
+
+- switch (nh[off]) {
+- case IPV6_TLV_PAD1:
+- optlen = 1;
++ if (nh[off] == IPV6_TLV_PAD1) {
+ padlen++;
+ if (padlen > 7)
+ goto bad;
+- break;
++ off++;
++ len--;
++ continue;
++ }
++ if (len < 2)
++ goto bad;
++ optlen = nh[off + 1] + 2;
++ if (optlen > len)
++ goto bad;
+
+- case IPV6_TLV_PADN:
++ if (nh[off] == IPV6_TLV_PADN) {
+ /* RFC 2460 states that the purpose of PadN is
+ * to align the containing header to multiples
+ * of 8. 7 is therefore the highest valid value.
+@@ -163,12 +168,7 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
+ if (nh[off + i] != 0)
+ goto bad;
+ }
+- break;
+-
+- default: /* Other TLV code so scan list */
+- if (optlen > len)
+- goto bad;
+-
++ } else {
+ tlv_count++;
+ if (tlv_count > max_count)
+ goto bad;
+@@ -188,7 +188,6 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
+ return false;
+
+ padlen = 0;
+- break;
+ }
+ off += optlen;
+ len -= optlen;
+--
+2.30.2
+
--- /dev/null
+From 6f10e915b6d892edfa84d207873e872d8e5ff97f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Jun 2021 14:32:40 +0300
+Subject: iwlwifi: increase PNVM load timeout
+
+From: Luca Coelho <luciano.coelho@intel.com>
+
+[ Upstream commit 5cc816ef9db1fe03f73e56e9d8f118add9c6efe4 ]
+
+The FW has a watchdog of 200ms in the PNVM load flow, so the driver
+should have a slightly higher timeout. Change the timeout from 100ms
+to 250ms.
+
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Fixes: 70d3ca86b025 ("iwlwifi: mvm: ring the doorbell and wait for PNVM load completion")
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Link: https://lore.kernel.org/r/iwlwifi.20210612142637.ba22aec1e2be.I36bfadc28c480f4fc57266c075a79e8ea4a6934f@changeid
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/fw/pnvm.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h
+index e4f91bce222d..61d3d4e0b7d9 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h
+@@ -1,7 +1,7 @@
+ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+ /******************************************************************************
+ *
+- * Copyright(c) 2020 Intel Corporation
++ * Copyright(c) 2020-2021 Intel Corporation
+ *
+ *****************************************************************************/
+
+@@ -10,7 +10,7 @@
+
+ #include "fw/notif-wait.h"
+
+-#define MVM_UCODE_PNVM_TIMEOUT (HZ / 10)
++#define MVM_UCODE_PNVM_TIMEOUT (HZ / 4)
+
+ int iwl_pnvm_load(struct iwl_trans *trans,
+ struct iwl_notif_wait_data *notif_wait);
+--
+2.30.2
+
--- /dev/null
+From 02f5b625dfd93313efaaaebc0eec3074b2ca4f81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 May 2021 18:59:15 -0500
+Subject: kbuild: Fix objtool dependency for 'OBJECT_FILES_NON_STANDARD_<obj>
+ := n'
+
+From: Josh Poimboeuf <jpoimboe@redhat.com>
+
+[ Upstream commit 8852c552402979508fdc395ae07aa8761aa46045 ]
+
+"OBJECT_FILES_NON_STANDARD_vma.o := n" has a dependency bug. When
+objtool source is updated, the affected object doesn't get re-analyzed
+by objtool.
+
+Peter's new variable-sized jump label feature relies on objtool
+rewriting the object file. Otherwise the system can fail to boot. That
+effectively upgrades this minor dependency issue to a major bug.
+
+The problem is that variables in prerequisites are expanded early,
+during the read-in phase. The '$(objtool_dep)' variable indirectly uses
+'$@', which isn't yet available when the target prerequisites are
+evaluated.
+
+Use '.SECONDEXPANSION:' which causes '$(objtool_dep)' to be expanded in
+a later phase, after the target-specific '$@' variable has been defined.
+
+Fixes: b9ab5ebb14ec ("objtool: Add CONFIG_STACK_VALIDATION option")
+Fixes: ab3257042c26 ("jump_label, x86: Allow short NOPs")
+Reported-by: Matthew Wilcox <willy@infradead.org>
+Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/Makefile.build | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/scripts/Makefile.build b/scripts/Makefile.build
+index 949f723efe53..34d257653fb4 100644
+--- a/scripts/Makefile.build
++++ b/scripts/Makefile.build
+@@ -268,7 +268,8 @@ define rule_as_o_S
+ endef
+
+ # Built-in and composite module parts
+-$(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE
++.SECONDEXPANSION:
++$(obj)/%.o: $(src)/%.c $(recordmcount_source) $$(objtool_dep) FORCE
+ $(call if_changed_rule,cc_o_c)
+ $(call cmd,force_checksrc)
+
+@@ -349,7 +350,7 @@ cmd_modversions_S = \
+ fi
+ endif
+
+-$(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE
++$(obj)/%.o: $(src)/%.S $$(objtool_dep) FORCE
+ $(call if_changed_rule,as_o_S)
+
+ targets += $(filter-out $(subdir-builtin), $(real-obj-y))
+--
+2.30.2
+
--- /dev/null
+From adbb1af72e05c49c0d7eb9a39703af0153bfd2f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jun 2021 19:41:34 -0700
+Subject: kbuild: skip per-CPU BTF generation for pahole v1.18-v1.21
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit a0b8200d06ad6450c179407baa5f0f52f8cfcc97 ]
+
+Commit "mm/page_alloc: convert per-cpu list protection to local_lock" will
+introduce a zero-sized per-CPU variable, which causes pahole to generate
+invalid BTF. Only pahole versions 1.18 through 1.21 are impacted, as
+before 1.18 pahole doesn't know anything about per-CPU variables, and 1.22
+contains the proper fix for the issue.
+
+Luckily, pahole 1.18 got --skip_encoding_btf_vars option disabling BTF
+generation for per-CPU variables in anticipation of some unanticipated
+problems. So use this escape hatch to disable per-CPU var BTF info on
+those problematic pahole versions. Users relying on availability of
+per-CPU var BTFs would need to upgrade to pahole 1.22+, but everyone won't
+notice any regressions.
+
+Link: https://lkml.kernel.org/r/20210530002536.3193829-1-andrii@kernel.org
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Mel Gorman <mgorman@techsingularity.net>
+Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
+Cc: Hao Luo <haoluo@google.com>
+Cc: Michal Suchanek <msuchanek@suse.de>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/link-vmlinux.sh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
+index 0e0f6466b18d..475faa15854e 100755
+--- a/scripts/link-vmlinux.sh
++++ b/scripts/link-vmlinux.sh
+@@ -235,6 +235,10 @@ gen_btf()
+
+ vmlinux_link ${1}
+
++ if [ "${pahole_ver}" -ge "118" ] && [ "${pahole_ver}" -le "121" ]; then
++ # pahole 1.18 through 1.21 can't handle zero-sized per-CPU vars
++ extra_paholeopt="${extra_paholeopt} --skip_encoding_btf_vars"
++ fi
+ if [ "${pahole_ver}" -ge "121" ]; then
+ extra_paholeopt="${extra_paholeopt} --btf_gen_floats"
+ fi
+--
+2.30.2
+
--- /dev/null
+From dd641a3601ea14bdef6bf86ac13c80d5faa9aa3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 18:54:03 -0700
+Subject: kfence: unconditionally use unbound work queue
+
+From: Marco Elver <elver@google.com>
+
+[ Upstream commit ff06e45d3aace3f93d23956c1e655224f363ebe2 ]
+
+Unconditionally use unbound work queue, and not just if wq_power_efficient
+is true. Because if the system is idle, KFENCE may wait, and by being run
+on the unbound work queue, we permit the scheduler to make better
+scheduling decisions and not require pinning KFENCE to the same CPU upon
+waking up.
+
+Link: https://lkml.kernel.org/r/20210521111630.472579-1-elver@google.com
+Fixes: 36f0b35d0894 ("kfence: use power-efficient work queue to run delayed work")
+Signed-off-by: Marco Elver <elver@google.com>
+Reported-by: Hillf Danton <hdanton@sina.com>
+Reviewed-by: Alexander Potapenko <glider@google.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/kfence/core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/mm/kfence/core.c b/mm/kfence/core.c
+index 4d21ac44d5d3..d7666ace9d2e 100644
+--- a/mm/kfence/core.c
++++ b/mm/kfence/core.c
+@@ -636,7 +636,7 @@ static void toggle_allocation_gate(struct work_struct *work)
+ /* Disable static key and reset timer. */
+ static_branch_disable(&kfence_allocation_key);
+ #endif
+- queue_delayed_work(system_power_efficient_wq, &kfence_timer,
++ queue_delayed_work(system_unbound_wq, &kfence_timer,
+ msecs_to_jiffies(kfence_sample_interval));
+ }
+ static DECLARE_DELAYED_WORK(kfence_timer, toggle_allocation_gate);
+@@ -666,7 +666,7 @@ void __init kfence_init(void)
+ }
+
+ WRITE_ONCE(kfence_enabled, true);
+- queue_delayed_work(system_power_efficient_wq, &kfence_timer, 0);
++ queue_delayed_work(system_unbound_wq, &kfence_timer, 0);
+ pr_info("initialized - using %lu bytes for %d objects at 0x%p-0x%p\n", KFENCE_POOL_SIZE,
+ CONFIG_KFENCE_NUM_OBJECTS, (void *)__kfence_pool,
+ (void *)(__kfence_pool + KFENCE_POOL_SIZE));
+--
+2.30.2
+
--- /dev/null
+From 1d12bc97cb809e566f8e3a233594b1ab74b60134 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jun 2021 19:33:35 -0700
+Subject: kthread_worker: fix return value when kthread_mod_delayed_work()
+ races with kthread_cancel_delayed_work_sync()
+
+From: Petr Mladek <pmladek@suse.com>
+
+[ Upstream commit d71ba1649fa3c464c51ec7163e4b817345bff2c7 ]
+
+kthread_mod_delayed_work() might race with
+kthread_cancel_delayed_work_sync() or another kthread_mod_delayed_work()
+call. The function lets the other operation win when it sees
+work->canceling counter set. And it returns @false.
+
+But it should return @true as it is done by the related workqueue API, see
+mod_delayed_work_on().
+
+The reason is that the return value might be used for reference counting.
+It has to distinguish the case when the number of queued works has changed
+or stayed the same.
+
+The change is safe. kthread_mod_delayed_work() return value is not
+checked anywhere at the moment.
+
+Link: https://lore.kernel.org/r/20210521163526.GA17916@redhat.com
+Link: https://lkml.kernel.org/r/20210610133051.15337-4-pmladek@suse.com
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Reported-by: Oleg Nesterov <oleg@redhat.com>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nick Desaulniers <ndesaulniers@google.com>
+Cc: Tejun Heo <tj@kernel.org>
+Cc: Minchan Kim <minchan@google.com>
+Cc: <jenhaochen@google.com>
+Cc: Martin Liu <liumartin@google.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/kthread.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/kernel/kthread.c b/kernel/kthread.c
+index 6e02094849d3..08931e525dd9 100644
+--- a/kernel/kthread.c
++++ b/kernel/kthread.c
+@@ -1162,14 +1162,14 @@ static bool __kthread_cancel_work(struct kthread_work *work)
+ * modify @dwork's timer so that it expires after @delay. If @delay is zero,
+ * @work is guaranteed to be queued immediately.
+ *
+- * Return: %true if @dwork was pending and its timer was modified,
+- * %false otherwise.
++ * Return: %false if @dwork was idle and queued, %true otherwise.
+ *
+ * A special case is when the work is being canceled in parallel.
+ * It might be caused either by the real kthread_cancel_delayed_work_sync()
+ * or yet another kthread_mod_delayed_work() call. We let the other command
+- * win and return %false here. The caller is supposed to synchronize these
+- * operations a reasonable way.
++ * win and return %true here. The return value can be used for reference
++ * counting and the number of queued works stays the same. Anyway, the caller
++ * is supposed to synchronize these operations a reasonable way.
+ *
+ * This function is safe to call from any context including IRQ handler.
+ * See __kthread_cancel_work() and kthread_delayed_work_timer_fn()
+@@ -1181,13 +1181,15 @@ bool kthread_mod_delayed_work(struct kthread_worker *worker,
+ {
+ struct kthread_work *work = &dwork->work;
+ unsigned long flags;
+- int ret = false;
++ int ret;
+
+ raw_spin_lock_irqsave(&worker->lock, flags);
+
+ /* Do not bother with canceling when never queued. */
+- if (!work->worker)
++ if (!work->worker) {
++ ret = false;
+ goto fast_queue;
++ }
+
+ /* Work must not be used with >1 worker, see kthread_queue_work() */
+ WARN_ON_ONCE(work->worker != worker);
+@@ -1205,8 +1207,11 @@ bool kthread_mod_delayed_work(struct kthread_worker *worker,
+ * be used for reference counting.
+ */
+ kthread_cancel_delayed_work_timer(work, &flags);
+- if (work->canceling)
++ if (work->canceling) {
++ /* The number of works in the queue does not change. */
++ ret = true;
+ goto out;
++ }
+ ret = __kthread_cancel_work(work);
+
+ fast_queue:
+--
+2.30.2
+
--- /dev/null
+From d920e3422f459f1410090c9b08e5b76f99036a45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jun 2021 20:57:25 -0700
+Subject: kunit: Fix result propagation for parameterised tests
+
+From: David Gow <davidgow@google.com>
+
+[ Upstream commit 384426bd101cb3cd580b18de19d4891ec5ca5bf9 ]
+
+When one parameter of a parameterised test failed, its failure would be
+propagated to the overall test, but not to the suite result (unless it
+was the last parameter).
+
+This is because test_case->success was being reset to the test->success
+result after each parameter was used, so a failing test's result would
+be overwritten by a non-failing result. The overall test result was
+handled in a third variable, test_result, but this was discarded after
+the status line was printed.
+
+Instead, just propagate the result after each parameter run.
+
+Signed-off-by: David Gow <davidgow@google.com>
+Fixes: fadb08e7c750 ("kunit: Support for Parameterized Testing")
+Reviewed-by: Marco Elver <elver@google.com>
+Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/kunit/test.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/lib/kunit/test.c b/lib/kunit/test.c
+index 2f6cc0123232..17973a4a44c2 100644
+--- a/lib/kunit/test.c
++++ b/lib/kunit/test.c
+@@ -376,7 +376,7 @@ static void kunit_run_case_catch_errors(struct kunit_suite *suite,
+ context.test_case = test_case;
+ kunit_try_catch_run(try_catch, &context);
+
+- test_case->success = test->success;
++ test_case->success &= test->success;
+ }
+
+ int kunit_run_tests(struct kunit_suite *suite)
+@@ -388,7 +388,7 @@ int kunit_run_tests(struct kunit_suite *suite)
+
+ kunit_suite_for_each_test_case(suite, test_case) {
+ struct kunit test = { .param_value = NULL, .param_index = 0 };
+- bool test_success = true;
++ test_case->success = true;
+
+ if (test_case->generate_params) {
+ /* Get initial param. */
+@@ -398,7 +398,6 @@ int kunit_run_tests(struct kunit_suite *suite)
+
+ do {
+ kunit_run_case_catch_errors(suite, test_case, &test);
+- test_success &= test_case->success;
+
+ if (test_case->generate_params) {
+ if (param_desc[0] == '\0') {
+@@ -420,7 +419,7 @@ int kunit_run_tests(struct kunit_suite *suite)
+ }
+ } while (test.param_value);
+
+- kunit_print_ok_not_ok(&test, true, test_success,
++ kunit_print_ok_not_ok(&test, true, test_case->success,
+ kunit_test_case_num(suite, test_case),
+ test_case->name);
+ }
+--
+2.30.2
+
--- /dev/null
+From 2c77b707fab19d075f3365ce2b988fd3a22755ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 11:51:39 +0100
+Subject: KVM: arm64: Don't zero the cycle count register when PMCR_EL0.P is
+ set
+
+From: Alexandru Elisei <alexandru.elisei@arm.com>
+
+[ Upstream commit 2a71fabf6a1bc9162a84e18d6ab991230ca4d588 ]
+
+According to ARM DDI 0487G.a, page D13-3895, setting the PMCR_EL0.P bit to
+1 has the following effect:
+
+"Reset all event counters accessible in the current Exception level, not
+including PMCCNTR_EL0, to zero."
+
+Similar behaviour is described for AArch32 on page G8-7022. Make it so.
+
+Fixes: c01d6a18023b ("KVM: arm64: pmu: Only handle supported event counters")
+Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20210618105139.83795-1-alexandru.elisei@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kvm/pmu-emul.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
+index a0bbb7111f57..f33825c995cb 100644
+--- a/arch/arm64/kvm/pmu-emul.c
++++ b/arch/arm64/kvm/pmu-emul.c
+@@ -578,6 +578,7 @@ void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val)
+ kvm_pmu_set_counter_value(vcpu, ARMV8_PMU_CYCLE_IDX, 0);
+
+ if (val & ARMV8_PMU_PMCR_P) {
++ mask &= ~BIT(ARMV8_PMU_CYCLE_IDX);
+ for_each_set_bit(i, &mask, 32)
+ kvm_pmu_set_counter_value(vcpu, i, 0);
+ }
+--
+2.30.2
+
--- /dev/null
+From bcd77602c0d9815803b0bf504264ea9d47d6bbec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Jun 2021 16:50:02 +0100
+Subject: KVM: arm64: Restore PMU configuration on first run
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit d0c94c49792cf780cbfefe29f81bb8c3b73bc76b ]
+
+Restoring a guest with an active virtual PMU results in no perf
+counters being instanciated on the host side. Not quite what
+you'd expect from a restore.
+
+In order to fix this, force a writeback of PMCR_EL0 on the first
+run of a vcpu (using a new request so that it happens once the
+vcpu has been loaded). This will in turn create all the host-side
+counters that were missing.
+
+Reported-by: Jinank Jain <jinankj@amazon.de>
+Tested-by: Jinank Jain <jinankj@amazon.de>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/87wnrbylxv.wl-maz@kernel.org
+Link: https://lore.kernel.org/r/b53dfcf9bbc4db7f96154b1cd5188d72b9766358.camel@amazon.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/kvm_host.h | 1 +
+ arch/arm64/kvm/arm.c | 4 ++++
+ arch/arm64/kvm/pmu-emul.c | 3 +++
+ 3 files changed, 8 insertions(+)
+
+diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
+index 7cd7d5c8c4bc..6336b4309114 100644
+--- a/arch/arm64/include/asm/kvm_host.h
++++ b/arch/arm64/include/asm/kvm_host.h
+@@ -46,6 +46,7 @@
+ #define KVM_REQ_VCPU_RESET KVM_ARCH_REQ(2)
+ #define KVM_REQ_RECORD_STEAL KVM_ARCH_REQ(3)
+ #define KVM_REQ_RELOAD_GICv4 KVM_ARCH_REQ(4)
++#define KVM_REQ_RELOAD_PMU KVM_ARCH_REQ(5)
+
+ #define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
+ KVM_DIRTY_LOG_INITIALLY_SET)
+diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
+index e720148232a0..facf4d41d32a 100644
+--- a/arch/arm64/kvm/arm.c
++++ b/arch/arm64/kvm/arm.c
+@@ -689,6 +689,10 @@ static void check_vcpu_requests(struct kvm_vcpu *vcpu)
+ vgic_v4_load(vcpu);
+ preempt_enable();
+ }
++
++ if (kvm_check_request(KVM_REQ_RELOAD_PMU, vcpu))
++ kvm_pmu_handle_pmcr(vcpu,
++ __vcpu_sys_reg(vcpu, PMCR_EL0));
+ }
+ }
+
+diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
+index fd167d4f4215..a0bbb7111f57 100644
+--- a/arch/arm64/kvm/pmu-emul.c
++++ b/arch/arm64/kvm/pmu-emul.c
+@@ -850,6 +850,9 @@ int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu)
+ return -EINVAL;
+ }
+
++ /* One-off reload of the PMU on first run */
++ kvm_make_request(KVM_REQ_RELOAD_PMU, vcpu);
++
+ return 0;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 3d1b84393112c13dbdc8bc0481b536818d4a9b57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Jun 2021 10:26:02 -0700
+Subject: KVM: nVMX: Add a return code to vmx_complete_nested_posted_interrupt
+
+From: Jim Mattson <jmattson@google.com>
+
+[ Upstream commit 650293c3de6b042c4a2e87b2bc678efcff3843e8 ]
+
+No functional change intended.
+
+Signed-off-by: Jim Mattson <jmattson@google.com>
+Reviewed-by: Oliver Upton <oupton@google.com>
+Message-Id: <20210604172611.281819-4-jmattson@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/vmx/nested.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
+index 4ceadec6aeb6..5677cef81642 100644
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -3682,7 +3682,7 @@ void nested_mark_vmcs12_pages_dirty(struct kvm_vcpu *vcpu)
+ }
+ }
+
+-static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
++static int vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
+ {
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+ int max_irr;
+@@ -3690,17 +3690,17 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
+ u16 status;
+
+ if (!vmx->nested.pi_desc || !vmx->nested.pi_pending)
+- return;
++ return 0;
+
+ vmx->nested.pi_pending = false;
+ if (!pi_test_and_clear_on(vmx->nested.pi_desc))
+- return;
++ return 0;
+
+ max_irr = find_last_bit((unsigned long *)vmx->nested.pi_desc->pir, 256);
+ if (max_irr != 256) {
+ vapic_page = vmx->nested.virtual_apic_map.hva;
+ if (!vapic_page)
+- return;
++ return 0;
+
+ __kvm_apic_update_irr(vmx->nested.pi_desc->pir,
+ vapic_page, &max_irr);
+@@ -3713,6 +3713,7 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
+ }
+
+ nested_mark_vmcs12_pages_dirty(vcpu);
++ return 0;
+ }
+
+ static void nested_vmx_inject_exception_vmexit(struct kvm_vcpu *vcpu,
+@@ -3887,8 +3888,7 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu)
+ }
+
+ no_vmexit:
+- vmx_complete_nested_posted_interrupt(vcpu);
+- return 0;
++ return vmx_complete_nested_posted_interrupt(vcpu);
+ }
+
+ static u32 vmx_get_preemption_timer_value(struct kvm_vcpu *vcpu)
+--
+2.30.2
+
--- /dev/null
+From 040f6150d7c2ebb75e4998c4665cbc75da5562ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jun 2021 16:42:23 -0700
+Subject: KVM: nVMX: Don't clobber nested MMU's A/D status on EPTP switch
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 272b0a998d084e7667284bdd2d0c675c6a2d11de ]
+
+Drop bogus logic that incorrectly clobbers the accessed/dirty enabling
+status of the nested MMU on an EPTP switch. When nested EPT is enabled,
+walk_mmu points at L2's _legacy_ page tables, not L1's EPT for L2.
+
+This is likely a benign bug, as mmu->ept_ad is never consumed (since the
+MMU is not a nested EPT MMU), and stuffing mmu_role.base.ad_disabled will
+never propagate into future shadow pages since the nested MMU isn't used
+to map anything, just to walk L2's page tables.
+
+Note, KVM also does a full MMU reload, i.e. the guest_mmu will be
+recreated using the new EPTP, and thus any change in A/D enabling will be
+properly recognized in the relevant MMU.
+
+Fixes: 41ab93727467 ("KVM: nVMX: Emulate EPTP switching for the L1 hypervisor")
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20210609234235.1244004-4-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/vmx/nested.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
+index ba82b8563b07..2e63171864a7 100644
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -5488,8 +5488,6 @@ static int nested_vmx_eptp_switching(struct kvm_vcpu *vcpu,
+ {
+ u32 index = kvm_rcx_read(vcpu);
+ u64 new_eptp;
+- bool accessed_dirty;
+- struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
+
+ if (!nested_cpu_has_eptp_switching(vmcs12) ||
+ !nested_cpu_has_ept(vmcs12))
+@@ -5498,13 +5496,10 @@ static int nested_vmx_eptp_switching(struct kvm_vcpu *vcpu,
+ if (index >= VMFUNC_EPTP_ENTRIES)
+ return 1;
+
+-
+ if (kvm_vcpu_read_guest_page(vcpu, vmcs12->eptp_list_address >> PAGE_SHIFT,
+ &new_eptp, index * 8, 8))
+ return 1;
+
+- accessed_dirty = !!(new_eptp & VMX_EPTP_AD_ENABLE_BIT);
+-
+ /*
+ * If the (L2) guest does a vmfunc to the currently
+ * active ept pointer, we don't have to do anything else
+@@ -5513,8 +5508,6 @@ static int nested_vmx_eptp_switching(struct kvm_vcpu *vcpu,
+ if (!nested_vmx_check_eptp(vcpu, new_eptp))
+ return 1;
+
+- mmu->ept_ad = accessed_dirty;
+- mmu->mmu_role.base.ad_disabled = !accessed_dirty;
+ vmcs12->ept_pointer = new_eptp;
+
+ kvm_make_request(KVM_REQ_MMU_RELOAD, vcpu);
+--
+2.30.2
+
--- /dev/null
+From 353619000e173b3f8f571f479e04a5865e65f41a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jun 2021 16:42:22 -0700
+Subject: KVM: nVMX: Ensure 64-bit shift when checking VMFUNC bitmap
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 0e75225dfa4c5d5d51291f54a3d2d5895bad38da ]
+
+Use BIT_ULL() instead of an open-coded shift to check whether or not a
+function is enabled in L1's VMFUNC bitmap. This is a benign bug as KVM
+supports only bit 0, and will fail VM-Enter if any other bits are set,
+i.e. bits 63:32 are guaranteed to be zero.
+
+Note, "function" is bounded by hardware as VMFUNC will #UD before taking
+a VM-Exit if the function is greater than 63.
+
+Before:
+ if ((vmcs12->vm_function_control & (1 << function)) == 0)
+ 0x000000000001a916 <+118>: mov $0x1,%eax
+ 0x000000000001a91b <+123>: shl %cl,%eax
+ 0x000000000001a91d <+125>: cltq
+ 0x000000000001a91f <+127>: and 0x128(%rbx),%rax
+
+After:
+ if (!(vmcs12->vm_function_control & BIT_ULL(function & 63)))
+ 0x000000000001a955 <+117>: mov 0x128(%rbx),%rdx
+ 0x000000000001a95c <+124>: bt %rax,%rdx
+
+Fixes: 27c42a1bb867 ("KVM: nVMX: Enable VMFUNC for the L1 hypervisor")
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20210609234235.1244004-3-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/vmx/nested.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
+index 1dd092d35cae..ba82b8563b07 100644
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -5540,7 +5540,7 @@ static int handle_vmfunc(struct kvm_vcpu *vcpu)
+ }
+
+ vmcs12 = get_vmcs12(vcpu);
+- if ((vmcs12->vm_function_control & (1 << function)) == 0)
++ if (!(vmcs12->vm_function_control & BIT_ULL(function)))
+ goto fail;
+
+ switch (function) {
+--
+2.30.2
+
--- /dev/null
+From 2aab6aef57420eddc754a0a1bca8d3c0aa712b01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jun 2021 16:42:21 -0700
+Subject: KVM: nVMX: Sync all PGDs on nested transition with shadow paging
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 07ffaf343e34b555c9e7ea39a9c81c439a706f13 ]
+
+Trigger a full TLB flush on behalf of the guest on nested VM-Enter and
+VM-Exit when VPID is disabled for L2. kvm_mmu_new_pgd() syncs only the
+current PGD, which can theoretically leave stale, unsync'd entries in a
+previous guest PGD, which could be consumed if L2 is allowed to load CR3
+with PCID_NOFLUSH=1.
+
+Rename KVM_REQ_HV_TLB_FLUSH to KVM_REQ_TLB_FLUSH_GUEST so that it can
+be utilized for its obvious purpose of emulating a guest TLB flush.
+
+Note, there is no change the actual TLB flush executed by KVM, even
+though the fast PGD switch uses KVM_REQ_TLB_FLUSH_CURRENT. When VPID is
+disabled for L2, vpid02 is guaranteed to be '0', and thus
+nested_get_vpid02() will return the VPID that is shared by L1 and L2.
+
+Generate the request outside of kvm_mmu_new_pgd(), as getting the common
+helper to correctly identify which requested is needed is quite painful.
+E.g. using KVM_REQ_TLB_FLUSH_GUEST when nested EPT is in play is wrong as
+a TLB flush from the L1 kernel's perspective does not invalidate EPT
+mappings. And, by using KVM_REQ_TLB_FLUSH_GUEST, nVMX can do future
+simplification by moving the logic into nested_vmx_transition_tlb_flush().
+
+Fixes: 41fab65e7c44 ("KVM: nVMX: Skip MMU sync on nested VMX transition when possible")
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20210609234235.1244004-2-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/kvm_host.h | 2 +-
+ arch/x86/kvm/hyperv.c | 2 +-
+ arch/x86/kvm/vmx/nested.c | 17 ++++++++++++-----
+ arch/x86/kvm/x86.c | 2 +-
+ 4 files changed, 15 insertions(+), 8 deletions(-)
+
+diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
+index 46c99434c9fd..fbd55c682d5e 100644
+--- a/arch/x86/include/asm/kvm_host.h
++++ b/arch/x86/include/asm/kvm_host.h
+@@ -85,7 +85,7 @@
+ #define KVM_REQ_APICV_UPDATE \
+ KVM_ARCH_REQ_FLAGS(25, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
+ #define KVM_REQ_TLB_FLUSH_CURRENT KVM_ARCH_REQ(26)
+-#define KVM_REQ_HV_TLB_FLUSH \
++#define KVM_REQ_TLB_FLUSH_GUEST \
+ KVM_ARCH_REQ_FLAGS(27, KVM_REQUEST_NO_WAKEUP)
+ #define KVM_REQ_APF_READY KVM_ARCH_REQ(28)
+ #define KVM_REQ_MSR_FILTER_CHANGED KVM_ARCH_REQ(29)
+diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
+index f00830e5202f..fdd1eca717fd 100644
+--- a/arch/x86/kvm/hyperv.c
++++ b/arch/x86/kvm/hyperv.c
+@@ -1704,7 +1704,7 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, u64 ingpa, u16 rep_cnt, bool
+ * vcpu->arch.cr3 may not be up-to-date for running vCPUs so we can't
+ * analyze it here, flush TLB regardless of the specified address space.
+ */
+- kvm_make_vcpus_request_mask(kvm, KVM_REQ_HV_TLB_FLUSH,
++ kvm_make_vcpus_request_mask(kvm, KVM_REQ_TLB_FLUSH_GUEST,
+ NULL, vcpu_mask, &hv_vcpu->tlb_flush);
+
+ ret_success:
+diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
+index 5677cef81642..1dd092d35cae 100644
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -1127,12 +1127,19 @@ static int nested_vmx_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3, bool ne
+
+ /*
+ * Unconditionally skip the TLB flush on fast CR3 switch, all TLB
+- * flushes are handled by nested_vmx_transition_tlb_flush(). See
+- * nested_vmx_transition_mmu_sync for details on skipping the MMU sync.
++ * flushes are handled by nested_vmx_transition_tlb_flush().
+ */
+- if (!nested_ept)
+- kvm_mmu_new_pgd(vcpu, cr3, true,
+- !nested_vmx_transition_mmu_sync(vcpu));
++ if (!nested_ept) {
++ kvm_mmu_new_pgd(vcpu, cr3, true, true);
++
++ /*
++ * A TLB flush on VM-Enter/VM-Exit flushes all linear mappings
++ * across all PCIDs, i.e. all PGDs need to be synchronized.
++ * See nested_vmx_transition_mmu_sync() for more details.
++ */
++ if (nested_vmx_transition_mmu_sync(vcpu))
++ kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
++ }
+
+ vcpu->arch.cr3 = cr3;
+ kvm_register_mark_available(vcpu, VCPU_EXREG_CR3);
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 203aabf4346e..dad282fe0dac 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -9171,7 +9171,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
+ }
+ if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu))
+ kvm_vcpu_flush_tlb_current(vcpu);
+- if (kvm_check_request(KVM_REQ_HV_TLB_FLUSH, vcpu))
++ if (kvm_check_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu))
+ kvm_vcpu_flush_tlb_guest(vcpu);
+
+ if (kvm_check_request(KVM_REQ_REPORT_TPR_ACCESS, vcpu)) {
+--
+2.30.2
+
--- /dev/null
+From 62f6e2730bbd471df8b0e222f7b42f3b8cef9fe9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Jun 2021 14:04:41 +1000
+Subject: KVM: PPC: Book3S HV: Fix TLB management on SMT8 POWER9 and POWER10
+ processors
+
+From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+
+[ Upstream commit 77bbbc0cf84834ed130838f7ac1988567f4d0288 ]
+
+The POWER9 vCPU TLB management code assumes all threads in a core share
+a TLB, and that TLBIEL execued by one thread will invalidate TLBs for
+all threads. This is not the case for SMT8 capable POWER9 and POWER10
+(big core) processors, where the TLB is split between groups of threads.
+This results in TLB multi-hits, random data corruption, etc.
+
+Fix this by introducing cpu_first_tlb_thread_sibling etc., to determine
+which siblings share TLBs, and use that in the guest TLB flushing code.
+
+[npiggin@gmail.com: add changelog and comment]
+
+Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20210602040441.3984352-1-npiggin@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/cputhreads.h | 30 +++++++++++++++++++++++++++
+ arch/powerpc/kvm/book3s_hv.c | 13 ++++++------
+ arch/powerpc/kvm/book3s_hv_builtin.c | 2 +-
+ arch/powerpc/kvm/book3s_hv_rm_mmu.c | 2 +-
+ 4 files changed, 39 insertions(+), 8 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h
+index 98c8bd155bf9..b167186aaee4 100644
+--- a/arch/powerpc/include/asm/cputhreads.h
++++ b/arch/powerpc/include/asm/cputhreads.h
+@@ -98,6 +98,36 @@ static inline int cpu_last_thread_sibling(int cpu)
+ return cpu | (threads_per_core - 1);
+ }
+
++/*
++ * tlb_thread_siblings are siblings which share a TLB. This is not
++ * architected, is not something a hypervisor could emulate and a future
++ * CPU may change behaviour even in compat mode, so this should only be
++ * used on PowerNV, and only with care.
++ */
++static inline int cpu_first_tlb_thread_sibling(int cpu)
++{
++ if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8))
++ return cpu & ~0x6; /* Big Core */
++ else
++ return cpu_first_thread_sibling(cpu);
++}
++
++static inline int cpu_last_tlb_thread_sibling(int cpu)
++{
++ if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8))
++ return cpu | 0x6; /* Big Core */
++ else
++ return cpu_last_thread_sibling(cpu);
++}
++
++static inline int cpu_tlb_thread_sibling_step(void)
++{
++ if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8))
++ return 2; /* Big Core */
++ else
++ return 1;
++}
++
+ static inline u32 get_tensr(void)
+ {
+ #ifdef CONFIG_BOOKE
+diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
+index bc0813644666..67cc164c4ac1 100644
+--- a/arch/powerpc/kvm/book3s_hv.c
++++ b/arch/powerpc/kvm/book3s_hv.c
+@@ -2657,7 +2657,7 @@ static void radix_flush_cpu(struct kvm *kvm, int cpu, struct kvm_vcpu *vcpu)
+ cpumask_t *cpu_in_guest;
+ int i;
+
+- cpu = cpu_first_thread_sibling(cpu);
++ cpu = cpu_first_tlb_thread_sibling(cpu);
+ if (nested) {
+ cpumask_set_cpu(cpu, &nested->need_tlb_flush);
+ cpu_in_guest = &nested->cpu_in_guest;
+@@ -2671,9 +2671,10 @@ static void radix_flush_cpu(struct kvm *kvm, int cpu, struct kvm_vcpu *vcpu)
+ * the other side is the first smp_mb() in kvmppc_run_core().
+ */
+ smp_mb();
+- for (i = 0; i < threads_per_core; ++i)
+- if (cpumask_test_cpu(cpu + i, cpu_in_guest))
+- smp_call_function_single(cpu + i, do_nothing, NULL, 1);
++ for (i = cpu; i <= cpu_last_tlb_thread_sibling(cpu);
++ i += cpu_tlb_thread_sibling_step())
++ if (cpumask_test_cpu(i, cpu_in_guest))
++ smp_call_function_single(i, do_nothing, NULL, 1);
+ }
+
+ static void kvmppc_prepare_radix_vcpu(struct kvm_vcpu *vcpu, int pcpu)
+@@ -2704,8 +2705,8 @@ static void kvmppc_prepare_radix_vcpu(struct kvm_vcpu *vcpu, int pcpu)
+ */
+ if (prev_cpu != pcpu) {
+ if (prev_cpu >= 0 &&
+- cpu_first_thread_sibling(prev_cpu) !=
+- cpu_first_thread_sibling(pcpu))
++ cpu_first_tlb_thread_sibling(prev_cpu) !=
++ cpu_first_tlb_thread_sibling(pcpu))
+ radix_flush_cpu(kvm, prev_cpu, vcpu);
+ if (nested)
+ nested->prev_cpu[vcpu->arch.nested_vcpu_id] = pcpu;
+diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
+index 7a0e33a9c980..3edc25c89092 100644
+--- a/arch/powerpc/kvm/book3s_hv_builtin.c
++++ b/arch/powerpc/kvm/book3s_hv_builtin.c
+@@ -800,7 +800,7 @@ void kvmppc_check_need_tlb_flush(struct kvm *kvm, int pcpu,
+ * Thus we make all 4 threads use the same bit.
+ */
+ if (cpu_has_feature(CPU_FTR_ARCH_300))
+- pcpu = cpu_first_thread_sibling(pcpu);
++ pcpu = cpu_first_tlb_thread_sibling(pcpu);
+
+ if (nested)
+ need_tlb_flush = &nested->need_tlb_flush;
+diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+index 7a0f12404e0e..502d9ebe3ae4 100644
+--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
++++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+@@ -56,7 +56,7 @@ static int global_invalidates(struct kvm *kvm)
+ * so use the bit for the first thread to represent the core.
+ */
+ if (cpu_has_feature(CPU_FTR_ARCH_300))
+- cpu = cpu_first_thread_sibling(cpu);
++ cpu = cpu_first_tlb_thread_sibling(cpu);
+ cpumask_clear_cpu(cpu, &kvm->arch.need_tlb_flush);
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 41e19d4c3dde05e114f5b1f12a05dedd823b6f07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Jun 2021 16:03:56 +0200
+Subject: KVM: s390: get rid of register asm usage
+
+From: Heiko Carstens <hca@linux.ibm.com>
+
+[ Upstream commit 4fa3b91bdee1b08348c82660668ca0ca34e271ad ]
+
+Using register asm statements has been proven to be very error prone,
+especially when using code instrumentation where gcc may add function
+calls, which clobbers register contents in an unexpected way.
+
+Therefore get rid of register asm statements in kvm code, even though
+there is currently nothing wrong with them. This way we know for sure
+that this bug class won't be introduced here.
+
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Link: https://lore.kernel.org/r/20210621140356.1210771-1-hca@linux.ibm.com
+[borntraeger@de.ibm.com: checkpatch strict fix]
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kvm/kvm-s390.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
+index 1296fc10f80c..876fc1f7282a 100644
+--- a/arch/s390/kvm/kvm-s390.c
++++ b/arch/s390/kvm/kvm-s390.c
+@@ -329,31 +329,31 @@ static void allow_cpu_feat(unsigned long nr)
+
+ static inline int plo_test_bit(unsigned char nr)
+ {
+- register unsigned long r0 asm("0") = (unsigned long) nr | 0x100;
++ unsigned long function = (unsigned long)nr | 0x100;
+ int cc;
+
+ asm volatile(
++ " lgr 0,%[function]\n"
+ /* Parameter registers are ignored for "test bit" */
+ " plo 0,0,0,0(0)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ : "=d" (cc)
+- : "d" (r0)
+- : "cc");
++ : [function] "d" (function)
++ : "cc", "0");
+ return cc == 0;
+ }
+
+ static __always_inline void __insn32_query(unsigned int opcode, u8 *query)
+ {
+- register unsigned long r0 asm("0") = 0; /* query function */
+- register unsigned long r1 asm("1") = (unsigned long) query;
+-
+ asm volatile(
+- /* Parameter regs are ignored */
++ " lghi 0,0\n"
++ " lgr 1,%[query]\n"
++ /* Parameter registers are ignored */
+ " .insn rrf,%[opc] << 16,2,4,6,0\n"
+ :
+- : "d" (r0), "a" (r1), [opc] "i" (opcode)
+- : "cc", "memory");
++ : [query] "d" ((unsigned long)query), [opc] "i" (opcode)
++ : "cc", "memory", "0", "1");
+ }
+
+ #define INSN_SORTL 0xb938
+--
+2.30.2
+
--- /dev/null
+From 87a5f35ae2d503e5702b5b1a19df2cac6aa89cd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 21:55:32 +0800
+Subject: KVM: selftests: fix triple fault if ept=0 in dirty_log_test
+
+From: Hou Wenlong <houwenlong93@linux.alibaba.com>
+
+[ Upstream commit e5830fb13b8cad5e3bdf84f0f7a3dcb4f4d9bcbb ]
+
+Commit 22f232d134e1 ("KVM: selftests: x86: Set supported CPUIDs on
+default VM") moved vcpu_set_cpuid into vm_create_with_vcpus, but
+dirty_log_test doesn't use it to create vm. So vcpu's CPUIDs is
+not set, the guest's pa_bits in kvm would be smaller than the
+value queried by userspace.
+
+However, the dirty track memory slot is in the highest GPA, the
+reserved bits in gpte would be set with wrong pa_bits.
+For shadow paging, page fault would fail in permission_fault and
+be injected into guest. Since guest doesn't have idt, it finally
+leads to vm_exit for triple fault.
+
+Move vcpu_set_cpuid into vm_vcpu_add_default to set supported
+CPUIDs on default vcpu, since almost all tests need it.
+
+Fixes: 22f232d134e1 ("KVM: selftests: x86: Set supported CPUIDs on default VM")
+Signed-off-by: Hou Wenlong <houwenlong93@linux.alibaba.com>
+Message-Id: <411ea2173f89abce56fc1fca5af913ed9c5a89c9.1624351343.git.houwenlong93@linux.alibaba.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/kvm/lib/kvm_util.c | 4 ----
+ tools/testing/selftests/kvm/lib/x86_64/processor.c | 3 +++
+ tools/testing/selftests/kvm/steal_time.c | 2 --
+ tools/testing/selftests/kvm/x86_64/set_boot_cpu_id.c | 2 --
+ 4 files changed, 3 insertions(+), 8 deletions(-)
+
+diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
+index a2b732cf96ea..8ea854d7822d 100644
+--- a/tools/testing/selftests/kvm/lib/kvm_util.c
++++ b/tools/testing/selftests/kvm/lib/kvm_util.c
+@@ -375,10 +375,6 @@ struct kvm_vm *vm_create_with_vcpus(enum vm_guest_mode mode, uint32_t nr_vcpus,
+ uint32_t vcpuid = vcpuids ? vcpuids[i] : i;
+
+ vm_vcpu_add_default(vm, vcpuid, guest_code);
+-
+-#ifdef __x86_64__
+- vcpu_set_cpuid(vm, vcpuid, kvm_get_supported_cpuid());
+-#endif
+ }
+
+ return vm;
+diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c
+index efe235044421..595322b24e4c 100644
+--- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
++++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c
+@@ -600,6 +600,9 @@ void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, void *guest_code)
+ /* Setup the MP state */
+ mp_state.mp_state = 0;
+ vcpu_set_mp_state(vm, vcpuid, &mp_state);
++
++ /* Setup supported CPUIDs */
++ vcpu_set_cpuid(vm, vcpuid, kvm_get_supported_cpuid());
+ }
+
+ /*
+diff --git a/tools/testing/selftests/kvm/steal_time.c b/tools/testing/selftests/kvm/steal_time.c
+index fcc840088c91..a6fe75cb9a6e 100644
+--- a/tools/testing/selftests/kvm/steal_time.c
++++ b/tools/testing/selftests/kvm/steal_time.c
+@@ -73,8 +73,6 @@ static void steal_time_init(struct kvm_vm *vm)
+ for (i = 0; i < NR_VCPUS; ++i) {
+ int ret;
+
+- vcpu_set_cpuid(vm, i, kvm_get_supported_cpuid());
+-
+ /* ST_GPA_BASE is identity mapped */
+ st_gva[i] = (void *)(ST_GPA_BASE + i * STEAL_TIME_SIZE);
+ sync_global_to_guest(vm, st_gva[i]);
+diff --git a/tools/testing/selftests/kvm/x86_64/set_boot_cpu_id.c b/tools/testing/selftests/kvm/x86_64/set_boot_cpu_id.c
+index 12c558fc8074..c8d2bbe202d0 100644
+--- a/tools/testing/selftests/kvm/x86_64/set_boot_cpu_id.c
++++ b/tools/testing/selftests/kvm/x86_64/set_boot_cpu_id.c
+@@ -106,8 +106,6 @@ static void add_x86_vcpu(struct kvm_vm *vm, uint32_t vcpuid, bool bsp_code)
+ vm_vcpu_add_default(vm, vcpuid, guest_bsp_vcpu);
+ else
+ vm_vcpu_add_default(vm, vcpuid, guest_not_bsp_vcpu);
+-
+- vcpu_set_cpuid(vm, vcpuid, kvm_get_supported_cpuid());
+ }
+
+ static void run_vm_bsp(uint32_t bsp_vcpu)
+--
+2.30.2
+
--- /dev/null
+From 0f8e2fb1c7a85d7115d6f4c153ac36b57296b5b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 13:05:11 -0700
+Subject: KVM: selftests: Remove errant asm/barrier.h include to fix arm64
+ build
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit ecc3a92c6f4953c134a9590c762755e6593f507c ]
+
+Drop an unnecessary include of asm/barrier.h from dirty_log_test.c to
+allow the test to build on arm64. arm64, s390, and x86 all build cleanly
+without the include (PPC and MIPS aren't supported in KVM's selftests).
+
+arm64's barrier.h includes linux/kasan-checks.h, which is not copied
+into tools/.
+
+ In file included from ../../../../tools/include/asm/barrier.h:8,
+ from dirty_log_test.c:19:
+ .../arm64/include/asm/barrier.h:12:10: fatal error: linux/kasan-checks.h: No such file or directory
+ 12 | #include <linux/kasan-checks.h>
+ | ^~~~~~~~~~~~~~~~~~~~~~
+ compilation terminated.
+
+Fixes: 84292e565951 ("KVM: selftests: Add dirty ring buffer test")
+Cc: Peter Xu <peterx@redhat.com>
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20210622200529.3650424-2-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/kvm/dirty_log_test.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/tools/testing/selftests/kvm/dirty_log_test.c b/tools/testing/selftests/kvm/dirty_log_test.c
+index 81edbd23d371..b4d24f50aca6 100644
+--- a/tools/testing/selftests/kvm/dirty_log_test.c
++++ b/tools/testing/selftests/kvm/dirty_log_test.c
+@@ -16,7 +16,6 @@
+ #include <errno.h>
+ #include <linux/bitmap.h>
+ #include <linux/bitops.h>
+-#include <asm/barrier.h>
+ #include <linux/atomic.h>
+
+ #include "kvm_util.h"
+--
+2.30.2
+
--- /dev/null
+From 7f2e72e83890a0c4f8209defcaaba012d35b2abe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jun 2021 12:57:10 +1200
+Subject: KVM: x86/mmu: Fix pf_fixed count in tdp_mmu_map_handle_target_level()
+
+From: Kai Huang <kai.huang@intel.com>
+
+[ Upstream commit 857f84743e4b78500afae010d866675642e18e90 ]
+
+Currently pf_fixed is not increased when prefault is true. This is not
+correct, since prefault here really means "async page fault completed".
+In that case, the original page fault from the guest was morphed into as
+async page fault and pf_fixed was not increased. So when prefault
+indicates async page fault is completed, pf_fixed should be increased.
+
+Additionally, currently pf_fixed is also increased even when page fault
+is spurious, while legacy MMU increases pf_fixed when page fault returns
+RET_PF_EMULATE or RET_PF_FIXED.
+
+To fix above two issues, change to increase pf_fixed when return value
+is not RET_PF_SPURIOUS (RET_PF_RETRY has already been ruled out by
+reaching here).
+
+More information:
+https://lore.kernel.org/kvm/cover.1620200410.git.kai.huang@intel.com/T/#mbb5f8083e58a2cd262231512b9211cbe70fc3bd5
+
+Fixes: bb18842e2111 ("kvm: x86/mmu: Add TDP MMU PF handler")
+Reviewed-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Kai Huang <kai.huang@intel.com>
+Message-Id: <2ea8b7f5d4f03c99b32bc56fc982e1e4e3d3fc6b.1623717884.git.kai.huang@intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/mmu/tdp_mmu.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
+index 35b0ece7beff..8773bd5287da 100644
+--- a/arch/x86/kvm/mmu/tdp_mmu.c
++++ b/arch/x86/kvm/mmu/tdp_mmu.c
+@@ -949,7 +949,11 @@ static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu, int write,
+ rcu_dereference(iter->sptep));
+ }
+
+- if (!prefault)
++ /*
++ * Increase pf_fixed in both RET_PF_EMULATE and RET_PF_FIXED to be
++ * consistent with legacy MMU behavior.
++ */
++ if (ret != RET_PF_SPURIOUS)
+ vcpu->stat.pf_fixed++;
+
+ return ret;
+--
+2.30.2
+
--- /dev/null
+From 9e378748ab22089ddb44f2f48f3a0482b56cf207 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jun 2021 12:57:09 +1200
+Subject: KVM: x86/mmu: Fix return value in tdp_mmu_map_handle_target_level()
+
+From: Kai Huang <kai.huang@intel.com>
+
+[ Upstream commit 57a3e96d6d17ae5ac9861ef34af024a627f1c3bb ]
+
+Currently tdp_mmu_map_handle_target_level() returns 0, which is
+RET_PF_RETRY, when page fault is actually fixed. This makes
+kvm_tdp_mmu_map() also return RET_PF_RETRY in this case, instead of
+RET_PF_FIXED. Fix by initializing ret to RET_PF_FIXED.
+
+Note that kvm_mmu_page_fault() resumes guest on both RET_PF_RETRY and
+RET_PF_FIXED, which means in practice returning the two won't make
+difference, so this fix alone won't be necessary for stable tree.
+
+Fixes: bb18842e2111 ("kvm: x86/mmu: Add TDP MMU PF handler")
+Reviewed-by: Sean Christopherson <seanjc@google.com>
+Reviewed-by: Ben Gardon <bgardon@google.com>
+Signed-off-by: Kai Huang <kai.huang@intel.com>
+Message-Id: <f9e8956223a586cd28c090879a8ff40f5eb6d609.1623717884.git.kai.huang@intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/mmu/tdp_mmu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
+index 237317b1eddd..35b0ece7beff 100644
+--- a/arch/x86/kvm/mmu/tdp_mmu.c
++++ b/arch/x86/kvm/mmu/tdp_mmu.c
+@@ -912,7 +912,7 @@ static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu, int write,
+ kvm_pfn_t pfn, bool prefault)
+ {
+ u64 new_spte;
+- int ret = 0;
++ int ret = RET_PF_FIXED;
+ int make_spte_ret = 0;
+
+ if (unlikely(is_noslot_pfn(pfn)))
+--
+2.30.2
+
--- /dev/null
+From 5037c6ef055bf1c4ccda850e1e92c1335972b618 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 May 2021 11:06:46 +0800
+Subject: leds: as3645a: Fix error return code in as3645a_parse_node()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit 96a30960a2c5246c8ffebe8a3c9031f9df094d97 ]
+
+Return error code -ENODEV rather than '0' when the indicator node can not
+be found.
+
+Fixes: a56ba8fbcb55 ("media: leds: as3645a: Add LED flash class driver")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Signed-off-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/leds-as3645a.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/leds/leds-as3645a.c b/drivers/leds/leds-as3645a.c
+index e8922fa03379..80411d41e802 100644
+--- a/drivers/leds/leds-as3645a.c
++++ b/drivers/leds/leds-as3645a.c
+@@ -545,6 +545,7 @@ static int as3645a_parse_node(struct as3645a *flash,
+ if (!flash->indicator_node) {
+ dev_warn(&flash->client->dev,
+ "can't find indicator node\n");
++ rval = -ENODEV;
+ goto out_err;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 2b3d0e429a683583043f6f7ca15aef3aa8cc4704 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 12:50:18 +0300
+Subject: leds: class: The -ENOTSUPP should never be seen by user space
+
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+
+[ Upstream commit 0ac40af86077982a5346dbc9655172d2775d6b08 ]
+
+Drop the bogus error code and let of_led_get() to take care about absent
+of_node.
+
+Fixes: e389240ad992 ("leds: Add managed API to get a LED from a device driver")
+Cc: Jean-Jacques Hiblot <jjhiblot@ti.com>
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/led-class.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
+index 2e495ff67856..fa3f5f504ff7 100644
+--- a/drivers/leds/led-class.c
++++ b/drivers/leds/led-class.c
+@@ -285,10 +285,6 @@ struct led_classdev *__must_check devm_of_led_get(struct device *dev,
+ if (!dev)
+ return ERR_PTR(-EINVAL);
+
+- /* Not using device tree? */
+- if (!IS_ENABLED(CONFIG_OF) || !dev->of_node)
+- return ERR_PTR(-ENOTSUPP);
+-
+ led = of_led_get(dev->of_node, index);
+ if (IS_ERR(led))
+ return led;
+--
+2.30.2
+
--- /dev/null
+From f423bf52df1d9faabe007cc3ebeb5a7ba5b34f0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 13:21:01 +0200
+Subject: leds: ktd2692: Fix an error handling path
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit ee78b9360e14c276f5ceaa4a0d06f790f04ccdad ]
+
+In 'ktd2692_parse_dt()', if an error occurs after a successful
+'regulator_enable()' call, we should call 'regulator_enable()'.
+
+This is the same in 'ktd2692_probe()', if an error occurs after a
+successful 'ktd2692_parse_dt()' call.
+
+Instead of adding 'regulator_enable()' in several places, implement a
+resource managed solution and simplify the remove function accordingly.
+
+Fixes: b7da8c5c725c ("leds: Add ktd2692 flash LED driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/leds-ktd2692.c | 27 ++++++++++++++++++---------
+ 1 file changed, 18 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/leds/leds-ktd2692.c b/drivers/leds/leds-ktd2692.c
+index 632f10db4b3f..f341da1503a4 100644
+--- a/drivers/leds/leds-ktd2692.c
++++ b/drivers/leds/leds-ktd2692.c
+@@ -256,6 +256,17 @@ static void ktd2692_setup(struct ktd2692_context *led)
+ | KTD2692_REG_FLASH_CURRENT_BASE);
+ }
+
++static void regulator_disable_action(void *_data)
++{
++ struct device *dev = _data;
++ struct ktd2692_context *led = dev_get_drvdata(dev);
++ int ret;
++
++ ret = regulator_disable(led->regulator);
++ if (ret)
++ dev_err(dev, "Failed to disable supply: %d\n", ret);
++}
++
+ static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev,
+ struct ktd2692_led_config_data *cfg)
+ {
+@@ -286,8 +297,14 @@ static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev,
+
+ if (led->regulator) {
+ ret = regulator_enable(led->regulator);
+- if (ret)
++ if (ret) {
+ dev_err(dev, "Failed to enable supply: %d\n", ret);
++ } else {
++ ret = devm_add_action_or_reset(dev,
++ regulator_disable_action, dev);
++ if (ret)
++ return ret;
++ }
+ }
+
+ child_node = of_get_next_available_child(np, NULL);
+@@ -377,17 +394,9 @@ static int ktd2692_probe(struct platform_device *pdev)
+ static int ktd2692_remove(struct platform_device *pdev)
+ {
+ struct ktd2692_context *led = platform_get_drvdata(pdev);
+- int ret;
+
+ led_classdev_flash_unregister(&led->fled_cdev);
+
+- if (led->regulator) {
+- ret = regulator_disable(led->regulator);
+- if (ret)
+- dev_err(&pdev->dev,
+- "Failed to disable supply: %d\n", ret);
+- }
+-
+ mutex_destroy(&led->lock);
+
+ return 0;
+--
+2.30.2
+
--- /dev/null
+From b67a8a65f9e67e04452b7f12d0984d75e712809a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 12:50:24 +0300
+Subject: leds: lgm-sso: Fix clock handling
+
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+
+[ Upstream commit fba8a6f2263bc54683cf3fd75df4dbd5d041c195 ]
+
+The clock handling has a few issues:
+ - when getting second clock fails, the first one left prepared and enabled
+ - on ->remove() clocks are unprepared and disabled twice
+
+Fix all these by converting to use bulk clock operations since both clocks
+are mandatory.
+
+Fixes: c3987cd2bca3 ("leds: lgm: Add LED controller driver for LGM SoC")
+Cc: Amireddy Mallikarjuna reddy <mallikarjunax.reddy@linux.intel.com>
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/blink/leds-lgm-sso.c | 44 ++++++++++++-------------------
+ 1 file changed, 17 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/leds/blink/leds-lgm-sso.c b/drivers/leds/blink/leds-lgm-sso.c
+index 6a63846d10b5..7d5f0bf2817a 100644
+--- a/drivers/leds/blink/leds-lgm-sso.c
++++ b/drivers/leds/blink/leds-lgm-sso.c
+@@ -132,8 +132,7 @@ struct sso_led_priv {
+ struct regmap *mmap;
+ struct device *dev;
+ struct platform_device *pdev;
+- struct clk *gclk;
+- struct clk *fpid_clk;
++ struct clk_bulk_data clocks[2];
+ u32 fpid_clkrate;
+ u32 gptc_clkrate;
+ u32 freq[MAX_FREQ_RANK];
+@@ -763,12 +762,11 @@ static int sso_probe_gpios(struct sso_led_priv *priv)
+ return sso_gpio_gc_init(dev, priv);
+ }
+
+-static void sso_clk_disable(void *data)
++static void sso_clock_disable_unprepare(void *data)
+ {
+ struct sso_led_priv *priv = data;
+
+- clk_disable_unprepare(priv->fpid_clk);
+- clk_disable_unprepare(priv->gclk);
++ clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks);
+ }
+
+ static int intel_sso_led_probe(struct platform_device *pdev)
+@@ -785,36 +783,30 @@ static int intel_sso_led_probe(struct platform_device *pdev)
+ priv->dev = dev;
+
+ /* gate clock */
+- priv->gclk = devm_clk_get(dev, "sso");
+- if (IS_ERR(priv->gclk)) {
+- dev_err(dev, "get sso gate clock failed!\n");
+- return PTR_ERR(priv->gclk);
+- }
++ priv->clocks[0].id = "sso";
++
++ /* fpid clock */
++ priv->clocks[1].id = "fpid";
+
+- ret = clk_prepare_enable(priv->gclk);
++ ret = devm_clk_bulk_get(dev, ARRAY_SIZE(priv->clocks), priv->clocks);
+ if (ret) {
+- dev_err(dev, "Failed to prepare/enable sso gate clock!\n");
++ dev_err(dev, "Getting clocks failed!\n");
+ return ret;
+ }
+
+- priv->fpid_clk = devm_clk_get(dev, "fpid");
+- if (IS_ERR(priv->fpid_clk)) {
+- dev_err(dev, "Failed to get fpid clock!\n");
+- return PTR_ERR(priv->fpid_clk);
+- }
+-
+- ret = clk_prepare_enable(priv->fpid_clk);
++ ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clocks), priv->clocks);
+ if (ret) {
+- dev_err(dev, "Failed to prepare/enable fpid clock!\n");
++ dev_err(dev, "Failed to prepare and enable clocks!\n");
+ return ret;
+ }
+- priv->fpid_clkrate = clk_get_rate(priv->fpid_clk);
+
+- ret = devm_add_action_or_reset(dev, sso_clk_disable, priv);
+- if (ret) {
+- dev_err(dev, "Failed to devm_add_action_or_reset, %d\n", ret);
++ ret = devm_add_action_or_reset(dev, sso_clock_disable_unprepare, priv);
++ if (ret)
+ return ret;
+- }
++
++ priv->fpid_clkrate = clk_get_rate(priv->clocks[1].clk);
++
++ priv->mmap = syscon_node_to_regmap(dev->of_node);
+
+ priv->mmap = syscon_node_to_regmap(dev->of_node);
+ if (IS_ERR(priv->mmap)) {
+@@ -859,8 +851,6 @@ static int intel_sso_led_remove(struct platform_device *pdev)
+ sso_led_shutdown(led);
+ }
+
+- clk_disable_unprepare(priv->fpid_clk);
+- clk_disable_unprepare(priv->gclk);
+ regmap_exit(priv->mmap);
+
+ return 0;
+--
+2.30.2
+
--- /dev/null
+From 527f862ea2973eb03cc8c22115dd7443a1a5c263 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 12:50:31 +0300
+Subject: leds: lm3532: select regmap I2C API
+
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+
+[ Upstream commit 99be74f61cb0292b518f5e6d7e5c6611555c2ec7 ]
+
+Regmap APIs should be selected, otherwise link can fail
+
+ERROR: modpost: "__devm_regmap_init_i2c" [drivers/leds/leds-lm3532.ko] undefined!
+
+Fixes: bc1b8492c764 ("leds: lm3532: Introduce the lm3532 LED driver")
+Cc: Dan Murphy <dmurphy@ti.com>
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
+index 49d99cb084db..c81b1e60953c 100644
+--- a/drivers/leds/Kconfig
++++ b/drivers/leds/Kconfig
+@@ -199,6 +199,7 @@ config LEDS_LM3530
+
+ config LEDS_LM3532
+ tristate "LCD Backlight driver for LM3532"
++ select REGMAP_I2C
+ depends on LEDS_CLASS
+ depends on I2C
+ help
+--
+2.30.2
+
--- /dev/null
+From b935bae748f6cdeeadac91a7fc0d43880c2debfb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 12:50:33 +0300
+Subject: leds: lm36274: Put fwnode in error case during ->probe()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+
+[ Upstream commit 3c5f655c44bb65cb7e3c219d08c130ce5fa45d7f ]
+
+device_get_next_child_node() bumps a reference counting of a returned variable.
+We have to balance it whenever we return to the caller.
+
+In the older code the same is implied with device_for_each_child_node().
+
+Fixes: 11e1bbc116a7 ("leds: lm36274: Introduce the TI LM36274 LED driver")
+Fixes: a448fcf19c9c ("leds: lm36274: don't iterate through children since there is only one")
+Cc: Dan Murphy <dmurphy@ti.com>
+Cc: Marek Behún <marek.behun@nic.cz>
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/leds-lm36274.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/leds/leds-lm36274.c b/drivers/leds/leds-lm36274.c
+index aadb03468a40..a23a9424c2f3 100644
+--- a/drivers/leds/leds-lm36274.c
++++ b/drivers/leds/leds-lm36274.c
+@@ -127,6 +127,7 @@ static int lm36274_probe(struct platform_device *pdev)
+
+ ret = lm36274_init(chip);
+ if (ret) {
++ fwnode_handle_put(init_data.fwnode);
+ dev_err(chip->dev, "Failed to init the device\n");
+ return ret;
+ }
+--
+2.30.2
+
--- /dev/null
+From 955c3c0d1c5a73f435e3cdbac47a01d40dda8b3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 12:50:35 +0300
+Subject: leds: lm3692x: Put fwnode in any case during ->probe()
+
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+
+[ Upstream commit f55db1c7fadc2a29c9fa4ff3aec98dbb111f2206 ]
+
+device_get_next_child_node() bumps a reference counting of a returned variable.
+We have to balance it whenever we return to the caller.
+
+Fixes: 9a5c1c64ac0a ("leds: lm3692x: Change DT calls to fwnode calls")
+Cc: Dan Murphy <dmurphy@ti.com>
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/leds-lm3692x.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/leds/leds-lm3692x.c b/drivers/leds/leds-lm3692x.c
+index e945de45388c..55e6443997ec 100644
+--- a/drivers/leds/leds-lm3692x.c
++++ b/drivers/leds/leds-lm3692x.c
+@@ -435,6 +435,7 @@ static int lm3692x_probe_dt(struct lm3692x_led *led)
+
+ ret = fwnode_property_read_u32(child, "reg", &led->led_enable);
+ if (ret) {
++ fwnode_handle_put(child);
+ dev_err(&led->client->dev, "reg DT property missing\n");
+ return ret;
+ }
+@@ -449,12 +450,11 @@ static int lm3692x_probe_dt(struct lm3692x_led *led)
+
+ ret = devm_led_classdev_register_ext(&led->client->dev, &led->led_dev,
+ &init_data);
+- if (ret) {
++ if (ret)
+ dev_err(&led->client->dev, "led register err: %d\n", ret);
+- return ret;
+- }
+
+- return 0;
++ fwnode_handle_put(init_data.fwnode);
++ return ret;
+ }
+
+ static int lm3692x_probe(struct i2c_client *client,
+--
+2.30.2
+
--- /dev/null
+From 316f3a97e4b8ee14e31fb66eef42b70877a885b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 12:50:39 +0300
+Subject: leds: lm3697: Don't spam logs when probe is deferred
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 807553f8bf4afa673750e52905e0f9488179112f ]
+
+When requesting GPIO line the probe can be deferred.
+In such case don't spam logs with an error message.
+This can be achieved by switching to dev_err_probe().
+
+Fixes: 5c1d824cda9f ("leds: lm3697: Introduce the lm3697 driver")
+Cc: Dan Murphy <dmurphy@ti.com>
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/leds-lm3697.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/leds/leds-lm3697.c b/drivers/leds/leds-lm3697.c
+index 7d216cdb91a8..912e8bb22a99 100644
+--- a/drivers/leds/leds-lm3697.c
++++ b/drivers/leds/leds-lm3697.c
+@@ -203,11 +203,9 @@ static int lm3697_probe_dt(struct lm3697 *priv)
+
+ priv->enable_gpio = devm_gpiod_get_optional(dev, "enable",
+ GPIOD_OUT_LOW);
+- if (IS_ERR(priv->enable_gpio)) {
+- ret = PTR_ERR(priv->enable_gpio);
+- dev_err(dev, "Failed to get enable gpio: %d\n", ret);
+- return ret;
+- }
++ if (IS_ERR(priv->enable_gpio))
++ return dev_err_probe(dev, PTR_ERR(priv->enable_gpio),
++ "Failed to get enable GPIO\n");
+
+ priv->regulator = devm_regulator_get(dev, "vled");
+ if (IS_ERR(priv->regulator))
+--
+2.30.2
+
--- /dev/null
+From 87ee6cca6a5bb7d5196ba0f82639bd78563a3bc0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 12:50:40 +0300
+Subject: leds: lp50xx: Put fwnode in error case during ->probe()
+
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+
+[ Upstream commit f1e1d532da7e6ef355528a22fb97d9a8fbf76c4e ]
+
+fwnode_for_each_child_node() bumps a reference counting of a returned variable.
+We have to balance it whenever we return to the caller.
+
+OTOH, the successful iteration will drop reference count under the hood, no need
+to do it twice.
+
+Fixes: 242b81170fb8 ("leds: lp50xx: Add the LP50XX family of the RGB LED driver")
+Cc: Dan Murphy <dmurphy@ti.com>
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/leds-lp50xx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/leds/leds-lp50xx.c b/drivers/leds/leds-lp50xx.c
+index 06230614fdc5..401df1e2e05d 100644
+--- a/drivers/leds/leds-lp50xx.c
++++ b/drivers/leds/leds-lp50xx.c
+@@ -490,6 +490,7 @@ static int lp50xx_probe_dt(struct lp50xx *priv)
+ ret = fwnode_property_read_u32(led_node, "color",
+ &color_id);
+ if (ret) {
++ fwnode_handle_put(led_node);
+ dev_err(priv->dev, "Cannot read color\n");
+ goto child_out;
+ }
+@@ -512,7 +513,6 @@ static int lp50xx_probe_dt(struct lp50xx *priv)
+ goto child_out;
+ }
+ i++;
+- fwnode_handle_put(child);
+ }
+
+ return 0;
+--
+2.30.2
+
--- /dev/null
+From d62584700509ec16de9b98d0df3f0df210d05852 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 18:55:49 -0700
+Subject: lib/math/rational.c: fix divide by zero
+
+From: Trent Piepho <tpiepho@gmail.com>
+
+[ Upstream commit 65a0d3c14685663ba111038a35db70f559e39336 ]
+
+If the input is out of the range of the allowed values, either larger than
+the largest value or closer to zero than the smallest non-zero allowed
+value, then a division by zero would occur.
+
+In the case of input too large, the division by zero will occur on the
+first iteration. The best result (largest allowed value) will be found by
+always choosing the semi-convergent and excluding the denominator based
+limit when finding it.
+
+In the case of the input too small, the division by zero will occur on the
+second iteration. The numerator based semi-convergent should not be
+calculated to avoid the division by zero. But the semi-convergent vs
+previous convergent test is still needed, which effectively chooses
+between 0 (the previous convergent) vs the smallest allowed fraction (best
+semi-convergent) as the result.
+
+Link: https://lkml.kernel.org/r/20210525144250.214670-1-tpiepho@gmail.com
+Fixes: 323dd2c3ed0 ("lib/math/rational.c: fix possible incorrect result from rational fractions helper")
+Signed-off-by: Trent Piepho <tpiepho@gmail.com>
+Reported-by: Yiyuan Guo <yguoaz@gmail.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: Oskar Schirmer <oskar@scara.com>
+Cc: Daniel Latypov <dlatypov@google.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/math/rational.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/lib/math/rational.c b/lib/math/rational.c
+index 9781d521963d..c0ab51d8fbb9 100644
+--- a/lib/math/rational.c
++++ b/lib/math/rational.c
+@@ -12,6 +12,7 @@
+ #include <linux/compiler.h>
+ #include <linux/export.h>
+ #include <linux/minmax.h>
++#include <linux/limits.h>
+
+ /*
+ * calculate best rational approximation for a given fraction
+@@ -78,13 +79,18 @@ void rational_best_approximation(
+ * found below as 't'.
+ */
+ if ((n2 > max_numerator) || (d2 > max_denominator)) {
+- unsigned long t = min((max_numerator - n0) / n1,
+- (max_denominator - d0) / d1);
++ unsigned long t = ULONG_MAX;
+
+- /* This tests if the semi-convergent is closer
+- * than the previous convergent.
++ if (d1)
++ t = (max_denominator - d0) / d1;
++ if (n1)
++ t = min(t, (max_numerator - n0) / n1);
++
++ /* This tests if the semi-convergent is closer than the previous
++ * convergent. If d1 is zero there is no previous convergent as this
++ * is the 1st iteration, so always choose the semi-convergent.
+ */
+- if (2u * t > a || (2u * t == a && d0 * dp > d1 * d)) {
++ if (!d1 || 2u * t > a || (2u * t == a && d0 * dp > d1 * d)) {
+ n1 = n0 + t * n1;
+ d1 = d0 + t * d1;
+ }
+--
+2.30.2
+
--- /dev/null
+From b6ce7db8eddfe108a3265d9b3baac34c51e45777 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 May 2021 17:12:04 +0100
+Subject: lib: vsprintf: Fix handling of number field widths in vsscanf
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit 900fdc4573766dd43b847b4f54bd4a1ee2bc7360 ]
+
+The existing code attempted to handle numbers by doing a strto[u]l(),
+ignoring the field width, and then repeatedly dividing to extract the
+field out of the full converted value. If the string contains a run of
+valid digits longer than will fit in a long or long long, this would
+overflow and no amount of dividing can recover the correct value.
+
+This patch fixes vsscanf() to obey number field widths when parsing
+the number.
+
+A new _parse_integer_limit() is added that takes a limit for the number
+of characters to parse. The number field conversion in vsscanf is changed
+to use this new function.
+
+If a number starts with a radix prefix, the field width must be long
+enough for at last one digit after the prefix. If not, it will be handled
+like this:
+
+ sscanf("0x4", "%1i", &i): i=0, scanning continues with the 'x'
+ sscanf("0x4", "%2i", &i): i=0, scanning continues with the '4'
+
+This is consistent with the observed behaviour of userland sscanf.
+
+Note that this patch does NOT fix the problem of a single field value
+overflowing the target type. So for example:
+
+ sscanf("123456789abcdef", "%x", &i);
+
+Will not produce the correct result because the value obviously overflows
+INT_MAX. But sscanf will report a successful conversion.
+
+Note that where a very large number is used to mean "unlimited", the value
+INT_MAX is used for consistency with the behaviour of vsnprintf().
+
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Reviewed-by: Petr Mladek <pmladek@suse.com>
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Link: https://lore.kernel.org/r/20210514161206.30821-2-rf@opensource.cirrus.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/kstrtox.c | 13 ++++++--
+ lib/kstrtox.h | 2 ++
+ lib/vsprintf.c | 82 +++++++++++++++++++++++++++++---------------------
+ 3 files changed, 60 insertions(+), 37 deletions(-)
+
+diff --git a/lib/kstrtox.c b/lib/kstrtox.c
+index a118b0b1e9b2..0b5fe8b41173 100644
+--- a/lib/kstrtox.c
++++ b/lib/kstrtox.c
+@@ -39,20 +39,22 @@ const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
+
+ /*
+ * Convert non-negative integer string representation in explicitly given radix
+- * to an integer.
++ * to an integer. A maximum of max_chars characters will be converted.
++ *
+ * Return number of characters consumed maybe or-ed with overflow bit.
+ * If overflow occurs, result integer (incorrect) is still returned.
+ *
+ * Don't you dare use this function.
+ */
+-unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p)
++unsigned int _parse_integer_limit(const char *s, unsigned int base, unsigned long long *p,
++ size_t max_chars)
+ {
+ unsigned long long res;
+ unsigned int rv;
+
+ res = 0;
+ rv = 0;
+- while (1) {
++ while (max_chars--) {
+ unsigned int c = *s;
+ unsigned int lc = c | 0x20; /* don't tolower() this line */
+ unsigned int val;
+@@ -82,6 +84,11 @@ unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long
+ return rv;
+ }
+
++unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p)
++{
++ return _parse_integer_limit(s, base, p, INT_MAX);
++}
++
+ static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
+ {
+ unsigned long long _res;
+diff --git a/lib/kstrtox.h b/lib/kstrtox.h
+index 3b4637bcd254..158c400ca865 100644
+--- a/lib/kstrtox.h
++++ b/lib/kstrtox.h
+@@ -4,6 +4,8 @@
+
+ #define KSTRTOX_OVERFLOW (1U << 31)
+ const char *_parse_integer_fixup_radix(const char *s, unsigned int *base);
++unsigned int _parse_integer_limit(const char *s, unsigned int base, unsigned long long *res,
++ size_t max_chars);
+ unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *res);
+
+ #endif
+diff --git a/lib/vsprintf.c b/lib/vsprintf.c
+index f0c35d9b65bf..077a4a7c6f00 100644
+--- a/lib/vsprintf.c
++++ b/lib/vsprintf.c
+@@ -53,6 +53,31 @@
+ #include <linux/string_helpers.h>
+ #include "kstrtox.h"
+
++static unsigned long long simple_strntoull(const char *startp, size_t max_chars,
++ char **endp, unsigned int base)
++{
++ const char *cp;
++ unsigned long long result = 0ULL;
++ size_t prefix_chars;
++ unsigned int rv;
++
++ cp = _parse_integer_fixup_radix(startp, &base);
++ prefix_chars = cp - startp;
++ if (prefix_chars < max_chars) {
++ rv = _parse_integer_limit(cp, base, &result, max_chars - prefix_chars);
++ /* FIXME */
++ cp += (rv & ~KSTRTOX_OVERFLOW);
++ } else {
++ /* Field too short for prefix + digit, skip over without converting */
++ cp = startp + max_chars;
++ }
++
++ if (endp)
++ *endp = (char *)cp;
++
++ return result;
++}
++
+ /**
+ * simple_strtoull - convert a string to an unsigned long long
+ * @cp: The start of the string
+@@ -63,18 +88,7 @@
+ */
+ unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
+ {
+- unsigned long long result;
+- unsigned int rv;
+-
+- cp = _parse_integer_fixup_radix(cp, &base);
+- rv = _parse_integer(cp, base, &result);
+- /* FIXME */
+- cp += (rv & ~KSTRTOX_OVERFLOW);
+-
+- if (endp)
+- *endp = (char *)cp;
+-
+- return result;
++ return simple_strntoull(cp, INT_MAX, endp, base);
+ }
+ EXPORT_SYMBOL(simple_strtoull);
+
+@@ -109,6 +123,21 @@ long simple_strtol(const char *cp, char **endp, unsigned int base)
+ }
+ EXPORT_SYMBOL(simple_strtol);
+
++static long long simple_strntoll(const char *cp, size_t max_chars, char **endp,
++ unsigned int base)
++{
++ /*
++ * simple_strntoull() safely handles receiving max_chars==0 in the
++ * case cp[0] == '-' && max_chars == 1.
++ * If max_chars == 0 we can drop through and pass it to simple_strntoull()
++ * and the content of *cp is irrelevant.
++ */
++ if (*cp == '-' && max_chars > 0)
++ return -simple_strntoull(cp + 1, max_chars - 1, endp, base);
++
++ return simple_strntoull(cp, max_chars, endp, base);
++}
++
+ /**
+ * simple_strtoll - convert a string to a signed long long
+ * @cp: The start of the string
+@@ -119,10 +148,7 @@ EXPORT_SYMBOL(simple_strtol);
+ */
+ long long simple_strtoll(const char *cp, char **endp, unsigned int base)
+ {
+- if (*cp == '-')
+- return -simple_strtoull(cp + 1, endp, base);
+-
+- return simple_strtoull(cp, endp, base);
++ return simple_strntoll(cp, INT_MAX, endp, base);
+ }
+ EXPORT_SYMBOL(simple_strtoll);
+
+@@ -3576,25 +3602,13 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
+ break;
+
+ if (is_sign)
+- val.s = qualifier != 'L' ?
+- simple_strtol(str, &next, base) :
+- simple_strtoll(str, &next, base);
++ val.s = simple_strntoll(str,
++ field_width >= 0 ? field_width : INT_MAX,
++ &next, base);
+ else
+- val.u = qualifier != 'L' ?
+- simple_strtoul(str, &next, base) :
+- simple_strtoull(str, &next, base);
+-
+- if (field_width > 0 && next - str > field_width) {
+- if (base == 0)
+- _parse_integer_fixup_radix(str, &base);
+- while (next - str > field_width) {
+- if (is_sign)
+- val.s = div_s64(val.s, base);
+- else
+- val.u = div_u64(val.u, base);
+- --next;
+- }
+- }
++ val.u = simple_strntoull(str,
++ field_width >= 0 ? field_width : INT_MAX,
++ &next, base);
+
+ switch (qualifier) {
+ case 'H': /* that's 'hh' in format */
+--
+2.30.2
+
--- /dev/null
+From 30ed7317b87774f4b0b3afefa41b9d825eaf004d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 May 2021 22:41:17 -0700
+Subject: libbpf: Fix ELF symbol visibility update logic
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit 247b8634e6446dbc8024685f803290501cba226f ]
+
+Fix silly bug in updating ELF symbol's visibility.
+
+Fixes: a46349227cd8 ("libbpf: Add linker extern resolution support for functions and global variables")
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20210507054119.270888-6-andrii@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/linker.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c
+index 9de084b1c699..f44f8a37f780 100644
+--- a/tools/lib/bpf/linker.c
++++ b/tools/lib/bpf/linker.c
+@@ -1780,7 +1780,7 @@ static void sym_update_visibility(Elf64_Sym *sym, int sym_vis)
+ /* libelf doesn't provide setters for ST_VISIBILITY,
+ * but it is stored in the lower 2 bits of st_other
+ */
+- sym->st_other &= 0x03;
++ sym->st_other &= ~0x03;
+ sym->st_other |= sym_vis;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 6852356961ceb7028d660252b95be238650bdc78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jun 2021 20:57:18 +0200
+Subject: lockdep: Fix wait-type for empty stack
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit f8b298cc39f0619544c607eaef09fd0b2afd10f3 ]
+
+Even the very first lock can violate the wait-context check, consider
+the various IRQ contexts.
+
+Fixes: de8f5e4f2dc1 ("lockdep: Introduce wait-type checks")
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: Joerg Roedel <jroedel@suse.de>
+Link: https://lore.kernel.org/r/20210617190313.256987481@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/locking/lockdep.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
+index 39b6392b4826..9125bd419216 100644
+--- a/kernel/locking/lockdep.c
++++ b/kernel/locking/lockdep.c
+@@ -4693,7 +4693,7 @@ static int check_wait_context(struct task_struct *curr, struct held_lock *next)
+ u8 curr_inner;
+ int depth;
+
+- if (!curr->lockdep_depth || !next_inner || next->trylock)
++ if (!next_inner || next->trylock)
+ return 0;
+
+ if (!next_outer)
+--
+2.30.2
+
--- /dev/null
+From f841cb75c4d9c9882bc357aac2d24f051d915163 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jun 2021 20:57:19 +0200
+Subject: lockdep/selftests: Fix selftests vs PROVE_RAW_LOCK_NESTING
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit c0c2c0dad6a06e0c05e9a52d65f932bd54364c97 ]
+
+When PROVE_RAW_LOCK_NESTING=y many of the selftests FAILED because
+HARDIRQ context is out-of-bounds for spinlocks. Instead make the
+default hardware context the threaded hardirq context, which preserves
+the old locking rules.
+
+The wait-type specific locking selftests will have a non-threaded
+HARDIRQ variant.
+
+Fixes: de8f5e4f2dc1 ("lockdep: Introduce wait-type checks")
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: Joerg Roedel <jroedel@suse.de>
+Link: https://lore.kernel.org/r/20210617190313.322096283@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/locking-selftest.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c
+index 2d85abac1744..0f6b262e0964 100644
+--- a/lib/locking-selftest.c
++++ b/lib/locking-selftest.c
+@@ -194,6 +194,7 @@ static void init_shared_classes(void)
+ #define HARDIRQ_ENTER() \
+ local_irq_disable(); \
+ __irq_enter(); \
++ lockdep_hardirq_threaded(); \
+ WARN_ON(!in_irq());
+
+ #define HARDIRQ_EXIT() \
+--
+2.30.2
+
--- /dev/null
+From 0f1fc4e8eca8b18225fe585f2ecfdf8c2cf4dac3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Jun 2021 01:01:09 +0800
+Subject: lockding/lockdep: Avoid to find wrong lock dep path in
+ check_irq_usage()
+
+From: Boqun Feng <boqun.feng@gmail.com>
+
+[ Upstream commit 7b1f8c6179769af6ffa055e1169610b51d71edd5 ]
+
+In the step #3 of check_irq_usage(), we seach backwards to find a lock
+whose usage conflicts the usage of @target_entry1 on safe/unsafe.
+However, we should only keep the irq-unsafe usage of @target_entry1 into
+consideration, because it could be a case where a lock is hardirq-unsafe
+but soft-safe, and in check_irq_usage() we find it because its
+hardirq-unsafe could result into a hardirq-safe-unsafe deadlock, but
+currently since we don't filter out the other usage bits, so we may find
+a lock dependency path softirq-unsafe -> softirq-safe, which in fact
+doesn't cause a deadlock. And this may cause misleading lockdep splats.
+
+Fix this by only keeping LOCKF_ENABLED_IRQ_ALL bits when we try the
+backwards search.
+
+Reported-by: Johannes Berg <johannes@sipsolutions.net>
+Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20210618170110.3699115-4-boqun.feng@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/locking/lockdep.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
+index e51fa6575c39..39b6392b4826 100644
+--- a/kernel/locking/lockdep.c
++++ b/kernel/locking/lockdep.c
+@@ -2773,8 +2773,18 @@ static int check_irq_usage(struct task_struct *curr, struct held_lock *prev,
+ * Step 3: we found a bad match! Now retrieve a lock from the backward
+ * list whose usage mask matches the exclusive usage mask from the
+ * lock found on the forward list.
++ *
++ * Note, we should only keep the LOCKF_ENABLED_IRQ_ALL bits, considering
++ * the follow case:
++ *
++ * When trying to add A -> B to the graph, we find that there is a
++ * hardirq-safe L, that L -> ... -> A, and another hardirq-unsafe M,
++ * that B -> ... -> M. However M is **softirq-safe**, if we use exact
++ * invert bits of M's usage_mask, we will find another lock N that is
++ * **softirq-unsafe** and N -> ... -> A, however N -> .. -> M will not
++ * cause a inversion deadlock.
+ */
+- backward_mask = original_mask(target_entry1->class->usage_mask);
++ backward_mask = original_mask(target_entry1->class->usage_mask & LOCKF_ENABLED_IRQ_ALL);
+
+ ret = find_usage_backwards(&this, backward_mask, &target_entry);
+ if (bfs_error(ret)) {
+--
+2.30.2
+
--- /dev/null
+From 7dddf30cbebfce99938183f52b006acb32c501bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Jun 2021 01:01:07 +0800
+Subject: locking/lockdep: Fix the dep path printing for backwards BFS
+
+From: Boqun Feng <boqun.feng@gmail.com>
+
+[ Upstream commit 69c7a5fb2482636f525f016c8333fdb9111ecb9d ]
+
+We use the same code to print backwards lock dependency path as the
+forwards lock dependency path, and this could result into incorrect
+printing because for a backwards lock_list ->trace is not the call trace
+where the lock of ->class is acquired.
+
+Fix this by introducing a separate function on printing the backwards
+dependency path. Also add a few comments about the printing while we are
+at it.
+
+Reported-by: Johannes Berg <johannes@sipsolutions.net>
+Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20210618170110.3699115-2-boqun.feng@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/locking/lockdep.c | 108 ++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 106 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
+index e32313072506..e51fa6575c39 100644
+--- a/kernel/locking/lockdep.c
++++ b/kernel/locking/lockdep.c
+@@ -2306,7 +2306,56 @@ static void print_lock_class_header(struct lock_class *class, int depth)
+ }
+
+ /*
+- * printk the shortest lock dependencies from @start to @end in reverse order:
++ * Dependency path printing:
++ *
++ * After BFS we get a lock dependency path (linked via ->parent of lock_list),
++ * printing out each lock in the dependency path will help on understanding how
++ * the deadlock could happen. Here are some details about dependency path
++ * printing:
++ *
++ * 1) A lock_list can be either forwards or backwards for a lock dependency,
++ * for a lock dependency A -> B, there are two lock_lists:
++ *
++ * a) lock_list in the ->locks_after list of A, whose ->class is B and
++ * ->links_to is A. In this case, we can say the lock_list is
++ * "A -> B" (forwards case).
++ *
++ * b) lock_list in the ->locks_before list of B, whose ->class is A
++ * and ->links_to is B. In this case, we can say the lock_list is
++ * "B <- A" (bacwards case).
++ *
++ * The ->trace of both a) and b) point to the call trace where B was
++ * acquired with A held.
++ *
++ * 2) A "helper" lock_list is introduced during BFS, this lock_list doesn't
++ * represent a certain lock dependency, it only provides an initial entry
++ * for BFS. For example, BFS may introduce a "helper" lock_list whose
++ * ->class is A, as a result BFS will search all dependencies starting with
++ * A, e.g. A -> B or A -> C.
++ *
++ * The notation of a forwards helper lock_list is like "-> A", which means
++ * we should search the forwards dependencies starting with "A", e.g A -> B
++ * or A -> C.
++ *
++ * The notation of a bacwards helper lock_list is like "<- B", which means
++ * we should search the backwards dependencies ending with "B", e.g.
++ * B <- A or B <- C.
++ */
++
++/*
++ * printk the shortest lock dependencies from @root to @leaf in reverse order.
++ *
++ * We have a lock dependency path as follow:
++ *
++ * @root @leaf
++ * | |
++ * V V
++ * ->parent ->parent
++ * | lock_list | <--------- | lock_list | ... | lock_list | <--------- | lock_list |
++ * | -> L1 | | L1 -> L2 | ... |Ln-2 -> Ln-1| | Ln-1 -> Ln|
++ *
++ * , so it's natural that we start from @leaf and print every ->class and
++ * ->trace until we reach the @root.
+ */
+ static void __used
+ print_shortest_lock_dependencies(struct lock_list *leaf,
+@@ -2334,6 +2383,61 @@ print_shortest_lock_dependencies(struct lock_list *leaf,
+ } while (entry && (depth >= 0));
+ }
+
++/*
++ * printk the shortest lock dependencies from @leaf to @root.
++ *
++ * We have a lock dependency path (from a backwards search) as follow:
++ *
++ * @leaf @root
++ * | |
++ * V V
++ * ->parent ->parent
++ * | lock_list | ---------> | lock_list | ... | lock_list | ---------> | lock_list |
++ * | L2 <- L1 | | L3 <- L2 | ... | Ln <- Ln-1 | | <- Ln |
++ *
++ * , so when we iterate from @leaf to @root, we actually print the lock
++ * dependency path L1 -> L2 -> .. -> Ln in the non-reverse order.
++ *
++ * Another thing to notice here is that ->class of L2 <- L1 is L1, while the
++ * ->trace of L2 <- L1 is the call trace of L2, in fact we don't have the call
++ * trace of L1 in the dependency path, which is alright, because most of the
++ * time we can figure out where L1 is held from the call trace of L2.
++ */
++static void __used
++print_shortest_lock_dependencies_backwards(struct lock_list *leaf,
++ struct lock_list *root)
++{
++ struct lock_list *entry = leaf;
++ const struct lock_trace *trace = NULL;
++ int depth;
++
++ /*compute depth from generated tree by BFS*/
++ depth = get_lock_depth(leaf);
++
++ do {
++ print_lock_class_header(entry->class, depth);
++ if (trace) {
++ printk("%*s ... acquired at:\n", depth, "");
++ print_lock_trace(trace, 2);
++ printk("\n");
++ }
++
++ /*
++ * Record the pointer to the trace for the next lock_list
++ * entry, see the comments for the function.
++ */
++ trace = entry->trace;
++
++ if (depth == 0 && (entry != root)) {
++ printk("lockdep:%s bad path found in chain graph\n", __func__);
++ break;
++ }
++
++ entry = get_lock_parent(entry);
++ depth--;
++ } while (entry && (depth >= 0));
++}
++
+ static void
+ print_irq_lock_scenario(struct lock_list *safe_entry,
+ struct lock_list *unsafe_entry,
+@@ -2451,7 +2555,7 @@ print_bad_irq_dependency(struct task_struct *curr,
+ prev_root->trace = save_trace();
+ if (!prev_root->trace)
+ return;
+- print_shortest_lock_dependencies(backwards_entry, prev_root);
++ print_shortest_lock_dependencies_backwards(backwards_entry, prev_root);
+
+ pr_warn("\nthe dependencies between the lock to be acquired");
+ pr_warn(" and %s-irq-unsafe lock:\n", irqclass);
+--
+2.30.2
+
--- /dev/null
+From dfdff8c6df5357e36d4a0b912962a2ec747dcba4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 May 2021 15:41:50 -0700
+Subject: locking/lockdep: Reduce LOCKDEP dependency list
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit b8e00abe7d9fe21dd13609e2e3a707e38902b105 ]
+
+Some arches (um, sparc64, riscv, xtensa) cause a Kconfig warning for
+LOCKDEP.
+These arch-es select LOCKDEP_SUPPORT but they are not listed as one
+of the arch-es that LOCKDEP depends on.
+
+Since (16) arch-es define the Kconfig symbol LOCKDEP_SUPPORT if they
+intend to have LOCKDEP support, replace the awkward list of
+arch-es that LOCKDEP depends on with the LOCKDEP_SUPPORT symbol.
+
+But wait. LOCKDEP_SUPPORT is included in LOCK_DEBUGGING_SUPPORT,
+which is already a dependency here, so LOCKDEP_SUPPORT is redundant
+and not needed.
+That leaves the FRAME_POINTER dependency, but it is part of an
+expression like this:
+ depends on (A && B) && (FRAME_POINTER || B')
+where B' is a dependency of B so if B is true then B' is true
+and the value of FRAME_POINTER does not matter.
+Thus we can also delete the FRAME_POINTER dependency.
+
+Fixes this kconfig warning: (for um, sparc64, riscv, xtensa)
+
+WARNING: unmet direct dependencies detected for LOCKDEP
+ Depends on [n]: DEBUG_KERNEL [=y] && LOCK_DEBUGGING_SUPPORT [=y] && (FRAME_POINTER [=n] || MIPS || PPC || S390 || MICROBLAZE || ARM || ARC || X86)
+ Selected by [y]:
+ - PROVE_LOCKING [=y] && DEBUG_KERNEL [=y] && LOCK_DEBUGGING_SUPPORT [=y]
+ - LOCK_STAT [=y] && DEBUG_KERNEL [=y] && LOCK_DEBUGGING_SUPPORT [=y]
+ - DEBUG_LOCK_ALLOC [=y] && DEBUG_KERNEL [=y] && LOCK_DEBUGGING_SUPPORT [=y]
+
+Fixes: 7d37cb2c912d ("lib: fix kconfig dependency on ARCH_WANT_FRAME_POINTERS")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Acked-by: Waiman Long <longman@redhat.com>
+Link: https://lkml.kernel.org/r/20210524224150.8009-1-rdunlap@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/Kconfig.debug | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 678c13967580..1e1bd6f4a13d 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -1372,7 +1372,6 @@ config LOCKDEP
+ bool
+ depends on DEBUG_KERNEL && LOCK_DEBUGGING_SUPPORT
+ select STACKTRACE
+- depends on FRAME_POINTER || MIPS || PPC || S390 || MICROBLAZE || ARM || ARC || X86
+ select KALLSYMS
+ select KALLSYMS_ALL
+
+--
+2.30.2
+
--- /dev/null
+From 53b67701b5caddbb040edfffd01bf2338f7c6937 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 May 2021 17:12:51 -0700
+Subject: m68k: atari: Fix ATARI_KBD_CORE kconfig unmet dependency warning
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit c1367ee016e3550745315fb9a2dd1e4ce02cdcf6 ]
+
+Since the code for ATARI_KBD_CORE does not use drivers/input/keyboard/
+code, just move ATARI_KBD_CORE to arch/m68k/Kconfig.machine to remove
+the dependency on INPUT_KEYBOARD.
+
+Removes this kconfig warning:
+
+ WARNING: unmet direct dependencies detected for ATARI_KBD_CORE
+ Depends on [n]: !UML && INPUT [=y] && INPUT_KEYBOARD [=n]
+ Selected by [y]:
+ - MOUSE_ATARI [=y] && !UML && INPUT [=y] && INPUT_MOUSE [=y] && ATARI [=y]
+
+Fixes: c04cb856e20a ("m68k: Atari keyboard and mouse support.")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Suggested-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Suggested-by: Michael Schmitz <schmitzmic@gmail.com>
+Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Link: https://lore.kernel.org/r/20210527001251.8529-1-rdunlap@infradead.org
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/m68k/Kconfig.machine | 3 +++
+ drivers/input/keyboard/Kconfig | 3 ---
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine
+index 4d59ec2f5b8d..d964c1f27399 100644
+--- a/arch/m68k/Kconfig.machine
++++ b/arch/m68k/Kconfig.machine
+@@ -25,6 +25,9 @@ config ATARI
+ this kernel on an Atari, say Y here and browse the material
+ available in <file:Documentation/m68k>; otherwise say N.
+
++config ATARI_KBD_CORE
++ bool
++
+ config MAC
+ bool "Macintosh support"
+ depends on MMU
+diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
+index 32d15809ae58..40a070a2e7f5 100644
+--- a/drivers/input/keyboard/Kconfig
++++ b/drivers/input/keyboard/Kconfig
+@@ -67,9 +67,6 @@ config KEYBOARD_AMIGA
+ To compile this driver as a module, choose M here: the
+ module will be called amikbd.
+
+-config ATARI_KBD_CORE
+- bool
+-
+ config KEYBOARD_APPLESPI
+ tristate "Apple SPI keyboard and trackpad"
+ depends on ACPI && EFI
+--
+2.30.2
+
--- /dev/null
+From e0a966daf18bb86c35a1006af4c9c392d692095f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 21:48:25 +0800
+Subject: mac80211: remove iwlwifi specific workaround NDPs of null_response
+
+From: Ping-Ke Shih <pkshih@realtek.com>
+
+[ Upstream commit 744757e46bf13ec3a7b3507d17ab3faab9516d43 ]
+
+Remove the remaining workaround that is not removed by the
+commit e41eb3e408de ("mac80211: remove iwlwifi specific workaround
+that broke sta NDP tx")
+
+Fixes: 41cbb0f5a295 ("mac80211: add support for HE")
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://lore.kernel.org/r/20210623134826.10318-1-pkshih@realtek.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/sta_info.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
+index f2fb69da9b6e..13250cadb420 100644
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -1398,11 +1398,6 @@ static void ieee80211_send_null_response(struct sta_info *sta, int tid,
+ struct ieee80211_tx_info *info;
+ struct ieee80211_chanctx_conf *chanctx_conf;
+
+- /* Don't send NDPs when STA is connected HE */
+- if (sdata->vif.type == NL80211_IFTYPE_STATION &&
+- !(sdata->u.mgd.flags & IEEE80211_STA_DISABLE_HE))
+- return;
+-
+ if (qos) {
+ fc = cpu_to_le16(IEEE80211_FTYPE_DATA |
+ IEEE80211_STYPE_QOS_NULLFUNC |
+--
+2.30.2
+
--- /dev/null
+From a2710b1046f524e979319186a1bb8b1b1ac912d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 08:39:18 +0800
+Subject: mailbox: qcom: Use PLATFORM_DEVID_AUTO to register platform device
+
+From: Shawn Guo <shawn.guo@linaro.org>
+
+[ Upstream commit 96e39e95c01283ff5695dafe659df88ada802159 ]
+
+In adding APCS clock support for MSM8939, the second clock registration
+fails due to duplicate device name like below.
+
+[ 0.519657] sysfs: cannot create duplicate filename '/bus/platform/devices/qcom-apcs-msm8916-clk'
+...
+[ 0.661158] qcom_apcs_ipc b111000.mailbox: failed to register APCS clk
+
+This is because MSM8939 has 3 APCS instances for Cluster0 (little cores),
+Cluster1 (big cores) and CCI (Cache Coherent Interconnect). Although
+only APCS of Cluster0 and Cluster1 have IPC bits, each of 3 APCS has
+A53PLL clock control bits. That said, 3 'qcom-apcs-msm8916-clk' devices
+need to be registered to instantiate all 3 clocks. Use PLATFORM_DEVID_AUTO
+rather than PLATFORM_DEVID_NONE for platform_device_register_data() call
+to fix the issue above.
+
+Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
+Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/qcom-apcs-ipc-mailbox.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mailbox/qcom-apcs-ipc-mailbox.c b/drivers/mailbox/qcom-apcs-ipc-mailbox.c
+index f25324d03842..15236d729625 100644
+--- a/drivers/mailbox/qcom-apcs-ipc-mailbox.c
++++ b/drivers/mailbox/qcom-apcs-ipc-mailbox.c
+@@ -132,7 +132,7 @@ static int qcom_apcs_ipc_probe(struct platform_device *pdev)
+ if (apcs_data->clk_name) {
+ apcs->clk = platform_device_register_data(&pdev->dev,
+ apcs_data->clk_name,
+- PLATFORM_DEVID_NONE,
++ PLATFORM_DEVID_AUTO,
+ NULL, 0);
+ if (IS_ERR(apcs->clk))
+ dev_err(&pdev->dev, "failed to register APCS clk\n");
+--
+2.30.2
+
--- /dev/null
+From d144027da0dd45ad40121a9a1086fb276e15b605 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 18:26:24 -0700
+Subject: Makefile: fix GDB warning with CONFIG_RELR
+
+From: Nick Desaulniers <ndesaulniers@google.com>
+
+[ Upstream commit 27f2a4db76e8d8a8b601fc1c6a7a17f88bd907ab ]
+
+GDB produces the following warning when debugging kernels built with
+CONFIG_RELR:
+
+BFD: /android0/linux-next/vmlinux: unknown type [0x13] section `.relr.dyn'
+
+when loading a kernel built with CONFIG_RELR into GDB. It can also
+prevent debugging symbols using such relocations.
+
+Peter sugguests:
+ [That flag] means that lld will use dynamic tags and section type
+ numbers in the OS-specific range rather than the generic range. The
+ kernel itself doesn't care about these numbers; it determines the
+ location of the RELR section using symbols defined by a linker script.
+
+Link: https://github.com/ClangBuiltLinux/linux/issues/1057
+Suggested-by: Peter Collingbourne <pcc@google.com>
+Reviewed-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
+Link: https://lore.kernel.org/r/20210522012626.2811297-1-ndesaulniers@google.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Makefile | 2 +-
+ scripts/tools-support-relr.sh | 3 ++-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 069607cfe283..bc039bb78f30 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1039,7 +1039,7 @@ LDFLAGS_vmlinux += $(call ld-option, -X,)
+ endif
+
+ ifeq ($(CONFIG_RELR),y)
+-LDFLAGS_vmlinux += --pack-dyn-relocs=relr
++LDFLAGS_vmlinux += --pack-dyn-relocs=relr --use-android-relr-tags
+ endif
+
+ # We never want expected sections to be placed heuristically by the
+diff --git a/scripts/tools-support-relr.sh b/scripts/tools-support-relr.sh
+index 45e8aa360b45..cb55878bd5b8 100755
+--- a/scripts/tools-support-relr.sh
++++ b/scripts/tools-support-relr.sh
+@@ -7,7 +7,8 @@ trap "rm -f $tmp_file.o $tmp_file $tmp_file.bin" EXIT
+ cat << "END" | $CC -c -x c - -o $tmp_file.o >/dev/null 2>&1
+ void *p = &p;
+ END
+-$LD $tmp_file.o -shared -Bsymbolic --pack-dyn-relocs=relr -o $tmp_file
++$LD $tmp_file.o -shared -Bsymbolic --pack-dyn-relocs=relr \
++ --use-android-relr-tags -o $tmp_file
+
+ # Despite printing an error message, GNU nm still exits with exit code 0 if it
+ # sees a relr section. So we need to check that nothing is printed to stderr.
+--
+2.30.2
+
--- /dev/null
+From 896237d44400fb3567146c955eecba99fc54cff4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Jun 2021 18:13:27 +0200
+Subject: mark pstore-blk as broken
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit d07f3b081ee632268786601f55e1334d1f68b997 ]
+
+pstore-blk just pokes directly into the pagecache for the block
+device without going through the file operations for that by faking
+up it's own file operations that do not match the block device ones.
+
+As this breaks the control of the block layer of it's page cache,
+and even now just works by accident only the best thing is to just
+disable this driver.
+
+Fixes: 17639f67c1d6 ("pstore/blk: Introduce backend for block devices")
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20210608161327.1537919-1-hch@lst.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/pstore/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
+index 8adabde685f1..328da35da390 100644
+--- a/fs/pstore/Kconfig
++++ b/fs/pstore/Kconfig
+@@ -173,6 +173,7 @@ config PSTORE_BLK
+ tristate "Log panic/oops to a block device"
+ depends on PSTORE
+ depends on BLOCK
++ depends on BROKEN
+ select PSTORE_ZONE
+ default n
+ help
+--
+2.30.2
+
--- /dev/null
+From 6bc99f10bf422e006791c356b0f2f598700f159c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 17:46:16 +0800
+Subject: md: revert io stats accounting
+
+From: Guoqing Jiang <jgq516@gmail.com>
+
+[ Upstream commit ad3fc798800fb7ca04c1dfc439dba946818048d8 ]
+
+The commit 41d2d848e5c0 ("md: improve io stats accounting") could cause
+double fault problem per the report [1], and also it is not correct to
+change ->bi_end_io if md don't own it, so let's revert it.
+
+And io stats accounting will be replemented in later commits.
+
+[1]. https://lore.kernel.org/linux-raid/3bf04253-3fad-434a-63a7-20214e38cf26@gmail.com/T/#t
+
+Fixes: 41d2d848e5c0 ("md: improve io stats accounting")
+Signed-off-by: Guoqing Jiang <jiangguoqing@kylinos.cn>
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md.c | 45 ---------------------------------------------
+ drivers/md/md.h | 1 -
+ 2 files changed, 46 deletions(-)
+
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 49f897fbb89b..7ba00e4c862d 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -441,30 +441,6 @@ check_suspended:
+ }
+ EXPORT_SYMBOL(md_handle_request);
+
+-struct md_io {
+- struct mddev *mddev;
+- bio_end_io_t *orig_bi_end_io;
+- void *orig_bi_private;
+- struct block_device *orig_bi_bdev;
+- unsigned long start_time;
+-};
+-
+-static void md_end_io(struct bio *bio)
+-{
+- struct md_io *md_io = bio->bi_private;
+- struct mddev *mddev = md_io->mddev;
+-
+- bio_end_io_acct_remapped(bio, md_io->start_time, md_io->orig_bi_bdev);
+-
+- bio->bi_end_io = md_io->orig_bi_end_io;
+- bio->bi_private = md_io->orig_bi_private;
+-
+- mempool_free(md_io, &mddev->md_io_pool);
+-
+- if (bio->bi_end_io)
+- bio->bi_end_io(bio);
+-}
+-
+ static blk_qc_t md_submit_bio(struct bio *bio)
+ {
+ const int rw = bio_data_dir(bio);
+@@ -489,21 +465,6 @@ static blk_qc_t md_submit_bio(struct bio *bio)
+ return BLK_QC_T_NONE;
+ }
+
+- if (bio->bi_end_io != md_end_io) {
+- struct md_io *md_io;
+-
+- md_io = mempool_alloc(&mddev->md_io_pool, GFP_NOIO);
+- md_io->mddev = mddev;
+- md_io->orig_bi_end_io = bio->bi_end_io;
+- md_io->orig_bi_private = bio->bi_private;
+- md_io->orig_bi_bdev = bio->bi_bdev;
+-
+- bio->bi_end_io = md_end_io;
+- bio->bi_private = md_io;
+-
+- md_io->start_time = bio_start_io_acct(bio);
+- }
+-
+ /* bio could be mergeable after passing to underlayer */
+ bio->bi_opf &= ~REQ_NOMERGE;
+
+@@ -5608,7 +5569,6 @@ static void md_free(struct kobject *ko)
+
+ bioset_exit(&mddev->bio_set);
+ bioset_exit(&mddev->sync_set);
+- mempool_exit(&mddev->md_io_pool);
+ kfree(mddev);
+ }
+
+@@ -5705,11 +5665,6 @@ static int md_alloc(dev_t dev, char *name)
+ */
+ mddev->hold_active = UNTIL_STOP;
+
+- error = mempool_init_kmalloc_pool(&mddev->md_io_pool, BIO_POOL_SIZE,
+- sizeof(struct md_io));
+- if (error)
+- goto abort;
+-
+ error = -ENOMEM;
+ mddev->queue = blk_alloc_queue(NUMA_NO_NODE);
+ if (!mddev->queue)
+diff --git a/drivers/md/md.h b/drivers/md/md.h
+index fb7eab58cfd5..4da240ffe2c5 100644
+--- a/drivers/md/md.h
++++ b/drivers/md/md.h
+@@ -487,7 +487,6 @@ struct mddev {
+ struct bio_set sync_set; /* for sync operations like
+ * metadata and bitmap writes
+ */
+- mempool_t md_io_pool;
+
+ /* Generic flush handling.
+ * The last to finish preflush schedules a worker to submit
+--
+2.30.2
+
--- /dev/null
+From e4af1f34c9b985455883a9472f790506faf7ad47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 17:05:27 +0200
+Subject: media: am437x: fix pm_runtime_get_sync() usage count
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit c41e02493334985cca1a22efd5ca962ce3abb061 ]
+
+The pm_runtime_get_sync() internally increments the
+dev->power.usage_count without decrementing it, even on errors.
+Replace it by the new pm_runtime_resume_and_get(), introduced by:
+commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter")
+in order to properly decrement the usage counter, avoiding
+a potential PM usage counter leak.
+
+While here, ensure that the driver will check if PM runtime
+resumed at vpfe_initialize_device().
+
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/am437x/am437x-vpfe.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c
+index 6cdc77dda0e4..1c9cb9e05fdf 100644
+--- a/drivers/media/platform/am437x/am437x-vpfe.c
++++ b/drivers/media/platform/am437x/am437x-vpfe.c
+@@ -1021,7 +1021,9 @@ static int vpfe_initialize_device(struct vpfe_device *vpfe)
+ if (ret)
+ return ret;
+
+- pm_runtime_get_sync(vpfe->pdev);
++ ret = pm_runtime_resume_and_get(vpfe->pdev);
++ if (ret < 0)
++ return ret;
+
+ vpfe_config_enable(&vpfe->ccdc, 1);
+
+@@ -2443,7 +2445,11 @@ static int vpfe_probe(struct platform_device *pdev)
+ pm_runtime_enable(&pdev->dev);
+
+ /* for now just enable it here instead of waiting for the open */
+- pm_runtime_get_sync(&pdev->dev);
++ ret = pm_runtime_resume_and_get(&pdev->dev);
++ if (ret < 0) {
++ vpfe_err(vpfe, "Unable to resume device.\n");
++ goto probe_out_v4l2_unregister;
++ }
+
+ vpfe_ccdc_config_defaults(ccdc);
+
+@@ -2530,6 +2536,11 @@ static int vpfe_suspend(struct device *dev)
+
+ /* only do full suspend if streaming has started */
+ if (vb2_start_streaming_called(&vpfe->buffer_queue)) {
++ /*
++ * ignore RPM resume errors here, as it is already too late.
++ * A check like that should happen earlier, either at
++ * open() or just before start streaming.
++ */
+ pm_runtime_get_sync(dev);
+ vpfe_config_enable(ccdc, 1);
+
+--
+2.30.2
+
--- /dev/null
+From e8c6d40225ab4e1fcfac6090f1cd12516cae1912 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 May 2021 16:20:38 +0200
+Subject: media: au0828: fix a NULL vs IS_ERR() check
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 8f2e452730d2bcd59fe05246f0e19a4c52e0012d ]
+
+The media_device_usb_allocate() function returns error pointers when
+it's enabled and something goes wrong. It can return NULL as well, but
+only if CONFIG_MEDIA_CONTROLLER is disabled so that doesn't apply here.
+
+Fixes: 812658d88d26 ("media: change au0828 to use Media Device Allocator API")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/au0828/au0828-core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
+index a8a72d5fbd12..caefac07af92 100644
+--- a/drivers/media/usb/au0828/au0828-core.c
++++ b/drivers/media/usb/au0828/au0828-core.c
+@@ -199,8 +199,8 @@ static int au0828_media_device_init(struct au0828_dev *dev,
+ struct media_device *mdev;
+
+ mdev = media_device_usb_allocate(udev, KBUILD_MODNAME, THIS_MODULE);
+- if (!mdev)
+- return -ENOMEM;
++ if (IS_ERR(mdev))
++ return PTR_ERR(mdev);
+
+ dev->media_dev = mdev;
+ #endif
+--
+2.30.2
+
--- /dev/null
+From 703463c034e85008b2fe1501a865bd39fbfe3c52 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Apr 2021 00:12:26 +0200
+Subject: media: bt878: do not schedule tasklet when it is not setup
+
+From: Tong Zhang <ztong0001@gmail.com>
+
+[ Upstream commit a3a54bf4bddaecda8b5767209cfc703f0be2841d ]
+
+There is a problem with the tasklet in bt878. bt->tasklet is set by
+dvb-bt8xx.ko, and bt878.ko can be loaded independently.
+In this case if interrupt comes it may cause null-ptr-dereference.
+To solve this issue, we check if the tasklet is actually set before
+calling tasklet_schedule.
+
+[ 1.750438] bt878(0): irq FDSR FBUS risc_pc=
+[ 1.750728] BUG: kernel NULL pointer dereference, address: 0000000000000000
+[ 1.752969] RIP: 0010:0x0
+[ 1.757526] Call Trace:
+[ 1.757659] <IRQ>
+[ 1.757770] tasklet_action_common.isra.0+0x107/0x110
+[ 1.758041] tasklet_action+0x22/0x30
+[ 1.758237] __do_softirq+0xe0/0x29b
+[ 1.758430] irq_exit_rcu+0xa4/0xb0
+[ 1.758618] common_interrupt+0x8d/0xa0
+[ 1.758824] </IRQ>
+
+Signed-off-by: Tong Zhang <ztong0001@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/bt8xx/bt878.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c
+index 78dd35c9b65d..7ca309121fb5 100644
+--- a/drivers/media/pci/bt8xx/bt878.c
++++ b/drivers/media/pci/bt8xx/bt878.c
+@@ -300,7 +300,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id)
+ }
+ if (astat & BT878_ARISCI) {
+ bt->finished_block = (stat & BT878_ARISCS) >> 28;
+- tasklet_schedule(&bt->tasklet);
++ if (bt->tasklet.callback)
++ tasklet_schedule(&bt->tasklet);
+ break;
+ }
+ count++;
+--
+2.30.2
+
--- /dev/null
+From 5146426862aa2478f115b46c36e9331c669aa699 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 May 2021 17:18:36 +0200
+Subject: media: bt8xx: Fix a missing check bug in bt878_probe
+
+From: Zheyu Ma <zheyuma97@gmail.com>
+
+[ Upstream commit 1a4520090681853e6b850cbe54b27247a013e0e5 ]
+
+In 'bt878_irq', the driver calls 'tasklet_schedule', but this tasklet is
+set in 'dvb_bt8xx_load_card' of another driver 'dvb-bt8xx'.
+However, this two drivers are separate. The user may not load the
+'dvb-bt8xx' driver when loading the 'bt8xx' driver, that is, the tasklet
+has not been initialized when 'tasklet_schedule' is called, so it is
+necessary to check whether the tasklet is initialized in 'bt878_probe'.
+
+Fix this by adding a check at the end of bt878_probe.
+
+The KASAN's report reveals it:
+
+BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
+PGD 800000006aab2067 P4D 800000006aab2067 PUD 6b2ea067 PMD 0
+Oops: 0010 [#1] PREEMPT SMP KASAN PTI
+CPU: 2 PID: 8724 Comm: syz-executor.0 Not tainted 4.19.177-
+gdba4159c14ef-dirty #40
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-59-
+gc9ba5276e321-prebuilt.qemu.org 04/01/2014
+RIP: 0010: (null)
+Code: Bad RIP value.
+RSP: 0018:ffff88806c287ea0 EFLAGS: 00010246
+RAX: fffffbfff1b01774 RBX: dffffc0000000000 RCX: 0000000000000000
+RDX: 0000000000000000 RSI: 1ffffffff1b01775 RDI: 0000000000000000
+RBP: ffff88806c287f00 R08: fffffbfff1b01774 R09: fffffbfff1b01774
+R10: 0000000000000001 R11: fffffbfff1b01773 R12: 0000000000000000
+R13: ffff88806c29f530 R14: ffffffff8d80bb88 R15: ffffffff8d80bb90
+FS: 00007f6b550e6700(0000) GS:ffff88806c280000(0000) knlGS:
+0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: ffffffffffffffd6 CR3: 000000005ec98000 CR4: 00000000000006e0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <IRQ>
+ tasklet_action_common.isra.17+0x141/0x420 kernel/softirq.c:522
+ tasklet_action+0x50/0x70 kernel/softirq.c:540
+ __do_softirq+0x224/0x92c kernel/softirq.c:292
+ invoke_softirq kernel/softirq.c:372 [inline]
+ irq_exit+0x15a/0x180 kernel/softirq.c:412
+ exiting_irq arch/x86/include/asm/apic.h:535 [inline]
+ do_IRQ+0x123/0x1e0 arch/x86/kernel/irq.c:260
+ common_interrupt+0xf/0xf arch/x86/entry/entry_64.S:670
+ </IRQ>
+RIP: 0010:__do_sys_interrupt kernel/sys.c:2593 [inline]
+RIP: 0010:__se_sys_interrupt kernel/sys.c:2584 [inline]
+RIP: 0010:__x64_sys_interrupt+0x5b/0x80 kernel/sys.c:2584
+Code: ba 00 04 00 00 48 c7 c7 c0 99 31 8c e8 ae 76 5e 01 48 85 c0 75 21 e8
+14 ae 24 00 48 c7 c3 c0 99 31 8c b8 0c 00 00 00 0f 01 c1 <31> db e8 fe ad
+24 00 48 89 d8 5b 5d c3 48 c7 c3 ea ff ff ff eb ec
+RSP: 0018:ffff888054167f10 EFLAGS: 00000212 ORIG_RAX: ffffffffffffffde
+RAX: 000000000000000c RBX: ffffffff8c3199c0 RCX: ffffc90001ca6000
+RDX: 000000000000001a RSI: ffffffff813478fc RDI: ffffffff8c319dc0
+RBP: ffff888054167f18 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000080 R11: fffffbfff18633b7 R12: ffff888054167f58
+R13: ffff88805f638000 R14: 0000000000000000 R15: 0000000000000000
+ do_syscall_64+0xb0/0x4e0 arch/x86/entry/common.c:293
+ entry_SYSCALL_64_after_hwframe+0x49/0xbe
+RIP: 0033:0x4692a9
+Code: f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 48 89 f8 48 89 f7
+48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff
+ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f6b550e5c48 EFLAGS: 00000246 ORIG_RAX: 000000000000014f
+RAX: ffffffffffffffda RBX: 000000000077bf60 RCX: 00000000004692a9
+RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000020000140
+RBP: 00000000004cf7eb R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 000000000077bf60
+R13: 0000000000000000 R14: 000000000077bf60 R15: 00007fff55a1dca0
+Modules linked in:
+Dumping ftrace buffer:
+ (ftrace buffer empty)
+CR2: 0000000000000000
+---[ end trace 68e5849c3f77cbb6 ]---
+RIP: 0010: (null)
+Code: Bad RIP value.
+RSP: 0018:ffff88806c287ea0 EFLAGS: 00010246
+RAX: fffffbfff1b01774 RBX: dffffc0000000000 RCX: 0000000000000000
+RDX: 0000000000000000 RSI: 1ffffffff1b01775 RDI: 0000000000000000
+RBP: ffff88806c287f00 R08: fffffbfff1b01774 R09: fffffbfff1b01774
+R10: 0000000000000001 R11: fffffbfff1b01773 R12: 0000000000000000
+R13: ffff88806c29f530 R14: ffffffff8d80bb88 R15: ffffffff8d80bb90
+FS: 00007f6b550e6700(0000) GS:ffff88806c280000(0000) knlGS:
+0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: ffffffffffffffd6 CR3: 000000005ec98000 CR4: 00000000000006e0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+
+Reported-by: Zheyu Ma <zheyuma97@gmail.com>
+Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/bt8xx/bt878.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c
+index 7ca309121fb5..90972d6952f1 100644
+--- a/drivers/media/pci/bt8xx/bt878.c
++++ b/drivers/media/pci/bt8xx/bt878.c
+@@ -478,6 +478,9 @@ static int bt878_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
+ btwrite(0, BT878_AINT_MASK);
+ bt878_num++;
+
++ if (!bt->tasklet.func)
++ tasklet_disable(&bt->tasklet);
++
+ return 0;
+
+ fail2:
+--
+2.30.2
+
--- /dev/null
+From 6386a2fc347bbb315842164c5115ad4940bed8e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 14:23:47 +0200
+Subject: media: cedrus: Fix .buf_prepare
+
+From: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+
+[ Upstream commit d84b9202d712309840f8b5abee0ed272506563bd ]
+
+The driver should only set the payload on .buf_prepare if the
+buffer is CAPTURE type. If an OUTPUT buffer has a zero bytesused
+set by userspace then v4l2-core will set it to buffer length.
+
+If we overwrite bytesused for OUTPUT buffers, too, then
+vb2_get_plane_payload() will return incorrect value which might be then
+written to hw registers by the driver in cedrus_h264.c or cedrus_vp8.c.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/sunxi/cedrus/cedrus_video.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
+index b62eb8e84057..bf731caf2ed5 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
+@@ -457,7 +457,13 @@ static int cedrus_buf_prepare(struct vb2_buffer *vb)
+ if (vb2_plane_size(vb, 0) < pix_fmt->sizeimage)
+ return -EINVAL;
+
+- vb2_set_plane_payload(vb, 0, pix_fmt->sizeimage);
++ /*
++ * Buffer's bytesused must be written by driver for CAPTURE buffers.
++ * (for OUTPUT buffers, if userspace passes 0 bytesused, v4l2-core sets
++ * it to buffer length).
++ */
++ if (V4L2_TYPE_IS_CAPTURE(vq->type))
++ vb2_set_plane_payload(vb, 0, pix_fmt->sizeimage);
+
+ return 0;
+ }
+--
+2.30.2
+
--- /dev/null
+From 923314cbd77dd796036a3f23d0a61a5d6661db4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 10:00:49 +0200
+Subject: media: cobalt: fix race condition in setting HPD
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+[ Upstream commit 3d37ef41bed0854805ab9af22c422267510e1344 ]
+
+The cobalt_s_bit_sysctrl reads the old register value over PCI,
+then changes a bit and sets writes the new value to the register.
+
+This is used among other things for setting the HPD output pin.
+
+But if the HPD is changed for multiple inputs at the same time,
+then this causes a race condition where a stale value is read.
+
+Serialize this function with a mutex.
+
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/cobalt/cobalt-driver.c | 1 +
+ drivers/media/pci/cobalt/cobalt-driver.h | 7 ++++++-
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c
+index 839503e654f4..16af58f2f93c 100644
+--- a/drivers/media/pci/cobalt/cobalt-driver.c
++++ b/drivers/media/pci/cobalt/cobalt-driver.c
+@@ -667,6 +667,7 @@ static int cobalt_probe(struct pci_dev *pci_dev,
+ return -ENOMEM;
+ cobalt->pci_dev = pci_dev;
+ cobalt->instance = i;
++ mutex_init(&cobalt->pci_lock);
+
+ retval = v4l2_device_register(&pci_dev->dev, &cobalt->v4l2_dev);
+ if (retval) {
+diff --git a/drivers/media/pci/cobalt/cobalt-driver.h b/drivers/media/pci/cobalt/cobalt-driver.h
+index bca68572b324..12c33e035904 100644
+--- a/drivers/media/pci/cobalt/cobalt-driver.h
++++ b/drivers/media/pci/cobalt/cobalt-driver.h
+@@ -251,6 +251,8 @@ struct cobalt {
+ int instance;
+ struct pci_dev *pci_dev;
+ struct v4l2_device v4l2_dev;
++ /* serialize PCI access in cobalt_s_bit_sysctrl() */
++ struct mutex pci_lock;
+
+ void __iomem *bar0, *bar1;
+
+@@ -320,10 +322,13 @@ static inline u32 cobalt_g_sysctrl(struct cobalt *cobalt)
+ static inline void cobalt_s_bit_sysctrl(struct cobalt *cobalt,
+ int bit, int val)
+ {
+- u32 ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE);
++ u32 ctrl;
+
++ mutex_lock(&cobalt->pci_lock);
++ ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE);
+ cobalt_write_bar1(cobalt, COBALT_SYS_CTRL_BASE,
+ (ctrl & ~(1UL << bit)) | (val << bit));
++ mutex_unlock(&cobalt->pci_lock);
+ }
+
+ static inline u32 cobalt_g_sysstat(struct cobalt *cobalt)
+--
+2.30.2
+
--- /dev/null
+From 97bdee22077bc00ddbe0be743599837c6703f5ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Apr 2021 21:43:45 +0200
+Subject: media: cpia2: fix memory leak in cpia2_usb_probe
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+[ Upstream commit be8656e62e9e791837b606a027802b504a945c97 ]
+
+syzbot reported leak in cpia2 usb driver. The problem was
+in invalid error handling.
+
+v4l2_device_register() is called in cpia2_init_camera_struct(), but
+all error cases after cpia2_init_camera_struct() did not call the
+v4l2_device_unregister()
+
+Reported-by: syzbot+d1e69c888f0d3866ead4@syzkaller.appspotmail.com
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/cpia2/cpia2.h | 1 +
+ drivers/media/usb/cpia2/cpia2_core.c | 12 ++++++++++++
+ drivers/media/usb/cpia2/cpia2_usb.c | 13 +++++++------
+ 3 files changed, 20 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/media/usb/cpia2/cpia2.h b/drivers/media/usb/cpia2/cpia2.h
+index 50835f5f7512..57b7f1ea68da 100644
+--- a/drivers/media/usb/cpia2/cpia2.h
++++ b/drivers/media/usb/cpia2/cpia2.h
+@@ -429,6 +429,7 @@ int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd);
+ int cpia2_do_command(struct camera_data *cam,
+ unsigned int command,
+ unsigned char direction, unsigned char param);
++void cpia2_deinit_camera_struct(struct camera_data *cam, struct usb_interface *intf);
+ struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf);
+ int cpia2_init_camera(struct camera_data *cam);
+ int cpia2_allocate_buffers(struct camera_data *cam);
+diff --git a/drivers/media/usb/cpia2/cpia2_core.c b/drivers/media/usb/cpia2/cpia2_core.c
+index e747548ab286..b5a2d06fb356 100644
+--- a/drivers/media/usb/cpia2/cpia2_core.c
++++ b/drivers/media/usb/cpia2/cpia2_core.c
+@@ -2163,6 +2163,18 @@ static void reset_camera_struct(struct camera_data *cam)
+ cam->height = cam->params.roi.height;
+ }
+
++/******************************************************************************
++ *
++ * cpia2_init_camera_struct
++ *
++ * Deinitialize camera struct
++ *****************************************************************************/
++void cpia2_deinit_camera_struct(struct camera_data *cam, struct usb_interface *intf)
++{
++ v4l2_device_unregister(&cam->v4l2_dev);
++ kfree(cam);
++}
++
+ /******************************************************************************
+ *
+ * cpia2_init_camera_struct
+diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c
+index 3ab80a7b4498..76aac06f9fb8 100644
+--- a/drivers/media/usb/cpia2/cpia2_usb.c
++++ b/drivers/media/usb/cpia2/cpia2_usb.c
+@@ -844,15 +844,13 @@ static int cpia2_usb_probe(struct usb_interface *intf,
+ ret = set_alternate(cam, USBIF_CMDONLY);
+ if (ret < 0) {
+ ERR("%s: usb_set_interface error (ret = %d)\n", __func__, ret);
+- kfree(cam);
+- return ret;
++ goto alt_err;
+ }
+
+
+ if((ret = cpia2_init_camera(cam)) < 0) {
+ ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret);
+- kfree(cam);
+- return ret;
++ goto alt_err;
+ }
+ LOG(" CPiA Version: %d.%02d (%d.%d)\n",
+ cam->params.version.firmware_revision_hi,
+@@ -872,11 +870,14 @@ static int cpia2_usb_probe(struct usb_interface *intf,
+ ret = cpia2_register_camera(cam);
+ if (ret < 0) {
+ ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret);
+- kfree(cam);
+- return ret;
++ goto alt_err;
+ }
+
+ return 0;
++
++alt_err:
++ cpia2_deinit_camera_struct(cam, intf);
++ return ret;
+ }
+
+ /******************************************************************************
+--
+2.30.2
+
--- /dev/null
+From e0ac55fc63fd3cf4241b8821a6051f76ed8532bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jun 2021 13:13:54 +0200
+Subject: media: dvb_net: avoid speculation from net slot
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit abc0226df64dc137b48b911c1fe4319aec5891bb ]
+
+The risk of especulation is actually almost-non-existing here,
+as there are very few users of TCP/IP using the DVB stack,
+as, this is mainly used with DVB-S/S2 cards, and only by people
+that receives TCP/IP from satellite connections, which limits
+a lot the number of users of such feature(*).
+
+(*) In thesis, DVB-C cards could also benefit from it, but I'm
+yet to see a hardware that supports it.
+
+Yet, fixing it is trivial.
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/dvb-core/dvb_net.c | 25 +++++++++++++++++++------
+ 1 file changed, 19 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c
+index 89620da983ba..dddebea644bb 100644
+--- a/drivers/media/dvb-core/dvb_net.c
++++ b/drivers/media/dvb-core/dvb_net.c
+@@ -45,6 +45,7 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/netdevice.h>
++#include <linux/nospec.h>
+ #include <linux/etherdevice.h>
+ #include <linux/dvb/net.h>
+ #include <linux/uio.h>
+@@ -1462,14 +1463,20 @@ static int dvb_net_do_ioctl(struct file *file,
+ struct net_device *netdev;
+ struct dvb_net_priv *priv_data;
+ struct dvb_net_if *dvbnetif = parg;
++ int if_num = dvbnetif->if_num;
+
+- if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
+- !dvbnet->state[dvbnetif->if_num]) {
++ if (if_num >= DVB_NET_DEVICES_MAX) {
+ ret = -EINVAL;
+ goto ioctl_error;
+ }
++ if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX);
+
+- netdev = dvbnet->device[dvbnetif->if_num];
++ if (!dvbnet->state[if_num]) {
++ ret = -EINVAL;
++ goto ioctl_error;
++ }
++
++ netdev = dvbnet->device[if_num];
+
+ priv_data = netdev_priv(netdev);
+ dvbnetif->pid=priv_data->pid;
+@@ -1522,14 +1529,20 @@ static int dvb_net_do_ioctl(struct file *file,
+ struct net_device *netdev;
+ struct dvb_net_priv *priv_data;
+ struct __dvb_net_if_old *dvbnetif = parg;
++ int if_num = dvbnetif->if_num;
++
++ if (if_num >= DVB_NET_DEVICES_MAX) {
++ ret = -EINVAL;
++ goto ioctl_error;
++ }
++ if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX);
+
+- if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
+- !dvbnet->state[dvbnetif->if_num]) {
++ if (!dvbnet->state[if_num]) {
+ ret = -EINVAL;
+ goto ioctl_error;
+ }
+
+- netdev = dvbnet->device[dvbnetif->if_num];
++ netdev = dvbnet->device[if_num];
+
+ priv_data = netdev_priv(netdev);
+ dvbnetif->pid=priv_data->pid;
+--
+2.30.2
+
--- /dev/null
+From 3a5654040b2a09bb9a14ecfafe42d02d9950f2fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jun 2021 14:32:29 +0200
+Subject: media: dvbdev: fix error logic at dvb_register_device()
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 1fec2ecc252301110e4149e6183fa70460d29674 ]
+
+As reported by smatch:
+
+ drivers/media/dvb-core/dvbdev.c: drivers/media/dvb-core/dvbdev.c:510 dvb_register_device() warn: '&dvbdev->list_head' not removed from list
+ drivers/media/dvb-core/dvbdev.c: drivers/media/dvb-core/dvbdev.c:530 dvb_register_device() warn: '&dvbdev->list_head' not removed from list
+ drivers/media/dvb-core/dvbdev.c: drivers/media/dvb-core/dvbdev.c:545 dvb_register_device() warn: '&dvbdev->list_head' not removed from list
+
+The error logic inside dvb_register_device() doesn't remove
+devices from the dvb_adapter_list in case of errors.
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/dvb-core/dvbdev.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
+index 3862ddc86ec4..795d9bfaba5c 100644
+--- a/drivers/media/dvb-core/dvbdev.c
++++ b/drivers/media/dvb-core/dvbdev.c
+@@ -506,6 +506,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ break;
+
+ if (minor == MAX_DVB_MINORS) {
++ list_del (&dvbdev->list_head);
+ kfree(dvbdevfops);
+ kfree(dvbdev);
+ up_write(&minor_rwsem);
+@@ -526,6 +527,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ __func__);
+
+ dvb_media_device_free(dvbdev);
++ list_del (&dvbdev->list_head);
+ kfree(dvbdevfops);
+ kfree(dvbdev);
+ mutex_unlock(&dvbdev_register_lock);
+@@ -541,6 +543,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n",
+ __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
+ dvb_media_device_free(dvbdev);
++ list_del (&dvbdev->list_head);
+ kfree(dvbdevfops);
+ kfree(dvbdev);
+ return PTR_ERR(clsdev);
+--
+2.30.2
+
--- /dev/null
+From d6445a2619747cc41199737ba36665a1cb18f8db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 15:06:52 +0200
+Subject: media: dvd_usb: memory leak in cinergyt2_fe_attach
+
+From: Dongliang Mu <mudongliangabcd@gmail.com>
+
+[ Upstream commit 9ad1efee086e0e913914fa2b2173efb830bad68c ]
+
+When the driver fails to talk with the hardware with dvb_usb_generic_rw,
+it will return an error to dvb_usb_adapter_frontend_init. However, the
+driver forgets to free the resource (e.g., struct cinergyt2_fe_state),
+which leads to a memory leak.
+
+Fix this by freeing struct cinergyt2_fe_state when dvb_usb_generic_rw
+fails in cinergyt2_frontend_attach.
+
+backtrace:
+ [<0000000056e17b1a>] kmalloc include/linux/slab.h:552 [inline]
+ [<0000000056e17b1a>] kzalloc include/linux/slab.h:682 [inline]
+ [<0000000056e17b1a>] cinergyt2_fe_attach+0x21/0x80 drivers/media/usb/dvb-usb/cinergyT2-fe.c:271
+ [<00000000ae0b1711>] cinergyt2_frontend_attach+0x21/0x70 drivers/media/usb/dvb-usb/cinergyT2-core.c:74
+ [<00000000d0254861>] dvb_usb_adapter_frontend_init+0x11b/0x1b0 drivers/media/usb/dvb-usb/dvb-usb-dvb.c:290
+ [<0000000002e08ac6>] dvb_usb_adapter_init drivers/media/usb/dvb-usb/dvb-usb-init.c:84 [inline]
+ [<0000000002e08ac6>] dvb_usb_init drivers/media/usb/dvb-usb/dvb-usb-init.c:173 [inline]
+ [<0000000002e08ac6>] dvb_usb_device_init.cold+0x4d0/0x6ae drivers/media/usb/dvb-usb/dvb-usb-init.c:287
+
+Reported-by: syzbot+e1de8986786b3722050e@syzkaller.appspotmail.com
+Signed-off-by: Dongliang Mu <mudongliangabcd@gmail.com>
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/dvb-usb/cinergyT2-core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/media/usb/dvb-usb/cinergyT2-core.c b/drivers/media/usb/dvb-usb/cinergyT2-core.c
+index 969a7ec71dff..4116ba5c45fc 100644
+--- a/drivers/media/usb/dvb-usb/cinergyT2-core.c
++++ b/drivers/media/usb/dvb-usb/cinergyT2-core.c
+@@ -78,6 +78,8 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
+
+ ret = dvb_usb_generic_rw(d, st->data, 1, st->data, 3, 0);
+ if (ret < 0) {
++ if (adap->fe_adap[0].fe)
++ adap->fe_adap[0].fe->ops.release(adap->fe_adap[0].fe);
+ deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep state info\n");
+ }
+ mutex_unlock(&d->data_mutex);
+--
+2.30.2
+
--- /dev/null
+From 7f5bf22a53357563bd0eb6668291e0d7100e63fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 20:32:49 +0200
+Subject: media: em28xx: Fix possible memory leak of em28xx struct
+
+From: Igor Matheus Andrade Torrente <igormtorrente@gmail.com>
+
+[ Upstream commit ac5688637144644f06ed1f3c6d4dd8bb7db96020 ]
+
+The em28xx struct kref isn't being decreased after an error in the
+em28xx_ir_init, leading to a possible memory leak.
+
+A kref_put and em28xx_shutdown_buttons is added to the error handler code.
+
+Signed-off-by: Igor Matheus Andrade Torrente <igormtorrente@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/em28xx/em28xx-input.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c
+index 5aa15a7a49de..59529cbf9cd0 100644
+--- a/drivers/media/usb/em28xx/em28xx-input.c
++++ b/drivers/media/usb/em28xx/em28xx-input.c
+@@ -720,7 +720,8 @@ static int em28xx_ir_init(struct em28xx *dev)
+ dev->board.has_ir_i2c = 0;
+ dev_warn(&dev->intf->dev,
+ "No i2c IR remote control device found.\n");
+- return -ENODEV;
++ err = -ENODEV;
++ goto ref_put;
+ }
+ }
+
+@@ -735,7 +736,7 @@ static int em28xx_ir_init(struct em28xx *dev)
+
+ ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+ if (!ir)
+- return -ENOMEM;
++ goto ref_put;
+ rc = rc_allocate_device(RC_DRIVER_SCANCODE);
+ if (!rc)
+ goto error;
+@@ -839,6 +840,9 @@ error:
+ dev->ir = NULL;
+ rc_free_device(rc);
+ kfree(ir);
++ref_put:
++ em28xx_shutdown_buttons(dev);
++ kref_put(&dev->ref, em28xx_free_device);
+ return err;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 78f15d80a243184907f3c17c5b95fdfc9a28ea9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 17:19:18 +0200
+Subject: media: exynos-gsc: fix pm_runtime_get_sync() usage count
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 59087b66ea6730c130c57d23bd9fd139b78c1ba5 ]
+
+The pm_runtime_get_sync() internally increments the
+dev->power.usage_count without decrementing it, even on errors.
+Replace it by the new pm_runtime_resume_and_get(), introduced by:
+commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter")
+in order to properly decrement the usage counter, avoiding
+a potential PM usage counter leak.
+
+As a bonus, as pm_runtime_get_sync() always return 0 on
+success, the logic can be simplified.
+
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/exynos-gsc/gsc-m2m.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c
+index 27a3c92c73bc..f1cf847d1cc2 100644
+--- a/drivers/media/platform/exynos-gsc/gsc-m2m.c
++++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c
+@@ -56,10 +56,8 @@ static void __gsc_m2m_job_abort(struct gsc_ctx *ctx)
+ static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count)
+ {
+ struct gsc_ctx *ctx = q->drv_priv;
+- int ret;
+
+- ret = pm_runtime_get_sync(&ctx->gsc_dev->pdev->dev);
+- return ret > 0 ? 0 : ret;
++ return pm_runtime_resume_and_get(&ctx->gsc_dev->pdev->dev);
+ }
+
+ static void __gsc_m2m_cleanup_queue(struct gsc_ctx *ctx)
+--
+2.30.2
+
--- /dev/null
+From 821d4fb3c095f5a2a6b486640d25b8af9dd0794c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 May 2021 10:12:31 +0200
+Subject: media: exynos4-is: Fix a use after free in isp_video_release
+
+From: Lv Yunlong <lyl2019@mail.ustc.edu.cn>
+
+[ Upstream commit 01fe904c9afd26e79c1f73aa0ca2e3d785e5e319 ]
+
+In isp_video_release, file->private_data is freed via
+_vb2_fop_release()->v4l2_fh_release(). But the freed
+file->private_data is still used in v4l2_fh_is_singular_file()
+->v4l2_fh_is_singular(file->private_data), which is a use
+after free bug.
+
+My patch uses a variable 'is_singular_file' to avoid the uaf.
+v3: https://lore.kernel.org/patchwork/patch/1419058/
+
+Fixes: 34947b8aebe3f ("[media] exynos4-is: Add the FIMC-IS ISP capture DMA driver")
+Signed-off-by: Lv Yunlong <lyl2019@mail.ustc.edu.cn>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/exynos4-is/fimc-isp-video.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
+index 8d9dc597deaa..83688a7982f7 100644
+--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
++++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
+@@ -305,17 +305,20 @@ static int isp_video_release(struct file *file)
+ struct fimc_is_video *ivc = &isp->video_capture;
+ struct media_entity *entity = &ivc->ve.vdev.entity;
+ struct media_device *mdev = entity->graph_obj.mdev;
++ bool is_singular_file;
+
+ mutex_lock(&isp->video_lock);
+
+- if (v4l2_fh_is_singular_file(file) && ivc->streaming) {
++ is_singular_file = v4l2_fh_is_singular_file(file);
++
++ if (is_singular_file && ivc->streaming) {
+ media_pipeline_stop(entity);
+ ivc->streaming = 0;
+ }
+
+ _vb2_fop_release(file, NULL);
+
+- if (v4l2_fh_is_singular_file(file)) {
++ if (is_singular_file) {
+ fimc_pipeline_call(&ivc->ve, close);
+
+ mutex_lock(&mdev->graph_mutex);
+--
+2.30.2
+
--- /dev/null
+From d606729a7deea68d6428cd2ddbdd90234da6d7bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 17:19:17 +0200
+Subject: media: exynos4-is: fix pm_runtime_get_sync() usage count
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 59f96244af9403ddf4810ec5c0fbe8920857634e ]
+
+The pm_runtime_get_sync() internally increments the
+dev->power.usage_count without decrementing it, even on errors.
+
+On some places, this is ok, but on others the usage count
+ended being unbalanced on failures.
+
+Replace it by the new pm_runtime_resume_and_get(), introduced by:
+commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter")
+in order to properly decrement the usage counter, avoiding
+a potential PM usage counter leak.
+
+As a bonus, such function always return zero on success. So,
+some code can be simplified.
+
+Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/exynos4-is/fimc-capture.c | 6 ++----
+ drivers/media/platform/exynos4-is/fimc-is.c | 4 ++--
+ drivers/media/platform/exynos4-is/fimc-isp-video.c | 3 +--
+ drivers/media/platform/exynos4-is/fimc-isp.c | 7 +++----
+ drivers/media/platform/exynos4-is/fimc-lite.c | 5 +++--
+ drivers/media/platform/exynos4-is/fimc-m2m.c | 5 +----
+ drivers/media/platform/exynos4-is/media-dev.c | 9 +++------
+ drivers/media/platform/exynos4-is/mipi-csis.c | 10 ++++------
+ 8 files changed, 19 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
+index 13c838d3f947..0da36443173c 100644
+--- a/drivers/media/platform/exynos4-is/fimc-capture.c
++++ b/drivers/media/platform/exynos4-is/fimc-capture.c
+@@ -478,11 +478,9 @@ static int fimc_capture_open(struct file *file)
+ goto unlock;
+
+ set_bit(ST_CAPT_BUSY, &fimc->state);
+- ret = pm_runtime_get_sync(&fimc->pdev->dev);
+- if (ret < 0) {
+- pm_runtime_put_sync(&fimc->pdev->dev);
++ ret = pm_runtime_resume_and_get(&fimc->pdev->dev);
++ if (ret < 0)
+ goto unlock;
+- }
+
+ ret = v4l2_fh_open(file);
+ if (ret) {
+diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
+index 972d9601d236..1b24f5bfc4af 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is.c
++++ b/drivers/media/platform/exynos4-is/fimc-is.c
+@@ -828,9 +828,9 @@ static int fimc_is_probe(struct platform_device *pdev)
+ goto err_irq;
+ }
+
+- ret = pm_runtime_get_sync(dev);
++ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0)
+- goto err_pm;
++ goto err_irq;
+
+ vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
+index 612b9872afc8..8d9dc597deaa 100644
+--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
++++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
+@@ -275,7 +275,7 @@ static int isp_video_open(struct file *file)
+ if (ret < 0)
+ goto unlock;
+
+- ret = pm_runtime_get_sync(&isp->pdev->dev);
++ ret = pm_runtime_resume_and_get(&isp->pdev->dev);
+ if (ret < 0)
+ goto rel_fh;
+
+@@ -293,7 +293,6 @@ static int isp_video_open(struct file *file)
+ if (!ret)
+ goto unlock;
+ rel_fh:
+- pm_runtime_put_noidle(&isp->pdev->dev);
+ v4l2_fh_release(file);
+ unlock:
+ mutex_unlock(&isp->video_lock);
+diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
+index a77c49b18511..74b49d30901e 100644
+--- a/drivers/media/platform/exynos4-is/fimc-isp.c
++++ b/drivers/media/platform/exynos4-is/fimc-isp.c
+@@ -304,11 +304,10 @@ static int fimc_isp_subdev_s_power(struct v4l2_subdev *sd, int on)
+ pr_debug("on: %d\n", on);
+
+ if (on) {
+- ret = pm_runtime_get_sync(&is->pdev->dev);
+- if (ret < 0) {
+- pm_runtime_put(&is->pdev->dev);
++ ret = pm_runtime_resume_and_get(&is->pdev->dev);
++ if (ret < 0)
+ return ret;
+- }
++
+ set_bit(IS_ST_PWR_ON, &is->state);
+
+ ret = fimc_is_start_firmware(is);
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index fe20af3a7178..4d8b18078ff3 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -469,9 +469,9 @@ static int fimc_lite_open(struct file *file)
+ }
+
+ set_bit(ST_FLITE_IN_USE, &fimc->state);
+- ret = pm_runtime_get_sync(&fimc->pdev->dev);
++ ret = pm_runtime_resume_and_get(&fimc->pdev->dev);
+ if (ret < 0)
+- goto err_pm;
++ goto err_in_use;
+
+ ret = v4l2_fh_open(file);
+ if (ret < 0)
+@@ -499,6 +499,7 @@ static int fimc_lite_open(struct file *file)
+ v4l2_fh_release(file);
+ err_pm:
+ pm_runtime_put_sync(&fimc->pdev->dev);
++err_in_use:
+ clear_bit(ST_FLITE_IN_USE, &fimc->state);
+ unlock:
+ mutex_unlock(&fimc->lock);
+diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c
+index c9704a147e5c..df8e2aa454d8 100644
+--- a/drivers/media/platform/exynos4-is/fimc-m2m.c
++++ b/drivers/media/platform/exynos4-is/fimc-m2m.c
+@@ -73,17 +73,14 @@ static void fimc_m2m_shutdown(struct fimc_ctx *ctx)
+ static int start_streaming(struct vb2_queue *q, unsigned int count)
+ {
+ struct fimc_ctx *ctx = q->drv_priv;
+- int ret;
+
+- ret = pm_runtime_get_sync(&ctx->fimc_dev->pdev->dev);
+- return ret > 0 ? 0 : ret;
++ return pm_runtime_resume_and_get(&ctx->fimc_dev->pdev->dev);
+ }
+
+ static void stop_streaming(struct vb2_queue *q)
+ {
+ struct fimc_ctx *ctx = q->drv_priv;
+
+-
+ fimc_m2m_shutdown(ctx);
+ fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
+ pm_runtime_put(&ctx->fimc_dev->pdev->dev);
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index 13d192ba4aa6..e025178db06c 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -512,11 +512,9 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
+ if (!fmd->pmf)
+ return -ENXIO;
+
+- ret = pm_runtime_get_sync(fmd->pmf);
+- if (ret < 0) {
+- pm_runtime_put(fmd->pmf);
++ ret = pm_runtime_resume_and_get(fmd->pmf);
++ if (ret < 0)
+ return ret;
+- }
+
+ fmd->num_sensors = 0;
+
+@@ -1291,8 +1289,7 @@ static int cam_clk_prepare(struct clk_hw *hw)
+ if (camclk->fmd->pmf == NULL)
+ return -ENODEV;
+
+- ret = pm_runtime_get_sync(camclk->fmd->pmf);
+- return ret < 0 ? ret : 0;
++ return pm_runtime_resume_and_get(camclk->fmd->pmf);
+ }
+
+ static void cam_clk_unprepare(struct clk_hw *hw)
+diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
+index 1aac167abb17..ebf39c856894 100644
+--- a/drivers/media/platform/exynos4-is/mipi-csis.c
++++ b/drivers/media/platform/exynos4-is/mipi-csis.c
+@@ -494,7 +494,7 @@ static int s5pcsis_s_power(struct v4l2_subdev *sd, int on)
+ struct device *dev = &state->pdev->dev;
+
+ if (on)
+- return pm_runtime_get_sync(dev);
++ return pm_runtime_resume_and_get(dev);
+
+ return pm_runtime_put_sync(dev);
+ }
+@@ -509,11 +509,9 @@ static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable)
+
+ if (enable) {
+ s5pcsis_clear_counters(state);
+- ret = pm_runtime_get_sync(&state->pdev->dev);
+- if (ret && ret != 1) {
+- pm_runtime_put_noidle(&state->pdev->dev);
++ ret = pm_runtime_resume_and_get(&state->pdev->dev);
++ if (ret < 0)
+ return ret;
+- }
+ }
+
+ mutex_lock(&state->lock);
+@@ -535,7 +533,7 @@ unlock:
+ if (!enable)
+ pm_runtime_put(&state->pdev->dev);
+
+- return ret == 1 ? 0 : ret;
++ return ret;
+ }
+
+ static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd,
+--
+2.30.2
+
--- /dev/null
+From c3cd95c8298318e44a186ec2957b462672eaee2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jun 2021 17:19:06 +0200
+Subject: media: Fix Media Controller API config checks
+
+From: Shuah Khan <skhan@linuxfoundation.org>
+
+[ Upstream commit 50e7a31d30e8221632675abed3be306382324ca2 ]
+
+Smatch static checker warns that "mdev" can be null:
+
+sound/usb/media.c:287 snd_media_device_create()
+ warn: 'mdev' can also be NULL
+
+If CONFIG_MEDIA_CONTROLLER is disabled, this file should not be included
+in the build.
+
+The below conditions in the sound/usb/Makefile are in place to ensure that
+media.c isn't included in the build.
+
+sound/usb/Makefile:
+snd-usb-audio-$(CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER) += media.o
+
+select SND_USB_AUDIO_USE_MEDIA_CONTROLLER if MEDIA_CONTROLLER &&
+ (MEDIA_SUPPORT=y || MEDIA_SUPPORT=SND_USB_AUDIO)
+
+The following config check in include/media/media-dev-allocator.h is
+in place to enable the API only when CONFIG_MEDIA_CONTROLLER and
+CONFIG_USB are enabled.
+
+ #if defined(CONFIG_MEDIA_CONTROLLER) && defined(CONFIG_USB)
+
+This check doesn't work as intended when CONFIG_USB=m. When CONFIG_USB=m,
+CONFIG_USB_MODULE is defined and CONFIG_USB is not. The above config check
+doesn't catch that CONFIG_USB is defined as a module and disables the API.
+This results in sound/usb enabling Media Controller specific ALSA driver
+code, while Media disables the Media Controller API.
+
+Fix the problem requires two changes:
+
+1. Change the check to use IS_ENABLED to detect when CONFIG_USB is enabled
+ as a module or static. Since CONFIG_MEDIA_CONTROLLER is a bool, leave
+ the check unchanged to be consistent with drivers/media/Makefile.
+
+2. Change the drivers/media/mc/Makefile to include mc-dev-allocator.o
+ in mc-objs when CONFIG_USB is enabled.
+
+Link: https://lore.kernel.org/alsa-devel/YLeAvT+R22FQ%2FEyw@mwanda/
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/mc/Makefile | 2 +-
+ include/media/media-dev-allocator.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/mc/Makefile b/drivers/media/mc/Makefile
+index 119037f0e686..2b7af42ba59c 100644
+--- a/drivers/media/mc/Makefile
++++ b/drivers/media/mc/Makefile
+@@ -3,7 +3,7 @@
+ mc-objs := mc-device.o mc-devnode.o mc-entity.o \
+ mc-request.o
+
+-ifeq ($(CONFIG_USB),y)
++ifneq ($(CONFIG_USB),)
+ mc-objs += mc-dev-allocator.o
+ endif
+
+diff --git a/include/media/media-dev-allocator.h b/include/media/media-dev-allocator.h
+index b35ea6062596..2ab54d426c64 100644
+--- a/include/media/media-dev-allocator.h
++++ b/include/media/media-dev-allocator.h
+@@ -19,7 +19,7 @@
+
+ struct usb_device;
+
+-#if defined(CONFIG_MEDIA_CONTROLLER) && defined(CONFIG_USB)
++#if defined(CONFIG_MEDIA_CONTROLLER) && IS_ENABLED(CONFIG_USB)
+ /**
+ * media_device_usb_allocate() - Allocate and return struct &media device
+ *
+--
+2.30.2
+
--- /dev/null
+From 26e72333509c6651be888cefdef7b1760978d763 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 May 2021 13:09:18 +0200
+Subject: media: gspca/gl860: fix zero-length control requests
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 8ed339f23d41e21660a389adf2e7b2966d457ff6 ]
+
+The direction of the pipe argument must match the request-type direction
+bit or control requests may fail depending on the host-controller-driver
+implementation.
+
+Control transfers without a data stage are treated as OUT requests by
+the USB stack and should be using usb_sndctrlpipe(). Failing to do so
+will now trigger a warning.
+
+Fix the gl860_RTx() helper so that zero-length control reads fail with
+an error message instead. Note that there are no current callers that
+would trigger this.
+
+Fixes: 4f7cb8837cec ("V4L/DVB (12954): gspca - gl860: Addition of GL860 based webcams")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/gspca/gl860/gl860.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/usb/gspca/gl860/gl860.c b/drivers/media/usb/gspca/gl860/gl860.c
+index 2c05ea2598e7..ce4ee8bc75c8 100644
+--- a/drivers/media/usb/gspca/gl860/gl860.c
++++ b/drivers/media/usb/gspca/gl860/gl860.c
+@@ -561,8 +561,8 @@ int gl860_RTx(struct gspca_dev *gspca_dev,
+ len, 400 + 200 * (len > 1));
+ memcpy(pdata, gspca_dev->usb_buf, len);
+ } else {
+- r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+- req, pref, val, index, NULL, len, 400);
++ gspca_err(gspca_dev, "zero-length read request\n");
++ r = -EINVAL;
+ }
+ }
+
+--
+2.30.2
+
--- /dev/null
+From b7ff06a222c0ce3913a22c8f92f3c8ce35a75ef9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Apr 2021 08:27:55 +0200
+Subject: media: hantro: do a PM resume earlier
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 892bb6ecead9b834ba7ad1d07513e9eba1baa3a4 ]
+
+The device_run() first enables the clock and then
+tries to resume PM runtime, checking for errors.
+
+Well, if for some reason the pm_runtime can not resume,
+it would be better to detect it beforehand.
+
+So, change the order inside device_run().
+
+Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
+Fixes: 775fec69008d ("media: add Rockchip VPU JPEG encoder driver")
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/hantro/hantro_drv.c | 33 +++++++++++++++--------
+ 1 file changed, 22 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
+index 595e82a82728..eea2009fa17b 100644
+--- a/drivers/staging/media/hantro/hantro_drv.c
++++ b/drivers/staging/media/hantro/hantro_drv.c
+@@ -56,16 +56,12 @@ dma_addr_t hantro_get_ref(struct hantro_ctx *ctx, u64 ts)
+ return hantro_get_dec_buf_addr(ctx, buf);
+ }
+
+-static void hantro_job_finish(struct hantro_dev *vpu,
+- struct hantro_ctx *ctx,
+- enum vb2_buffer_state result)
++static void hantro_job_finish_no_pm(struct hantro_dev *vpu,
++ struct hantro_ctx *ctx,
++ enum vb2_buffer_state result)
+ {
+ struct vb2_v4l2_buffer *src, *dst;
+
+- pm_runtime_mark_last_busy(vpu->dev);
+- pm_runtime_put_autosuspend(vpu->dev);
+- clk_bulk_disable(vpu->variant->num_clocks, vpu->clocks);
+-
+ src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+
+@@ -81,6 +77,18 @@ static void hantro_job_finish(struct hantro_dev *vpu,
+ result);
+ }
+
++static void hantro_job_finish(struct hantro_dev *vpu,
++ struct hantro_ctx *ctx,
++ enum vb2_buffer_state result)
++{
++ pm_runtime_mark_last_busy(vpu->dev);
++ pm_runtime_put_autosuspend(vpu->dev);
++
++ clk_bulk_disable(vpu->variant->num_clocks, vpu->clocks);
++
++ hantro_job_finish_no_pm(vpu, ctx, result);
++}
++
+ void hantro_irq_done(struct hantro_dev *vpu,
+ enum vb2_buffer_state result)
+ {
+@@ -152,12 +160,15 @@ static void device_run(void *priv)
+ src = hantro_get_src_buf(ctx);
+ dst = hantro_get_dst_buf(ctx);
+
++ ret = pm_runtime_get_sync(ctx->dev->dev);
++ if (ret < 0) {
++ pm_runtime_put_noidle(ctx->dev->dev);
++ goto err_cancel_job;
++ }
++
+ ret = clk_bulk_enable(ctx->dev->variant->num_clocks, ctx->dev->clocks);
+ if (ret)
+ goto err_cancel_job;
+- ret = pm_runtime_get_sync(ctx->dev->dev);
+- if (ret < 0)
+- goto err_cancel_job;
+
+ v4l2_m2m_buf_copy_metadata(src, dst, true);
+
+@@ -165,7 +176,7 @@ static void device_run(void *priv)
+ return;
+
+ err_cancel_job:
+- hantro_job_finish(ctx->dev, ctx, VB2_BUF_STATE_ERROR);
++ hantro_job_finish_no_pm(ctx->dev, ctx, VB2_BUF_STATE_ERROR);
+ }
+
+ static struct v4l2_m2m_ops vpu_m2m_ops = {
+--
+2.30.2
+
--- /dev/null
+From 6c67842cc376ebd5536513b64f148d41469ea6f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 14:23:46 +0200
+Subject: media: hantro: Fix .buf_prepare
+
+From: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+
+[ Upstream commit 082aaecff35fbe1937531057911b1dd1fc6b496e ]
+
+The driver should only set the payload on .buf_prepare if the
+buffer is CAPTURE type. If an OUTPUT buffer has a zero bytesused
+set by userspace then v4l2-core will set it to buffer length.
+
+If we overwrite bytesused for OUTPUT buffers, too, then
+vb2_get_plane_payload() will return incorrect value which might be then
+written to hw registers by the driver in hantro_g1_h264_dec.c.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/hantro/hantro_v4l2.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c
+index 1bc118e375a1..7ccc6405036a 100644
+--- a/drivers/staging/media/hantro/hantro_v4l2.c
++++ b/drivers/staging/media/hantro/hantro_v4l2.c
+@@ -639,7 +639,14 @@ static int hantro_buf_prepare(struct vb2_buffer *vb)
+ ret = hantro_buf_plane_check(vb, pix_fmt);
+ if (ret)
+ return ret;
+- vb2_set_plane_payload(vb, 0, pix_fmt->plane_fmt[0].sizeimage);
++ /*
++ * Buffer's bytesused must be written by driver for CAPTURE buffers.
++ * (for OUTPUT buffers, if userspace passes 0 bytesused, v4l2-core sets
++ * it to buffer length).
++ */
++ if (V4L2_TYPE_IS_CAPTURE(vq->type))
++ vb2_set_plane_payload(vb, 0, pix_fmt->plane_fmt[0].sizeimage);
++
+ return 0;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 543cf4a356dc947a5b153df93ded4ff864238cf9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Apr 2021 09:15:54 +0200
+Subject: media: hevc: Fix dependent slice segment flags
+
+From: Jernej Skrabec <jernej.skrabec@siol.net>
+
+[ Upstream commit 67a7e53d5b21f3a84efc03a4e62db7caf97841ef ]
+
+Dependent slice segment flag for PPS control is misnamed. It should have
+"enabled" at the end. It only tells if this flag is present in slice
+header or not and not the actual value.
+
+Fix this by renaming the PPS flag and introduce another flag for slice
+control which tells actual value.
+
+Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 5 ++++-
+ drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 4 ++--
+ include/media/hevc-ctrls.h | 3 ++-
+ 3 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+index b0de4e6e7ebd..514b334470ea 100644
+--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
++++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+@@ -3053,7 +3053,7 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
+ :stub-columns: 0
+ :widths: 1 1 2
+
+- * - ``V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT``
++ * - ``V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED``
+ - 0x00000001
+ -
+ * - ``V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT``
+@@ -3277,6 +3277,9 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
+ * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED``
+ - 0x00000100
+ -
++ * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT``
++ - 0x00000200
++ -
+
+ .. raw:: latex
+
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+index ce497d0197df..10744fab7cea 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+@@ -477,8 +477,8 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
+ slice_params->flags);
+
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_DEPENDENT_SLICE_SEGMENT,
+- V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT,
+- pps->flags);
++ V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT,
++ slice_params->flags);
+
+ /* FIXME: For multi-slice support. */
+ reg |= VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_FIRST_SLICE_SEGMENT_IN_PIC;
+diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
+index b4cb2ef02f17..226fcfa0e026 100644
+--- a/include/media/hevc-ctrls.h
++++ b/include/media/hevc-ctrls.h
+@@ -81,7 +81,7 @@ struct v4l2_ctrl_hevc_sps {
+ __u64 flags;
+ };
+
+-#define V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT (1ULL << 0)
++#define V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED (1ULL << 0)
+ #define V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT (1ULL << 1)
+ #define V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED (1ULL << 2)
+ #define V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT (1ULL << 3)
+@@ -160,6 +160,7 @@ struct v4l2_hevc_pred_weight_table {
+ #define V4L2_HEVC_SLICE_PARAMS_FLAG_USE_INTEGER_MV (1ULL << 6)
+ #define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED (1ULL << 7)
+ #define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED (1ULL << 8)
++#define V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT (1ULL << 9)
+
+ struct v4l2_ctrl_hevc_slice_params {
+ __u32 bit_size;
+--
+2.30.2
+
--- /dev/null
+From aa9dc7b91f66d838e38a25b5c038b3a25fb26863 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Apr 2021 08:36:00 +0200
+Subject: media: i2c: ccs-core: return the right error code at suspend
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 6005a8e955e4e451e4bf6000affaab566d4cab5e ]
+
+If pm_runtime resume logic fails, return the error code
+provided by it, instead of -EAGAIN, as, depending on what
+caused it to fail, it may not be something that would be
+recovered.
+
+Fixes: cbba45d43631 ("[media] smiapp: Use runtime PM")
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ccs/ccs-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c
+index 9dc3f45da3dc..b05f409014b2 100644
+--- a/drivers/media/i2c/ccs/ccs-core.c
++++ b/drivers/media/i2c/ccs/ccs-core.c
+@@ -3093,7 +3093,7 @@ static int __maybe_unused ccs_suspend(struct device *dev)
+ if (rval < 0) {
+ pm_runtime_put_noidle(dev);
+
+- return -EAGAIN;
++ return rval;
+ }
+
+ if (sensor->streaming)
+--
+2.30.2
+
--- /dev/null
+From c9c64c7672000d5d60f994a97bdcd3d60490373e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Apr 2021 22:19:55 +0200
+Subject: media: I2C: change 'RST' to "RSET" to fix multiple build errors
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 8edcb5049ac29aa3c8acc5ef15dd4036543d747e ]
+
+The use of an enum named 'RST' conflicts with a #define macro
+named 'RST' in arch/mips/include/asm/mach-rc32434/rb.h.
+
+The MIPS use of RST was there first (AFAICT), so change the
+media/i2c/ uses of RST to be named 'RSET'.
+'git grep -w RSET' does not report any naming conflicts with the
+new name.
+
+This fixes multiple build errors:
+
+arch/mips/include/asm/mach-rc32434/rb.h:15:14: error: expected identifier before '(' token
+ 15 | #define RST (1 << 15)
+ | ^
+drivers/media/i2c/s5c73m3/s5c73m3.h:356:2: note: in expansion of macro 'RST'
+ 356 | RST,
+ | ^~~
+
+../arch/mips/include/asm/mach-rc32434/rb.h:15:14: error: expected identifier before '(' token
+ 15 | #define RST (1 << 15)
+ | ^
+../drivers/media/i2c/s5k6aa.c:180:2: note: in expansion of macro 'RST'
+ 180 | RST,
+ | ^~~
+
+../arch/mips/include/asm/mach-rc32434/rb.h:15:14: error: expected identifier before '(' token
+ 15 | #define RST (1 << 15)
+ | ^
+../drivers/media/i2c/s5k5baf.c:238:2: note: in expansion of macro 'RST'
+ 238 | RST,
+ | ^~~
+
+and some others that I have trimmed.
+
+Fixes: cac47f1822fc ("[media] V4L: Add S5C73M3 camera driver")
+Fixes: 8b99312b7214 ("[media] Add v4l2 subdev driver for S5K4ECGX sensor")
+Fixes: 7d459937dc09 ("[media] Add driver for Samsung S5K5BAF camera sensor")
+Fixes: bfa8dd3a0524 ("[media] v4l: Add v4l2 subdev driver for S5K6AAFX sensor")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Reported-by: kernel test robot <lkp@intel.com>
+Cc: Shawn Guo <shawnguo@kernel.org>
+Cc: Sascha Hauer <s.hauer@pengutronix.de>
+Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
+Cc: Fabio Estevam <festevam@gmail.com>
+Cc: NXP Linux Team <linux-imx@nxp.com>
+Cc: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+Cc: Andrzej Hajda <a.hajda@samsung.com>
+Cc: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Cc: Sangwook Lee <sangwook.lee@linaro.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/s5c73m3/s5c73m3-core.c | 6 +++---
+ drivers/media/i2c/s5c73m3/s5c73m3.h | 2 +-
+ drivers/media/i2c/s5k4ecgx.c | 10 +++++-----
+ drivers/media/i2c/s5k5baf.c | 6 +++---
+ drivers/media/i2c/s5k6aa.c | 10 +++++-----
+ 5 files changed, 17 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+index 5b4c4a3547c9..71804a70bc6d 100644
+--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
++++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+@@ -1386,7 +1386,7 @@ static int __s5c73m3_power_on(struct s5c73m3 *state)
+ s5c73m3_gpio_deassert(state, STBY);
+ usleep_range(100, 200);
+
+- s5c73m3_gpio_deassert(state, RST);
++ s5c73m3_gpio_deassert(state, RSET);
+ usleep_range(50, 100);
+
+ return 0;
+@@ -1401,7 +1401,7 @@ static int __s5c73m3_power_off(struct s5c73m3 *state)
+ {
+ int i, ret;
+
+- if (s5c73m3_gpio_assert(state, RST))
++ if (s5c73m3_gpio_assert(state, RSET))
+ usleep_range(10, 50);
+
+ if (s5c73m3_gpio_assert(state, STBY))
+@@ -1606,7 +1606,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state)
+
+ state->mclk_frequency = pdata->mclk_frequency;
+ state->gpio[STBY] = pdata->gpio_stby;
+- state->gpio[RST] = pdata->gpio_reset;
++ state->gpio[RSET] = pdata->gpio_reset;
+ return 0;
+ }
+
+diff --git a/drivers/media/i2c/s5c73m3/s5c73m3.h b/drivers/media/i2c/s5c73m3/s5c73m3.h
+index ef7e85b34263..c3fcfdd3ea66 100644
+--- a/drivers/media/i2c/s5c73m3/s5c73m3.h
++++ b/drivers/media/i2c/s5c73m3/s5c73m3.h
+@@ -353,7 +353,7 @@ struct s5c73m3_ctrls {
+
+ enum s5c73m3_gpio_id {
+ STBY,
+- RST,
++ RSET,
+ GPIO_NUM,
+ };
+
+diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c
+index b2d53417badf..4e97309a67f4 100644
+--- a/drivers/media/i2c/s5k4ecgx.c
++++ b/drivers/media/i2c/s5k4ecgx.c
+@@ -173,7 +173,7 @@ static const char * const s5k4ecgx_supply_names[] = {
+
+ enum s5k4ecgx_gpio_id {
+ STBY,
+- RST,
++ RSET,
+ GPIO_NUM,
+ };
+
+@@ -476,7 +476,7 @@ static int __s5k4ecgx_power_on(struct s5k4ecgx *priv)
+ if (s5k4ecgx_gpio_set_value(priv, STBY, priv->gpio[STBY].level))
+ usleep_range(30, 50);
+
+- if (s5k4ecgx_gpio_set_value(priv, RST, priv->gpio[RST].level))
++ if (s5k4ecgx_gpio_set_value(priv, RSET, priv->gpio[RSET].level))
+ usleep_range(30, 50);
+
+ return 0;
+@@ -484,7 +484,7 @@ static int __s5k4ecgx_power_on(struct s5k4ecgx *priv)
+
+ static int __s5k4ecgx_power_off(struct s5k4ecgx *priv)
+ {
+- if (s5k4ecgx_gpio_set_value(priv, RST, !priv->gpio[RST].level))
++ if (s5k4ecgx_gpio_set_value(priv, RSET, !priv->gpio[RSET].level))
+ usleep_range(30, 50);
+
+ if (s5k4ecgx_gpio_set_value(priv, STBY, !priv->gpio[STBY].level))
+@@ -872,7 +872,7 @@ static int s5k4ecgx_config_gpios(struct s5k4ecgx *priv,
+ int ret;
+
+ priv->gpio[STBY].gpio = -EINVAL;
+- priv->gpio[RST].gpio = -EINVAL;
++ priv->gpio[RSET].gpio = -EINVAL;
+
+ ret = s5k4ecgx_config_gpio(gpio->gpio, gpio->level, "S5K4ECGX_STBY");
+
+@@ -891,7 +891,7 @@ static int s5k4ecgx_config_gpios(struct s5k4ecgx *priv,
+ s5k4ecgx_free_gpios(priv);
+ return ret;
+ }
+- priv->gpio[RST] = *gpio;
++ priv->gpio[RSET] = *gpio;
+ if (gpio_is_valid(gpio->gpio))
+ gpio_set_value(gpio->gpio, 0);
+
+diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
+index 6e702b57c37d..bc560817e504 100644
+--- a/drivers/media/i2c/s5k5baf.c
++++ b/drivers/media/i2c/s5k5baf.c
+@@ -235,7 +235,7 @@ struct s5k5baf_gpio {
+
+ enum s5k5baf_gpio_id {
+ STBY,
+- RST,
++ RSET,
+ NUM_GPIOS,
+ };
+
+@@ -969,7 +969,7 @@ static int s5k5baf_power_on(struct s5k5baf *state)
+
+ s5k5baf_gpio_deassert(state, STBY);
+ usleep_range(50, 100);
+- s5k5baf_gpio_deassert(state, RST);
++ s5k5baf_gpio_deassert(state, RSET);
+ return 0;
+
+ err_reg_dis:
+@@ -987,7 +987,7 @@ static int s5k5baf_power_off(struct s5k5baf *state)
+ state->apply_cfg = 0;
+ state->apply_crop = 0;
+
+- s5k5baf_gpio_assert(state, RST);
++ s5k5baf_gpio_assert(state, RSET);
+ s5k5baf_gpio_assert(state, STBY);
+
+ if (!IS_ERR(state->clock))
+diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c
+index 038e38500760..e9be7323a22e 100644
+--- a/drivers/media/i2c/s5k6aa.c
++++ b/drivers/media/i2c/s5k6aa.c
+@@ -177,7 +177,7 @@ static const char * const s5k6aa_supply_names[] = {
+
+ enum s5k6aa_gpio_id {
+ STBY,
+- RST,
++ RSET,
+ GPIO_NUM,
+ };
+
+@@ -841,7 +841,7 @@ static int __s5k6aa_power_on(struct s5k6aa *s5k6aa)
+ ret = s5k6aa->s_power(1);
+ usleep_range(4000, 5000);
+
+- if (s5k6aa_gpio_deassert(s5k6aa, RST))
++ if (s5k6aa_gpio_deassert(s5k6aa, RSET))
+ msleep(20);
+
+ return ret;
+@@ -851,7 +851,7 @@ static int __s5k6aa_power_off(struct s5k6aa *s5k6aa)
+ {
+ int ret;
+
+- if (s5k6aa_gpio_assert(s5k6aa, RST))
++ if (s5k6aa_gpio_assert(s5k6aa, RSET))
+ usleep_range(100, 150);
+
+ if (s5k6aa->s_power) {
+@@ -1510,7 +1510,7 @@ static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa,
+ int ret;
+
+ s5k6aa->gpio[STBY].gpio = -EINVAL;
+- s5k6aa->gpio[RST].gpio = -EINVAL;
++ s5k6aa->gpio[RSET].gpio = -EINVAL;
+
+ gpio = &pdata->gpio_stby;
+ if (gpio_is_valid(gpio->gpio)) {
+@@ -1533,7 +1533,7 @@ static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa,
+ if (ret < 0)
+ return ret;
+
+- s5k6aa->gpio[RST] = *gpio;
++ s5k6aa->gpio[RSET] = *gpio;
+ }
+
+ return 0;
+--
+2.30.2
+
--- /dev/null
+From 3877b04b8657067bde7f877a84dd6dab2c8e6f90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 17:19:13 +0200
+Subject: media: i2c: imx334: fix the pm runtime get logic
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 62c90446868b439929cb04395f04a709a64ae04b ]
+
+The PM runtime get logic is currently broken, as it checks if
+ret is zero instead of checking if it is an error code,
+as reported by Dan Carpenter.
+
+While here, use the pm_runtime_resume_and_get() as added by:
+commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter")
+added pm_runtime_resume_and_get() in order to automatically handle
+dev->power.usage_count decrement on errors. As a bonus, such function
+always return zero on success.
+
+It should also be noticed that a fail of pm_runtime_get_sync() would
+potentially result in a spurious runtime_suspend(), instead of
+using pm_runtime_put_noidle().
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Daniele Alessandrelli <daniele.alessandrelli@intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/imx334.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/i2c/imx334.c b/drivers/media/i2c/imx334.c
+index 047aa7658d21..23f28606e570 100644
+--- a/drivers/media/i2c/imx334.c
++++ b/drivers/media/i2c/imx334.c
+@@ -717,9 +717,9 @@ static int imx334_set_stream(struct v4l2_subdev *sd, int enable)
+ }
+
+ if (enable) {
+- ret = pm_runtime_get_sync(imx334->dev);
+- if (ret)
+- goto error_power_off;
++ ret = pm_runtime_resume_and_get(imx334->dev);
++ if (ret < 0)
++ goto error_unlock;
+
+ ret = imx334_start_streaming(imx334);
+ if (ret)
+@@ -737,6 +737,7 @@ static int imx334_set_stream(struct v4l2_subdev *sd, int enable)
+
+ error_power_off:
+ pm_runtime_put(imx334->dev);
++error_unlock:
+ mutex_unlock(&imx334->mutex);
+
+ return ret;
+--
+2.30.2
+
--- /dev/null
+From e9256e3a4fd19e77307e6a5dfb93672515a9d7f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 07:09:53 +0200
+Subject: media: i2c: ov2659: Use clk_{prepare_enable,disable_unprepare}() to
+ set xvclk on/off
+
+From: Dillon Min <dillon.minfei@gmail.com>
+
+[ Upstream commit 24786ccd9c80fdb05494aa4d90fcb8f34295c193 ]
+
+On some platform(imx6q), xvclk might not switch on in advance,
+also for power save purpose, xvclk should not be always on.
+so, add clk_prepare_enable(), clk_disable_unprepare() in driver
+side to set xvclk on/off at proper stage.
+
+Add following changes:
+- add 'struct clk *clk;' in 'struct ov2659 {}'
+- enable xvclk in ov2659_power_on()
+- disable xvclk in ov2659_power_off()
+
+Signed-off-by: Dillon Min <dillon.minfei@gmail.com>
+Acked-by: Lad Prabhakar <prabhakar.csengg@gmail.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ov2659.c | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
+index 42f64175a6df..fb78a1cedc03 100644
+--- a/drivers/media/i2c/ov2659.c
++++ b/drivers/media/i2c/ov2659.c
+@@ -204,6 +204,7 @@ struct ov2659 {
+ struct i2c_client *client;
+ struct v4l2_ctrl_handler ctrls;
+ struct v4l2_ctrl *link_frequency;
++ struct clk *clk;
+ const struct ov2659_framesize *frame_size;
+ struct sensor_register *format_ctrl_regs;
+ struct ov2659_pll_ctrl pll;
+@@ -1270,6 +1271,8 @@ static int ov2659_power_off(struct device *dev)
+
+ gpiod_set_value(ov2659->pwdn_gpio, 1);
+
++ clk_disable_unprepare(ov2659->clk);
++
+ return 0;
+ }
+
+@@ -1278,9 +1281,17 @@ static int ov2659_power_on(struct device *dev)
+ struct i2c_client *client = to_i2c_client(dev);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ov2659 *ov2659 = to_ov2659(sd);
++ int ret;
+
+ dev_dbg(&client->dev, "%s:\n", __func__);
+
++ ret = clk_prepare_enable(ov2659->clk);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable clock\n",
++ __func__);
++ return ret;
++ }
++
+ gpiod_set_value(ov2659->pwdn_gpio, 0);
+
+ if (ov2659->resetb_gpio) {
+@@ -1425,7 +1436,6 @@ static int ov2659_probe(struct i2c_client *client)
+ const struct ov2659_platform_data *pdata = ov2659_get_pdata(client);
+ struct v4l2_subdev *sd;
+ struct ov2659 *ov2659;
+- struct clk *clk;
+ int ret;
+
+ if (!pdata) {
+@@ -1440,11 +1450,11 @@ static int ov2659_probe(struct i2c_client *client)
+ ov2659->pdata = pdata;
+ ov2659->client = client;
+
+- clk = devm_clk_get(&client->dev, "xvclk");
+- if (IS_ERR(clk))
+- return PTR_ERR(clk);
++ ov2659->clk = devm_clk_get(&client->dev, "xvclk");
++ if (IS_ERR(ov2659->clk))
++ return PTR_ERR(ov2659->clk);
+
+- ov2659->xvclk_frequency = clk_get_rate(clk);
++ ov2659->xvclk_frequency = clk_get_rate(ov2659->clk);
+ if (ov2659->xvclk_frequency < 6000000 ||
+ ov2659->xvclk_frequency > 27000000)
+ return -EINVAL;
+@@ -1506,7 +1516,9 @@ static int ov2659_probe(struct i2c_client *client)
+ ov2659->frame_size = &ov2659_framesizes[2];
+ ov2659->format_ctrl_regs = ov2659_formats[0].format_ctrl_regs;
+
+- ov2659_power_on(&client->dev);
++ ret = ov2659_power_on(&client->dev);
++ if (ret < 0)
++ goto error;
+
+ ret = ov2659_detect(sd);
+ if (ret < 0)
+--
+2.30.2
+
--- /dev/null
+From 9e0b38bbf2fd5c5358b9ed41b93577687aec4f30 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jun 2021 14:46:10 +0200
+Subject: media: i2c: rdacm21: Fix OV10640 powerup
+
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+
+[ Upstream commit ff75332b260cd33cc19000fdb5d256d9db4470d1 ]
+
+The OV10640 image sensor powerdown signal is controlled by the first
+line of the OV490 GPIO pad #1, but the pad #0 identifier
+OV490_GPIO_OUTPUT_VALUE0 was erroneously used. As a result the image
+sensor powerdown signal was never asserted but was left floating and
+kept high by an internal pull-up resistor, causing sporadic failures
+during the image sensor startup phase.
+
+Fix this by using the correct GPIO pad identifier and wait the mandatory
+1.5 millisecond delay after the powerup lane is asserted. The reset
+delay is not characterized in the chip manual if not as "255 XVCLK +
+initialization". Wait for at least 3 milliseconds to guarantee the SCCB
+bus is available.
+
+While at it also fix the reset sequence, as the reset line was released
+before the powerdown one, and the line was not cycled.
+
+This commit fixes a sporadic start-up error triggered by a failure to
+read the OV10640 chip ID:
+rdacm21 8-0054: OV10640 ID mismatch: (0x01)
+
+Fixes: a59f853b3b4b ("media: i2c: Add driver for RDACM21 camera module")
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/rdacm21.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c
+index 179d107f494c..4b0dfd0a75e1 100644
+--- a/drivers/media/i2c/rdacm21.c
++++ b/drivers/media/i2c/rdacm21.c
+@@ -333,13 +333,19 @@ static int ov10640_initialize(struct rdacm21_device *dev)
+ {
+ u8 val;
+
+- /* Power-up OV10640 by setting RESETB and PWDNB pins high. */
++ /* Enable GPIO0#0 (reset) and GPIO1#0 (pwdn) as output lines. */
+ ov490_write_reg(dev, OV490_GPIO_SEL0, OV490_GPIO0);
+ ov490_write_reg(dev, OV490_GPIO_SEL1, OV490_SPWDN0);
+ ov490_write_reg(dev, OV490_GPIO_DIRECTION0, OV490_GPIO0);
+ ov490_write_reg(dev, OV490_GPIO_DIRECTION1, OV490_SPWDN0);
++
++ /* Power up OV10640 and then reset it. */
++ ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE1, OV490_SPWDN0);
++ usleep_range(1500, 3000);
++
++ ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE0, 0x00);
++ usleep_range(1500, 3000);
+ ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE0, OV490_GPIO0);
+- ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE0, OV490_SPWDN0);
+ usleep_range(3000, 5000);
+
+ /* Read OV10640 ID to test communications. */
+--
+2.30.2
+
--- /dev/null
+From 843454e81a8f7a06f959500f4900db439af4ae1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jun 2021 14:46:11 +0200
+Subject: media: i2c: rdacm21: Power up OV10640 before OV490
+
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+
+[ Upstream commit 2b821698dc73c00719e3dc367db712f727bbda85 ]
+
+The current RDACM21 initialization routine powers up the OV10640 image
+sensor after the OV490 ISP. The ISP is programmed with a firmware loaded
+from an embedded serial flash that (most probably) tries to interact and
+program also the image sensor connected to the ISP.
+
+As described in commit "media: i2c: rdacm21: Fix OV10640 powerup" the
+image sensor powerdown signal is kept high by an internal pull up
+resistor and occasionally fails to startup correctly if the powerdown
+line is not asserted explicitly. Failures in the OV10640 startup causes
+the OV490 firmware to fail to boot correctly resulting in the camera
+module initialization to fail consequentially.
+
+Fix this by powering up the OV10640 image sensor before testing the
+OV490 firmware boot completion, by splitting the ov10640_initialize()
+function in an ov10640_power_up() one and an ov10640_check_id() one.
+
+Also make sure the OV10640 identification procedure gives enough time to
+the image sensor to resume after the programming phase performed by the
+OV490 firmware by repeating the ID read procedure.
+
+This commit fixes a sporadic start-up error triggered by a failure to
+detect the OV490 firmware boot completion:
+rdacm21 8-0054: Timeout waiting for firmware boot
+
+[hverkuil: fixed two typos in commit log]
+
+Fixes: a59f853b3b4b ("media: i2c: Add driver for RDACM21 camera module")
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/rdacm21.c | 46 ++++++++++++++++++++++++++-----------
+ 1 file changed, 32 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c
+index 4b0dfd0a75e1..50e2af522760 100644
+--- a/drivers/media/i2c/rdacm21.c
++++ b/drivers/media/i2c/rdacm21.c
+@@ -69,6 +69,7 @@
+ #define OV490_ISP_VSIZE_LOW 0x80820062
+ #define OV490_ISP_VSIZE_HIGH 0x80820063
+
++#define OV10640_PID_TIMEOUT 20
+ #define OV10640_ID_HIGH 0xa6
+ #define OV10640_CHIP_ID 0x300a
+ #define OV10640_PIXEL_RATE 55000000
+@@ -329,10 +330,8 @@ static const struct v4l2_subdev_ops rdacm21_subdev_ops = {
+ .pad = &rdacm21_subdev_pad_ops,
+ };
+
+-static int ov10640_initialize(struct rdacm21_device *dev)
++static void ov10640_power_up(struct rdacm21_device *dev)
+ {
+- u8 val;
+-
+ /* Enable GPIO0#0 (reset) and GPIO1#0 (pwdn) as output lines. */
+ ov490_write_reg(dev, OV490_GPIO_SEL0, OV490_GPIO0);
+ ov490_write_reg(dev, OV490_GPIO_SEL1, OV490_SPWDN0);
+@@ -347,18 +346,35 @@ static int ov10640_initialize(struct rdacm21_device *dev)
+ usleep_range(1500, 3000);
+ ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE0, OV490_GPIO0);
+ usleep_range(3000, 5000);
++}
+
+- /* Read OV10640 ID to test communications. */
+- ov490_write_reg(dev, OV490_SCCB_SLAVE0_DIR, OV490_SCCB_SLAVE_READ);
+- ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_HIGH, OV10640_CHIP_ID >> 8);
+- ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_LOW, OV10640_CHIP_ID & 0xff);
+-
+- /* Trigger SCCB slave transaction and give it some time to complete. */
+- ov490_write_reg(dev, OV490_HOST_CMD, OV490_HOST_CMD_TRIGGER);
+- usleep_range(1000, 1500);
++static int ov10640_check_id(struct rdacm21_device *dev)
++{
++ unsigned int i;
++ u8 val;
+
+- ov490_read_reg(dev, OV490_SCCB_SLAVE0_DIR, &val);
+- if (val != OV10640_ID_HIGH) {
++ /* Read OV10640 ID to test communications. */
++ for (i = 0; i < OV10640_PID_TIMEOUT; ++i) {
++ ov490_write_reg(dev, OV490_SCCB_SLAVE0_DIR,
++ OV490_SCCB_SLAVE_READ);
++ ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_HIGH,
++ OV10640_CHIP_ID >> 8);
++ ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_LOW,
++ OV10640_CHIP_ID & 0xff);
++
++ /*
++ * Trigger SCCB slave transaction and give it some time
++ * to complete.
++ */
++ ov490_write_reg(dev, OV490_HOST_CMD, OV490_HOST_CMD_TRIGGER);
++ usleep_range(1000, 1500);
++
++ ov490_read_reg(dev, OV490_SCCB_SLAVE0_DIR, &val);
++ if (val == OV10640_ID_HIGH)
++ break;
++ usleep_range(1000, 1500);
++ }
++ if (i == OV10640_PID_TIMEOUT) {
+ dev_err(dev->dev, "OV10640 ID mismatch: (0x%02x)\n", val);
+ return -ENODEV;
+ }
+@@ -374,6 +390,8 @@ static int ov490_initialize(struct rdacm21_device *dev)
+ unsigned int i;
+ int ret;
+
++ ov10640_power_up(dev);
++
+ /*
+ * Read OV490 Id to test communications. Give it up to 40msec to
+ * exit from reset.
+@@ -411,7 +429,7 @@ static int ov490_initialize(struct rdacm21_device *dev)
+ return -ENODEV;
+ }
+
+- ret = ov10640_initialize(dev);
++ ret = ov10640_check_id(dev);
+ if (ret)
+ return ret;
+
+--
+2.30.2
+
--- /dev/null
+From 95f026f46c4be4f9f606b102b4609e2cfba3765b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 May 2021 16:29:23 +0200
+Subject: media: imx-csi: Skip first few frames from a BT.656 source
+
+From: Steve Longerbeam <slongerbeam@gmail.com>
+
+[ Upstream commit e198be37e52551bb863d07d2edc535d0932a3c4f ]
+
+Some BT.656 sensors (e.g. ADV718x) transmit frames with unstable BT.656
+sync codes after initial power on. This confuses the imx CSI,resulting
+in vertical and/or horizontal sync issues. Skip the first 20 frames
+to avoid the unstable sync codes.
+
+[fabio: fixed checkpatch warning and increased the frame skipping to 20]
+
+Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
+Signed-off-by: Fabio Estevam <festevam@gmail.com>
+Reviewed-by: Tim Harvey <tharvey@gateworks.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/imx/imx-media-csi.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
+index e3bfd635a89a..6a94fff49bf6 100644
+--- a/drivers/staging/media/imx/imx-media-csi.c
++++ b/drivers/staging/media/imx/imx-media-csi.c
+@@ -750,9 +750,10 @@ static int csi_setup(struct csi_priv *priv)
+
+ static int csi_start(struct csi_priv *priv)
+ {
+- struct v4l2_fract *output_fi;
++ struct v4l2_fract *input_fi, *output_fi;
+ int ret;
+
++ input_fi = &priv->frame_interval[CSI_SINK_PAD];
+ output_fi = &priv->frame_interval[priv->active_output_pad];
+
+ /* start upstream */
+@@ -761,6 +762,17 @@ static int csi_start(struct csi_priv *priv)
+ if (ret)
+ return ret;
+
++ /* Skip first few frames from a BT.656 source */
++ if (priv->upstream_ep.bus_type == V4L2_MBUS_BT656) {
++ u32 delay_usec, bad_frames = 20;
++
++ delay_usec = DIV_ROUND_UP_ULL((u64)USEC_PER_SEC *
++ input_fi->numerator * bad_frames,
++ input_fi->denominator);
++
++ usleep_range(delay_usec, delay_usec + 1000);
++ }
++
+ if (priv->dest == IPU_CSI_DEST_IDMAC) {
+ ret = csi_idmac_start(priv);
+ if (ret)
+--
+2.30.2
+
--- /dev/null
+From 682ece87def95867b7ab7da7ec8e18ce1b6cf3de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Apr 2021 04:29:52 +0200
+Subject: media: imx: imx7_mipi_csis: Fix logging of only error event counters
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+[ Upstream commit d2fcc9c2de1191ea80366e3658711753738dd10a ]
+
+The mipi_csis_events array ends with 6 non-error events, not 4. Update
+mipi_csis_log_counters() accordingly. While at it, log event counters in
+forward order, as there's no reason to log them backward.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Rui Miguel Silva <rmfrfs@gmail.com>
+Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
+Tested-by: Frieder Schrempf <frieder.schrempf@kontron.de>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/imx/imx7-mipi-csis.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c
+index 025fdc488bd6..25d0f89b2e53 100644
+--- a/drivers/staging/media/imx/imx7-mipi-csis.c
++++ b/drivers/staging/media/imx/imx7-mipi-csis.c
+@@ -666,13 +666,15 @@ static void mipi_csis_clear_counters(struct csi_state *state)
+
+ static void mipi_csis_log_counters(struct csi_state *state, bool non_errors)
+ {
+- int i = non_errors ? MIPI_CSIS_NUM_EVENTS : MIPI_CSIS_NUM_EVENTS - 4;
++ unsigned int num_events = non_errors ? MIPI_CSIS_NUM_EVENTS
++ : MIPI_CSIS_NUM_EVENTS - 6;
+ struct device *dev = &state->pdev->dev;
+ unsigned long flags;
++ unsigned int i;
+
+ spin_lock_irqsave(&state->slock, flags);
+
+- for (i--; i >= 0; i--) {
++ for (i = 0; i < num_events; ++i) {
+ if (state->events[i].counter > 0 || state->debug)
+ dev_info(dev, "%s events: %d\n", state->events[i].name,
+ state->events[i].counter);
+--
+2.30.2
+
--- /dev/null
+From 9bd0b221d5cc2a46d07d7dc115b3fc5a4ca523f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Apr 2021 20:14:09 +0200
+Subject: media: ipu3-cio2: Fix reference counting when looping over ACPI
+ devices
+
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+
+[ Upstream commit 2cb2705cf7ffe41dc5bd81290e4241bfb7f031cc ]
+
+When we continue, due to device is disabled, loop we have to drop
+reference count. When we have an array full of devices we have to also
+drop the reference count. Note, in this case the
+cio2_bridge_unregister_sensors() is called by the caller.
+
+Fixes: 803abec64ef9 ("media: ipu3-cio2: Add cio2-bridge to ipu3-cio2 driver")
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Daniel Scally <djrscally@gmail.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/intel/ipu3/cio2-bridge.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c
+index e8511787c1e4..4657e99df033 100644
+--- a/drivers/media/pci/intel/ipu3/cio2-bridge.c
++++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c
+@@ -173,14 +173,15 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
+ int ret;
+
+ for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) {
+- if (!adev->status.enabled)
++ if (!adev->status.enabled) {
++ acpi_dev_put(adev);
+ continue;
++ }
+
+ if (bridge->n_sensors >= CIO2_NUM_PORTS) {
++ acpi_dev_put(adev);
+ dev_err(&cio2->dev, "Exceeded available CIO2 ports\n");
+- cio2_bridge_unregister_sensors(bridge);
+- ret = -EINVAL;
+- goto err_out;
++ return -EINVAL;
+ }
+
+ sensor = &bridge->sensors[bridge->n_sensors];
+@@ -228,7 +229,6 @@ err_free_swnodes:
+ software_node_unregister_nodes(sensor->swnodes);
+ err_put_adev:
+ acpi_dev_put(sensor->adev);
+-err_out:
+ return ret;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From f5f2b17583ca44a3b7a9672ee7dc9e019640e6da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 16:54:25 +0200
+Subject: media: marvel-ccic: fix some issues when getting pm_runtime
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit e7c617cab7a522fba5b20f9033ee98565b6f3546 ]
+
+Calling pm_runtime_get_sync() is bad, since even when it
+returns an error, pm_runtime_put*() should be called.
+So, use instead pm_runtime_resume_and_get().
+
+While here, ensure that the error condition will be checked
+during clock enable an media open() calls.
+
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/marvell-ccic/mcam-core.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c
+index 141bf5d97a04..ea87110d9073 100644
+--- a/drivers/media/platform/marvell-ccic/mcam-core.c
++++ b/drivers/media/platform/marvell-ccic/mcam-core.c
+@@ -918,6 +918,7 @@ static int mclk_enable(struct clk_hw *hw)
+ struct mcam_camera *cam = container_of(hw, struct mcam_camera, mclk_hw);
+ int mclk_src;
+ int mclk_div;
++ int ret;
+
+ /*
+ * Clock the sensor appropriately. Controller clock should
+@@ -931,7 +932,9 @@ static int mclk_enable(struct clk_hw *hw)
+ mclk_div = 2;
+ }
+
+- pm_runtime_get_sync(cam->dev);
++ ret = pm_runtime_resume_and_get(cam->dev);
++ if (ret < 0)
++ return ret;
+ clk_enable(cam->clk[0]);
+ mcam_reg_write(cam, REG_CLKCTRL, (mclk_src << 29) | mclk_div);
+ mcam_ctlr_power_up(cam);
+@@ -1611,7 +1614,9 @@ static int mcam_v4l_open(struct file *filp)
+ ret = sensor_call(cam, core, s_power, 1);
+ if (ret)
+ goto out;
+- pm_runtime_get_sync(cam->dev);
++ ret = pm_runtime_resume_and_get(cam->dev);
++ if (ret < 0)
++ goto out;
+ __mcam_cam_reset(cam);
+ mcam_set_config_needed(cam, 1);
+ }
+--
+2.30.2
+
--- /dev/null
+From 34bea56c3fdb0509e3ff8802bd3b63a4762895b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 16:57:16 +0200
+Subject: media: mdk-mdp: fix pm_runtime_get_sync() usage count
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit d07bb9702cf5f5ccf3fb661e6cab54bbc33cd23f ]
+
+The pm_runtime_get_sync() internally increments the
+dev->power.usage_count without decrementing it, even on errors.
+Replace it by the new pm_runtime_resume_and_get(), introduced by:
+commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter")
+in order to properly decrement the usage counter, avoiding
+a potential PM usage counter leak.
+
+While here, fix the return contition of mtk_mdp_m2m_start_streaming(),
+as it doesn't make any sense to return 0 if the PM runtime failed
+to resume.
+
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
+index ace4528cdc5e..f14779e7596e 100644
+--- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
++++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
+@@ -391,12 +391,12 @@ static int mtk_mdp_m2m_start_streaming(struct vb2_queue *q, unsigned int count)
+ struct mtk_mdp_ctx *ctx = q->drv_priv;
+ int ret;
+
+- ret = pm_runtime_get_sync(&ctx->mdp_dev->pdev->dev);
++ ret = pm_runtime_resume_and_get(&ctx->mdp_dev->pdev->dev);
+ if (ret < 0)
+- mtk_mdp_dbg(1, "[%d] pm_runtime_get_sync failed:%d",
++ mtk_mdp_dbg(1, "[%d] pm_runtime_resume_and_get failed:%d",
+ ctx->id, ret);
+
+- return 0;
++ return ret;
+ }
+
+ static void *mtk_mdp_m2m_buf_remove(struct mtk_mdp_ctx *ctx,
+--
+2.30.2
+
--- /dev/null
+From e8145ee47ec10a85463afb812f6d7e48c8d0286e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 17:19:09 +0200
+Subject: media: mtk-vcodec: fix PM runtime get logic
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 908711f542c17fe61e5d653da1beb8e5ab5c7b50 ]
+
+Currently, the driver just assumes that PM runtime logic
+succeded resuming the device.
+
+That may not be the case, as pm_runtime_get_sync()
+can fail (but keeping the usage count incremented).
+
+Replace the code to use pm_runtime_resume_and_get(),
+and letting it return the error code.
+
+This way, if mtk_vcodec_dec_pw_on() fails, the logic
+under fops_vcodec_open() will do the right thing and
+return an error, instead of just assuming that the
+device is ready to be used.
+
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 4 +++-
+ drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 8 +++++---
+ drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h | 2 +-
+ 3 files changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+index 147dfef1638d..f87dc47d9e63 100644
+--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
++++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+@@ -126,7 +126,9 @@ static int fops_vcodec_open(struct file *file)
+ mtk_vcodec_dec_set_default_params(ctx);
+
+ if (v4l2_fh_is_singular(&ctx->fh)) {
+- mtk_vcodec_dec_pw_on(&dev->pm);
++ ret = mtk_vcodec_dec_pw_on(&dev->pm);
++ if (ret < 0)
++ goto err_load_fw;
+ /*
+ * Does nothing if firmware was already loaded.
+ */
+diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+index ddee7046ce42..6038db96f71c 100644
+--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
++++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+@@ -88,13 +88,15 @@ void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev)
+ put_device(dev->pm.larbvdec);
+ }
+
+-void mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
++int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
+ {
+ int ret;
+
+- ret = pm_runtime_get_sync(pm->dev);
++ ret = pm_runtime_resume_and_get(pm->dev);
+ if (ret)
+- mtk_v4l2_err("pm_runtime_get_sync fail %d", ret);
++ mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
++
++ return ret;
+ }
+
+ void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
+diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+index 872d8bf8cfaf..280aeaefdb65 100644
+--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
++++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+@@ -12,7 +12,7 @@
+ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *dev);
+ void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev);
+
+-void mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);
++int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);
+ void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm);
+ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm);
+ void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm);
+--
+2.30.2
+
--- /dev/null
+From cb5e03214eee513a6e5eb614bdfcb1223a46a3d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 19:27:45 +0200
+Subject: media: mtk-vpu: on suspend, read/write regs only if vpu is running
+
+From: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
+
+[ Upstream commit 11420749c6b4b237361750de3d5b5579175f8622 ]
+
+If the vpu is not running, we should not rely on VPU_IDLE_REG
+value. In this case, the suspend cb should only unprepare the
+clock. This fixes a system-wide suspend to ram failure:
+
+[ 273.073363] PM: suspend entry (deep)
+[ 273.410502] mtk-msdc 11230000.mmc: phase: [map:ffffffff] [maxlen:32] [final:10]
+[ 273.455926] Filesystems sync: 0.378 seconds
+[ 273.589707] Freezing user space processes ... (elapsed 0.003 seconds) done.
+[ 273.600104] OOM killer disabled.
+[ 273.603409] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
+[ 273.613361] mwifiex_sdio mmc2:0001:1: None of the WOWLAN triggers enabled
+[ 274.784952] mtk_vpu 10020000.vpu: vpu idle timeout
+[ 274.789764] PM: dpm_run_callback(): platform_pm_suspend+0x0/0x70 returns -5
+[ 274.796740] mtk_vpu 10020000.vpu: PM: failed to suspend: error -5
+[ 274.802842] PM: Some devices failed to suspend, or early wake event detected
+[ 275.426489] OOM killer enabled.
+[ 275.429718] Restarting tasks ...
+[ 275.435765] done.
+[ 275.447510] PM: suspend exit
+
+Fixes: 1f565e263c3e ("media: mtk-vpu: VPU should be in idle state before system is suspended")
+Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mtk-vpu/mtk_vpu.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c
+index c8a56271b259..7c4428cf14e6 100644
+--- a/drivers/media/platform/mtk-vpu/mtk_vpu.c
++++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c
+@@ -987,6 +987,12 @@ static int mtk_vpu_suspend(struct device *dev)
+ return ret;
+ }
+
++ if (!vpu_running(vpu)) {
++ vpu_clock_disable(vpu);
++ clk_unprepare(vpu->clk);
++ return 0;
++ }
++
+ mutex_lock(&vpu->vpu_mutex);
+ /* disable vpu timer interrupt */
+ vpu_cfg_writel(vpu, vpu_cfg_readl(vpu, VPU_INT_STATUS) | VPU_IDLE_STATE,
+--
+2.30.2
+
--- /dev/null
+From e8bc8d76571418306f994c84fd07117f516a5b65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 19:08:58 +0200
+Subject: media: pvrusb2: fix warning in pvr2_i2c_core_done
+
+From: Anirudh Rayabharam <mail@anirudhrb.com>
+
+[ Upstream commit f8194e5e63fdcb349e8da9eef9e574d5b1d687cb ]
+
+syzbot has reported the following warning in pvr2_i2c_done:
+
+ sysfs group 'power' not found for kobject '1-0043'
+
+When the device is disconnected (pvr_hdw_disconnect), the i2c adapter is
+not unregistered along with the USB and v4l2 teardown. As part of the USB
+device disconnect, the sysfs files of the subdevices are also deleted.
+So, by the time pvr_i2c_core_done is called by pvr_context_destroy, the
+sysfs files have been deleted.
+
+To fix this, unregister the i2c adapter too in pvr_hdw_disconnect. Make
+the device deregistration code shared by calling pvr_hdw_disconnect from
+pvr2_hdw_destroy.
+
+Reported-by: syzbot+e74a998ca8f1df9cc332@syzkaller.appspotmail.com
+Tested-by: syzbot+e74a998ca8f1df9cc332@syzkaller.appspotmail.com
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Anirudh Rayabharam <mail@anirudhrb.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+index f4a727918e35..d38dee1792e4 100644
+--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
++++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+@@ -2676,9 +2676,8 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
+ pvr2_stream_destroy(hdw->vid_stream);
+ hdw->vid_stream = NULL;
+ }
+- pvr2_i2c_core_done(hdw);
+ v4l2_device_unregister(&hdw->v4l2_dev);
+- pvr2_hdw_remove_usb_stuff(hdw);
++ pvr2_hdw_disconnect(hdw);
+ mutex_lock(&pvr2_unit_mtx);
+ do {
+ if ((hdw->unit_number >= 0) &&
+@@ -2705,6 +2704,7 @@ void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
+ {
+ pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw);
+ LOCK_TAKE(hdw->big_lock);
++ pvr2_i2c_core_done(hdw);
+ LOCK_TAKE(hdw->ctl_lock);
+ pvr2_hdw_remove_usb_stuff(hdw);
+ LOCK_GIVE(hdw->ctl_lock);
+--
+2.30.2
+
--- /dev/null
+From e95cc4c19801121d13f8ca54fcc3d64f8255303d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 May 2021 07:38:56 +0200
+Subject: media: rc: i2c: Fix an error message
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 9c87ae1a0dbeb5794957421157fd266d38a869b4 ]
+
+'ret' is known to be 1 here. In fact 'i' is expected instead.
+Store the return value of 'i2c_master_recv()' in 'ret' so that the error
+message print the correct error code.
+
+Fixes: acaa34bf06e9 ("media: rc: implement zilog transmitter")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/ir-kbd-i2c.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c
+index e8119ad0bc71..92376592455e 100644
+--- a/drivers/media/i2c/ir-kbd-i2c.c
++++ b/drivers/media/i2c/ir-kbd-i2c.c
+@@ -678,8 +678,8 @@ static int zilog_tx(struct rc_dev *rcdev, unsigned int *txbuf,
+ goto out_unlock;
+ }
+
+- i = i2c_master_recv(ir->tx_c, buf, 1);
+- if (i != 1) {
++ ret = i2c_master_recv(ir->tx_c, buf, 1);
++ if (ret != 1) {
+ dev_err(&ir->rc->dev, "i2c_master_recv failed with %d\n", ret);
+ ret = -EIO;
+ goto out_unlock;
+--
+2.30.2
+
--- /dev/null
+From 1cf74cf07c4be912cb0a9351e96f3cff3c06c8b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 May 2021 14:23:45 +0200
+Subject: media: rkvdec: Fix .buf_prepare
+
+From: Ezequiel Garcia <ezequiel@collabora.com>
+
+[ Upstream commit ba1ed4ae760a81caf39f54232e089d95157a0dba ]
+
+The driver should only set the payload on .buf_prepare if the
+buffer is CAPTURE type. If an OUTPUT buffer has a zero bytesused
+set by userspace then v4l2-core will set it to buffer length.
+
+If we overwrite bytesused for OUTPUT buffers, too, then
+vb2_get_plane_payload() will return incorrect value which might be then
+written to hw registers by the driver in rkvdec-h264.c.
+
+[Changed the comment and used V4L2_TYPE_IS_CAPTURE macro]
+
+Fixes: cd33c830448ba ("media: rkvdec: Add the rkvdec driver")
+Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
+Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/rkvdec/rkvdec.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
+index 8c17615f3a7a..7131156c1f2c 100644
+--- a/drivers/staging/media/rkvdec/rkvdec.c
++++ b/drivers/staging/media/rkvdec/rkvdec.c
+@@ -481,7 +481,15 @@ static int rkvdec_buf_prepare(struct vb2_buffer *vb)
+ if (vb2_plane_size(vb, i) < sizeimage)
+ return -EINVAL;
+ }
+- vb2_set_plane_payload(vb, 0, f->fmt.pix_mp.plane_fmt[0].sizeimage);
++
++ /*
++ * Buffer's bytesused must be written by driver for CAPTURE buffers.
++ * (for OUTPUT buffers, if userspace passes 0 bytesused, v4l2-core sets
++ * it to buffer length).
++ */
++ if (V4L2_TYPE_IS_CAPTURE(vq->type))
++ vb2_set_plane_payload(vb, 0, f->fmt.pix_mp.plane_fmt[0].sizeimage);
++
+ return 0;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From f3ea2b2fa20a3370244d537b10b6b3fcfc3c285c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 17:04:23 +0200
+Subject: media: s5p: fix pm_runtime_get_sync() usage count
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit fdc34e82c0f968ac4c157bd3d8c299ebc24c9c63 ]
+
+The pm_runtime_get_sync() internally increments the
+dev->power.usage_count without decrementing it, even on errors.
+Replace it by the new pm_runtime_resume_and_get(), introduced by:
+commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter")
+in order to properly decrement the usage counter, avoiding
+a potential PM usage counter leak.
+
+While here, check if the PM runtime error was caught at
+s5p_cec_adap_enable().
+
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/cec/platform/s5p/s5p_cec.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/cec/platform/s5p/s5p_cec.c b/drivers/media/cec/platform/s5p/s5p_cec.c
+index 2a3e7ffefe0a..2250c1cbc64e 100644
+--- a/drivers/media/cec/platform/s5p/s5p_cec.c
++++ b/drivers/media/cec/platform/s5p/s5p_cec.c
+@@ -35,10 +35,13 @@ MODULE_PARM_DESC(debug, "debug level (0-2)");
+
+ static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable)
+ {
++ int ret;
+ struct s5p_cec_dev *cec = cec_get_drvdata(adap);
+
+ if (enable) {
+- pm_runtime_get_sync(cec->dev);
++ ret = pm_runtime_resume_and_get(cec->dev);
++ if (ret < 0)
++ return ret;
+
+ s5p_cec_reset(cec);
+
+--
+2.30.2
+
--- /dev/null
+From e27e630a50dfc185efa095b637ed2e0ad9a74fe5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 May 2021 17:18:32 +0200
+Subject: media: s5p-g2d: Fix a memory leak on ctx->fh.m2m_ctx
+
+From: Dillon Min <dillon.minfei@gmail.com>
+
+[ Upstream commit 5d11e6aad1811ea293ee2996cec9124f7fccb661 ]
+
+The m2m_ctx resources was allocated by v4l2_m2m_ctx_init() in g2d_open()
+should be freed from g2d_release() when it's not used.
+
+Fix it
+
+Fixes: 918847341af0 ("[media] v4l: add G2D driver for s5p device family")
+Signed-off-by: Dillon Min <dillon.minfei@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/s5p-g2d/g2d.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c
+index 15bcb7f6e113..1cb5eaabf340 100644
+--- a/drivers/media/platform/s5p-g2d/g2d.c
++++ b/drivers/media/platform/s5p-g2d/g2d.c
+@@ -276,6 +276,9 @@ static int g2d_release(struct file *file)
+ struct g2d_dev *dev = video_drvdata(file);
+ struct g2d_ctx *ctx = fh2ctx(file->private_data);
+
++ mutex_lock(&dev->mutex);
++ v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
++ mutex_unlock(&dev->mutex);
+ v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+--
+2.30.2
+
--- /dev/null
+From 743ba056bd46ccf3ef4585ceb66983e9ccf2c82d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 17:19:10 +0200
+Subject: media: s5p-jpeg: fix pm_runtime_get_sync() usage count
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 10343de268d10cf07b092b8b525e12ad558ead77 ]
+
+The pm_runtime_get_sync() internally increments the
+dev->power.usage_count without decrementing it, even on errors.
+Replace it by the new pm_runtime_resume_and_get(), introduced by:
+commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter")
+in order to properly decrement the usage counter, avoiding
+a potential PM usage counter leak.
+
+As a plus, pm_runtime_resume_and_get() doesn't return
+positive numbers, so the return code validation can
+be removed.
+
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Acked-by: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/s5p-jpeg/jpeg-core.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
+index 026111505f5a..d402e456f27d 100644
+--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
++++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
+@@ -2566,11 +2566,8 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
+ static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
+ {
+ struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
+- int ret;
+-
+- ret = pm_runtime_get_sync(ctx->jpeg->dev);
+
+- return ret > 0 ? 0 : ret;
++ return pm_runtime_resume_and_get(ctx->jpeg->dev);
+ }
+
+ static void s5p_jpeg_stop_streaming(struct vb2_queue *q)
+--
+2.30.2
+
--- /dev/null
+From 7b2331fc98e958a1b387292a06b8d8465e78cb3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 22:44:57 +0200
+Subject: media: s5p-mfc: Fix display delay control creation
+
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+
+[ Upstream commit 61c6f04a988e420a1fc5e8e81cf9aebf142a7bd6 ]
+
+v4l2_ctrl_new_std() fails if the caller provides no 'step' parameter for
+integer control, so define it to fix following error:
+
+s5p_mfc_dec_ctrls_setup:1166: Adding control (1) failed
+
+Fixes: c3042bff918a ("media: s5p-mfc: Use display delay and display enable std controls")
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
+index a92a9ca6e87e..c1d3bda8385b 100644
+--- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
++++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
+@@ -172,6 +172,7 @@ static struct mfc_control controls[] = {
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 16383,
++ .step = 1,
+ .default_value = 0,
+ },
+ {
+--
+2.30.2
+
--- /dev/null
+From 31b023607c4005bfeacd0e1a194ef5fa041cf823 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Apr 2021 09:38:56 +0200
+Subject: media: s5p_cec: decrement usage count if disabled
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 747bad54a677d8633ec14b39dfbeb859c821d7f2 ]
+
+There's a bug at s5p_cec_adap_enable(): if called to
+disable the device, it should call pm_runtime_put()
+instead of pm_runtime_disable(), as the goal here is to
+decrement the usage_count and not to disable PM runtime.
+
+Reported-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Fixes: 1bcbf6f4b6b0 ("[media] cec: s5p-cec: Add s5p-cec driver")
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/cec/platform/s5p/s5p_cec.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/cec/platform/s5p/s5p_cec.c b/drivers/media/cec/platform/s5p/s5p_cec.c
+index 2250c1cbc64e..028a09a7531e 100644
+--- a/drivers/media/cec/platform/s5p/s5p_cec.c
++++ b/drivers/media/cec/platform/s5p/s5p_cec.c
+@@ -54,7 +54,7 @@ static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable)
+ } else {
+ s5p_cec_mask_tx_interrupts(cec);
+ s5p_cec_mask_rx_interrupts(cec);
+- pm_runtime_disable(cec->dev);
++ pm_runtime_put(cec->dev);
+ }
+
+ return 0;
+--
+2.30.2
+
--- /dev/null
+From 7296abe6b4e6c1b633524b94aad343de0fe1e6c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 17:07:41 +0200
+Subject: media: sh_vou: fix pm_runtime_get_sync() usage count
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 6e8b1526db164c9d4b9dacfb9bc48e365d7c4860 ]
+
+The pm_runtime_get_sync() internally increments the
+dev->power.usage_count without decrementing it, even on errors.
+Replace it by the new pm_runtime_resume_and_get(), introduced by:
+commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter")
+in order to properly decrement the usage counter, avoiding
+a potential PM usage counter leak.
+
+While here, check if the PM runtime error was caught at open time.
+
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/sh_vou.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
+index 4ac48441f22c..ca4310e26c49 100644
+--- a/drivers/media/platform/sh_vou.c
++++ b/drivers/media/platform/sh_vou.c
+@@ -1133,7 +1133,11 @@ static int sh_vou_open(struct file *file)
+ if (v4l2_fh_is_singular_file(file) &&
+ vou_dev->status == SH_VOU_INITIALISING) {
+ /* First open */
+- pm_runtime_get_sync(vou_dev->v4l2_dev.dev);
++ err = pm_runtime_resume_and_get(vou_dev->v4l2_dev.dev);
++ if (err < 0) {
++ v4l2_fh_release(file);
++ goto done_open;
++ }
+ err = sh_vou_hw_init(vou_dev);
+ if (err < 0) {
+ pm_runtime_put(vou_dev->v4l2_dev.dev);
+--
+2.30.2
+
--- /dev/null
+From 721b4947d9e8844f71f6c6f9527314ef960d5841 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jun 2021 08:57:02 +0200
+Subject: media: siano: fix device register error path
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 5368b1ee2939961a16e74972b69088433fc52195 ]
+
+As reported by smatch:
+ drivers/media/common/siano/smsdvb-main.c:1231 smsdvb_hotplug() warn: '&client->entry' not removed from list
+
+If an error occur at the end of the registration logic, it won't
+drop the device from the list.
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/common/siano/smsdvb-main.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c
+index cd5bafe9a3ac..7e4100263381 100644
+--- a/drivers/media/common/siano/smsdvb-main.c
++++ b/drivers/media/common/siano/smsdvb-main.c
+@@ -1212,6 +1212,10 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
+ return 0;
+
+ media_graph_error:
++ mutex_lock(&g_smsdvb_clientslock);
++ list_del(&client->entry);
++ mutex_unlock(&g_smsdvb_clientslock);
++
+ smsdvb_debugfs_release(client);
+
+ client_error:
+--
+2.30.2
+
--- /dev/null
+From 7f6580a039e99b41bb5a9ff1f7b874383456bbd4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Mar 2021 19:40:43 -0600
+Subject: media: siano: Fix out-of-bounds warnings in
+ smscore_load_firmware_family2()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit 13dfead49db07225335d4f587a560a2210391a1a ]
+
+Rename struct sms_msg_data4 to sms_msg_data5 and increase the size of
+its msg_data array from 4 to 5 elements. Notice that at some point
+the 5th element of msg_data is being accessed in function
+smscore_load_firmware_family2():
+
+1006 trigger_msg->msg_data[4] = 4; /* Task ID */
+
+Also, there is no need for the object _trigger_msg_ of type struct
+sms_msg_data *, when _msg_ can be used, directly. Notice that msg_data
+in struct sms_msg_data is a one-element array, which causes multiple
+out-of-bounds warnings when accessing beyond its first element
+in function smscore_load_firmware_family2():
+
+ 992 struct sms_msg_data *trigger_msg =
+ 993 (struct sms_msg_data *) msg;
+ 994
+ 995 pr_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ\n");
+ 996 SMS_INIT_MSG(&msg->x_msg_header,
+ 997 MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
+ 998 sizeof(struct sms_msg_hdr) +
+ 999 sizeof(u32) * 5);
+1000
+1001 trigger_msg->msg_data[0] = firmware->start_address;
+1002 /* Entry point */
+1003 trigger_msg->msg_data[1] = 6; /* Priority */
+1004 trigger_msg->msg_data[2] = 0x200; /* Stack size */
+1005 trigger_msg->msg_data[3] = 0; /* Parameter */
+1006 trigger_msg->msg_data[4] = 4; /* Task ID */
+
+even when enough dynamic memory is allocated for _msg_:
+
+ 929 /* PAGE_SIZE buffer shall be enough and dma aligned */
+ 930 msg = kmalloc(PAGE_SIZE, GFP_KERNEL | coredev->gfp_buf_flags);
+
+but as _msg_ is casted to (struct sms_msg_data *):
+
+ 992 struct sms_msg_data *trigger_msg =
+ 993 (struct sms_msg_data *) msg;
+
+the out-of-bounds warnings are actually valid and should be addressed.
+
+Fix this by declaring object _msg_ of type struct sms_msg_data5 *,
+which contains a 5-elements array, instead of just 4. And use
+_msg_ directly, instead of creating object trigger_msg.
+
+This helps with the ongoing efforts to enable -Warray-bounds by fixing
+the following warnings:
+
+ CC [M] drivers/media/common/siano/smscoreapi.o
+drivers/media/common/siano/smscoreapi.c: In function ‘smscore_load_firmware_family2’:
+drivers/media/common/siano/smscoreapi.c:1003:24: warning: array subscript 1 is above array bounds of ‘u32[1]’ {aka ‘unsigned int[1]’} [-Warray-bounds]
+ 1003 | trigger_msg->msg_data[1] = 6; /* Priority */
+ | ~~~~~~~~~~~~~~~~~~~~~^~~
+In file included from drivers/media/common/siano/smscoreapi.c:12:
+drivers/media/common/siano/smscoreapi.h:619:6: note: while referencing ‘msg_data’
+ 619 | u32 msg_data[1];
+ | ^~~~~~~~
+drivers/media/common/siano/smscoreapi.c:1004:24: warning: array subscript 2 is above array bounds of ‘u32[1]’ {aka ‘unsigned int[1]’} [-Warray-bounds]
+ 1004 | trigger_msg->msg_data[2] = 0x200; /* Stack size */
+ | ~~~~~~~~~~~~~~~~~~~~~^~~
+In file included from drivers/media/common/siano/smscoreapi.c:12:
+drivers/media/common/siano/smscoreapi.h:619:6: note: while referencing ‘msg_data’
+ 619 | u32 msg_data[1];
+ | ^~~~~~~~
+drivers/media/common/siano/smscoreapi.c:1005:24: warning: array subscript 3 is above array bounds of ‘u32[1]’ {aka ‘unsigned int[1]’} [-Warray-bounds]
+ 1005 | trigger_msg->msg_data[3] = 0; /* Parameter */
+ | ~~~~~~~~~~~~~~~~~~~~~^~~
+In file included from drivers/media/common/siano/smscoreapi.c:12:
+drivers/media/common/siano/smscoreapi.h:619:6: note: while referencing ‘msg_data’
+ 619 | u32 msg_data[1];
+ | ^~~~~~~~
+drivers/media/common/siano/smscoreapi.c:1006:24: warning: array subscript 4 is above array bounds of ‘u32[1]’ {aka ‘unsigned int[1]’} [-Warray-bounds]
+ 1006 | trigger_msg->msg_data[4] = 4; /* Task ID */
+ | ~~~~~~~~~~~~~~~~~~~~~^~~
+In file included from drivers/media/common/siano/smscoreapi.c:12:
+drivers/media/common/siano/smscoreapi.h:619:6: note: while referencing ‘msg_data’
+ 619 | u32 msg_data[1];
+ | ^~~~~~~~
+
+Fixes: 018b0c6f8acb ("[media] siano: make load firmware logic to work with newer firmwares")
+Co-developed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/common/siano/smscoreapi.c | 22 +++++++++-------------
+ drivers/media/common/siano/smscoreapi.h | 4 ++--
+ 2 files changed, 11 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c
+index 410cc3ac6f94..bceaf91faa15 100644
+--- a/drivers/media/common/siano/smscoreapi.c
++++ b/drivers/media/common/siano/smscoreapi.c
+@@ -908,7 +908,7 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
+ void *buffer, size_t size)
+ {
+ struct sms_firmware *firmware = (struct sms_firmware *) buffer;
+- struct sms_msg_data4 *msg;
++ struct sms_msg_data5 *msg;
+ u32 mem_address, calc_checksum = 0;
+ u32 i, *ptr;
+ u8 *payload = firmware->payload;
+@@ -989,24 +989,20 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
+ goto exit_fw_download;
+
+ if (coredev->mode == DEVICE_MODE_NONE) {
+- struct sms_msg_data *trigger_msg =
+- (struct sms_msg_data *) msg;
+-
+ pr_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ\n");
+ SMS_INIT_MSG(&msg->x_msg_header,
+ MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
+- sizeof(struct sms_msg_hdr) +
+- sizeof(u32) * 5);
++ sizeof(*msg));
+
+- trigger_msg->msg_data[0] = firmware->start_address;
++ msg->msg_data[0] = firmware->start_address;
+ /* Entry point */
+- trigger_msg->msg_data[1] = 6; /* Priority */
+- trigger_msg->msg_data[2] = 0x200; /* Stack size */
+- trigger_msg->msg_data[3] = 0; /* Parameter */
+- trigger_msg->msg_data[4] = 4; /* Task ID */
++ msg->msg_data[1] = 6; /* Priority */
++ msg->msg_data[2] = 0x200; /* Stack size */
++ msg->msg_data[3] = 0; /* Parameter */
++ msg->msg_data[4] = 4; /* Task ID */
+
+- rc = smscore_sendrequest_and_wait(coredev, trigger_msg,
+- trigger_msg->x_msg_header.msg_length,
++ rc = smscore_sendrequest_and_wait(coredev, msg,
++ msg->x_msg_header.msg_length,
+ &coredev->trigger_done);
+ } else {
+ SMS_INIT_MSG(&msg->x_msg_header, MSG_SW_RELOAD_EXEC_REQ,
+diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h
+index 4a6b9f4c44ac..f8789ee0d554 100644
+--- a/drivers/media/common/siano/smscoreapi.h
++++ b/drivers/media/common/siano/smscoreapi.h
+@@ -624,9 +624,9 @@ struct sms_msg_data2 {
+ u32 msg_data[2];
+ };
+
+-struct sms_msg_data4 {
++struct sms_msg_data5 {
+ struct sms_msg_hdr x_msg_header;
+- u32 msg_data[4];
++ u32 msg_data[5];
+ };
+
+ struct sms_data_download {
+--
+2.30.2
+
--- /dev/null
+From d0c105e0764664a16a0c241aa0c06fb127e24f4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 May 2021 14:04:49 +0200
+Subject: media: st-hva: Fix potential NULL pointer dereferences
+
+From: Evgeny Novikov <novikov@ispras.ru>
+
+[ Upstream commit b7fdd208687ba59ebfb09b2199596471c63b69e3 ]
+
+When ctx_id >= HVA_MAX_INSTANCES in hva_hw_its_irq_thread() it tries to
+access fields of ctx that is NULL at that point. The patch gets rid of
+these accesses.
+
+Found by Linux Driver Verification project (linuxtesting.org).
+
+Signed-off-by: Evgeny Novikov <novikov@ispras.ru>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/sti/hva/hva-hw.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/sti/hva/hva-hw.c b/drivers/media/platform/sti/hva/hva-hw.c
+index f59811e27f51..6eeee5017fac 100644
+--- a/drivers/media/platform/sti/hva/hva-hw.c
++++ b/drivers/media/platform/sti/hva/hva-hw.c
+@@ -130,8 +130,7 @@ static irqreturn_t hva_hw_its_irq_thread(int irq, void *arg)
+ ctx_id = (hva->sts_reg & 0xFF00) >> 8;
+ if (ctx_id >= HVA_MAX_INSTANCES) {
+ dev_err(dev, "%s %s: bad context identifier: %d\n",
+- ctx->name, __func__, ctx_id);
+- ctx->hw_err = true;
++ HVA_PREFIX, __func__, ctx_id);
+ goto out;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 7607cfecede08028749a685a076cb3c70d46fe6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 17:19:21 +0200
+Subject: media: sti/bdisp: fix pm_runtime_get_sync() usage count
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit c44eac5b72e23c31eefc0e10a71d9650036b8341 ]
+
+The pm_runtime_get_sync() internally increments the
+dev->power.usage_count without decrementing it, even on errors.
+
+The bdisp_start_streaming() doesn't take it into account, which
+would unbalance PM usage counter at bdisp_stop_streaming().
+
+The logic at bdisp_probe() is correct, but the best is to use
+the same call along the driver.
+
+So, replace it by the new pm_runtime_resume_and_get(), introduced by:
+commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter")
+in order to properly decrement the usage counter, avoiding
+a potential PM usage counter leak.
+
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
+index 060ca85f64d5..85288da9d2ae 100644
+--- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
++++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
+@@ -499,7 +499,7 @@ static int bdisp_start_streaming(struct vb2_queue *q, unsigned int count)
+ {
+ struct bdisp_ctx *ctx = q->drv_priv;
+ struct vb2_v4l2_buffer *buf;
+- int ret = pm_runtime_get_sync(ctx->bdisp_dev->dev);
++ int ret = pm_runtime_resume_and_get(ctx->bdisp_dev->dev);
+
+ if (ret < 0) {
+ dev_err(ctx->bdisp_dev->dev, "failed to set runtime PM\n");
+@@ -1364,10 +1364,10 @@ static int bdisp_probe(struct platform_device *pdev)
+
+ /* Power management */
+ pm_runtime_enable(dev);
+- ret = pm_runtime_get_sync(dev);
++ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0) {
+ dev_err(dev, "failed to set PM\n");
+- goto err_pm;
++ goto err_remove;
+ }
+
+ /* Filters */
+@@ -1395,6 +1395,7 @@ err_filter:
+ bdisp_hw_free_filters(bdisp->dev);
+ err_pm:
+ pm_runtime_put(dev);
++err_remove:
+ bdisp_debugfs_remove(bdisp);
+ v4l2_device_unregister(&bdisp->v4l2_dev);
+ err_clk:
+--
+2.30.2
+
--- /dev/null
+From b9043daafceeaefab79c7ee361044c73be457634 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 May 2021 11:26:31 +0200
+Subject: media: sti: fix obj-$(config) targets
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 56c1f0876293888f686e31278d183d4af2cac3c3 ]
+
+The right thing to do is to add a new object to the building
+system when a certain config option is selected, and *not*
+override them.
+
+So, fix obj-$(config) logic at sti makefiles, using "+=",
+instead of ":=".
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/sti/bdisp/Makefile | 2 +-
+ drivers/media/platform/sti/delta/Makefile | 2 +-
+ drivers/media/platform/sti/hva/Makefile | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/platform/sti/bdisp/Makefile b/drivers/media/platform/sti/bdisp/Makefile
+index caf7ccd193ea..39ade0a34723 100644
+--- a/drivers/media/platform/sti/bdisp/Makefile
++++ b/drivers/media/platform/sti/bdisp/Makefile
+@@ -1,4 +1,4 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+-obj-$(CONFIG_VIDEO_STI_BDISP) := bdisp.o
++obj-$(CONFIG_VIDEO_STI_BDISP) += bdisp.o
+
+ bdisp-objs := bdisp-v4l2.o bdisp-hw.o bdisp-debug.o
+diff --git a/drivers/media/platform/sti/delta/Makefile b/drivers/media/platform/sti/delta/Makefile
+index 92b37e216f00..32412fa4c632 100644
+--- a/drivers/media/platform/sti/delta/Makefile
++++ b/drivers/media/platform/sti/delta/Makefile
+@@ -1,5 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+-obj-$(CONFIG_VIDEO_STI_DELTA_DRIVER) := st-delta.o
++obj-$(CONFIG_VIDEO_STI_DELTA_DRIVER) += st-delta.o
+ st-delta-y := delta-v4l2.o delta-mem.o delta-ipc.o delta-debug.o
+
+ # MJPEG support
+diff --git a/drivers/media/platform/sti/hva/Makefile b/drivers/media/platform/sti/hva/Makefile
+index 74b41ec52f97..b5a5478bdd01 100644
+--- a/drivers/media/platform/sti/hva/Makefile
++++ b/drivers/media/platform/sti/hva/Makefile
+@@ -1,4 +1,4 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+-obj-$(CONFIG_VIDEO_STI_HVA) := st-hva.o
++obj-$(CONFIG_VIDEO_STI_HVA) += st-hva.o
+ st-hva-y := hva-v4l2.o hva-hw.o hva-mem.o hva-h264.o
+ st-hva-$(CONFIG_VIDEO_STI_HVA_DEBUGFS) += hva-debugfs.o
+--
+2.30.2
+
--- /dev/null
+From 1254757d75a39001823d3523547258dac1c48e60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 12:34:05 +0200
+Subject: media: subdev: remove VIDIOC_DQEVENT_TIME32 handling
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 765ba251d2522e2a0daa2f0793fd0f0ce34816ec ]
+
+Converting the VIDIOC_DQEVENT_TIME32/VIDIOC_DQEVENT32/
+VIDIOC_DQEVENT32_TIME32 arguments to the canonical form is done in common
+code, but for some reason I ended up adding another conversion helper to
+subdev_do_ioctl() as well. I must have concluded that this does not go
+through the common conversion, but it has done that since the ioctl
+handler was first added.
+
+I assume this one is harmless as there should be no way to arrive here
+from user space if CONFIG_COMPAT_32BIT_TIME is set, but since it is dead
+code, it should just get removed.
+
+On a 64-bit architecture, as well as a 32-bit architecture without
+CONFIG_COMPAT_32BIT_TIME, handling this command is a mistake,
+and the kernel should return an error.
+
+Fixes: 1a6c0b36dd19 ("media: v4l2-core: fix VIDIOC_DQEVENT for time64 ABI")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/v4l2-core/v4l2-subdev.c | 24 ------------------------
+ 1 file changed, 24 deletions(-)
+
+diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
+index 956dafab43d4..bf3aa9252458 100644
+--- a/drivers/media/v4l2-core/v4l2-subdev.c
++++ b/drivers/media/v4l2-core/v4l2-subdev.c
+@@ -428,30 +428,6 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
+
+ return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK);
+
+- case VIDIOC_DQEVENT_TIME32: {
+- struct v4l2_event_time32 *ev32 = arg;
+- struct v4l2_event ev = { };
+-
+- if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
+- return -ENOIOCTLCMD;
+-
+- rval = v4l2_event_dequeue(vfh, &ev, file->f_flags & O_NONBLOCK);
+-
+- *ev32 = (struct v4l2_event_time32) {
+- .type = ev.type,
+- .pending = ev.pending,
+- .sequence = ev.sequence,
+- .timestamp.tv_sec = ev.timestamp.tv_sec,
+- .timestamp.tv_nsec = ev.timestamp.tv_nsec,
+- .id = ev.id,
+- };
+-
+- memcpy(&ev32->u, &ev.u, sizeof(ev.u));
+- memcpy(&ev32->reserved, &ev.reserved, sizeof(ev.reserved));
+-
+- return rval;
+- }
+-
+ case VIDIOC_SUBSCRIBE_EVENT:
+ return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);
+
+--
+2.30.2
+
--- /dev/null
+From e1ad6255155f4ab8a8451baf59e0fcc9e7e8f322 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 17:19:10 +0200
+Subject: media: sunxi: fix pm_runtime_get_sync() usage count
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 9c298f82d8392f799a0595f50076afa1d91e9092 ]
+
+The pm_runtime_get_sync() internally increments the
+dev->power.usage_count without decrementing it, even on errors.
+Replace it by the new pm_runtime_resume_and_get(), introduced by:
+commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter")
+in order to properly decrement the usage counter, avoiding
+a potential PM usage counter leak.
+
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c b/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c
+index 3f81dd17755c..fbcca59a0517 100644
+--- a/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c
++++ b/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c
+@@ -494,7 +494,7 @@ static int rotate_start_streaming(struct vb2_queue *vq, unsigned int count)
+ struct device *dev = ctx->dev->dev;
+ int ret;
+
+- ret = pm_runtime_get_sync(dev);
++ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0) {
+ dev_err(dev, "Failed to enable module\n");
+
+--
+2.30.2
+
--- /dev/null
+From 479b07bbcc949bc95253e8b8bb79d502bd249c5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 May 2021 08:58:30 +0200
+Subject: media: tc358743: Fix error return code in tc358743_probe_of()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit a6b1e7093f0a099571fc8836ab4a589633f956a8 ]
+
+When the CSI bps per lane is not in the valid range, an appropriate error
+code -EINVAL should be returned. However, we currently do not explicitly
+assign this error code to 'ret'. As a result, 0 was incorrectly returned.
+
+Fixes: 256148246852 ("[media] tc358743: support probe from device tree")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/tc358743.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
+index 1b309bb743c7..f21da11caf22 100644
+--- a/drivers/media/i2c/tc358743.c
++++ b/drivers/media/i2c/tc358743.c
+@@ -1974,6 +1974,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
+ bps_pr_lane = 2 * endpoint.link_frequencies[0];
+ if (bps_pr_lane < 62500000U || bps_pr_lane > 1000000000U) {
+ dev_err(dev, "unsupported bps per lane: %u bps\n", bps_pr_lane);
++ ret = -EINVAL;
+ goto disable_clk;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 782c1509010bf1b9f6e34282c1e8aed52dc527b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 May 2021 10:24:02 +0200
+Subject: media: v4l2-core: Avoid the dangling pointer in v4l2_fh_release
+
+From: Lv Yunlong <lyl2019@mail.ustc.edu.cn>
+
+[ Upstream commit 7dd0c9e547b6924e18712b6b51aa3cba1896ee2c ]
+
+A use after free bug caused by the dangling pointer
+filp->privitate_data in v4l2_fh_release.
+See https://lore.kernel.org/patchwork/patch/1419058/.
+
+My patch sets the dangling pointer to NULL to provide
+robust.
+
+Signed-off-by: Lv Yunlong <lyl2019@mail.ustc.edu.cn>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/v4l2-core/v4l2-fh.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/v4l2-core/v4l2-fh.c b/drivers/media/v4l2-core/v4l2-fh.c
+index 684574f58e82..90eec79ee995 100644
+--- a/drivers/media/v4l2-core/v4l2-fh.c
++++ b/drivers/media/v4l2-core/v4l2-fh.c
+@@ -96,6 +96,7 @@ int v4l2_fh_release(struct file *filp)
+ v4l2_fh_del(fh);
+ v4l2_fh_exit(fh);
+ kfree(fh);
++ filp->private_data = NULL;
+ }
+ return 0;
+ }
+--
+2.30.2
+
--- /dev/null
+From 48b1448120b02180778ae6713ad46d0e42c3a3dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 12:34:02 +0200
+Subject: media: v4l2-core: ignore native time32 ioctls on 64-bit
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit c344f07aa1b4ba38ca8fabe407a2afe2f436323c ]
+
+Syzbot found that passing ioctl command 0xc0505609 into a 64-bit
+kernel from a 32-bit process causes uninitialized kernel memory to
+get passed to drivers instead of the user space data:
+
+BUG: KMSAN: uninit-value in check_array_args drivers/media/v4l2-core/v4l2-ioctl.c:3041 [inline]
+BUG: KMSAN: uninit-value in video_usercopy+0x1631/0x3d30 drivers/media/v4l2-core/v4l2-ioctl.c:3315
+CPU: 0 PID: 19595 Comm: syz-executor.4 Not tainted 5.11.0-rc7-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:79 [inline]
+ dump_stack+0x21c/0x280 lib/dump_stack.c:120
+ kmsan_report+0xfb/0x1e0 mm/kmsan/kmsan_report.c:118
+ __msan_warning+0x5f/0xa0 mm/kmsan/kmsan_instr.c:197
+ check_array_args drivers/media/v4l2-core/v4l2-ioctl.c:3041 [inline]
+ video_usercopy+0x1631/0x3d30 drivers/media/v4l2-core/v4l2-ioctl.c:3315
+ video_ioctl2+0x9f/0xb0 drivers/media/v4l2-core/v4l2-ioctl.c:3391
+ v4l2_ioctl+0x255/0x290 drivers/media/v4l2-core/v4l2-dev.c:360
+ v4l2_compat_ioctl32+0x2c6/0x370 drivers/media/v4l2-core/v4l2-compat-ioctl32.c:1248
+ __do_compat_sys_ioctl fs/ioctl.c:842 [inline]
+ __se_compat_sys_ioctl+0x53d/0x1100 fs/ioctl.c:793
+ __ia32_compat_sys_ioctl+0x4a/0x70 fs/ioctl.c:793
+ do_syscall_32_irqs_on arch/x86/entry/common.c:79 [inline]
+ __do_fast_syscall_32+0x102/0x160 arch/x86/entry/common.c:141
+ do_fast_syscall_32+0x6a/0xc0 arch/x86/entry/common.c:166
+ do_SYSENTER_32+0x73/0x90 arch/x86/entry/common.c:209
+ entry_SYSENTER_compat_after_hwframe+0x4d/0x5c
+
+The time32 commands are defined but were never meant to be called on
+64-bit machines, as those have always used time64 interfaces. I missed
+this in my patch that introduced the time64 handling on 32-bit platforms.
+
+The problem in this case is the mismatch of one function checking for
+the numeric value of the command and another function checking for the
+type of process (native vs compat) instead, with the result being that
+for this combination, nothing gets copied into the buffer at all.
+
+Avoid this by only trying to convert the time32 commands when running
+on a 32-bit kernel where these are defined in a meaningful way.
+
+[hverkuil: fix 3 warnings: switch with no cases]
+
+Fixes: 577c89b0ce72 ("media: v4l2-core: fix v4l2_buffer handling for time64 ABI")
+Reported-by: syzbot+142888ffec98ab194028@syzkaller.appspotmail.com
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/v4l2-core/v4l2-ioctl.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
+index 2673f51aafa4..07d823656ee6 100644
+--- a/drivers/media/v4l2-core/v4l2-ioctl.c
++++ b/drivers/media/v4l2-core/v4l2-ioctl.c
+@@ -3072,8 +3072,8 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
+
+ static unsigned int video_translate_cmd(unsigned int cmd)
+ {
++#if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
+ switch (cmd) {
+-#ifdef CONFIG_COMPAT_32BIT_TIME
+ case VIDIOC_DQEVENT_TIME32:
+ return VIDIOC_DQEVENT;
+ case VIDIOC_QUERYBUF_TIME32:
+@@ -3084,8 +3084,8 @@ static unsigned int video_translate_cmd(unsigned int cmd)
+ return VIDIOC_DQBUF;
+ case VIDIOC_PREPARE_BUF_TIME32:
+ return VIDIOC_PREPARE_BUF;
+-#endif
+ }
++#endif
+ if (in_compat_syscall())
+ return v4l2_compat_translate_cmd(cmd);
+
+@@ -3126,8 +3126,8 @@ static int video_get_user(void __user *arg, void *parg,
+ } else if (in_compat_syscall()) {
+ err = v4l2_compat_get_user(arg, parg, cmd);
+ } else {
++#if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
+ switch (cmd) {
+-#ifdef CONFIG_COMPAT_32BIT_TIME
+ case VIDIOC_QUERYBUF_TIME32:
+ case VIDIOC_QBUF_TIME32:
+ case VIDIOC_DQBUF_TIME32:
+@@ -3155,8 +3155,8 @@ static int video_get_user(void __user *arg, void *parg,
+ };
+ break;
+ }
+-#endif
+ }
++#endif
+ }
+
+ /* zero out anything we don't copy from userspace */
+@@ -3181,8 +3181,8 @@ static int video_put_user(void __user *arg, void *parg,
+ if (in_compat_syscall())
+ return v4l2_compat_put_user(arg, parg, cmd);
+
++#if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
+ switch (cmd) {
+-#ifdef CONFIG_COMPAT_32BIT_TIME
+ case VIDIOC_DQEVENT_TIME32: {
+ struct v4l2_event *ev = parg;
+ struct v4l2_event_time32 ev32;
+@@ -3230,8 +3230,8 @@ static int video_put_user(void __user *arg, void *parg,
+ return -EFAULT;
+ break;
+ }
+-#endif
+ }
++#endif
+
+ return 0;
+ }
+--
+2.30.2
+
--- /dev/null
+From 4f8065576d2cda31c9c257e4856428aceb348453 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Apr 2021 23:50:20 +0200
+Subject: media: venus: hfi_cmds: Fix conceal color property
+
+From: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+
+[ Upstream commit 6e2202ca1ee034920b029124151754aec67b61ba ]
+
+The conceal color property used for Venus v4 and v6 has the same
+payload structure. But currently v4 follow down to payload
+structure for v1. Correct this by moving set_property to v4.
+
+Fixes: 4ef6039fad8f ("media: venus: vdec: Add support for conceal control")
+Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/qcom/venus/hfi_cmds.c | 22 ++++++++++----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c b/drivers/media/platform/qcom/venus/hfi_cmds.c
+index 11a8347e5f5c..4b9dea7f6940 100644
+--- a/drivers/media/platform/qcom/venus/hfi_cmds.c
++++ b/drivers/media/platform/qcom/venus/hfi_cmds.c
+@@ -1226,6 +1226,17 @@ pkt_session_set_property_4xx(struct hfi_session_set_property_pkt *pkt,
+ pkt->shdr.hdr.size += sizeof(u32) + sizeof(*hdr10);
+ break;
+ }
++ case HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR: {
++ struct hfi_conceal_color_v4 *color = prop_data;
++ u32 *in = pdata;
++
++ color->conceal_color_8bit = *in & 0xff;
++ color->conceal_color_8bit |= ((*in >> 10) & 0xff) << 8;
++ color->conceal_color_8bit |= ((*in >> 20) & 0xff) << 16;
++ color->conceal_color_10bit = *in;
++ pkt->shdr.hdr.size += sizeof(u32) + sizeof(*color);
++ break;
++ }
+
+ case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE:
+ case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER:
+@@ -1279,17 +1290,6 @@ pkt_session_set_property_6xx(struct hfi_session_set_property_pkt *pkt,
+ pkt->shdr.hdr.size += sizeof(u32) + sizeof(*cq);
+ break;
+ }
+- case HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR: {
+- struct hfi_conceal_color_v4 *color = prop_data;
+- u32 *in = pdata;
+-
+- color->conceal_color_8bit = *in & 0xff;
+- color->conceal_color_8bit |= ((*in >> 10) & 0xff) << 8;
+- color->conceal_color_8bit |= ((*in >> 20) & 0xff) << 16;
+- color->conceal_color_10bit = *in;
+- pkt->shdr.hdr.size += sizeof(u32) + sizeof(*color);
+- break;
+- }
+ default:
+ return pkt_session_set_property_4xx(pkt, cookie, ptype, pdata);
+ }
+--
+2.30.2
+
--- /dev/null
+From 56ab6497a0f63e5ddd3f94497c48ab2dbf3333ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Apr 2021 10:39:47 +0200
+Subject: media: venus: Rework error fail recover logic
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 4cba5473c5ce0f1389d316c5dc6f83a0259df5eb ]
+
+The Venus code has a sort of watchdog that attempts to recover
+from IP errors, implemented as a delayed work job, which
+calls venus_sys_error_handler().
+
+Right now, it has several issues:
+
+1. It assumes that PM runtime resume never fails
+
+2. It internally runs two while() loops that also assume that
+ PM runtime will never fail to go idle:
+
+ while (pm_runtime_active(core->dev_dec) || pm_runtime_active(core->dev_enc))
+ msleep(10);
+
+...
+
+ while (core->pmdomains[0] && pm_runtime_active(core->pmdomains[0]))
+ usleep_range(1000, 1500);
+
+3. It uses an OR to merge all return codes and then report to the user
+
+4. If the hardware never recovers, it keeps running on every 10ms,
+ flooding the syslog with 2 messages (so, up to 200 messages
+ per second).
+
+Rework the code, in order to prevent that, by:
+
+1. check the return code from PM runtime resume;
+2. don't let the while() loops run forever;
+3. store the failed event;
+4. use warn ratelimited when it fails to recover.
+
+Fixes: af2c3834c8ca ("[media] media: venus: adding core part and helper functions")
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/qcom/venus/core.c | 60 +++++++++++++++++++-----
+ 1 file changed, 47 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
+index 54bac7ec14c5..91b15842c555 100644
+--- a/drivers/media/platform/qcom/venus/core.c
++++ b/drivers/media/platform/qcom/venus/core.c
+@@ -78,22 +78,32 @@ static const struct hfi_core_ops venus_core_ops = {
+ .event_notify = venus_event_notify,
+ };
+
++#define RPM_WAIT_FOR_IDLE_MAX_ATTEMPTS 10
++
+ static void venus_sys_error_handler(struct work_struct *work)
+ {
+ struct venus_core *core =
+ container_of(work, struct venus_core, work.work);
+- int ret = 0;
+-
+- pm_runtime_get_sync(core->dev);
++ int ret, i, max_attempts = RPM_WAIT_FOR_IDLE_MAX_ATTEMPTS;
++ const char *err_msg = "";
++ bool failed = false;
++
++ ret = pm_runtime_get_sync(core->dev);
++ if (ret < 0) {
++ err_msg = "resume runtime PM";
++ max_attempts = 0;
++ failed = true;
++ }
+
+ hfi_core_deinit(core, true);
+
+- dev_warn(core->dev, "system error has occurred, starting recovery!\n");
+-
+ mutex_lock(&core->lock);
+
+- while (pm_runtime_active(core->dev_dec) || pm_runtime_active(core->dev_enc))
++ for (i = 0; i < max_attempts; i++) {
++ if (!pm_runtime_active(core->dev_dec) && !pm_runtime_active(core->dev_enc))
++ break;
+ msleep(10);
++ }
+
+ venus_shutdown(core);
+
+@@ -101,31 +111,55 @@ static void venus_sys_error_handler(struct work_struct *work)
+
+ pm_runtime_put_sync(core->dev);
+
+- while (core->pmdomains[0] && pm_runtime_active(core->pmdomains[0]))
++ for (i = 0; i < max_attempts; i++) {
++ if (!core->pmdomains[0] || !pm_runtime_active(core->pmdomains[0]))
++ break;
+ usleep_range(1000, 1500);
++ }
+
+ hfi_reinit(core);
+
+- pm_runtime_get_sync(core->dev);
++ ret = pm_runtime_get_sync(core->dev);
++ if (ret < 0) {
++ err_msg = "resume runtime PM";
++ failed = true;
++ }
+
+- ret |= venus_boot(core);
+- ret |= hfi_core_resume(core, true);
++ ret = venus_boot(core);
++ if (ret && !failed) {
++ err_msg = "boot Venus";
++ failed = true;
++ }
++
++ ret = hfi_core_resume(core, true);
++ if (ret && !failed) {
++ err_msg = "resume HFI";
++ failed = true;
++ }
+
+ enable_irq(core->irq);
+
+ mutex_unlock(&core->lock);
+
+- ret |= hfi_core_init(core);
++ ret = hfi_core_init(core);
++ if (ret && !failed) {
++ err_msg = "init HFI";
++ failed = true;
++ }
+
+ pm_runtime_put_sync(core->dev);
+
+- if (ret) {
++ if (failed) {
+ disable_irq_nosync(core->irq);
+- dev_warn(core->dev, "recovery failed (%d)\n", ret);
++ dev_warn_ratelimited(core->dev,
++ "System error has occurred, recovery failed to %s\n",
++ err_msg);
+ schedule_delayed_work(&core->work, msecs_to_jiffies(10));
+ return;
+ }
+
++ dev_warn(core->dev, "system error has occurred (recovered)\n");
++
+ mutex_lock(&core->lock);
+ core->sys_error = false;
+ mutex_unlock(&core->lock);
+--
+2.30.2
+
--- /dev/null
+From 8933ac3f825be35390c1756d7ca628967cd27123 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 10:58:46 +0200
+Subject: media: vicodec: Use _BITUL() macro in UAPI headers
+
+From: Joe Richey <joerichey@google.com>
+
+[ Upstream commit ce67eaca95f8ab5c6aae41a10adfe9a6e8efa58c ]
+
+Replace BIT() in v4l2's UPAI header with _BITUL(). BIT() is not defined
+in the UAPI headers and its usage may cause userspace build errors.
+
+Fixes: 206bc0f6fb94 ("media: vicodec: mark the stateless FWHT API as stable")
+Signed-off-by: Joe Richey <joerichey@google.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/v4l2-controls.h | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
+index d43bec5f1afd..5afc19c68704 100644
+--- a/include/uapi/linux/v4l2-controls.h
++++ b/include/uapi/linux/v4l2-controls.h
+@@ -50,6 +50,7 @@
+ #ifndef __LINUX_V4L2_CONTROLS_H
+ #define __LINUX_V4L2_CONTROLS_H
+
++#include <linux/const.h>
+ #include <linux/types.h>
+
+ /* Control classes */
+@@ -1602,30 +1603,30 @@ struct v4l2_ctrl_h264_decode_params {
+ #define V4L2_FWHT_VERSION 3
+
+ /* Set if this is an interlaced format */
+-#define V4L2_FWHT_FL_IS_INTERLACED BIT(0)
++#define V4L2_FWHT_FL_IS_INTERLACED _BITUL(0)
+ /* Set if this is a bottom-first (NTSC) interlaced format */
+-#define V4L2_FWHT_FL_IS_BOTTOM_FIRST BIT(1)
++#define V4L2_FWHT_FL_IS_BOTTOM_FIRST _BITUL(1)
+ /* Set if each 'frame' contains just one field */
+-#define V4L2_FWHT_FL_IS_ALTERNATE BIT(2)
++#define V4L2_FWHT_FL_IS_ALTERNATE _BITUL(2)
+ /*
+ * If V4L2_FWHT_FL_IS_ALTERNATE was set, then this is set if this
+ * 'frame' is the bottom field, else it is the top field.
+ */
+-#define V4L2_FWHT_FL_IS_BOTTOM_FIELD BIT(3)
++#define V4L2_FWHT_FL_IS_BOTTOM_FIELD _BITUL(3)
+ /* Set if the Y' plane is uncompressed */
+-#define V4L2_FWHT_FL_LUMA_IS_UNCOMPRESSED BIT(4)
++#define V4L2_FWHT_FL_LUMA_IS_UNCOMPRESSED _BITUL(4)
+ /* Set if the Cb plane is uncompressed */
+-#define V4L2_FWHT_FL_CB_IS_UNCOMPRESSED BIT(5)
++#define V4L2_FWHT_FL_CB_IS_UNCOMPRESSED _BITUL(5)
+ /* Set if the Cr plane is uncompressed */
+-#define V4L2_FWHT_FL_CR_IS_UNCOMPRESSED BIT(6)
++#define V4L2_FWHT_FL_CR_IS_UNCOMPRESSED _BITUL(6)
+ /* Set if the chroma plane is full height, if cleared it is half height */
+-#define V4L2_FWHT_FL_CHROMA_FULL_HEIGHT BIT(7)
++#define V4L2_FWHT_FL_CHROMA_FULL_HEIGHT _BITUL(7)
+ /* Set if the chroma plane is full width, if cleared it is half width */
+-#define V4L2_FWHT_FL_CHROMA_FULL_WIDTH BIT(8)
++#define V4L2_FWHT_FL_CHROMA_FULL_WIDTH _BITUL(8)
+ /* Set if the alpha plane is uncompressed */
+-#define V4L2_FWHT_FL_ALPHA_IS_UNCOMPRESSED BIT(9)
++#define V4L2_FWHT_FL_ALPHA_IS_UNCOMPRESSED _BITUL(9)
+ /* Set if this is an I Frame */
+-#define V4L2_FWHT_FL_I_FRAME BIT(10)
++#define V4L2_FWHT_FL_I_FRAME _BITUL(10)
+
+ /* A 4-values flag - the number of components - 1 */
+ #define V4L2_FWHT_FL_COMPONENTS_NUM_MSK GENMASK(18, 16)
+--
+2.30.2
+
--- /dev/null
+From 629fe8ae41f6e6af95e256f7d5bd0bb8e2154aae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Mar 2021 15:44:08 +0100
+Subject: media: video-mux: Skip dangling endpoints
+
+From: Philipp Zabel <p.zabel@pengutronix.de>
+
+[ Upstream commit 95778c2d0979618e3349b1d2324ec282a5a6adbf ]
+
+i.MX6 device tree include files contain dangling endpoints for the
+board device tree writers' convenience. These are still included in
+many existing device trees.
+Treat dangling endpoints as non-existent to support them.
+
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Fixes: 612b385efb1e ("media: video-mux: Create media links in bound notifier")
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/video-mux.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c
+index 133122e38515..9bc0b4d8de09 100644
+--- a/drivers/media/platform/video-mux.c
++++ b/drivers/media/platform/video-mux.c
+@@ -362,7 +362,7 @@ static int video_mux_async_register(struct video_mux *vmux,
+
+ for (i = 0; i < num_input_pads; i++) {
+ struct v4l2_async_subdev *asd;
+- struct fwnode_handle *ep;
++ struct fwnode_handle *ep, *remote_ep;
+
+ ep = fwnode_graph_get_endpoint_by_id(
+ dev_fwnode(vmux->subdev.dev), i, 0,
+@@ -370,6 +370,14 @@ static int video_mux_async_register(struct video_mux *vmux,
+ if (!ep)
+ continue;
+
++ /* Skip dangling endpoints for backwards compatibility */
++ remote_ep = fwnode_graph_get_remote_endpoint(ep);
++ if (!remote_ep) {
++ fwnode_handle_put(ep);
++ continue;
++ }
++ fwnode_handle_put(remote_ep);
++
+ asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+ &vmux->notifier, ep, struct v4l2_async_subdev);
+
+--
+2.30.2
+
--- /dev/null
+From 5e0337be685dc38d94de2f09c6d9899d67e8aae7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 May 2021 12:39:45 -0400
+Subject: memstick: rtsx_usb_ms: fix UAF
+
+From: Tong Zhang <ztong0001@gmail.com>
+
+[ Upstream commit 42933c8aa14be1caa9eda41f65cde8a3a95d3e39 ]
+
+This patch fixes the following issues:
+1. memstick_free_host() will free the host, so the use of ms_dev(host) after
+it will be a problem. To fix this, move memstick_free_host() after when we
+are done with ms_dev(host).
+2. In rtsx_usb_ms_drv_remove(), pm need to be disabled before we remove
+and free host otherwise memstick_check will be called and UAF will
+happen.
+
+[ 11.351173] BUG: KASAN: use-after-free in rtsx_usb_ms_drv_remove+0x94/0x140 [rtsx_usb_ms]
+[ 11.357077] rtsx_usb_ms_drv_remove+0x94/0x140 [rtsx_usb_ms]
+[ 11.357376] platform_remove+0x2a/0x50
+[ 11.367531] Freed by task 298:
+[ 11.368537] kfree+0xa4/0x2a0
+[ 11.368711] device_release+0x51/0xe0
+[ 11.368905] kobject_put+0xa2/0x120
+[ 11.369090] rtsx_usb_ms_drv_remove+0x8c/0x140 [rtsx_usb_ms]
+[ 11.369386] platform_remove+0x2a/0x50
+
+[ 12.038408] BUG: KASAN: use-after-free in __mutex_lock.isra.0+0x3ec/0x7c0
+[ 12.045432] mutex_lock+0xc9/0xd0
+[ 12.046080] memstick_check+0x6a/0x578 [memstick]
+[ 12.046509] process_one_work+0x46d/0x750
+[ 12.052107] Freed by task 297:
+[ 12.053115] kfree+0xa4/0x2a0
+[ 12.053272] device_release+0x51/0xe0
+[ 12.053463] kobject_put+0xa2/0x120
+[ 12.053647] rtsx_usb_ms_drv_remove+0xc4/0x140 [rtsx_usb_ms]
+[ 12.053939] platform_remove+0x2a/0x50
+
+Signed-off-by: Tong Zhang <ztong0001@gmail.com>
+Co-developed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Link: https://lore.kernel.org/r/20210511163944.1233295-1-ztong0001@gmail.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/memstick/host/rtsx_usb_ms.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/memstick/host/rtsx_usb_ms.c b/drivers/memstick/host/rtsx_usb_ms.c
+index 102dbb8080da..29271ad4728a 100644
+--- a/drivers/memstick/host/rtsx_usb_ms.c
++++ b/drivers/memstick/host/rtsx_usb_ms.c
+@@ -799,9 +799,9 @@ static int rtsx_usb_ms_drv_probe(struct platform_device *pdev)
+
+ return 0;
+ err_out:
+- memstick_free_host(msh);
+ pm_runtime_disable(ms_dev(host));
+ pm_runtime_put_noidle(ms_dev(host));
++ memstick_free_host(msh);
+ return err;
+ }
+
+@@ -828,9 +828,6 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev)
+ }
+ mutex_unlock(&host->host_mutex);
+
+- memstick_remove_host(msh);
+- memstick_free_host(msh);
+-
+ /* Balance possible unbalanced usage count
+ * e.g. unconditional module removal
+ */
+@@ -838,10 +835,11 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev)
+ pm_runtime_put(ms_dev(host));
+
+ pm_runtime_disable(ms_dev(host));
+- platform_set_drvdata(pdev, NULL);
+-
++ memstick_remove_host(msh);
+ dev_dbg(ms_dev(host),
+ ": Realtek USB Memstick controller has been removed\n");
++ memstick_free_host(msh);
++ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+ }
+--
+2.30.2
+
--- /dev/null
+From 928f0eebaa2461f36451bf6362d6ec32c9251e7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 May 2021 19:32:18 -0700
+Subject: mfd: mp2629: Select MFD_CORE to fix build error
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit a933272041d852a1ef1c85f0c18b93e9999a41fa ]
+
+MFD_MP2629 should select MFD_CORE to a prevent build error:
+
+ERROR: modpost: "devm_mfd_add_devices" [drivers/mfd/mp2629.ko] undefined!
+
+Fixes: 06081646450e ("mfd: mp2629: Add support for mps battery charger")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
+index 5c7f2b100191..5c408c1dc58c 100644
+--- a/drivers/mfd/Kconfig
++++ b/drivers/mfd/Kconfig
+@@ -465,6 +465,7 @@ config MFD_MP2629
+ tristate "Monolithic Power Systems MP2629 ADC and Battery charger"
+ depends on I2C
+ select REGMAP_I2C
++ select MFD_CORE
+ help
+ Select this option to enable support for Monolithic Power Systems
+ battery charger. This provides ADC, thermal and battery charger power
+--
+2.30.2
+
--- /dev/null
+From 9903c3b0dbbfe0d40b1c1f1b686699028cb9cd44 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 17:15:52 +0300
+Subject: mfd: Remove software node conditionally and locate at right place
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 5a23e8b0fd6010e25ae58362292235cc9213ca57 ]
+
+Currently the software node is removed in error case and at ->remove()
+stage unconditionally, that ruins the symmetry. Besides, in some cases,
+when mfd_add_device() fails, the device_remove_software_node() call
+may lead to NULL pointer dereference:
+
+ BUG: kernel NULL pointer dereference, address: 00000000
+ ...
+ EIP: strlen+0x12/0x20
+ ...
+ kernfs_name_hash+0x13/0x70
+ kernfs_find_ns+0x32/0xc0
+ kernfs_remove_by_name_ns+0x2a/0x90
+ sysfs_remove_link+0x16/0x30
+ software_node_notify.cold+0x34/0x6b
+ device_remove_software_node+0x5a/0x90
+ mfd_add_device.cold+0x30a/0x427
+
+Fix all these by guarding device_remove_software_node() with a conditional
+and locating it at the right place.
+
+Fixes: 42e59982917a ("mfd: core: Add support for software nodes")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/mfd-core.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
+index 6f02b8022c6d..79f5c6a18815 100644
+--- a/drivers/mfd/mfd-core.c
++++ b/drivers/mfd/mfd-core.c
+@@ -266,18 +266,18 @@ static int mfd_add_device(struct device *parent, int id,
+ if (has_acpi_companion(&pdev->dev)) {
+ ret = acpi_check_resource_conflict(&res[r]);
+ if (ret)
+- goto fail_of_entry;
++ goto fail_res_conflict;
+ }
+ }
+ }
+
+ ret = platform_device_add_resources(pdev, res, cell->num_resources);
+ if (ret)
+- goto fail_of_entry;
++ goto fail_res_conflict;
+
+ ret = platform_device_add(pdev);
+ if (ret)
+- goto fail_of_entry;
++ goto fail_res_conflict;
+
+ if (cell->pm_runtime_no_callbacks)
+ pm_runtime_no_callbacks(&pdev->dev);
+@@ -286,13 +286,15 @@ static int mfd_add_device(struct device *parent, int id,
+
+ return 0;
+
++fail_res_conflict:
++ if (cell->swnode)
++ device_remove_software_node(&pdev->dev);
+ fail_of_entry:
+ list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list)
+ if (of_entry->dev == &pdev->dev) {
+ list_del(&of_entry->list);
+ kfree(of_entry);
+ }
+- device_remove_software_node(&pdev->dev);
+ fail_alias:
+ regulator_bulk_unregister_supply_alias(&pdev->dev,
+ cell->parent_supplies,
+@@ -358,11 +360,12 @@ static int mfd_remove_devices_fn(struct device *dev, void *data)
+ if (level && cell->level > *level)
+ return 0;
+
++ if (cell->swnode)
++ device_remove_software_node(&pdev->dev);
++
+ regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies,
+ cell->num_parent_supplies);
+
+- device_remove_software_node(&pdev->dev);
+-
+ platform_device_unregister(pdev);
+ return 0;
+ }
+--
+2.30.2
+
--- /dev/null
+From c6f926749a10fb06fcbaf92f3b78b3330783c43c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 May 2021 22:55:18 +0200
+Subject: mfd: rn5t618: Fix IRQ trigger by changing it to level mode
+
+From: Andreas Kemnade <andreas@kemnade.info>
+
+[ Upstream commit a1649a5260631979c68e5b2012f60f90300e646f ]
+
+During more massive generation of interrupts, the IRQ got stuck,
+and the subdevices did not see any new interrupts. That happens
+especially at wonky USB supply in combination with ADC reads.
+To fix that trigger the IRQ at level low instead of falling edge.
+
+Fixes: 0c81604516af ("mfd: rn5t618: Add IRQ support")
+Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/rn5t618.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mfd/rn5t618.c b/drivers/mfd/rn5t618.c
+index 6ed04e6dbc78..384acb459427 100644
+--- a/drivers/mfd/rn5t618.c
++++ b/drivers/mfd/rn5t618.c
+@@ -107,7 +107,7 @@ static int rn5t618_irq_init(struct rn5t618 *rn5t618)
+
+ ret = devm_regmap_add_irq_chip(rn5t618->dev, rn5t618->regmap,
+ rn5t618->irq,
+- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
++ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ 0, irq_chip, &rn5t618->irq_data);
+ if (ret)
+ dev_err(rn5t618->dev, "Failed to register IRQ chip\n");
+--
+2.30.2
+
--- /dev/null
+From f89adffa6cd8149b88cc77d2a66ac34a1065fc94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Jun 2021 22:14:20 +0800
+Subject: MIPS: Fix PKMAP with 32-bit MIPS huge page support
+
+From: Wei Li <liwei391@huawei.com>
+
+[ Upstream commit cf02ce742f09188272bcc8b0e62d789eb671fc4c ]
+
+When 32-bit MIPS huge page support is enabled, we halve the number of
+pointers a PTE page holds, making its last half go to waste.
+Correspondingly, we should halve the number of kmap entries, as we just
+initialized only a single pte table for that in pagetable_init().
+
+Fixes: 35476311e529 ("MIPS: Add partial 32-bit huge page support")
+Signed-off-by: Wei Li <liwei391@huawei.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/include/asm/highmem.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h
+index 292d0425717f..92a380210017 100644
+--- a/arch/mips/include/asm/highmem.h
++++ b/arch/mips/include/asm/highmem.h
+@@ -36,7 +36,7 @@ extern pte_t *pkmap_page_table;
+ * easily, subsequent pte tables have to be allocated in one physical
+ * chunk of RAM.
+ */
+-#ifdef CONFIG_PHYS_ADDR_T_64BIT
++#if defined(CONFIG_PHYS_ADDR_T_64BIT) || defined(CONFIG_MIPS_HUGE_TLB_SUPPORT)
+ #define LAST_PKMAP 512
+ #else
+ #define LAST_PKMAP 1024
+--
+2.30.2
+
--- /dev/null
+From b0d58df65f3092f5dbb0ee271537332077cbdca5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 May 2021 08:55:03 +0200
+Subject: misc/pvpanic-mmio: Fix error handling in 'pvpanic_mmio_probe()'
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 9a3c72ee6ffcd461bae1bbdf4e71dca6d5bc160c ]
+
+There is no error handling path in the probe function.
+Switch to managed resource so that errors in the probe are handled easily
+and simplify the remove function accordingly.
+
+Fixes: b3c0f8774668 ("misc/pvpanic: probe multiple instances")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/2a5dab18f10db783b27e0579ba66cc38d610734a.1621665058.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/pvpanic/pvpanic-mmio.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/misc/pvpanic/pvpanic-mmio.c b/drivers/misc/pvpanic/pvpanic-mmio.c
+index 4c0841776087..69b31f7adf4f 100644
+--- a/drivers/misc/pvpanic/pvpanic-mmio.c
++++ b/drivers/misc/pvpanic/pvpanic-mmio.c
+@@ -93,7 +93,7 @@ static int pvpanic_mmio_probe(struct platform_device *pdev)
+ return -EINVAL;
+ }
+
+- pi = kmalloc(sizeof(*pi), GFP_ATOMIC);
++ pi = devm_kmalloc(dev, sizeof(*pi), GFP_ATOMIC);
+ if (!pi)
+ return -ENOMEM;
+
+@@ -114,7 +114,6 @@ static int pvpanic_mmio_remove(struct platform_device *pdev)
+ struct pvpanic_instance *pi = dev_get_drvdata(&pdev->dev);
+
+ pvpanic_remove(pi);
+- kfree(pi);
+
+ return 0;
+ }
+--
+2.30.2
+
--- /dev/null
+From d03d8f8fc9aad04a477d3b04a62e3f6b576eb53b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 May 2021 08:54:33 +0200
+Subject: misc/pvpanic-pci: Fix error handling in 'pvpanic_pci_probe()'
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 372dae89972594393b57f29ec44e351fa7eedbbe ]
+
+There is no error handling path in the probe function.
+Switch to managed resource so that errors in the probe are handled easily
+and simplify the remove function accordingly.
+
+Fixes: db3a4f0abefd ("misc/pvpanic: add PCI driver")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/ab071b1f4ed6e1174f9199095fb16a58bb406090.1621665058.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/pvpanic/pvpanic-pci.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/misc/pvpanic/pvpanic-pci.c b/drivers/misc/pvpanic/pvpanic-pci.c
+index 9ecc4e8559d5..046ce4ecc195 100644
+--- a/drivers/misc/pvpanic/pvpanic-pci.c
++++ b/drivers/misc/pvpanic/pvpanic-pci.c
+@@ -78,15 +78,15 @@ static int pvpanic_pci_probe(struct pci_dev *pdev,
+ void __iomem *base;
+ int ret;
+
+- ret = pci_enable_device(pdev);
++ ret = pcim_enable_device(pdev);
+ if (ret < 0)
+ return ret;
+
+- base = pci_iomap(pdev, 0, 0);
++ base = pcim_iomap(pdev, 0, 0);
+ if (!base)
+ return -ENOMEM;
+
+- pi = kmalloc(sizeof(*pi), GFP_ATOMIC);
++ pi = devm_kmalloc(&pdev->dev, sizeof(*pi), GFP_ATOMIC);
+ if (!pi)
+ return -ENOMEM;
+
+@@ -107,9 +107,6 @@ static void pvpanic_pci_remove(struct pci_dev *pdev)
+ struct pvpanic_instance *pi = dev_get_drvdata(&pdev->dev);
+
+ pvpanic_remove(pi);
+- iounmap(pi->base);
+- kfree(pi);
+- pci_disable_device(pdev);
+ }
+
+ static struct pci_driver pvpanic_pci_driver = {
+--
+2.30.2
+
--- /dev/null
+From bb093c2c5e95b15278fbeac29fd623db68a3ac1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jun 2021 19:35:10 -0700
+Subject: mm/debug_vm_pgtable: ensure THP availability via
+ has_transparent_hugepage()
+
+From: Anshuman Khandual <anshuman.khandual@arm.com>
+
+[ Upstream commit 65ac1a60a57e2c55f2ac37f27095f6b012295e81 ]
+
+On certain platforms, THP support could not just be validated via the
+build option CONFIG_TRANSPARENT_HUGEPAGE. Instead
+has_transparent_hugepage() also needs to be called upon to verify THP
+runtime support. Otherwise the debug test will just run into unusable THP
+helpers like in the case of a 4K hash config on powerpc platform [1].
+This just moves all pfn_pmd() and pfn_pud() after THP runtime validation
+with has_transparent_hugepage() which prevents the mentioned problem.
+
+[1] https://bugzilla.kernel.org/show_bug.cgi?id=213069
+
+Link: https://lkml.kernel.org/r/1621397588-19211-1-git-send-email-anshuman.khandual@arm.com
+Fixes: 787d563b8642 ("mm/debug_vm_pgtable: fix kernel crash by checking for THP support")
+Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/debug_vm_pgtable.c | 63 ++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 51 insertions(+), 12 deletions(-)
+
+diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c
+index 297d1b349c19..92bfc37300df 100644
+--- a/mm/debug_vm_pgtable.c
++++ b/mm/debug_vm_pgtable.c
+@@ -146,13 +146,14 @@ static void __init pte_savedwrite_tests(unsigned long pfn, pgprot_t prot)
+ static void __init pmd_basic_tests(unsigned long pfn, int idx)
+ {
+ pgprot_t prot = protection_map[idx];
+- pmd_t pmd = pfn_pmd(pfn, prot);
+ unsigned long val = idx, *ptr = &val;
++ pmd_t pmd;
+
+ if (!has_transparent_hugepage())
+ return;
+
+ pr_debug("Validating PMD basic (%pGv)\n", ptr);
++ pmd = pfn_pmd(pfn, prot);
+
+ /*
+ * This test needs to be executed after the given page table entry
+@@ -185,7 +186,7 @@ static void __init pmd_advanced_tests(struct mm_struct *mm,
+ unsigned long pfn, unsigned long vaddr,
+ pgprot_t prot, pgtable_t pgtable)
+ {
+- pmd_t pmd = pfn_pmd(pfn, prot);
++ pmd_t pmd;
+
+ if (!has_transparent_hugepage())
+ return;
+@@ -232,9 +233,14 @@ static void __init pmd_advanced_tests(struct mm_struct *mm,
+
+ static void __init pmd_leaf_tests(unsigned long pfn, pgprot_t prot)
+ {
+- pmd_t pmd = pfn_pmd(pfn, prot);
++ pmd_t pmd;
++
++ if (!has_transparent_hugepage())
++ return;
+
+ pr_debug("Validating PMD leaf\n");
++ pmd = pfn_pmd(pfn, prot);
++
+ /*
+ * PMD based THP is a leaf entry.
+ */
+@@ -267,12 +273,16 @@ static void __init pmd_huge_tests(pmd_t *pmdp, unsigned long pfn, pgprot_t prot)
+
+ static void __init pmd_savedwrite_tests(unsigned long pfn, pgprot_t prot)
+ {
+- pmd_t pmd = pfn_pmd(pfn, prot);
++ pmd_t pmd;
+
+ if (!IS_ENABLED(CONFIG_NUMA_BALANCING))
+ return;
+
++ if (!has_transparent_hugepage())
++ return;
++
+ pr_debug("Validating PMD saved write\n");
++ pmd = pfn_pmd(pfn, prot);
+ WARN_ON(!pmd_savedwrite(pmd_mk_savedwrite(pmd_clear_savedwrite(pmd))));
+ WARN_ON(pmd_savedwrite(pmd_clear_savedwrite(pmd_mk_savedwrite(pmd))));
+ }
+@@ -281,13 +291,14 @@ static void __init pmd_savedwrite_tests(unsigned long pfn, pgprot_t prot)
+ static void __init pud_basic_tests(struct mm_struct *mm, unsigned long pfn, int idx)
+ {
+ pgprot_t prot = protection_map[idx];
+- pud_t pud = pfn_pud(pfn, prot);
+ unsigned long val = idx, *ptr = &val;
++ pud_t pud;
+
+ if (!has_transparent_hugepage())
+ return;
+
+ pr_debug("Validating PUD basic (%pGv)\n", ptr);
++ pud = pfn_pud(pfn, prot);
+
+ /*
+ * This test needs to be executed after the given page table entry
+@@ -323,7 +334,7 @@ static void __init pud_advanced_tests(struct mm_struct *mm,
+ unsigned long pfn, unsigned long vaddr,
+ pgprot_t prot)
+ {
+- pud_t pud = pfn_pud(pfn, prot);
++ pud_t pud;
+
+ if (!has_transparent_hugepage())
+ return;
+@@ -332,6 +343,7 @@ static void __init pud_advanced_tests(struct mm_struct *mm,
+ /* Align the address wrt HPAGE_PUD_SIZE */
+ vaddr &= HPAGE_PUD_MASK;
+
++ pud = pfn_pud(pfn, prot);
+ set_pud_at(mm, vaddr, pudp, pud);
+ pudp_set_wrprotect(mm, vaddr, pudp);
+ pud = READ_ONCE(*pudp);
+@@ -370,9 +382,13 @@ static void __init pud_advanced_tests(struct mm_struct *mm,
+
+ static void __init pud_leaf_tests(unsigned long pfn, pgprot_t prot)
+ {
+- pud_t pud = pfn_pud(pfn, prot);
++ pud_t pud;
++
++ if (!has_transparent_hugepage())
++ return;
+
+ pr_debug("Validating PUD leaf\n");
++ pud = pfn_pud(pfn, prot);
+ /*
+ * PUD based THP is a leaf entry.
+ */
+@@ -654,12 +670,16 @@ static void __init pte_protnone_tests(unsigned long pfn, pgprot_t prot)
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ static void __init pmd_protnone_tests(unsigned long pfn, pgprot_t prot)
+ {
+- pmd_t pmd = pmd_mkhuge(pfn_pmd(pfn, prot));
++ pmd_t pmd;
+
+ if (!IS_ENABLED(CONFIG_NUMA_BALANCING))
+ return;
+
++ if (!has_transparent_hugepage())
++ return;
++
+ pr_debug("Validating PMD protnone\n");
++ pmd = pmd_mkhuge(pfn_pmd(pfn, prot));
+ WARN_ON(!pmd_protnone(pmd));
+ WARN_ON(!pmd_present(pmd));
+ }
+@@ -679,18 +699,26 @@ static void __init pte_devmap_tests(unsigned long pfn, pgprot_t prot)
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ static void __init pmd_devmap_tests(unsigned long pfn, pgprot_t prot)
+ {
+- pmd_t pmd = pfn_pmd(pfn, prot);
++ pmd_t pmd;
++
++ if (!has_transparent_hugepage())
++ return;
+
+ pr_debug("Validating PMD devmap\n");
++ pmd = pfn_pmd(pfn, prot);
+ WARN_ON(!pmd_devmap(pmd_mkdevmap(pmd)));
+ }
+
+ #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
+ static void __init pud_devmap_tests(unsigned long pfn, pgprot_t prot)
+ {
+- pud_t pud = pfn_pud(pfn, prot);
++ pud_t pud;
++
++ if (!has_transparent_hugepage())
++ return;
+
+ pr_debug("Validating PUD devmap\n");
++ pud = pfn_pud(pfn, prot);
+ WARN_ON(!pud_devmap(pud_mkdevmap(pud)));
+ }
+ #else /* !CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD */
+@@ -733,25 +761,33 @@ static void __init pte_swap_soft_dirty_tests(unsigned long pfn, pgprot_t prot)
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ static void __init pmd_soft_dirty_tests(unsigned long pfn, pgprot_t prot)
+ {
+- pmd_t pmd = pfn_pmd(pfn, prot);
++ pmd_t pmd;
+
+ if (!IS_ENABLED(CONFIG_MEM_SOFT_DIRTY))
+ return;
+
++ if (!has_transparent_hugepage())
++ return;
++
+ pr_debug("Validating PMD soft dirty\n");
++ pmd = pfn_pmd(pfn, prot);
+ WARN_ON(!pmd_soft_dirty(pmd_mksoft_dirty(pmd)));
+ WARN_ON(pmd_soft_dirty(pmd_clear_soft_dirty(pmd)));
+ }
+
+ static void __init pmd_swap_soft_dirty_tests(unsigned long pfn, pgprot_t prot)
+ {
+- pmd_t pmd = pfn_pmd(pfn, prot);
++ pmd_t pmd;
+
+ if (!IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) ||
+ !IS_ENABLED(CONFIG_ARCH_ENABLE_THP_MIGRATION))
+ return;
+
++ if (!has_transparent_hugepage())
++ return;
++
+ pr_debug("Validating PMD swap soft dirty\n");
++ pmd = pfn_pmd(pfn, prot);
+ WARN_ON(!pmd_swp_soft_dirty(pmd_swp_mksoft_dirty(pmd)));
+ WARN_ON(pmd_swp_soft_dirty(pmd_swp_clear_soft_dirty(pmd)));
+ }
+@@ -780,6 +816,9 @@ static void __init pmd_swap_tests(unsigned long pfn, pgprot_t prot)
+ swp_entry_t swp;
+ pmd_t pmd;
+
++ if (!has_transparent_hugepage())
++ return;
++
+ pr_debug("Validating PMD swap\n");
+ pmd = pfn_pmd(pfn, prot);
+ swp = __pmd_to_swp_entry(pmd);
+--
+2.30.2
+
--- /dev/null
+From b2472b8fd43e8bfe8e7d5415c1918279c2d047ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jun 2021 19:40:46 -0700
+Subject: mm: define default MAX_PTRS_PER_* in include/pgtable.h
+
+From: Daniel Axtens <dja@axtens.net>
+
+[ Upstream commit c0f8aa4fa815daacb6eca52cae04820d6aecb7c2 ]
+
+Commit c65e774fb3f6 ("x86/mm: Make PGDIR_SHIFT and PTRS_PER_P4D variable")
+made PTRS_PER_P4D variable on x86 and introduced MAX_PTRS_PER_P4D as a
+constant for cases which need a compile-time constant (e.g. fixed-size
+arrays).
+
+powerpc likewise has boot-time selectable MMU features which can cause
+other mm "constants" to vary. For KASAN, we have some static
+PTE/PMD/PUD/P4D arrays so we need compile-time maximums for all these
+constants. Extend the MAX_PTRS_PER_ idiom, and place default definitions
+in include/pgtable.h. These define MAX_PTRS_PER_x to be PTRS_PER_x unless
+an architecture has defined MAX_PTRS_PER_x in its arch headers.
+
+Clean up pgtable-nop4d.h and s390's MAX_PTRS_PER_P4D definitions while
+we're at it: both can just pick up the default now.
+
+Link: https://lkml.kernel.org/r/20210624034050.511391-4-dja@axtens.net
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Acked-by: Andrey Konovalov <andreyknvl@gmail.com>
+Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Reviewed-by: Marco Elver <elver@google.com>
+Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Cc: Balbir Singh <bsingharora@gmail.com>
+Cc: Alexander Potapenko <glider@google.com>
+Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/include/asm/pgtable.h | 2 --
+ include/asm-generic/pgtable-nop4d.h | 1 -
+ include/linux/pgtable.h | 22 ++++++++++++++++++++++
+ 3 files changed, 22 insertions(+), 3 deletions(-)
+
+diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
+index 29c7ecd5ad1d..b38f7b781564 100644
+--- a/arch/s390/include/asm/pgtable.h
++++ b/arch/s390/include/asm/pgtable.h
+@@ -344,8 +344,6 @@ static inline int is_module_addr(void *addr)
+ #define PTRS_PER_P4D _CRST_ENTRIES
+ #define PTRS_PER_PGD _CRST_ENTRIES
+
+-#define MAX_PTRS_PER_P4D PTRS_PER_P4D
+-
+ /*
+ * Segment table and region3 table entry encoding
+ * (R = read-only, I = invalid, y = young bit):
+diff --git a/include/asm-generic/pgtable-nop4d.h b/include/asm-generic/pgtable-nop4d.h
+index ce2cbb3c380f..2f6b1befb129 100644
+--- a/include/asm-generic/pgtable-nop4d.h
++++ b/include/asm-generic/pgtable-nop4d.h
+@@ -9,7 +9,6 @@
+ typedef struct { pgd_t pgd; } p4d_t;
+
+ #define P4D_SHIFT PGDIR_SHIFT
+-#define MAX_PTRS_PER_P4D 1
+ #define PTRS_PER_P4D 1
+ #define P4D_SIZE (1UL << P4D_SHIFT)
+ #define P4D_MASK (~(P4D_SIZE-1))
+diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
+index a43047b1030d..c32600c9e1ad 100644
+--- a/include/linux/pgtable.h
++++ b/include/linux/pgtable.h
+@@ -1592,4 +1592,26 @@ typedef unsigned int pgtbl_mod_mask;
+ #define pte_leaf_size(x) PAGE_SIZE
+ #endif
+
++/*
++ * Some architectures have MMUs that are configurable or selectable at boot
++ * time. These lead to variable PTRS_PER_x. For statically allocated arrays it
++ * helps to have a static maximum value.
++ */
++
++#ifndef MAX_PTRS_PER_PTE
++#define MAX_PTRS_PER_PTE PTRS_PER_PTE
++#endif
++
++#ifndef MAX_PTRS_PER_PMD
++#define MAX_PTRS_PER_PMD PTRS_PER_PMD
++#endif
++
++#ifndef MAX_PTRS_PER_PUD
++#define MAX_PTRS_PER_PUD PTRS_PER_PUD
++#endif
++
++#ifndef MAX_PTRS_PER_P4D
++#define MAX_PTRS_PER_P4D PTRS_PER_P4D
++#endif
++
+ #endif /* _LINUX_PGTABLE_H */
+--
+2.30.2
+
--- /dev/null
+From 9379cecad48cfbf0dae25910d65ea72ec8b2fc44 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 18:47:50 -0700
+Subject: mm/huge_memory.c: add missing read-only THP checking in
+ transparent_hugepage_enabled()
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit e6be37b2e7bddfe0c76585ee7c7eee5acc8efeab ]
+
+Since commit 99cb0dbd47a1 ("mm,thp: add read-only THP support for
+(non-shmem) FS"), read-only THP file mapping is supported. But it forgot
+to add checking for it in transparent_hugepage_enabled(). To fix it, we
+add checking for read-only THP file mapping and also introduce helper
+transhuge_vma_enabled() to check whether thp is enabled for specified vma
+to reduce duplicated code. We rename transparent_hugepage_enabled to
+transparent_hugepage_active to make the code easier to follow as suggested
+by David Hildenbrand.
+
+[linmiaohe@huawei.com: define transhuge_vma_enabled next to transhuge_vma_suitable]
+ Link: https://lkml.kernel.org/r/20210514093007.4117906-1-linmiaohe@huawei.com
+
+Link: https://lkml.kernel.org/r/20210511134857.1581273-4-linmiaohe@huawei.com
+Fixes: 99cb0dbd47a1 ("mm,thp: add read-only THP support for (non-shmem) FS")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Reviewed-by: Yang Shi <shy828301@gmail.com>
+Cc: Alexey Dobriyan <adobriyan@gmail.com>
+Cc: "Aneesh Kumar K . V" <aneesh.kumar@linux.ibm.com>
+Cc: Anshuman Khandual <anshuman.khandual@arm.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Ralph Campbell <rcampbell@nvidia.com>
+Cc: Rik van Riel <riel@surriel.com>
+Cc: Song Liu <songliubraving@fb.com>
+Cc: William Kucharski <william.kucharski@oracle.com>
+Cc: Zi Yan <ziy@nvidia.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/proc/task_mmu.c | 2 +-
+ include/linux/huge_mm.h | 57 +++++++++++++++++++++++++----------------
+ mm/huge_memory.c | 11 +++++++-
+ mm/khugepaged.c | 4 +--
+ mm/shmem.c | 3 +--
+ 5 files changed, 48 insertions(+), 29 deletions(-)
+
+diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
+index fc9784544b24..7389df326edd 100644
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -832,7 +832,7 @@ static int show_smap(struct seq_file *m, void *v)
+ __show_smap(m, &mss, false);
+
+ seq_printf(m, "THPeligible: %d\n",
+- transparent_hugepage_enabled(vma));
++ transparent_hugepage_active(vma));
+
+ if (arch_pkeys_enabled())
+ seq_printf(m, "ProtectionKey: %8u\n", vma_pkey(vma));
+diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
+index 8a5f49abcfa2..b4e1ebaae825 100644
+--- a/include/linux/huge_mm.h
++++ b/include/linux/huge_mm.h
+@@ -115,9 +115,34 @@ extern struct kobj_attribute shmem_enabled_attr;
+
+ extern unsigned long transparent_hugepage_flags;
+
++static inline bool transhuge_vma_suitable(struct vm_area_struct *vma,
++ unsigned long haddr)
++{
++ /* Don't have to check pgoff for anonymous vma */
++ if (!vma_is_anonymous(vma)) {
++ if (!IS_ALIGNED((vma->vm_start >> PAGE_SHIFT) - vma->vm_pgoff,
++ HPAGE_PMD_NR))
++ return false;
++ }
++
++ if (haddr < vma->vm_start || haddr + HPAGE_PMD_SIZE > vma->vm_end)
++ return false;
++ return true;
++}
++
++static inline bool transhuge_vma_enabled(struct vm_area_struct *vma,
++ unsigned long vm_flags)
++{
++ /* Explicitly disabled through madvise. */
++ if ((vm_flags & VM_NOHUGEPAGE) ||
++ test_bit(MMF_DISABLE_THP, &vma->vm_mm->flags))
++ return false;
++ return true;
++}
++
+ /*
+ * to be used on vmas which are known to support THP.
+- * Use transparent_hugepage_enabled otherwise
++ * Use transparent_hugepage_active otherwise
+ */
+ static inline bool __transparent_hugepage_enabled(struct vm_area_struct *vma)
+ {
+@@ -128,15 +153,12 @@ static inline bool __transparent_hugepage_enabled(struct vm_area_struct *vma)
+ if (transparent_hugepage_flags & (1 << TRANSPARENT_HUGEPAGE_NEVER_DAX))
+ return false;
+
+- if (vma->vm_flags & VM_NOHUGEPAGE)
++ if (!transhuge_vma_enabled(vma, vma->vm_flags))
+ return false;
+
+ if (vma_is_temporary_stack(vma))
+ return false;
+
+- if (test_bit(MMF_DISABLE_THP, &vma->vm_mm->flags))
+- return false;
+-
+ if (transparent_hugepage_flags & (1 << TRANSPARENT_HUGEPAGE_FLAG))
+ return true;
+
+@@ -150,22 +172,7 @@ static inline bool __transparent_hugepage_enabled(struct vm_area_struct *vma)
+ return false;
+ }
+
+-bool transparent_hugepage_enabled(struct vm_area_struct *vma);
+-
+-static inline bool transhuge_vma_suitable(struct vm_area_struct *vma,
+- unsigned long haddr)
+-{
+- /* Don't have to check pgoff for anonymous vma */
+- if (!vma_is_anonymous(vma)) {
+- if (!IS_ALIGNED((vma->vm_start >> PAGE_SHIFT) - vma->vm_pgoff,
+- HPAGE_PMD_NR))
+- return false;
+- }
+-
+- if (haddr < vma->vm_start || haddr + HPAGE_PMD_SIZE > vma->vm_end)
+- return false;
+- return true;
+-}
++bool transparent_hugepage_active(struct vm_area_struct *vma);
+
+ #define transparent_hugepage_use_zero_page() \
+ (transparent_hugepage_flags & \
+@@ -352,7 +359,7 @@ static inline bool __transparent_hugepage_enabled(struct vm_area_struct *vma)
+ return false;
+ }
+
+-static inline bool transparent_hugepage_enabled(struct vm_area_struct *vma)
++static inline bool transparent_hugepage_active(struct vm_area_struct *vma)
+ {
+ return false;
+ }
+@@ -363,6 +370,12 @@ static inline bool transhuge_vma_suitable(struct vm_area_struct *vma,
+ return false;
+ }
+
++static inline bool transhuge_vma_enabled(struct vm_area_struct *vma,
++ unsigned long vm_flags)
++{
++ return false;
++}
++
+ static inline void prep_transhuge_page(struct page *page) {}
+
+ static inline bool is_transparent_hugepage(struct page *page)
+diff --git a/mm/huge_memory.c b/mm/huge_memory.c
+index 6d2a0119fc58..2496f787a829 100644
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -64,7 +64,14 @@ static atomic_t huge_zero_refcount;
+ struct page *huge_zero_page __read_mostly;
+ unsigned long huge_zero_pfn __read_mostly = ~0UL;
+
+-bool transparent_hugepage_enabled(struct vm_area_struct *vma)
++static inline bool file_thp_enabled(struct vm_area_struct *vma)
++{
++ return transhuge_vma_enabled(vma, vma->vm_flags) && vma->vm_file &&
++ !inode_is_open_for_write(vma->vm_file->f_inode) &&
++ (vma->vm_flags & VM_EXEC);
++}
++
++bool transparent_hugepage_active(struct vm_area_struct *vma)
+ {
+ /* The addr is used to check if the vma size fits */
+ unsigned long addr = (vma->vm_end & HPAGE_PMD_MASK) - HPAGE_PMD_SIZE;
+@@ -75,6 +82,8 @@ bool transparent_hugepage_enabled(struct vm_area_struct *vma)
+ return __transparent_hugepage_enabled(vma);
+ if (vma_is_shmem(vma))
+ return shmem_huge_enabled(vma);
++ if (IS_ENABLED(CONFIG_READ_ONLY_THP_FOR_FS))
++ return file_thp_enabled(vma);
+
+ return false;
+ }
+diff --git a/mm/khugepaged.c b/mm/khugepaged.c
+index 6c0185fdd815..d97b20fad6e8 100644
+--- a/mm/khugepaged.c
++++ b/mm/khugepaged.c
+@@ -442,9 +442,7 @@ static inline int khugepaged_test_exit(struct mm_struct *mm)
+ static bool hugepage_vma_check(struct vm_area_struct *vma,
+ unsigned long vm_flags)
+ {
+- /* Explicitly disabled through madvise. */
+- if ((vm_flags & VM_NOHUGEPAGE) ||
+- test_bit(MMF_DISABLE_THP, &vma->vm_mm->flags))
++ if (!transhuge_vma_enabled(vma, vm_flags))
+ return false;
+
+ /* Enabled via shmem mount options or sysfs settings. */
+diff --git a/mm/shmem.c b/mm/shmem.c
+index 53f21016608e..5fa21d66af20 100644
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -4040,8 +4040,7 @@ bool shmem_huge_enabled(struct vm_area_struct *vma)
+ loff_t i_size;
+ pgoff_t off;
+
+- if ((vma->vm_flags & VM_NOHUGEPAGE) ||
+- test_bit(MMF_DISABLE_THP, &vma->vm_mm->flags))
++ if (!transhuge_vma_enabled(vma, vma->vm_flags))
+ return false;
+ if (shmem_huge == SHMEM_HUGE_FORCE)
+ return true;
+--
+2.30.2
+
--- /dev/null
+From 0872f648a820acdd3f8082b7c81d072e3b62cb78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 18:47:57 -0700
+Subject: mm/huge_memory.c: don't discard hugepage if other processes are
+ mapping it
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit babbbdd08af98a59089334eb3effbed5a7a0cf7f ]
+
+If other processes are mapping any other subpages of the hugepage, i.e.
+in pte-mapped thp case, page_mapcount() will return 1 incorrectly. Then
+we would discard the page while other processes are still mapping it. Fix
+it by using total_mapcount() which can tell whether other processes are
+still mapping it.
+
+Link: https://lkml.kernel.org/r/20210511134857.1581273-6-linmiaohe@huawei.com
+Fixes: b8d3c4c3009d ("mm/huge_memory.c: don't split THP page when MADV_FREE syscall is called")
+Reviewed-by: Yang Shi <shy828301@gmail.com>
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Cc: Alexey Dobriyan <adobriyan@gmail.com>
+Cc: "Aneesh Kumar K . V" <aneesh.kumar@linux.ibm.com>
+Cc: Anshuman Khandual <anshuman.khandual@arm.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Ralph Campbell <rcampbell@nvidia.com>
+Cc: Rik van Riel <riel@surriel.com>
+Cc: Song Liu <songliubraving@fb.com>
+Cc: William Kucharski <william.kucharski@oracle.com>
+Cc: Zi Yan <ziy@nvidia.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/huge_memory.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mm/huge_memory.c b/mm/huge_memory.c
+index 2496f787a829..8857ef1543eb 100644
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -1613,7 +1613,7 @@ bool madvise_free_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
+ * If other processes are mapping this page, we couldn't discard
+ * the page unless they all do MADV_FREE so let's skip the page.
+ */
+- if (page_mapcount(page) != 1)
++ if (total_mapcount(page) != 1)
+ goto out;
+
+ if (!trylock_page(page))
+--
+2.30.2
+
--- /dev/null
+From 06a973eecca887e89846221ee2df771e2424b48e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 18:47:43 -0700
+Subject: mm/huge_memory.c: remove dedicated macro HPAGE_CACHE_INDEX_MASK
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit b2bd53f18bb7f7cfc91b3bb527d7809376700a8e ]
+
+Patch series "Cleanup and fixup for huge_memory:, v3.
+
+This series contains cleanups to remove dedicated macro and remove
+unnecessary tlb_remove_page_size() for huge zero pmd. Also this adds
+missing read-only THP checking for transparent_hugepage_enabled() and
+avoids discarding hugepage if other processes are mapping it. More
+details can be found in the respective changelogs.
+
+Thi patch (of 5):
+
+Rewrite the pgoff checking logic to remove macro HPAGE_CACHE_INDEX_MASK
+which is only used here to simplify the code.
+
+Link: https://lkml.kernel.org/r/20210511134857.1581273-1-linmiaohe@huawei.com
+Link: https://lkml.kernel.org/r/20210511134857.1581273-2-linmiaohe@huawei.com
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Reviewed-by: Yang Shi <shy828301@gmail.com>
+Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Cc: Zi Yan <ziy@nvidia.com>
+Cc: William Kucharski <william.kucharski@oracle.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: "Aneesh Kumar K . V" <aneesh.kumar@linux.ibm.com>
+Cc: Ralph Campbell <rcampbell@nvidia.com>
+Cc: Song Liu <songliubraving@fb.com>
+Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: Rik van Riel <riel@surriel.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Alexey Dobriyan <adobriyan@gmail.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/huge_mm.h | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
+index 2a8ebe6c222e..8a5f49abcfa2 100644
+--- a/include/linux/huge_mm.h
++++ b/include/linux/huge_mm.h
+@@ -152,15 +152,13 @@ static inline bool __transparent_hugepage_enabled(struct vm_area_struct *vma)
+
+ bool transparent_hugepage_enabled(struct vm_area_struct *vma);
+
+-#define HPAGE_CACHE_INDEX_MASK (HPAGE_PMD_NR - 1)
+-
+ static inline bool transhuge_vma_suitable(struct vm_area_struct *vma,
+ unsigned long haddr)
+ {
+ /* Don't have to check pgoff for anonymous vma */
+ if (!vma_is_anonymous(vma)) {
+- if (((vma->vm_start >> PAGE_SHIFT) & HPAGE_CACHE_INDEX_MASK) !=
+- (vma->vm_pgoff & HPAGE_CACHE_INDEX_MASK))
++ if (!IS_ALIGNED((vma->vm_start >> PAGE_SHIFT) - vma->vm_pgoff,
++ HPAGE_PMD_NR))
+ return false;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 3ec84187ec52888f9c60b8e398435c9380a2f332 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jun 2021 19:37:34 -0700
+Subject: mm: memcg/slab: properly set up gfp flags for objcg pointer array
+
+From: Waiman Long <longman@redhat.com>
+
+[ Upstream commit 41eb5df1cbc9b302fc263ad7c9f38cfc38b4df61 ]
+
+Patch series "mm: memcg/slab: Fix objcg pointer array handling problem", v4.
+
+Since the merging of the new slab memory controller in v5.9, the page
+structure stores a pointer to objcg pointer array for slab pages. When
+the slab has no used objects, it can be freed in free_slab() which will
+call kfree() to free the objcg pointer array in
+memcg_alloc_page_obj_cgroups(). If it happens that the objcg pointer
+array is the last used object in its slab, that slab may then be freed
+which may caused kfree() to be called again.
+
+With the right workload, the slab cache may be set up in a way that allows
+the recursive kfree() calling loop to nest deep enough to cause a kernel
+stack overflow and panic the system. In fact, we have a reproducer that
+can cause kernel stack overflow on a s390 system involving kmalloc-rcl-256
+and kmalloc-rcl-128 slabs with the following kfree() loop recursively
+called 74 times:
+
+ [ 285.520739] [<000000000ec432fc>] kfree+0x4bc/0x560 [ 285.520740]
+[<000000000ec43466>] __free_slab+0xc6/0x228 [ 285.520741]
+[<000000000ec41fc2>] __slab_free+0x3c2/0x3e0 [ 285.520742]
+[<000000000ec432fc>] kfree+0x4bc/0x560 : While investigating this issue, I
+also found an issue on the allocation side. If the objcg pointer array
+happen to come from the same slab or a circular dependency linkage is
+formed with multiple slabs, those affected slabs can never be freed again.
+
+This patch series addresses these two issues by introducing a new set of
+kmalloc-cg-<n> caches split from kmalloc-<n> caches. The new set will
+only contain non-reclaimable and non-dma objects that are accounted in
+memory cgroups whereas the old set are now for unaccounted objects only.
+By making this split, all the objcg pointer arrays will come from the
+kmalloc-<n> caches, but those caches will never hold any objcg pointer
+array. As a result, deeply nested kfree() call and the unfreeable slab
+problems are now gone.
+
+This patch (of 4):
+
+Since the merging of the new slab memory controller in v5.9, the page
+structure may store a pointer to obj_cgroup pointer array for slab pages.
+Currently, only the __GFP_ACCOUNT bit is masked off. However, the array
+is not readily reclaimable and doesn't need to come from the DMA buffer.
+So those GFP bits should be masked off as well.
+
+Do the flag bit clearing at memcg_alloc_page_obj_cgroups() to make sure
+that it is consistently applied no matter where it is called.
+
+Link: https://lkml.kernel.org/r/20210505200610.13943-1-longman@redhat.com
+Link: https://lkml.kernel.org/r/20210505200610.13943-2-longman@redhat.com
+Fixes: 286e04b8ed7a ("mm: memcg/slab: allocate obj_cgroups for non-root slab pages")
+Signed-off-by: Waiman Long <longman@redhat.com>
+Reviewed-by: Shakeel Butt <shakeelb@google.com>
+Acked-by: Roman Gushchin <guro@fb.com>
+Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Vladimir Davydov <vdavydov.dev@gmail.com>
+Cc: Christoph Lameter <cl@linux.com>
+Cc: Pekka Enberg <penberg@kernel.org>
+Cc: David Rientjes <rientjes@google.com>
+Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/memcontrol.c | 8 ++++++++
+ mm/slab.h | 1 -
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/mm/memcontrol.c b/mm/memcontrol.c
+index 64ada9e650a5..f4f2d05c8c7b 100644
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -2739,6 +2739,13 @@ retry:
+ }
+
+ #ifdef CONFIG_MEMCG_KMEM
++/*
++ * The allocated objcg pointers array is not accounted directly.
++ * Moreover, it should not come from DMA buffer and is not readily
++ * reclaimable. So those GFP bits should be masked off.
++ */
++#define OBJCGS_CLEAR_MASK (__GFP_DMA | __GFP_RECLAIMABLE | __GFP_ACCOUNT)
++
+ int memcg_alloc_page_obj_cgroups(struct page *page, struct kmem_cache *s,
+ gfp_t gfp, bool new_page)
+ {
+@@ -2746,6 +2753,7 @@ int memcg_alloc_page_obj_cgroups(struct page *page, struct kmem_cache *s,
+ unsigned long memcg_data;
+ void *vec;
+
++ gfp &= ~OBJCGS_CLEAR_MASK;
+ vec = kcalloc_node(objects, sizeof(struct obj_cgroup *), gfp,
+ page_to_nid(page));
+ if (!vec)
+diff --git a/mm/slab.h b/mm/slab.h
+index 18c1927cd196..b3294712a686 100644
+--- a/mm/slab.h
++++ b/mm/slab.h
+@@ -309,7 +309,6 @@ static inline void memcg_slab_post_alloc_hook(struct kmem_cache *s,
+ if (!memcg_kmem_enabled() || !objcg)
+ return;
+
+- flags &= ~__GFP_ACCOUNT;
+ for (i = 0; i < size; i++) {
+ if (likely(p[i])) {
+ page = virt_to_head_page(p[i]);
+--
+2.30.2
+
--- /dev/null
+From 912ca1348489c11423fe9a451c4fe612b5db2ec2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 18:51:29 -0700
+Subject: mm: migrate: fix missing update page_private to hugetlb_page_subpool
+
+From: Muchun Song <songmuchun@bytedance.com>
+
+[ Upstream commit 6acfb5ba150cf75005ce85e0e25d79ef2fec287c ]
+
+Since commit d6995da31122 ("hugetlb: use page.private for hugetlb specific
+page flags") converts page.private for hugetlb specific page flags. We
+should use hugetlb_page_subpool() to get the subpool pointer instead of
+page_private().
+
+This 'could' prevent the migration of hugetlb pages. page_private(hpage)
+is now used for hugetlb page specific flags. At migration time, the only
+flag which could be set is HPageVmemmapOptimized. This flag will only be
+set if the new vmemmap reduction feature is enabled. In addition,
+!page_mapping() implies an anonymous mapping. So, this will prevent
+migration of hugetb pages in anonymous mappings if the vmemmap reduction
+feature is enabled.
+
+In addition, that if statement checked for the rare race condition of a
+page being migrated while in the process of being freed. Since that check
+is now wrong, we could leak hugetlb subpool usage counts.
+
+The commit forgot to update it in the page migration routine. So fix it.
+
+[songmuchun@bytedance.com: fix compiler error when !CONFIG_HUGETLB_PAGE reported by Randy]
+ Link: https://lkml.kernel.org/r/20210521022747.35736-1-songmuchun@bytedance.com
+
+Link: https://lkml.kernel.org/r/20210520025949.1866-1-songmuchun@bytedance.com
+Fixes: d6995da31122 ("hugetlb: use page.private for hugetlb specific page flags")
+Signed-off-by: Muchun Song <songmuchun@bytedance.com>
+Reported-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Tested-by: Anshuman Khandual <anshuman.khandual@arm.com> [arm64]
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Xiongchun Duan <duanxiongchun@bytedance.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/hugetlb.h | 5 +++++
+ mm/migrate.c | 2 +-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
+index 3c0117656745..28a110ec2a0d 100644
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -875,6 +875,11 @@ static inline void huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
+ #else /* CONFIG_HUGETLB_PAGE */
+ struct hstate {};
+
++static inline struct hugepage_subpool *hugetlb_page_subpool(struct page *hpage)
++{
++ return NULL;
++}
++
+ static inline int isolate_or_dissolve_huge_page(struct page *page,
+ struct list_head *list)
+ {
+diff --git a/mm/migrate.c b/mm/migrate.c
+index 41ff2c9896c4..047209d6602e 100644
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -1288,7 +1288,7 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
+ * page_mapping() set, hugetlbfs specific move page routine will not
+ * be called and we could leak usage counts for subpools.
+ */
+- if (page_private(hpage) && !page_mapping(hpage)) {
++ if (hugetlb_page_subpool(hpage) && !page_mapping(hpage)) {
+ rc = -EBUSY;
+ goto out_unlock;
+ }
+--
+2.30.2
+
--- /dev/null
+From c93f0af89ade452b4863cc144050443ff5c157c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jun 2021 19:35:13 -0700
+Subject: mm: mmap_lock: use local locks instead of disabling preemption
+
+From: Nicolas Saenz Julienne <nsaenzju@redhat.com>
+
+[ Upstream commit 832b50725373e8c46781b7d4db104ec9cf564a6b ]
+
+mmap_lock will explicitly disable/enable preemption upon manipulating its
+local CPU variables. This is to be expected, but in this case, it doesn't
+play well with PREEMPT_RT. The preemption disabled code section also
+takes a spin-lock. Spin-locks in RT systems will try to schedule, which
+is exactly what we're trying to avoid.
+
+To mitigate this, convert the explicit preemption handling to local_locks.
+Which are RT aware, and will disable migration instead of preemption when
+PREEMPT_RT=y.
+
+The faulty call trace looks like the following:
+ __mmap_lock_do_trace_*()
+ preempt_disable()
+ get_mm_memcg_path()
+ cgroup_path()
+ kernfs_path_from_node()
+ spin_lock_irqsave() /* Scheduling while atomic! */
+
+Link: https://lkml.kernel.org/r/20210604163506.2103900-1-nsaenzju@redhat.com
+Fixes: 2b5067a8143e3 ("mm: mmap_lock: add tracepoints around lock acquisition ")
+Signed-off-by: Nicolas Saenz Julienne <nsaenzju@redhat.com>
+Tested-by: Axel Rasmussen <axelrasmussen@google.com>
+Reviewed-by: Axel Rasmussen <axelrasmussen@google.com>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/mmap_lock.c | 33 ++++++++++++++++++++++-----------
+ 1 file changed, 22 insertions(+), 11 deletions(-)
+
+diff --git a/mm/mmap_lock.c b/mm/mmap_lock.c
+index dcdde4f722a4..2ae3f33b85b1 100644
+--- a/mm/mmap_lock.c
++++ b/mm/mmap_lock.c
+@@ -11,6 +11,7 @@
+ #include <linux/rcupdate.h>
+ #include <linux/smp.h>
+ #include <linux/trace_events.h>
++#include <linux/local_lock.h>
+
+ EXPORT_TRACEPOINT_SYMBOL(mmap_lock_start_locking);
+ EXPORT_TRACEPOINT_SYMBOL(mmap_lock_acquire_returned);
+@@ -39,21 +40,30 @@ static int reg_refcount; /* Protected by reg_lock. */
+ */
+ #define CONTEXT_COUNT 4
+
+-static DEFINE_PER_CPU(char __rcu *, memcg_path_buf);
++struct memcg_path {
++ local_lock_t lock;
++ char __rcu *buf;
++ local_t buf_idx;
++};
++static DEFINE_PER_CPU(struct memcg_path, memcg_paths) = {
++ .lock = INIT_LOCAL_LOCK(lock),
++ .buf_idx = LOCAL_INIT(0),
++};
++
+ static char **tmp_bufs;
+-static DEFINE_PER_CPU(int, memcg_path_buf_idx);
+
+ /* Called with reg_lock held. */
+ static void free_memcg_path_bufs(void)
+ {
++ struct memcg_path *memcg_path;
+ int cpu;
+ char **old = tmp_bufs;
+
+ for_each_possible_cpu(cpu) {
+- *(old++) = rcu_dereference_protected(
+- per_cpu(memcg_path_buf, cpu),
++ memcg_path = per_cpu_ptr(&memcg_paths, cpu);
++ *(old++) = rcu_dereference_protected(memcg_path->buf,
+ lockdep_is_held(®_lock));
+- rcu_assign_pointer(per_cpu(memcg_path_buf, cpu), NULL);
++ rcu_assign_pointer(memcg_path->buf, NULL);
+ }
+
+ /* Wait for inflight memcg_path_buf users to finish. */
+@@ -88,7 +98,7 @@ int trace_mmap_lock_reg(void)
+ new = kmalloc(MEMCG_PATH_BUF_SIZE * CONTEXT_COUNT, GFP_KERNEL);
+ if (new == NULL)
+ goto out_fail_free;
+- rcu_assign_pointer(per_cpu(memcg_path_buf, cpu), new);
++ rcu_assign_pointer(per_cpu_ptr(&memcg_paths, cpu)->buf, new);
+ /* Don't need to wait for inflights, they'd have gotten NULL. */
+ }
+
+@@ -122,23 +132,24 @@ out:
+
+ static inline char *get_memcg_path_buf(void)
+ {
++ struct memcg_path *memcg_path = this_cpu_ptr(&memcg_paths);
+ char *buf;
+ int idx;
+
+ rcu_read_lock();
+- buf = rcu_dereference(*this_cpu_ptr(&memcg_path_buf));
++ buf = rcu_dereference(memcg_path->buf);
+ if (buf == NULL) {
+ rcu_read_unlock();
+ return NULL;
+ }
+- idx = this_cpu_add_return(memcg_path_buf_idx, MEMCG_PATH_BUF_SIZE) -
++ idx = local_add_return(MEMCG_PATH_BUF_SIZE, &memcg_path->buf_idx) -
+ MEMCG_PATH_BUF_SIZE;
+ return &buf[idx];
+ }
+
+ static inline void put_memcg_path_buf(void)
+ {
+- this_cpu_sub(memcg_path_buf_idx, MEMCG_PATH_BUF_SIZE);
++ local_sub(MEMCG_PATH_BUF_SIZE, &this_cpu_ptr(&memcg_paths)->buf_idx);
+ rcu_read_unlock();
+ }
+
+@@ -179,14 +190,14 @@ out:
+ #define TRACE_MMAP_LOCK_EVENT(type, mm, ...) \
+ do { \
+ const char *memcg_path; \
+- preempt_disable(); \
++ local_lock(&memcg_paths.lock); \
+ memcg_path = get_mm_memcg_path(mm); \
+ trace_mmap_lock_##type(mm, \
+ memcg_path != NULL ? memcg_path : "", \
+ ##__VA_ARGS__); \
+ if (likely(memcg_path != NULL)) \
+ put_memcg_path_buf(); \
+- preempt_enable(); \
++ local_unlock(&memcg_paths.lock); \
+ } while (0)
+
+ #else /* !CONFIG_MEMCG */
+--
+2.30.2
+
--- /dev/null
+From 5592c8669eb542c72d860161a74441c33eefd1a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jun 2021 19:42:33 -0700
+Subject: mm/page_alloc: fix counting of managed_pages
+
+From: Liu Shixin <liushixin2@huawei.com>
+
+[ Upstream commit f7ec104458e00d27a190348ac3a513f3df3699a4 ]
+
+commit f63661566fad ("mm/page_alloc.c: clear out zone->lowmem_reserve[] if
+the zone is empty") clears out zone->lowmem_reserve[] if zone is empty.
+But when zone is not empty and sysctl_lowmem_reserve_ratio[i] is set to
+zero, zone_managed_pages(zone) is not counted in the managed_pages either.
+This is inconsistent with the description of lowmem_reserve, so fix it.
+
+Link: https://lkml.kernel.org/r/20210527125707.3760259-1-liushixin2@huawei.com
+Fixes: f63661566fad ("mm/page_alloc.c: clear out zone->lowmem_reserve[] if the zone is empty")
+Signed-off-by: Liu Shixin <liushixin2@huawei.com>
+Reported-by: yangerkun <yangerkun@huawei.com>
+Reviewed-by: Baoquan He <bhe@redhat.com>
+Acked-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/page_alloc.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 2bf03c76504b..fc5beebf6988 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -8087,14 +8087,14 @@ static void setup_per_zone_lowmem_reserve(void)
+ unsigned long managed_pages = 0;
+
+ for (j = i + 1; j < MAX_NR_ZONES; j++) {
+- if (clear) {
+- zone->lowmem_reserve[j] = 0;
+- } else {
+- struct zone *upper_zone = &pgdat->node_zones[j];
++ struct zone *upper_zone = &pgdat->node_zones[j];
++
++ managed_pages += zone_managed_pages(upper_zone);
+
+- managed_pages += zone_managed_pages(upper_zone);
++ if (clear)
++ zone->lowmem_reserve[j] = 0;
++ else
+ zone->lowmem_reserve[j] = managed_pages / ratio;
+- }
+ }
+ }
+ }
+--
+2.30.2
+
--- /dev/null
+From 5a1ecea200f1e994d60f1b2a93c9a774e81ed58e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jun 2021 19:36:57 -0700
+Subject: mm/shmem: fix shmem_swapin() race with swapoff
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit 2efa33fc7f6ec94a3a538c1a264273c889be2b36 ]
+
+When I was investigating the swap code, I found the below possible race
+window:
+
+CPU 1 CPU 2
+----- -----
+shmem_swapin
+ swap_cluster_readahead
+ if (likely(si->flags & (SWP_BLKDEV | SWP_FS_OPS))) {
+ swapoff
+ ..
+ si->swap_file = NULL;
+ ..
+ struct inode *inode = si->swap_file->f_mapping->host;[oops!]
+
+Close this race window by using get/put_swap_device() to guard against
+concurrent swapoff.
+
+Link: https://lkml.kernel.org/r/20210426123316.806267-5-linmiaohe@huawei.com
+Fixes: 8fd2e0b505d1 ("mm: swap: check if swap backing device is congested or not")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Reviewed-by: "Huang, Ying" <ying.huang@intel.com>
+Cc: Dennis Zhou <dennis@kernel.org>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+Cc: Alex Shi <alexs@kernel.org>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Wei Yang <richard.weiyang@gmail.com>
+Cc: Yang Shi <shy828301@gmail.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Yu Zhao <yuzhao@google.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/shmem.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/mm/shmem.c b/mm/shmem.c
+index 5d46611cba8d..53f21016608e 100644
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -1696,7 +1696,8 @@ static int shmem_swapin_page(struct inode *inode, pgoff_t index,
+ struct address_space *mapping = inode->i_mapping;
+ struct shmem_inode_info *info = SHMEM_I(inode);
+ struct mm_struct *charge_mm = vma ? vma->vm_mm : current->mm;
+- struct page *page;
++ struct swap_info_struct *si;
++ struct page *page = NULL;
+ swp_entry_t swap;
+ int error;
+
+@@ -1704,6 +1705,12 @@ static int shmem_swapin_page(struct inode *inode, pgoff_t index,
+ swap = radix_to_swp_entry(*pagep);
+ *pagep = NULL;
+
++ /* Prevent swapoff from happening to us. */
++ si = get_swap_device(swap);
++ if (!si) {
++ error = EINVAL;
++ goto failed;
++ }
+ /* Look it up and read it in.. */
+ page = lookup_swap_cache(swap, NULL, 0);
+ if (!page) {
+@@ -1765,6 +1772,8 @@ static int shmem_swapin_page(struct inode *inode, pgoff_t index,
+ swap_free(swap);
+
+ *pagep = page;
++ if (si)
++ put_swap_device(si);
+ return 0;
+ failed:
+ if (!shmem_confirm_swap(mapping, index, swap))
+@@ -1775,6 +1784,9 @@ unlock:
+ put_page(page);
+ }
+
++ if (si)
++ put_swap_device(si);
++
+ return error;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 886494f5187a2d4a3e275a055735a4bdfd83e86f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 18:50:36 -0700
+Subject: mm/z3fold: fix potential memory leak in z3fold_destroy_pool()
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit dac0d1cfda56472378d330b1b76b9973557a7b1d ]
+
+There is a memory leak in z3fold_destroy_pool() as it forgets to
+free_percpu pool->unbuddied. Call free_percpu for pool->unbuddied to fix
+this issue.
+
+Link: https://lkml.kernel.org/r/20210619093151.1492174-6-linmiaohe@huawei.com
+Fixes: d30561c56f41 ("z3fold: use per-cpu unbuddied lists")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Reviewed-by: Vitaly Wool <vitaly.wool@konsulko.com>
+Cc: Hillf Danton <hdanton@sina.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/z3fold.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/mm/z3fold.c b/mm/z3fold.c
+index 7fe7adaaad01..33d8487ef6a8 100644
+--- a/mm/z3fold.c
++++ b/mm/z3fold.c
+@@ -1059,6 +1059,7 @@ static void z3fold_destroy_pool(struct z3fold_pool *pool)
+ destroy_workqueue(pool->compact_wq);
+ destroy_workqueue(pool->release_wq);
+ z3fold_unregister_migration(pool);
++ free_percpu(pool->unbuddied);
+ kfree(pool);
+ }
+
+--
+2.30.2
+
--- /dev/null
+From d81bd644c2a77d3d34ba28185bdfb8cc4d2e4f24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 18:50:39 -0700
+Subject: mm/z3fold: use release_z3fold_page_locked() to release locked z3fold
+ page
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit 28473d91ff7f686d58047ff55f2fa98ab59114a4 ]
+
+We should use release_z3fold_page_locked() to release z3fold page when
+it's locked, although it looks harmless to use release_z3fold_page() now.
+
+Link: https://lkml.kernel.org/r/20210619093151.1492174-7-linmiaohe@huawei.com
+Fixes: dcf5aedb24f8 ("z3fold: stricter locking and more careful reclaim")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Reviewed-by: Vitaly Wool <vitaly.wool@konsulko.com>
+Cc: Hillf Danton <hdanton@sina.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/z3fold.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mm/z3fold.c b/mm/z3fold.c
+index 33d8487ef6a8..ed0023dc5a3d 100644
+--- a/mm/z3fold.c
++++ b/mm/z3fold.c
+@@ -1383,7 +1383,7 @@ static int z3fold_reclaim_page(struct z3fold_pool *pool, unsigned int retries)
+ if (zhdr->foreign_handles ||
+ test_and_set_bit(PAGE_CLAIMED, &page->private)) {
+ if (kref_put(&zhdr->refcount,
+- release_z3fold_page))
++ release_z3fold_page_locked))
+ atomic64_dec(&pool->pages_nr);
+ else
+ z3fold_page_unlock(zhdr);
+--
+2.30.2
+
--- /dev/null
+From dd067a61e416d6173f6127ed2850fccbd76b2d5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 18:52:55 -0700
+Subject: mm/zswap.c: fix two bugs in zswap_writeback_entry()
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit 46b76f2e09dc35f70aca2f4349eb0d158f53fe93 ]
+
+In the ZSWAP_SWAPCACHE_FAIL and ZSWAP_SWAPCACHE_EXIST case, we forgot to
+call zpool_unmap_handle() when zpool can't sleep. And we might sleep in
+zswap_get_swap_cache_page() while zpool can't sleep. To fix all of these,
+zpool_unmap_handle() should be done before zswap_get_swap_cache_page()
+when zpool can't sleep.
+
+Link: https://lkml.kernel.org/r/20210522092242.3233191-4-linmiaohe@huawei.com
+Fixes: fc6697a89f56 ("mm/zswap: add the flag can_sleep_mapped")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Cc: Colin Ian King <colin.king@canonical.com>
+Cc: Dan Streetman <ddstreet@ieee.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Cc: Seth Jennings <sjenning@redhat.com>
+Cc: Tian Tao <tiantao6@hisilicon.com>
+Cc: Vitaly Wool <vitaly.wool@konsulko.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/zswap.c | 17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+diff --git a/mm/zswap.c b/mm/zswap.c
+index 20763267a219..706e0f98125a 100644
+--- a/mm/zswap.c
++++ b/mm/zswap.c
+@@ -967,6 +967,13 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
+ spin_unlock(&tree->lock);
+ BUG_ON(offset != entry->offset);
+
++ src = (u8 *)zhdr + sizeof(struct zswap_header);
++ if (!zpool_can_sleep_mapped(pool)) {
++ memcpy(tmp, src, entry->length);
++ src = tmp;
++ zpool_unmap_handle(pool, handle);
++ }
++
+ /* try to allocate swap cache page */
+ switch (zswap_get_swap_cache_page(swpentry, &page)) {
+ case ZSWAP_SWAPCACHE_FAIL: /* no memory or invalidate happened */
+@@ -982,17 +989,7 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
+ case ZSWAP_SWAPCACHE_NEW: /* page is locked */
+ /* decompress */
+ acomp_ctx = raw_cpu_ptr(entry->pool->acomp_ctx);
+-
+ dlen = PAGE_SIZE;
+- src = (u8 *)zhdr + sizeof(struct zswap_header);
+-
+- if (!zpool_can_sleep_mapped(pool)) {
+-
+- memcpy(tmp, src, entry->length);
+- src = tmp;
+-
+- zpool_unmap_handle(pool, handle);
+- }
+
+ mutex_lock(acomp_ctx->mutex);
+ sg_init_one(&input, src, entry->length);
+--
+2.30.2
+
--- /dev/null
+From 3519d36643e78981f921709ad97f8d473dde8207 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 11:00:20 +0930
+Subject: mmc: sdhci-of-aspeed: Turn down a phase correction warning
+
+From: Andrew Jeffery <andrew@aj.id.au>
+
+[ Upstream commit a7ab186f60785850b5af1be183867000485ad491 ]
+
+The card timing and the bus frequency are not changed atomically with
+respect to calls to the set_clock() callback in the driver. The result
+is the driver sees a transient state where there's a mismatch between
+the two and thus the inputs to the phase correction calculation
+formula are garbage.
+
+Switch from dev_warn() to dev_dbg() to avoid noise in the normal case,
+though the change does make bad configurations less likely to be
+noticed.
+
+Reported-by: Joel Stanley <joel@jms.id.au>
+Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
+Reviewed-by: Joel Stanley <joel@jms.id.au>
+Link: https://lore.kernel.org/r/20210607013020.85885-1-andrew@aj.id.au
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci-of-aspeed.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sdhci-of-aspeed.c b/drivers/mmc/host/sdhci-of-aspeed.c
+index d001c51074a0..e4665a438ec5 100644
+--- a/drivers/mmc/host/sdhci-of-aspeed.c
++++ b/drivers/mmc/host/sdhci-of-aspeed.c
+@@ -150,7 +150,7 @@ static int aspeed_sdhci_phase_to_tap(struct device *dev, unsigned long rate_hz,
+
+ tap = div_u64(phase_period_ps, prop_delay_ps);
+ if (tap > ASPEED_SDHCI_NR_TAPS) {
+- dev_warn(dev,
++ dev_dbg(dev,
+ "Requested out of range phase tap %d for %d degrees of phase compensation at %luHz, clamping to tap %d\n",
+ tap, phase_deg, rate_hz, ASPEED_SDHCI_NR_TAPS);
+ tap = ASPEED_SDHCI_NR_TAPS;
+--
+2.30.2
+
--- /dev/null
+From ef85593168da12f0dad5bc46510bae0ea7e9ff1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Jun 2021 11:54:03 +0200
+Subject: mmc: sdhci-sprd: use sdhci_sprd_writew
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+[ Upstream commit 961470820021e6f9d74db4837bd6831a1a30341b ]
+
+The sdhci_sprd_writew() was defined by never used in sdhci_ops:
+
+ drivers/mmc/host/sdhci-sprd.c:134:20: warning: unused function 'sdhci_sprd_writew'
+
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Link: https://lore.kernel.org/r/20210601095403.236007-2-krzysztof.kozlowski@canonical.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci-sprd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c
+index 5dc36efff47f..11e375579cfb 100644
+--- a/drivers/mmc/host/sdhci-sprd.c
++++ b/drivers/mmc/host/sdhci-sprd.c
+@@ -393,6 +393,7 @@ static void sdhci_sprd_request_done(struct sdhci_host *host,
+ static struct sdhci_ops sdhci_sprd_ops = {
+ .read_l = sdhci_sprd_readl,
+ .write_l = sdhci_sprd_writel,
++ .write_w = sdhci_sprd_writew,
+ .write_b = sdhci_sprd_writeb,
+ .set_clock = sdhci_sprd_set_clock,
+ .get_max_clock = sdhci_sprd_get_max_clock,
+--
+2.30.2
+
--- /dev/null
+From ec8cad51f0e2f9a898374ae5e2da604ac9c3c5b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 May 2021 10:03:21 +0800
+Subject: mmc: usdhi6rol0: fix error return code in usdhi6_probe()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit 2f9ae69e5267f53e89e296fccee291975a85f0eb ]
+
+Fix to return a negative error code from the error handling case instead
+of 0, as done elsewhere in this function.
+
+Fixes: 75fa9ea6e3c0 ("mmc: add a driver for the Renesas usdhi6rol0 SD/SDIO host controller")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Link: https://lore.kernel.org/r/20210508020321.1677-1-thunder.leizhen@huawei.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/usdhi6rol0.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mmc/host/usdhi6rol0.c b/drivers/mmc/host/usdhi6rol0.c
+index 615f3d008af1..b9b79b1089a0 100644
+--- a/drivers/mmc/host/usdhi6rol0.c
++++ b/drivers/mmc/host/usdhi6rol0.c
+@@ -1801,6 +1801,7 @@ static int usdhi6_probe(struct platform_device *pdev)
+
+ version = usdhi6_read(host, USDHI6_VERSION);
+ if ((version & 0xfff) != 0xa0d) {
++ ret = -EPERM;
+ dev_err(dev, "Version not recognized %x\n", version);
+ goto e_clk_off;
+ }
+--
+2.30.2
+
--- /dev/null
+From 748f00534ca4ad6fa31b56d63f13089a63cbcdbb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Jun 2021 13:33:20 +0000
+Subject: mmc: via-sdmmc: add a check against NULL pointer dereference
+
+From: Zheyu Ma <zheyuma97@gmail.com>
+
+[ Upstream commit 45c8ddd06c4b729c56a6083ab311bfbd9643f4a6 ]
+
+Before referencing 'host->data', the driver needs to check whether it is
+null pointer, otherwise it will cause a null pointer reference.
+
+This log reveals it:
+
+[ 29.355199] BUG: kernel NULL pointer dereference, address:
+0000000000000014
+[ 29.357323] #PF: supervisor write access in kernel mode
+[ 29.357706] #PF: error_code(0x0002) - not-present page
+[ 29.358088] PGD 0 P4D 0
+[ 29.358280] Oops: 0002 [#1] PREEMPT SMP PTI
+[ 29.358595] CPU: 2 PID: 0 Comm: swapper/2 Not tainted 5.12.4-
+g70e7f0549188-dirty #102
+[ 29.359164] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009),
+BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014
+[ 29.359978] RIP: 0010:via_sdc_isr+0x21f/0x410
+[ 29.360314] Code: ff ff e8 84 aa d0 fd 66 45 89 7e 28 66 41 f7 c4 00
+10 75 56 e8 72 aa d0 fd 66 41 f7 c4 00 c0 74 10 e8 65 aa d0 fd 48 8b 43
+18 <c7> 40 14 ac ff ff ff e8 55 aa d0 fd 48 89 df e8 ad fb ff ff e9 77
+[ 29.361661] RSP: 0018:ffffc90000118e98 EFLAGS: 00010046
+[ 29.362042] RAX: 0000000000000000 RBX: ffff888107d77880
+RCX: 0000000000000000
+[ 29.362564] RDX: 0000000000000000 RSI: ffffffff835d20bb
+RDI: 00000000ffffffff
+[ 29.363085] RBP: ffffc90000118ed8 R08: 0000000000000001
+R09: 0000000000000001
+[ 29.363604] R10: 0000000000000000 R11: 0000000000000001
+R12: 0000000000008600
+[ 29.364128] R13: ffff888107d779c8 R14: ffffc90009c00200
+R15: 0000000000008000
+[ 29.364651] FS: 0000000000000000(0000) GS:ffff88817bc80000(0000)
+knlGS:0000000000000000
+[ 29.365235] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 29.365655] CR2: 0000000000000014 CR3: 0000000005a2e000
+CR4: 00000000000006e0
+[ 29.366170] DR0: 0000000000000000 DR1: 0000000000000000
+DR2: 0000000000000000
+[ 29.366683] DR3: 0000000000000000 DR6: 00000000fffe0ff0
+DR7: 0000000000000400
+[ 29.367197] Call Trace:
+[ 29.367381] <IRQ>
+[ 29.367537] __handle_irq_event_percpu+0x53/0x3e0
+[ 29.367916] handle_irq_event_percpu+0x35/0x90
+[ 29.368247] handle_irq_event+0x39/0x60
+[ 29.368632] handle_fasteoi_irq+0xc2/0x1d0
+[ 29.368950] __common_interrupt+0x7f/0x150
+[ 29.369254] common_interrupt+0xb4/0xd0
+[ 29.369547] </IRQ>
+[ 29.369708] asm_common_interrupt+0x1e/0x40
+[ 29.370016] RIP: 0010:native_safe_halt+0x17/0x20
+[ 29.370360] Code: 07 0f 00 2d db 80 43 00 f4 5d c3 0f 1f 84 00 00 00
+00 00 8b 05 c2 37 e5 01 55 48 89 e5 85 c0 7e 07 0f 00 2d bb 80 43 00 fb
+f4 <5d> c3 cc cc cc cc cc cc cc 55 48 89 e5 e8 67 53 ff ff 8b 0d f9 91
+[ 29.371696] RSP: 0018:ffffc9000008fe90 EFLAGS: 00000246
+[ 29.372079] RAX: 0000000000000000 RBX: 0000000000000002
+RCX: 0000000000000000
+[ 29.372595] RDX: 0000000000000000 RSI: ffffffff854f67a4
+RDI: ffffffff85403406
+[ 29.373122] RBP: ffffc9000008fe90 R08: 0000000000000001
+R09: 0000000000000001
+[ 29.373646] R10: 0000000000000000 R11: 0000000000000001
+R12: ffffffff86009188
+[ 29.374160] R13: 0000000000000000 R14: 0000000000000000
+R15: ffff888100258000
+[ 29.374690] default_idle+0x9/0x10
+[ 29.374944] arch_cpu_idle+0xa/0x10
+[ 29.375198] default_idle_call+0x6e/0x250
+[ 29.375491] do_idle+0x1f0/0x2d0
+[ 29.375740] cpu_startup_entry+0x18/0x20
+[ 29.376034] start_secondary+0x11f/0x160
+[ 29.376328] secondary_startup_64_no_verify+0xb0/0xbb
+[ 29.376705] Modules linked in:
+[ 29.376939] Dumping ftrace buffer:
+[ 29.377187] (ftrace buffer empty)
+[ 29.377460] CR2: 0000000000000014
+[ 29.377712] ---[ end trace 51a473dffb618c47 ]---
+[ 29.378056] RIP: 0010:via_sdc_isr+0x21f/0x410
+[ 29.378380] Code: ff ff e8 84 aa d0 fd 66 45 89 7e 28 66 41 f7 c4 00
+10 75 56 e8 72 aa d0 fd 66 41 f7 c4 00 c0 74 10 e8 65 aa d0 fd 48 8b 43
+18 <c7> 40 14 ac ff ff ff e8 55 aa d0 fd 48 89 df e8 ad fb ff ff e9 77
+[ 29.379714] RSP: 0018:ffffc90000118e98 EFLAGS: 00010046
+[ 29.380098] RAX: 0000000000000000 RBX: ffff888107d77880
+RCX: 0000000000000000
+[ 29.380614] RDX: 0000000000000000 RSI: ffffffff835d20bb
+RDI: 00000000ffffffff
+[ 29.381134] RBP: ffffc90000118ed8 R08: 0000000000000001
+R09: 0000000000000001
+[ 29.381653] R10: 0000000000000000 R11: 0000000000000001
+R12: 0000000000008600
+[ 29.382176] R13: ffff888107d779c8 R14: ffffc90009c00200
+R15: 0000000000008000
+[ 29.382697] FS: 0000000000000000(0000) GS:ffff88817bc80000(0000)
+knlGS:0000000000000000
+[ 29.383277] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 29.383697] CR2: 0000000000000014 CR3: 0000000005a2e000
+CR4: 00000000000006e0
+[ 29.384223] DR0: 0000000000000000 DR1: 0000000000000000
+DR2: 0000000000000000
+[ 29.384736] DR3: 0000000000000000 DR6: 00000000fffe0ff0
+DR7: 0000000000000400
+[ 29.385260] Kernel panic - not syncing: Fatal exception in interrupt
+[ 29.385882] Dumping ftrace buffer:
+[ 29.386135] (ftrace buffer empty)
+[ 29.386401] Kernel Offset: disabled
+[ 29.386656] Rebooting in 1 seconds..
+
+Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
+Link: https://lore.kernel.org/r/1622727200-15808-1-git-send-email-zheyuma97@gmail.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/via-sdmmc.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c
+index a1d098560099..c32df5530b94 100644
+--- a/drivers/mmc/host/via-sdmmc.c
++++ b/drivers/mmc/host/via-sdmmc.c
+@@ -857,6 +857,9 @@ static void via_sdc_data_isr(struct via_crdr_mmc_host *host, u16 intmask)
+ {
+ BUG_ON(intmask == 0);
+
++ if (!host->data)
++ return;
++
+ if (intmask & VIA_CRDR_SDSTS_DT)
+ host->data->error = -ETIMEDOUT;
+ else if (intmask & (VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC))
+--
+2.30.2
+
--- /dev/null
+From b5cd3a55c3e0c08808e34a0f36cd4f5d89c78407 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Jun 2021 17:33:08 -0700
+Subject: mptcp: avoid race on msk state changes
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit 490274b47468793e3e157c2df6b2da0e646cc4a9 ]
+
+The msk socket state is currently updated in a few spots without
+owning the msk socket lock itself.
+
+Some of such operations are safe, as they happens before exposing
+the msk socket to user-space and can't race with other changes.
+
+A couple of them, at connect time, can actually race with close()
+or shutdown(), leaving breaking the socket state machine.
+
+This change addresses the issue moving such update under the msk
+socket lock with the usual:
+
+<acquire spinlock>
+<check sk lock onwers>
+<ev defer to release_cb>
+
+scheme.
+
+Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/56
+Fixes: 8fd738049ac3 ("mptcp: fallback in case of simultaneous connect")
+Fixes: c3c123d16c0e ("net: mptcp: don't hang in mptcp_sendmsg() after TCP fallback")
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/protocol.c | 5 +++++
+ net/mptcp/protocol.h | 2 ++
+ net/mptcp/subflow.c | 30 ++++++++++++++++++++++--------
+ 3 files changed, 29 insertions(+), 8 deletions(-)
+
+diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
+index 632350018fb6..8ead550df8b1 100644
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -2946,6 +2946,11 @@ static void mptcp_release_cb(struct sock *sk)
+ spin_lock_bh(&sk->sk_lock.slock);
+ }
+
++ /* be sure to set the current sk state before tacking actions
++ * depending on sk_state
++ */
++ if (test_and_clear_bit(MPTCP_CONNECTED, &mptcp_sk(sk)->flags))
++ __mptcp_set_connected(sk);
+ if (test_and_clear_bit(MPTCP_CLEAN_UNA, &mptcp_sk(sk)->flags))
+ __mptcp_clean_una_wakeup(sk);
+ if (test_and_clear_bit(MPTCP_ERROR_REPORT, &mptcp_sk(sk)->flags))
+diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
+index 5d7c44028e47..7b634568f49c 100644
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -109,6 +109,7 @@
+ #define MPTCP_ERROR_REPORT 8
+ #define MPTCP_RETRANSMIT 9
+ #define MPTCP_WORK_SYNC_SETSOCKOPT 10
++#define MPTCP_CONNECTED 11
+
+ static inline bool before64(__u64 seq1, __u64 seq2)
+ {
+@@ -579,6 +580,7 @@ void mptcp_get_options(const struct sk_buff *skb,
+ struct mptcp_options_received *mp_opt);
+
+ void mptcp_finish_connect(struct sock *sk);
++void __mptcp_set_connected(struct sock *sk);
+ static inline bool mptcp_is_fully_established(struct sock *sk)
+ {
+ return inet_sk_state_load(sk) == TCP_ESTABLISHED &&
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index f5bb3a0e9975..cbc452d0901e 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -371,6 +371,24 @@ static bool subflow_use_different_dport(struct mptcp_sock *msk, const struct soc
+ return inet_sk(sk)->inet_dport != inet_sk((struct sock *)msk)->inet_dport;
+ }
+
++void __mptcp_set_connected(struct sock *sk)
++{
++ if (sk->sk_state == TCP_SYN_SENT) {
++ inet_sk_state_store(sk, TCP_ESTABLISHED);
++ sk->sk_state_change(sk);
++ }
++}
++
++static void mptcp_set_connected(struct sock *sk)
++{
++ mptcp_data_lock(sk);
++ if (!sock_owned_by_user(sk))
++ __mptcp_set_connected(sk);
++ else
++ set_bit(MPTCP_CONNECTED, &mptcp_sk(sk)->flags);
++ mptcp_data_unlock(sk);
++}
++
+ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
+ {
+ struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
+@@ -379,10 +397,6 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
+
+ subflow->icsk_af_ops->sk_rx_dst_set(sk, skb);
+
+- if (inet_sk_state_load(parent) == TCP_SYN_SENT) {
+- inet_sk_state_store(parent, TCP_ESTABLISHED);
+- parent->sk_state_change(parent);
+- }
+
+ /* be sure no special action on any packet other than syn-ack */
+ if (subflow->conn_finished)
+@@ -411,6 +425,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
+ subflow->remote_key);
+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVEACK);
+ mptcp_finish_connect(sk);
++ mptcp_set_connected(parent);
+ } else if (subflow->request_join) {
+ u8 hmac[SHA256_DIGEST_SIZE];
+
+@@ -451,6 +466,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
+ } else if (mptcp_check_fallback(sk)) {
+ fallback:
+ mptcp_rcv_space_init(mptcp_sk(parent), sk);
++ mptcp_set_connected(parent);
+ }
+ return;
+
+@@ -558,6 +574,7 @@ static void mptcp_sock_destruct(struct sock *sk)
+
+ static void mptcp_force_close(struct sock *sk)
+ {
++ /* the msk is not yet exposed to user-space */
+ inet_sk_state_store(sk, TCP_CLOSE);
+ sk_common_release(sk);
+ }
+@@ -1474,10 +1491,7 @@ static void subflow_state_change(struct sock *sk)
+ mptcp_rcv_space_init(mptcp_sk(parent), sk);
+ pr_fallback(mptcp_sk(parent));
+ subflow->conn_finished = 1;
+- if (inet_sk_state_load(parent) == TCP_SYN_SENT) {
+- inet_sk_state_store(parent, TCP_ESTABLISHED);
+- parent->sk_state_change(parent);
+- }
++ mptcp_set_connected(parent);
+ }
+
+ /* as recvmsg() does not acquire the subflow socket for ssk selection
+--
+2.30.2
+
--- /dev/null
+From f1e94896930f6dc9b3dd755a1c262e2568a91394 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 15:02:21 -0700
+Subject: mptcp: fix 32 bit DSN expansion
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit 5957a8901db44c03540505ccedd95031c21ef2f2 ]
+
+The current implementation of 32 bit DSN expansion is buggy.
+After the previous patch, we can simply reuse the newly
+introduced helper to do the expansion safely.
+
+Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/120
+Fixes: 648ef4b88673 ("mptcp: Implement MPTCP receive path")
+Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/subflow.c | 17 +----------------
+ 1 file changed, 1 insertion(+), 16 deletions(-)
+
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 3a396451d628..f5bb3a0e9975 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -775,15 +775,6 @@ enum mapping_status {
+ MAPPING_DUMMY
+ };
+
+-static u64 expand_seq(u64 old_seq, u16 old_data_len, u64 seq)
+-{
+- if ((u32)seq == (u32)old_seq)
+- return old_seq;
+-
+- /* Assume map covers data not mapped yet. */
+- return seq | ((old_seq + old_data_len + 1) & GENMASK_ULL(63, 32));
+-}
+-
+ static void dbg_bad_map(struct mptcp_subflow_context *subflow, u32 ssn)
+ {
+ pr_debug("Bad mapping: ssn=%d map_seq=%d map_data_len=%d",
+@@ -907,13 +898,7 @@ static enum mapping_status get_mapping_status(struct sock *ssk,
+ data_len--;
+ }
+
+- if (!mpext->dsn64) {
+- map_seq = expand_seq(subflow->map_seq, subflow->map_data_len,
+- mpext->data_seq);
+- pr_debug("expanded seq=%llu", subflow->map_seq);
+- } else {
+- map_seq = mpext->data_seq;
+- }
++ map_seq = mptcp_expand_seq(READ_ONCE(msk->ack_seq), mpext->data_seq, mpext->dsn64);
+ WRITE_ONCE(mptcp_sk(subflow->conn)->use_64bit_ack, !!mpext->dsn64);
+
+ if (subflow->map_valid) {
+--
+2.30.2
+
--- /dev/null
+From 1b5d8f01259b008a4e95913db012125b8d1d1c00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 15:02:20 -0700
+Subject: mptcp: fix bad handling of 32 bit ack wrap-around
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit 1502328f17ab0684ca5ed6764433aa0a83bdaf95 ]
+
+When receiving 32 bits DSS ack from the peer, the MPTCP need
+to expand them to 64 bits value. The current code is buggy
+WRT detecting 32 bits ack wrap-around: when the wrap-around
+happens the current unsigned 32 bit ack value is lower than
+the previous one.
+
+Additionally check for possible reverse wrap and make the helper
+visible, so that we could re-use it for the next patch.
+
+Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/204
+Fixes: cc9d25669866 ("mptcp: update per unacked sequence on pkt reception")
+Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/options.c | 29 +++++++++++++++--------------
+ net/mptcp/protocol.h | 8 ++++++++
+ 2 files changed, 23 insertions(+), 14 deletions(-)
+
+diff --git a/net/mptcp/options.c b/net/mptcp/options.c
+index 9b263f27ce9b..b87e46f515fb 100644
+--- a/net/mptcp/options.c
++++ b/net/mptcp/options.c
+@@ -896,19 +896,20 @@ reset:
+ return false;
+ }
+
+-static u64 expand_ack(u64 old_ack, u64 cur_ack, bool use_64bit)
++u64 __mptcp_expand_seq(u64 old_seq, u64 cur_seq)
+ {
+- u32 old_ack32, cur_ack32;
+-
+- if (use_64bit)
+- return cur_ack;
+-
+- old_ack32 = (u32)old_ack;
+- cur_ack32 = (u32)cur_ack;
+- cur_ack = (old_ack & GENMASK_ULL(63, 32)) + cur_ack32;
+- if (unlikely(before(cur_ack32, old_ack32)))
+- return cur_ack + (1LL << 32);
+- return cur_ack;
++ u32 old_seq32, cur_seq32;
++
++ old_seq32 = (u32)old_seq;
++ cur_seq32 = (u32)cur_seq;
++ cur_seq = (old_seq & GENMASK_ULL(63, 32)) + cur_seq32;
++ if (unlikely(cur_seq32 < old_seq32 && before(old_seq32, cur_seq32)))
++ return cur_seq + (1LL << 32);
++
++ /* reverse wrap could happen, too */
++ if (unlikely(cur_seq32 > old_seq32 && after(old_seq32, cur_seq32)))
++ return cur_seq - (1LL << 32);
++ return cur_seq;
+ }
+
+ static void ack_update_msk(struct mptcp_sock *msk,
+@@ -926,7 +927,7 @@ static void ack_update_msk(struct mptcp_sock *msk,
+ * more dangerous than missing an ack
+ */
+ old_snd_una = msk->snd_una;
+- new_snd_una = expand_ack(old_snd_una, mp_opt->data_ack, mp_opt->ack64);
++ new_snd_una = mptcp_expand_seq(old_snd_una, mp_opt->data_ack, mp_opt->ack64);
+
+ /* ACK for data not even sent yet? Ignore. */
+ if (after64(new_snd_una, snd_nxt))
+@@ -963,7 +964,7 @@ bool mptcp_update_rcv_data_fin(struct mptcp_sock *msk, u64 data_fin_seq, bool us
+ return false;
+
+ WRITE_ONCE(msk->rcv_data_fin_seq,
+- expand_ack(READ_ONCE(msk->ack_seq), data_fin_seq, use_64bit));
++ mptcp_expand_seq(READ_ONCE(msk->ack_seq), data_fin_seq, use_64bit));
+ WRITE_ONCE(msk->rcv_data_fin, 1);
+
+ return true;
+diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
+index 385796f0ef19..5d7c44028e47 100644
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -593,6 +593,14 @@ int mptcp_setsockopt(struct sock *sk, int level, int optname,
+ int mptcp_getsockopt(struct sock *sk, int level, int optname,
+ char __user *optval, int __user *option);
+
++u64 __mptcp_expand_seq(u64 old_seq, u64 cur_seq);
++static inline u64 mptcp_expand_seq(u64 old_seq, u64 cur_seq, bool use_64bit)
++{
++ if (use_64bit)
++ return cur_seq;
++
++ return __mptcp_expand_seq(old_seq, cur_seq);
++}
+ void __mptcp_check_push(struct sock *sk, struct sock *ssk);
+ void __mptcp_data_acked(struct sock *sk);
+ void __mptcp_error_report(struct sock *sk);
+--
+2.30.2
+
--- /dev/null
+From 6e4158ca21f601ef7a7a9d456805d45b3bfb19ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 May 2021 16:54:24 -0700
+Subject: mptcp: fix pr_debug in mptcp_token_new_connect
+
+From: Jianguo Wu <wujianguo@chinatelecom.cn>
+
+[ Upstream commit 2f1af441fd5dd5caf0807bb19ce9bbf9325ce534 ]
+
+After commit 2c5ebd001d4f ("mptcp: refactor token container"),
+pr_debug() is called before mptcp_crypto_key_gen_sha() in
+mptcp_token_new_connect(), so the output local_key, token and
+idsn are 0, like:
+
+ MPTCP: ssk=00000000f6b3c4a2, local_key=0, token=0, idsn=0
+
+Move pr_debug() after mptcp_crypto_key_gen_sha().
+
+Fixes: 2c5ebd001d4f ("mptcp: refactor token container")
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Jianguo Wu <wujianguo@chinatelecom.cn>
+Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/token.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/mptcp/token.c b/net/mptcp/token.c
+index 8f0270a780ce..72a24e63b131 100644
+--- a/net/mptcp/token.c
++++ b/net/mptcp/token.c
+@@ -156,9 +156,6 @@ int mptcp_token_new_connect(struct sock *sk)
+ int retries = TOKEN_MAX_RETRIES;
+ struct token_bucket *bucket;
+
+- pr_debug("ssk=%p, local_key=%llu, token=%u, idsn=%llu\n",
+- sk, subflow->local_key, subflow->token, subflow->idsn);
+-
+ again:
+ mptcp_crypto_key_gen_sha(&subflow->local_key, &subflow->token,
+ &subflow->idsn);
+@@ -172,6 +169,9 @@ again:
+ goto again;
+ }
+
++ pr_debug("ssk=%p, local_key=%llu, token=%u, idsn=%llu\n",
++ sk, subflow->local_key, subflow->token, subflow->idsn);
++
+ WRITE_ONCE(msk->token, subflow->token);
+ __sk_nulls_add_node_rcu((struct sock *)msk, &bucket->msk_chain);
+ bucket->chain_len++;
+--
+2.30.2
+
--- /dev/null
+From 26215987e5a01e61a5d1e32355f19dea24f71b97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 May 2021 16:54:26 -0700
+Subject: mptcp: generate subflow hmac after mptcp_finish_join()
+
+From: Jianguo Wu <wujianguo@chinatelecom.cn>
+
+[ Upstream commit 0a4d8e96e4fd687af92b961d5cdcea0fdbde05fe ]
+
+For outgoing subflow join, when recv SYNACK, in subflow_finish_connect(),
+the mptcp_finish_join() may return false in some cases, and send a RESET
+to remote, and no local hmac is required.
+So generate subflow hmac after mptcp_finish_join().
+
+Fixes: ec3edaa7ca6c ("mptcp: Add handling of outgoing MP_JOIN requests")
+Signed-off-by: Jianguo Wu <wujianguo@chinatelecom.cn>
+Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/subflow.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index be1de4084196..3a396451d628 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -430,15 +430,15 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
+ goto do_reset;
+ }
+
++ if (!mptcp_finish_join(sk))
++ goto do_reset;
++
+ subflow_generate_hmac(subflow->local_key, subflow->remote_key,
+ subflow->local_nonce,
+ subflow->remote_nonce,
+ hmac);
+ memcpy(subflow->hmac, hmac, MPTCPOPT_HMAC_LEN);
+
+- if (!mptcp_finish_join(sk))
+- goto do_reset;
+-
+ subflow->mp_join = 1;
+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX);
+
+--
+2.30.2
+
--- /dev/null
+From 681512e7cd507f86bb0d1af18c01fc7e155d3e98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 May 2021 16:54:28 -0700
+Subject: mptcp: make sure flag signal is set when add addr with port
+
+From: Jianguo Wu <wujianguo@chinatelecom.cn>
+
+[ Upstream commit eb5fb629f56da3f40f496c807da44a7ce7644779 ]
+
+When add address with port, it is mean to create a listening socket,
+and send an ADD_ADDR to remote, so it must have flag signal set,
+add this check in mptcp_pm_parse_addr().
+
+Fixes: a77e9179c7651 ("mptcp: deal with MPTCP_PM_ADDR_ATTR_PORT in PM netlink")
+Acked-by: Geliang Tang <geliangtang@gmail.com>
+Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Signed-off-by: Jianguo Wu <wujianguo@chinatelecom.cn>
+Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/pm_netlink.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
+index 2469e06a3a9d..3f5d90a20235 100644
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -971,8 +971,14 @@ skip_family:
+ if (tb[MPTCP_PM_ADDR_ATTR_FLAGS])
+ entry->flags = nla_get_u32(tb[MPTCP_PM_ADDR_ATTR_FLAGS]);
+
+- if (tb[MPTCP_PM_ADDR_ATTR_PORT])
++ if (tb[MPTCP_PM_ADDR_ATTR_PORT]) {
++ if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) {
++ NL_SET_ERR_MSG_ATTR(info->extack, attr,
++ "flags must have signal when using port");
++ return -EINVAL;
++ }
+ entry->addr.port = htons(nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_PORT]));
++ }
+
+ return 0;
+ }
+--
+2.30.2
+
--- /dev/null
+From 1e8644124135c1b9f76291eba29964b2c4921982 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 23:14:54 +0800
+Subject: mt76: connac: fix WoW with disconnetion and bitmap pattern
+
+From: YN Chen <yn.chen@mediatek.com>
+
+[ Upstream commit 193e5f22eeb2a9661bff8bc0d8519e6ded48c807 ]
+
+Update MCU command usage to fix WoW configuration with disconnection
+and bitmap pattern and to avoid magic number.
+
+Fixes: ffa1bf97425b ("mt76: mt7921: introduce PM support")
+Reviewed-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: YN Chen <yn.chen@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 11 +++++++----
+ drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h | 8 ++++++++
+ 2 files changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+index 619561606f96..eb19721f9d79 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+@@ -1939,7 +1939,7 @@ mt76_connac_mcu_set_wow_pattern(struct mt76_dev *dev,
+ ptlv->index = index;
+
+ memcpy(ptlv->pattern, pattern->pattern, pattern->pattern_len);
+- memcpy(ptlv->mask, pattern->mask, pattern->pattern_len / 8);
++ memcpy(ptlv->mask, pattern->mask, DIV_ROUND_UP(pattern->pattern_len, 8));
+
+ return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_SUSPEND, true);
+ }
+@@ -1974,14 +1974,17 @@ mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif,
+ };
+
+ if (wowlan->magic_pkt)
+- req.wow_ctrl_tlv.trigger |= BIT(0);
++ req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_MAGIC;
+ if (wowlan->disconnect)
+- req.wow_ctrl_tlv.trigger |= BIT(2);
++ req.wow_ctrl_tlv.trigger |= (UNI_WOW_DETECT_TYPE_DISCONNECT |
++ UNI_WOW_DETECT_TYPE_BCN_LOST);
+ if (wowlan->nd_config) {
+ mt76_connac_mcu_sched_scan_req(phy, vif, wowlan->nd_config);
+- req.wow_ctrl_tlv.trigger |= BIT(5);
++ req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_SCH_SCAN_HIT;
+ mt76_connac_mcu_sched_scan_enable(phy, vif, suspend);
+ }
++ if (wowlan->n_patterns)
++ req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_BITMAP;
+
+ if (mt76_is_mmio(dev))
+ req.wow_ctrl_tlv.wakeup_hif = WOW_PCIE;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+index a1096861d04a..3bcae732872e 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+@@ -590,6 +590,14 @@ enum {
+ UNI_OFFLOAD_OFFLOAD_BMC_RPY_DETECT,
+ };
+
++#define UNI_WOW_DETECT_TYPE_MAGIC BIT(0)
++#define UNI_WOW_DETECT_TYPE_ANY BIT(1)
++#define UNI_WOW_DETECT_TYPE_DISCONNECT BIT(2)
++#define UNI_WOW_DETECT_TYPE_GTK_REKEY_FAIL BIT(3)
++#define UNI_WOW_DETECT_TYPE_BCN_LOST BIT(4)
++#define UNI_WOW_DETECT_TYPE_SCH_SCAN_HIT BIT(5)
++#define UNI_WOW_DETECT_TYPE_BITMAP BIT(6)
++
+ enum {
+ UNI_SUSPEND_MODE_SETTING,
+ UNI_SUSPEND_WOW_CTRL,
+--
+2.30.2
+
--- /dev/null
+From ee5003cc10b7fc98e7064cffd2989722e2b5ec91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 23:14:51 +0800
+Subject: mt76: connac: fw_own rely on all packet memory all being free
+
+From: Sean Wang <sean.wang@mediatek.com>
+
+[ Upstream commit 4bfa291251623486711693a69d9eaa539478d340 ]
+
+If the device is MMIO-based, we must ensure all TxD/TxP on the host
+memory all being consumed by the device prior to safely switching to
+fw_own state.
+
+Fixes: ec7bd7b4a9c0 ("mt76: connac: check wake refcount in mcu_fw_pmctrl")
+Reviewed-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt76_connac.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+index 6c889b90fd12..337c5ece7ec3 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+@@ -127,8 +127,12 @@ mt76_connac_pm_unref(struct mt76_connac_pm *pm)
+ static inline bool
+ mt76_connac_skip_fw_pmctrl(struct mt76_phy *phy, struct mt76_connac_pm *pm)
+ {
++ struct mt76_dev *dev = phy->dev;
+ bool ret;
+
++ if (dev->token_count)
++ return true;
++
+ spin_lock_bh(&pm->wake.lock);
+ ret = pm->wake.count || test_and_set_bit(MT76_STATE_PM, &phy->state);
+ spin_unlock_bh(&pm->wake.lock);
+--
+2.30.2
+
--- /dev/null
+From 9b5a2bf9cd8a5de55394697c6ac3a8014319ccf7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Apr 2021 12:05:00 +0200
+Subject: mt76: fix possible NULL pointer dereference in mt76_tx
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit d7400a2f3e295b8cee692c7a66e10f60015a3c37 ]
+
+Even if this is not a real issue since mt76_tx is never run with wcid set
+to NULL, fix a theoretical NULL pointer dereference in mt76_tx routine
+
+Fixes: db9f11d3433f7 ("mt76: store wcid tx rate info in one u32 reduce locking")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/tx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
+index 53ea8de82df0..441d06e30b1a 100644
+--- a/drivers/net/wireless/mediatek/mt76/tx.c
++++ b/drivers/net/wireless/mediatek/mt76/tx.c
+@@ -285,7 +285,7 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta,
+ skb_set_queue_mapping(skb, qid);
+ }
+
+- if (!(wcid->tx_info & MT_WCID_TX_INFO_SET))
++ if (wcid && !(wcid->tx_info & MT_WCID_TX_INFO_SET))
+ ieee80211_get_tx_rates(info->control.vif, sta, skb,
+ info->control.rates, 1);
+
+--
+2.30.2
+
--- /dev/null
+From 16e04729fd2406ac1edda9b99b946e7f9211cb4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Apr 2021 12:07:14 +0200
+Subject: mt76: mt7615: fix NULL pointer dereference in tx_prepare_skb()
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 8d3cdc1bbb1d355f0ebef973175ae5fd74286feb ]
+
+Fix theoretical NULL pointer dereference in mt7615_tx_prepare_skb and
+mt7663_usb_sdio_tx_prepare_skb routines. This issue has been identified
+by code analysis.
+
+Fixes: 6aa4ed7927f11 ("mt76: mt7615: implement DMA support for MT7622")
+Fixes: 4bb586bc33b98 ("mt76: mt7663u: sync probe sampling with rate configuration")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c | 5 +++--
+ drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c | 5 +++--
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
+index d7cbef752f9f..cc278d8cb888 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
+@@ -131,20 +131,21 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ struct mt76_tx_info *tx_info)
+ {
+ struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
+- struct mt7615_sta *msta = container_of(wcid, struct mt7615_sta, wcid);
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb);
+ struct ieee80211_key_conf *key = info->control.hw_key;
+ int pid, id;
+ u8 *txwi = (u8 *)txwi_ptr;
+ struct mt76_txwi_cache *t;
++ struct mt7615_sta *msta;
+ void *txp;
+
++ msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
+ if (!wcid)
+ wcid = &dev->mt76.global_wcid;
+
+ pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
+
+- if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) {
++ if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && msta) {
+ struct mt7615_phy *phy = &dev->phy;
+
+ if ((info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY) && mdev->phy2)
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
+index f8d3673c2cae..7010101f6b14 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
+@@ -191,14 +191,15 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ struct ieee80211_sta *sta,
+ struct mt76_tx_info *tx_info)
+ {
+- struct mt7615_sta *msta = container_of(wcid, struct mt7615_sta, wcid);
+ struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
+ struct sk_buff *skb = tx_info->skb;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
++ struct mt7615_sta *msta;
+ int pad;
+
++ msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
+ if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) &&
+- !msta->rate_probe) {
++ msta && !msta->rate_probe) {
+ /* request to configure sampling rate */
+ spin_lock_bh(&dev->mt76.lock);
+ mt7615_mac_set_rates(&dev->phy, msta, &info->control.rates[0],
+--
+2.30.2
+
--- /dev/null
+From 929d8fb15f1b046e63c7bd48b89cb7d98f1fb944 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Apr 2021 06:20:03 +0800
+Subject: mt76: mt7615: fix potential overflow on large shift
+
+From: Ryder Lee <ryder.lee@mediatek.com>
+
+[ Upstream commit 3253f8fddd954aba9ac88ce3c34551dcca505b21 ]
+
+Fix the following static checker warning:
+error: undefined (user controlled) shift '(((1))) << (c->omac_idx)'
+
+Fixes: 402a695b1ae6 ("mt76: mt7615: fix CSA notification for DBDC")
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+index aa42af9ebfd6..ae2191371f51 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+@@ -411,6 +411,9 @@ mt7615_mcu_rx_csa_notify(struct mt7615_dev *dev, struct sk_buff *skb)
+
+ c = (struct mt7615_mcu_csa_notify *)skb->data;
+
++ if (c->omac_idx > EXT_BSSID_MAX)
++ return;
++
+ if (ext_phy && ext_phy->omac_mask & BIT_ULL(c->omac_idx))
+ mphy = dev->mt76.phy2;
+
+--
+2.30.2
+
--- /dev/null
+From c92dd96e7ffe90d0eedbfb2b94894f98cc8ca35a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 May 2021 17:53:59 +0300
+Subject: mt76: mt7915: fix a signedness bug in mt7915_mcu_apply_tx_dpd()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 861fad474ec7638aeca46a508da4ea81612374b9 ]
+
+"idx" needs to be signed for the error handling to work.
+
+Fixes: 495184ac91bb ("mt76: mt7915: add support for applying pre-calibration data")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+index b3f14ff67c5a..764f25a828fa 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+@@ -3440,8 +3440,9 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
+ {
+ struct mt7915_dev *dev = phy->dev;
+ struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
+- u16 total = 2, idx, center_freq = chandef->center_freq1;
++ u16 total = 2, center_freq = chandef->center_freq1;
+ u8 *cal = dev->cal, *eep = dev->mt76.eeprom.data;
++ int idx;
+
+ if (!(eep[MT_EE_DO_PRE_CAL] & MT_EE_WIFI_CAL_DPD))
+ return 0;
+--
+2.30.2
+
--- /dev/null
+From 303a7ce593868d25cc620d811e69478d5520738c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 May 2021 12:45:58 +0800
+Subject: mt76: mt7915: fix MT_EE_CAL_GROUP_SIZE
+
+From: Ryder Lee <ryder.lee@mediatek.com>
+
+[ Upstream commit ee8ba94f9cc9afab570fd71ad421292f6360983c ]
+
+Fix wrong offset for pre-calibration data.
+
+Fixes: 495184ac91bb ("mt76: mt7915: add support for applying pre-calibration data")
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
+index 033fb592bdf0..30bf41b8ed15 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
+@@ -33,7 +33,7 @@ enum mt7915_eeprom_field {
+ #define MT_EE_WIFI_CAL_GROUP BIT(0)
+ #define MT_EE_WIFI_CAL_DPD GENMASK(2, 1)
+ #define MT_EE_CAL_UNIT 1024
+-#define MT_EE_CAL_GROUP_SIZE (44 * MT_EE_CAL_UNIT)
++#define MT_EE_CAL_GROUP_SIZE (49 * MT_EE_CAL_UNIT + 16)
+ #define MT_EE_CAL_DPD_SIZE (54 * MT_EE_CAL_UNIT)
+
+ #define MT_EE_WIFI_CONF0_TX_PATH GENMASK(2, 0)
+--
+2.30.2
+
--- /dev/null
+From 32716ae02809088496256d752039b24743ff5dc3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Jun 2021 14:55:58 +0800
+Subject: mt76: mt7915: fix rx fcs error count in testmode
+
+From: Shayne Chen <shayne.chen@mediatek.com>
+
+[ Upstream commit 89043529c8b833d87391f1844e9d1cc1643393eb ]
+
+FCS error packets are filtered by default and won't be reported to
+driver, so that RX fcs error and PER in testmode always show zero.
+Fix this issue by reading fcs error count from hw counter.
+
+We did't fix this issue by disabling fcs error rx filter since it may
+let HW suffer some SER errors.
+
+Fixes: 5d8a83f09941 ("mt76: mt7915: implement testmode rx support")
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../wireless/mediatek/mt76/mt7915/testmode.c | 21 +++++++++++++++++--
+ 1 file changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
+index f9d81e36ef09..b220b334906b 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
+@@ -464,10 +464,17 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
+ static void
+ mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
+ {
+- if (en)
++ mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, false);
++
++ if (en) {
++ struct mt7915_dev *dev = phy->dev;
++
+ mt7915_tm_update_channel(phy);
+
+- mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, en);
++ /* read-clear */
++ mt76_rr(dev, MT_MIB_SDR3(phy != &dev->phy));
++ mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, en);
++ }
+ }
+
+ static int
+@@ -690,7 +697,11 @@ static int
+ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
+ {
+ struct mt7915_phy *phy = mphy->priv;
++ struct mt7915_dev *dev = phy->dev;
++ bool ext_phy = phy != &dev->phy;
++ enum mt76_rxq_id q;
+ void *rx, *rssi;
++ u16 fcs_err;
+ int i;
+
+ rx = nla_nest_start(msg, MT76_TM_STATS_ATTR_LAST_RX);
+@@ -735,6 +746,12 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
+
+ nla_nest_end(msg, rx);
+
++ fcs_err = mt76_get_field(dev, MT_MIB_SDR3(ext_phy),
++ MT_MIB_SDR3_FCS_ERR_MASK);
++ q = ext_phy ? MT_RXQ_EXT : MT_RXQ_MAIN;
++ mphy->test.rx_stats.packets[q] += fcs_err;
++ mphy->test.rx_stats.fcs_error[q] += fcs_err;
++
+ return 0;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 49b012bf8bdf4bb084334e99555bdfba11430f0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 23:14:57 +0800
+Subject: mt76: mt7921: add back connection monitor support
+
+From: Sean Wang <sean.wang@mediatek.com>
+
+[ Upstream commit 10de032a31683585292cd10b598d896d7bcf276f ]
+
+Hw beacon cmd to the mt7921 firmware doesn't only filter out the beacon,
+but also performs its own connection monitoring, including periodic
+keep-alives to the AP and probing the AP on beacon loss. Will indicate
+the host with the event when the firmware detects the connection is lost.
+
+Fixes: 1d8efc741df8 ("mt76: mt7921: introduce Runtime PM support")
+Reviewed-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Deren Wu <deren.wu@mediatek.com>
+Signed-off-by: YN Chen <yn.chen@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/mediatek/mt76/mt7921/init.c | 4 +++
+ .../net/wireless/mediatek/mt76/mt7921/mcu.c | 32 +++++++++++++------
+ 2 files changed, 27 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+index b85e46f5820f..2cb0252e63b2 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+@@ -73,6 +73,7 @@ static void
+ mt7921_init_wiphy(struct ieee80211_hw *hw)
+ {
+ struct mt7921_phy *phy = mt7921_hw_phy(hw);
++ struct mt7921_dev *dev = phy->dev;
+ struct wiphy *wiphy = hw->wiphy;
+
+ hw->queues = 4;
+@@ -110,6 +111,9 @@ mt7921_init_wiphy(struct ieee80211_hw *hw)
+ ieee80211_hw_set(hw, SUPPORTS_PS);
+ ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
+
++ if (dev->pm.enable)
++ ieee80211_hw_set(hw, CONNECTION_MONITOR);
++
+ hw->max_tx_fragments = 4;
+ }
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+index 67dc4b4cc094..7c68182cad55 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+@@ -450,22 +450,33 @@ mt7921_mcu_scan_event(struct mt7921_dev *dev, struct sk_buff *skb)
+ }
+
+ static void
+-mt7921_mcu_beacon_loss_event(struct mt7921_dev *dev, struct sk_buff *skb)
++mt7921_mcu_connection_loss_iter(void *priv, u8 *mac,
++ struct ieee80211_vif *vif)
++{
++ struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
++ struct mt76_connac_beacon_loss_event *event = priv;
++
++ if (mvif->idx != event->bss_idx)
++ return;
++
++ if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER))
++ return;
++
++ ieee80211_connection_loss(vif);
++}
++
++static void
++mt7921_mcu_connection_loss_event(struct mt7921_dev *dev, struct sk_buff *skb)
+ {
+ struct mt76_connac_beacon_loss_event *event;
+- struct mt76_phy *mphy;
+- u8 band_idx = 0; /* DBDC support */
++ struct mt76_phy *mphy = &dev->mt76.phy;
+
+ skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
+ event = (struct mt76_connac_beacon_loss_event *)skb->data;
+- if (band_idx && dev->mt76.phy2)
+- mphy = dev->mt76.phy2;
+- else
+- mphy = &dev->mt76.phy;
+
+ ieee80211_iterate_active_interfaces_atomic(mphy->hw,
+ IEEE80211_IFACE_ITER_RESUME_ALL,
+- mt76_connac_mcu_beacon_loss_iter, event);
++ mt7921_mcu_connection_loss_iter, event);
+ }
+
+ static void
+@@ -530,7 +541,7 @@ mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
+
+ switch (rxd->eid) {
+ case MCU_EVENT_BSS_BEACON_LOSS:
+- mt7921_mcu_beacon_loss_event(dev, skb);
++ mt7921_mcu_connection_loss_event(dev, skb);
+ break;
+ case MCU_EVENT_SCHED_SCAN_DONE:
+ case MCU_EVENT_SCAN_DONE:
+@@ -1368,6 +1379,7 @@ mt7921_pm_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
+ {
+ struct mt7921_phy *phy = priv;
+ struct mt7921_dev *dev = phy->dev;
++ struct ieee80211_hw *hw = mt76_hw(dev);
+ int ret;
+
+ if (dev->pm.enable)
+@@ -1380,9 +1392,11 @@ mt7921_pm_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
+
+ if (dev->pm.enable) {
+ vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
++ ieee80211_hw_set(hw, CONNECTION_MONITOR);
+ mt76_set(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON);
+ } else {
+ vif->driver_flags &= ~IEEE80211_VIF_BEACON_FILTER;
++ __clear_bit(IEEE80211_HW_CONNECTION_MONITOR, hw->flags);
+ mt76_clear(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON);
+ }
+ }
+--
+2.30.2
+
--- /dev/null
+From 03437aba57db603fd8bd31226f96c314845e169d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 May 2021 11:46:38 +0800
+Subject: mt76: mt7921: avoid unnecessary consecutive WiFi resets
+
+From: Sean Wang <sean.wang@mediatek.com>
+
+[ Upstream commit f07ac384b4579f294bb1e0380ed501156219ed71 ]
+
+Avoid unnecessary consecutive WiFi resets by dropping reset
+request when reset work is working.
+
+Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 5 ++++-
+ drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h | 1 +
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+index 9bb88b2e28a9..4eac7c3206f9 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+@@ -1272,6 +1272,7 @@ void mt7921_mac_reset_work(struct work_struct *work)
+ hw = mt76_hw(dev);
+
+ dev_err(dev->mt76.dev, "chip reset\n");
++ dev->hw_full_reset = true;
+ ieee80211_stop_queues(hw);
+
+ cancel_delayed_work_sync(&dev->mphy.mac_work);
+@@ -1296,6 +1297,7 @@ void mt7921_mac_reset_work(struct work_struct *work)
+ ieee80211_scan_completed(dev->mphy.hw, &info);
+ }
+
++ dev->hw_full_reset = false;
+ ieee80211_wake_queues(hw);
+ ieee80211_iterate_active_interfaces(hw,
+ IEEE80211_IFACE_ITER_RESUME_ALL,
+@@ -1306,7 +1308,8 @@ void mt7921_reset(struct mt76_dev *mdev)
+ {
+ struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
+
+- queue_work(dev->mt76.wq, &dev->reset_work);
++ if (!dev->hw_full_reset)
++ queue_work(dev->mt76.wq, &dev->reset_work);
+ }
+
+ static void
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+index 59862ea4951c..4cc8a372b277 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+@@ -156,6 +156,7 @@ struct mt7921_dev {
+ u16 chainmask;
+
+ struct work_struct reset_work;
++ bool hw_full_reset;
+
+ struct list_head sta_poll_list;
+ spinlock_t sta_poll_lock;
+--
+2.30.2
+
--- /dev/null
+From 2ba915c200b0502cc60c5f2329df868548791f9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 23:14:55 +0800
+Subject: mt76: mt7921: consider the invalid value for to_rssi
+
+From: Sean Wang <sean.wang@mediatek.com>
+
+[ Upstream commit edb5aebc1c3db312e74e1dcf75b8626ee5300596 ]
+
+It is possible the RCPI from the certain antenna is an invalid value,
+especially packets are receiving while the system is frequently entering
+deep sleep mode, so consider calculating RSSI with the reasonable upper
+bound to avoid report the wrong value to the mac80211 layer.
+
+Fixes: 163f4d22c118 ("mt76: mt7921: add MAC support")
+Reviewed-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+index decf2d5f0ce3..9bb88b2e28a9 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+@@ -444,16 +444,19 @@ int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
+ status->chain_signal[1] = to_rssi(MT_PRXV_RCPI1, v1);
+ status->chain_signal[2] = to_rssi(MT_PRXV_RCPI2, v1);
+ status->chain_signal[3] = to_rssi(MT_PRXV_RCPI3, v1);
+- status->signal = status->chain_signal[0];
+-
+- for (i = 1; i < hweight8(mphy->antenna_mask); i++) {
+- if (!(status->chains & BIT(i)))
++ status->signal = -128;
++ for (i = 0; i < hweight8(mphy->antenna_mask); i++) {
++ if (!(status->chains & BIT(i)) ||
++ status->chain_signal[i] >= 0)
+ continue;
+
+ status->signal = max(status->signal,
+ status->chain_signal[i]);
+ }
+
++ if (status->signal == -128)
++ status->flag |= RX_FLAG_NO_SIGNAL_VAL;
++
+ stbc = FIELD_GET(MT_PRXV_STBC, v0);
+ gi = FIELD_GET(MT_PRXV_SGI, v0);
+ cck = false;
+--
+2.30.2
+
--- /dev/null
+From 98f16f45b1917027d3490e8bef66c366874e85cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 May 2021 23:08:05 +0200
+Subject: mt76: mt7921: do not schedule hw reset if the device is not running
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit d74c4b5667425c35d74906795a08e02e29df5b46 ]
+
+Do not schedule hw full reset if the device is not fully initialized
+(e.g if the channel has not been configured yet). This patch fixes
+the kernel crash reported below
+
+[ 44.440266] mt7921e 0000:01:00.0: chip reset failed
+[ 44.527575] Unable to handle kernel paging request at virtual address ffffffc02f3e0000
+[ 44.535771] Mem abort info:
+[ 44.538646] ESR = 0x96000006
+[ 44.541792] EC = 0x25: DABT (current EL), IL = 32 bits
+[ 44.547268] SET = 0, FnV = 0
+[ 44.550413] EA = 0, S1PTW = 0
+[ 44.553648] Data abort info:
+[ 44.556613] ISV = 0, ISS = 0x00000006
+[ 44.560563] CM = 0, WnR = 0
+[ 44.563619] swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000000955000
+[ 44.570530] [ffffffc02f3e0000] pgd=100000003ffff003, p4d=100000003ffff003, pud=100000003ffff003, pmd=0000000000000000
+[ 44.581489] Internal error: Oops: 96000006 [#1] SMP
+[ 44.606406] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G W 5.13.0-rc1-espressobin-12875-g6dc7f82ebc26 #33
+[ 44.617264] Hardware name: Globalscale Marvell ESPRESSOBin Board (DT)
+[ 44.623905] pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO BTYPE=--)
+[ 44.630100] pc : __queue_work+0x1f0/0x500
+[ 44.634249] lr : __queue_work+0x1e8/0x500
+[ 44.638384] sp : ffffffc010003d70
+[ 44.641798] x29: ffffffc010003d70 x28: 0000000000000000 x27: ffffff8003989200
+[ 44.649166] x26: ffffffc010c08510 x25: 0000000000000002 x24: ffffffc010ad90b0
+[ 44.656533] x23: ffffffc010c08508 x22: 0000000000000012 x21: 0000000000000000
+[ 44.663899] x20: ffffff8006385238 x19: ffffffc02f3e0000 x18: 00000000000003c9
+[ 44.671266] x17: 0000000000000000 x16: 0000000000000000 x15: 000009b1a8a3bf90
+[ 44.678632] x14: 0098968000000000 x13: 0000000000000000 x12: 0000000000000325
+[ 44.685998] x11: ffffff803fda1928 x10: 0000000000000001 x9 : ffffffc010003e98
+[ 44.693365] x8 : 0000000000000032 x7 : fff8000000000000 x6 : 0000000000000035
+[ 44.700732] x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffffffc010adf700
+[ 44.708098] x2 : ffffff8006385238 x1 : 000000007fffffff x0 : 0000000000000000
+[ 44.715465] Call trace:
+[ 44.717982] __queue_work+0x1f0/0x500
+[ 44.721760] delayed_work_timer_fn+0x18/0x20
+[ 44.726167] call_timer_fn+0x2c/0x178
+[ 44.729947] run_timer_softirq+0x488/0x5c8
+[ 44.734172] _stext+0x11c/0x378
+[ 44.737411] irq_exit+0x100/0x108
+[ 44.740830] __handle_domain_irq+0x60/0xb0
+[ 44.745059] gic_handle_irq+0x70/0x2b4
+[ 44.748929] el1_irq+0xb8/0x13c
+[ 44.752167] arch_cpu_idle+0x14/0x30
+[ 44.755858] default_idle_call+0x38/0x168
+[ 44.759994] do_idle+0x1fc/0x210
+[ 44.763325] cpu_startup_entry+0x20/0x58
+[ 44.767372] rest_init+0xb8/0xc8
+[ 44.770703] arch_call_rest_init+0xc/0x14
+[ 44.774841] start_kernel+0x408/0x424
+[ 44.778623] Code: aa1403e0 97fff54f aa0003f5 b5fff500 (f9400275)
+[ 44.784907] ---[ end trace be73c3142d8c36a9 ]---
+[ 44.789668] Kernel panic - not syncing: Oops: Fatal exception in interrupt
+
+Fixes: 0c1ce9884607 ("mt76: mt7921: add wifi reset support")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+index 4eac7c3206f9..5e00dd589331 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+@@ -1308,6 +1308,9 @@ void mt7921_reset(struct mt76_dev *mdev)
+ {
+ struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
+
++ if (!test_bit(MT76_STATE_RUNNING, &dev->mphy.state))
++ return;
++
+ if (!dev->hw_full_reset)
+ queue_work(dev->mt76.wq, &dev->reset_work);
+ }
+--
+2.30.2
+
--- /dev/null
+From dcbf1d7943ea79f72f1277913a0c2695deaee848 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 23:14:50 +0800
+Subject: mt76: mt7921: Don't alter Rx path classifier
+
+From: Sean Wang <sean.wang@mediatek.com>
+
+[ Upstream commit 2c80c02a682aefc073df2cfbb48c77c74579cb4a ]
+
+Keep Rx path classifier the mt7921 firmware prefers to allow frames pass
+through MCU.
+
+Fixes: 5c14a5f944b9 ("mt76: mt7921: introduce mt7921e support")
+Reviewed-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/mediatek/mt76/mt7921/init.c | 18 ------------------
+ 1 file changed, 18 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+index 1763ea0614ce..b85e46f5820f 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+@@ -116,30 +116,12 @@ mt7921_init_wiphy(struct ieee80211_hw *hw)
+ static void
+ mt7921_mac_init_band(struct mt7921_dev *dev, u8 band)
+ {
+- u32 mask, set;
+-
+ mt76_rmw_field(dev, MT_TMAC_CTCR0(band),
+ MT_TMAC_CTCR0_INS_DDLMT_REFTIME, 0x3f);
+ mt76_set(dev, MT_TMAC_CTCR0(band),
+ MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN |
+ MT_TMAC_CTCR0_INS_DDLMT_EN);
+
+- mask = MT_MDP_RCFR0_MCU_RX_MGMT |
+- MT_MDP_RCFR0_MCU_RX_CTL_NON_BAR |
+- MT_MDP_RCFR0_MCU_RX_CTL_BAR;
+- set = FIELD_PREP(MT_MDP_RCFR0_MCU_RX_MGMT, MT_MDP_TO_HIF) |
+- FIELD_PREP(MT_MDP_RCFR0_MCU_RX_CTL_NON_BAR, MT_MDP_TO_HIF) |
+- FIELD_PREP(MT_MDP_RCFR0_MCU_RX_CTL_BAR, MT_MDP_TO_HIF);
+- mt76_rmw(dev, MT_MDP_BNRCFR0(band), mask, set);
+-
+- mask = MT_MDP_RCFR1_MCU_RX_BYPASS |
+- MT_MDP_RCFR1_RX_DROPPED_UCAST |
+- MT_MDP_RCFR1_RX_DROPPED_MCAST;
+- set = FIELD_PREP(MT_MDP_RCFR1_MCU_RX_BYPASS, MT_MDP_TO_HIF) |
+- FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_UCAST, MT_MDP_TO_HIF) |
+- FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_MCAST, MT_MDP_TO_HIF);
+- mt76_rmw(dev, MT_MDP_BNRCFR1(band), mask, set);
+-
+ mt76_set(dev, MT_WF_RMAC_MIB_TIME0(band), MT_WF_RMAC_MIB_RXTIME_EN);
+ mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0(band), MT_WF_RMAC_MIB_RXTIME_EN);
+
+--
+2.30.2
+
--- /dev/null
+From f39d9237e4b762ef31622e9d87318dba7f30fee3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 May 2021 11:46:39 +0800
+Subject: mt76: mt7921: fix invalid register access in wake_work
+
+From: Sean Wang <sean.wang@mediatek.com>
+
+[ Upstream commit f86625ae0e35924ed495cdf0ff2d3133cb6e3010 ]
+
+Make sure mt7921_pm_wake_work wouldn't be scheduled after the driver is
+in suspend mode to fix the following the kernel crash.
+
+[ 3515.390012] mt7921e 0000:01:00.0: calling pci_pm_suspend+0x0/0x22c @ 2869, parent: 0000:00:00.0
+[ 3515.390015] mt7921e 0000:01:00.0: mt7921_pci_suspend +
+[ 3515.396395] anx7625 3-0058: anx7625_suspend+0x0/0x6c returned 0 after 0 usecs
+[ 3515.405965] mt7921e 0000:01:00.0: mt7921_pci_suspend -
+[ 3515.411336] usb 1-1.4: usb_dev_suspend+0x0/0x2c returned 0 after 1 usecs
+[ 3515.411513] SError Interrupt on CPU7, code 0xbe000011 -- SError
+[ 3515.411515] CPU: 7 PID: 2849 Comm: kworker/u16:27 Not tainted 5.4.114 #44
+[ 3515.411516] Hardware name: MediaTek Asurada rev1 board (DT)
+[ 3515.411517] Workqueue: mt76 mt7921_pm_wake_work [mt7921e]
+[ 3515.411518] pstate: 80c00009 (Nzcv daif +PAN +UAO)
+[ 3515.411519] pc : mt76_mmio_rr+0x30/0xf0 [mt76]
+[ 3515.411520] lr : mt7921_rr+0x38/0x44 [mt7921e]
+[ 3515.411520] sp : ffffffc015813c50
+[ 3515.411521] x29: ffffffc015813c50 x28: 0000000000000402
+[ 3515.411522] x27: ffffffe5a2012138 x26: ffffffe5a1eea018
+[ 3515.411524] x25: 00000000328be505 x24: 00000000000a0002
+[ 3515.411525] x23: 0000000000000006 x22: ffffffbd29b7a300
+[ 3515.411527] x21: ffffffbd29b7a300 x20: 00000000000e0010
+[ 3515.411528] x19: 00000000eac08f43 x18: 0000000000000000
+[ 3515.411529] x17: 0000000000000000 x16: ffffffe5a16b2914
+[ 3515.411531] x15: 0000000000000010 x14: 0000000000000010
+[ 3515.411532] x13: 00000000003dd3a2 x12: 0000000000010000
+[ 3515.411533] x11: ffffffe597abec14 x10: 0000000000000010
+[ 3515.411535] x9 : ffffffe597abeba8 x8 : ffffffc013ce0010
+[ 3515.411536] x7 : 000000b2b5593519 x6 : 0000000000300000
+[ 3515.411537] x5 : 0000000000000000 x4 : 0000000000000032
+[ 3515.411539] x3 : 0000000000000000 x2 : 0000000000000004
+[ 3515.411540] x1 : 00000000000e0010 x0 : ffffffbd29b7a300
+[ 3515.411542] Kernel panic - not syncing: Asynchronous SError Interrupt
+[ 3515.411543] CPU: 7 PID: 2849 Comm: kworker/u16:27 Not tainted 5.4.114 #44
+[ 3515.411544] Hardware name: MediaTek Asurada rev1 board (DT)
+[ 3515.411544] Workqueue: mt76 mt7921_pm_wake_work [mt7921e]
+[ 3515.411545] Call trace:
+[ 3515.411546] dump_backtrace+0x0/0x14c
+[ 3515.411546] show_stack+0x20/0x2c
+[ 3515.411547] dump_stack+0xa0/0xfc
+[ 3515.411548] panic+0x154/0x350
+[ 3515.411548] panic+0x0/0x350
+[ 3515.411549] arm64_serror_panic+0x78/0x84
+[ 3515.411550] do_serror+0x0/0x118
+[ 3515.411550] do_serror+0xa4/0x118
+[ 3515.411551] el1_error+0x84/0xf8
+[ 3515.411552] mt76_mmio_rr+0x30/0xf0 [mt76]
+[ 3515.411552] mt7921_rr+0x38/0x44 [mt7921e]
+[ 3515.411553] __mt76_poll_msec+0x5c/0x9c [mt76]
+[ 3515.411554] __mt7921_mcu_drv_pmctrl+0x50/0x94 [mt7921e]
+[ 3515.411555] mt7921_mcu_drv_pmctrl+0x38/0xb0 [mt7921e]
+[ 3515.411555] mt7921_pm_wake_work+0x34/0xd4 [mt7921e]
+[ 3515.411556] process_one_work+0x208/0x3c8
+[ 3515.411557] worker_thread+0x23c/0x3e8
+[ 3515.411557] kthread+0x144/0x178
+[ 3515.411558] ret_from_fork+0x10/0x18
+[ 3515.418831] SMP: stopping secondary CPUs
+[ 3515.418832] Kernel Offset: 0x2590c00000 from 0xffffffc010000000
+[ 3515.418832] PHYS_OFFSET: 0xffffffc400000000
+[ 3515.418833] CPU features: 0x080026,2a80aa18
+[ 3515.418834] Memory Limit: none
+[DL] 00000000 00000000 010701
+
+Fixes: 1d8efc741df80 ("mt76: mt7921: introduce Runtime PM support")
+Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/mediatek/mt76/mt76_connac.h | 1 +
+ .../wireless/mediatek/mt76/mt76_connac_mac.c | 6 +++++
+ .../net/wireless/mediatek/mt76/mt7921/pci.c | 25 +++++++++++++------
+ 3 files changed, 24 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+index 337c5ece7ec3..63c1d1a68a70 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+@@ -45,6 +45,7 @@ enum {
+
+ struct mt76_connac_pm {
+ bool enable;
++ bool suspended;
+
+ spinlock_t txq_lock;
+ struct {
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
+index 6f180c92d413..5f2705fbd680 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
+@@ -17,6 +17,9 @@ int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm)
+ if (!test_bit(MT76_STATE_PM, &phy->state))
+ return 0;
+
++ if (pm->suspended)
++ return 0;
++
+ queue_work(dev->wq, &pm->wake_work);
+ if (!wait_event_timeout(pm->wait,
+ !test_bit(MT76_STATE_PM, &phy->state),
+@@ -40,6 +43,9 @@ void mt76_connac_power_save_sched(struct mt76_phy *phy,
+ if (!pm->enable)
+ return;
+
++ if (pm->suspended)
++ return;
++
+ pm->last_activity = jiffies;
+
+ if (!test_bit(MT76_STATE_PM, &phy->state)) {
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+index fa02d934f0bf..13263f50dc00 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+@@ -188,21 +188,26 @@ static int mt7921_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+ {
+ struct mt76_dev *mdev = pci_get_drvdata(pdev);
+ struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
++ struct mt76_connac_pm *pm = &dev->pm;
+ bool hif_suspend;
+ int i, err;
+
+- err = mt76_connac_pm_wake(&dev->mphy, &dev->pm);
++ pm->suspended = true;
++ cancel_delayed_work_sync(&pm->ps_work);
++ cancel_work_sync(&pm->wake_work);
++
++ err = mt7921_mcu_drv_pmctrl(dev);
+ if (err < 0)
+- return err;
++ goto restore_suspend;
+
+ hif_suspend = !test_bit(MT76_STATE_SUSPEND, &dev->mphy.state);
+ if (hif_suspend) {
+ err = mt76_connac_mcu_set_hif_suspend(mdev, true);
+ if (err)
+- return err;
++ goto restore_suspend;
+ }
+
+- if (!dev->pm.enable)
++ if (!pm->enable)
+ mt76_connac_mcu_set_deep_sleep(&dev->mt76, true);
+
+ napi_disable(&mdev->tx_napi);
+@@ -231,27 +236,30 @@ static int mt7921_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+
+ err = mt7921_mcu_fw_pmctrl(dev);
+ if (err)
+- goto restore;
++ goto restore_napi;
+
+ pci_save_state(pdev);
+ err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ if (err)
+- goto restore;
++ goto restore_napi;
+
+ return 0;
+
+-restore:
++restore_napi:
+ mt76_for_each_q_rx(mdev, i) {
+ napi_enable(&mdev->napi[i]);
+ }
+ napi_enable(&mdev->tx_napi);
+
+- if (!dev->pm.enable)
++ if (!pm->enable)
+ mt76_connac_mcu_set_deep_sleep(&dev->mt76, false);
+
+ if (hif_suspend)
+ mt76_connac_mcu_set_hif_suspend(mdev, false);
+
++restore_suspend:
++ pm->suspended = false;
++
+ return err;
+ }
+
+@@ -261,6 +269,7 @@ static int mt7921_pci_resume(struct pci_dev *pdev)
+ struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
+ int i, err;
+
++ dev->pm.suspended = false;
+ err = pci_set_power_state(pdev, PCI_D0);
+ if (err)
+ return err;
+--
+2.30.2
+
--- /dev/null
+From 99976ba6730b55c86c48b27161eb6151ee2dd408 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jun 2021 05:31:10 +0800
+Subject: mt76: mt7921: fix kernel warning when reset on vif is not sta
+
+From: Sean Wang <sean.wang@mediatek.com>
+
+[ Upstream commit 78b0328ff8c46fce64eb969d2572c3f631735dc1 ]
+
+ieee80211_disconnect is only called for the staton mode.
+
+[ 714.050429] WARNING: CPU: 1 PID: 382 at net/mac80211/mlme.c:2787
+ieee80211_disconnect+0x108/0x118 [mac80211]
+[ 714.116704] Hardware name: MediaTek Asurada rev1 board (DT)
+[ 714.122303] Workqueue: mt76 mt7921_mac_reset_work [mt7921e]
+[ 714.127877] pstate: 20c00009 (nzCv daif +PAN +UAO)
+[ 714.132761] pc : ieee80211_disconnect+0x108/0x118 [mac80211]
+[ 714.138430] lr : mt7921_vif_connect_iter+0x28/0x54 [mt7921e]
+[ 714.144083] sp : ffffffc0107cbbd0
+[ 714.147394] x29: ffffffc0107cbbd0 x28: ffffffb26c9cb928
+[ 714.152706] x27: ffffffb26c9cbd98 x26: 0000000000000000
+[ 714.158017] x25: 0000000000000003 x24: ffffffb26c9c9c38
+[ 714.163328] x23: ffffffb26c9c9c38 x22: ffffffb26c9c8860
+[ 714.168639] x21: ffffffb23b940000 x20: ffffffb26c9c8860
+[ 714.173950] x19: 0000000000000001 x18: 000000000000b67e
+[ 714.179261] x17: 00000000064dd409 x16: ffffffd739cb28f0
+[ 714.184571] x15: 0000000000000000 x14: 0000000000000227
+[ 714.189881] x13: 0000000000000400 x12: ffffffd73a4eb060
+[ 714.195191] x11: 0000000000000000 x10: 0000000000000000
+[ 714.200502] x9 : ffffffd703a0a000 x8 : 0000000000000006
+[ 714.205812] x7 : 2828282828282828 x6 : ffffffb200440396
+[ 714.211122] x5 : 0000000000000000 x4 : 0000000000000004
+[ 714.216432] x3 : 0000000000000000 x2 : ffffffb23b940c90
+[ 714.221743] x1 : 0000000000000001 x0 : ffffffb23b940c90
+[ 714.227054] Call trace:
+[ 714.229594] ieee80211_disconnect+0x108/0x118 [mac80211]
+[ 714.234913] mt7921_vif_connect_iter+0x28/0x54 [mt7921e]
+[ 714.240313] __iterate_interfaces+0xc4/0xdc [mac80211]
+[ 714.245541] ieee80211_iterate_interfaces+0x4c/0x68 [mac80211]
+[ 714.251381] mt7921_mac_reset_work+0x410/0x468 [mt7921e]
+[ 714.256696] process_one_work+0x208/0x3c8
+[ 714.260706] worker_thread+0x23c/0x3e8
+[ 714.264456] kthread+0x140/0x17c
+[ 714.267685] ret_from_fork+0x10/0x18
+
+Fixes: 0c1ce9884607 ("mt76: mt7921: add wifi reset support")
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+index 5e00dd589331..853db0a52181 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+@@ -1199,7 +1199,8 @@ mt7921_vif_connect_iter(void *priv, u8 *mac,
+ struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
+ struct mt7921_dev *dev = mvif->phy->dev;
+
+- ieee80211_disconnect(vif, true);
++ if (vif->type == NL80211_IFTYPE_STATION)
++ ieee80211_disconnect(vif, true);
+
+ mt76_connac_mcu_uni_add_dev(&dev->mphy, vif, &mvif->sta.wcid, true);
+ mt7921_mcu_set_tx(dev, vif);
+--
+2.30.2
+
--- /dev/null
+From 694d79114b3ff5b716b7ada0d75f4c40f36fde55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 23:14:49 +0800
+Subject: mt76: mt7921: fix mt7921_wfsys_reset sequence
+
+From: Sean Wang <sean.wang@mediatek.com>
+
+[ Upstream commit 20eb83c749609199443972cf80fb6004fc36afc6 ]
+
+WiFi subsytem reset should control MT_WFSYS_SW_RST_B and then poll the
+same register until the bit WFSYS_SW_INIT_DONE bit is set.
+
+Fixes: 0c1ce9884607 ("mt76: mt7921: add wifi reset support")
+Reviewed-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/dma.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
+index 71e664ee7652..bd9143dc865f 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
+@@ -313,9 +313,9 @@ static int mt7921_dma_reset(struct mt7921_dev *dev, bool force)
+
+ int mt7921_wfsys_reset(struct mt7921_dev *dev)
+ {
+- mt76_set(dev, 0x70002600, BIT(0));
+- msleep(200);
+- mt76_clear(dev, 0x70002600, BIT(0));
++ mt76_clear(dev, MT_WFSYS_SW_RST_B, WFSYS_SW_RST_B);
++ msleep(50);
++ mt76_set(dev, MT_WFSYS_SW_RST_B, WFSYS_SW_RST_B);
+
+ if (!__mt76_poll_msec(&dev->mt76, MT_WFSYS_SW_RST_B,
+ WFSYS_SW_INIT_DONE, WFSYS_SW_INIT_DONE, 500))
+--
+2.30.2
+
--- /dev/null
+From 237d269bce315deb29b906184551e1da77dfb95b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 May 2021 11:46:40 +0800
+Subject: mt76: mt7921: fix OMAC idx usage
+
+From: Sean Wang <sean.wang@mediatek.com>
+
+[ Upstream commit 213f87289ea01514acdbfeed9f65bcb5f12aef70 ]
+
+OMAC idx have to be same with BSS idx according to firmware usage.
+
+Fixes: e0f9fdda81bd ("mt76: mt7921: add ieee80211_ops")
+Reviewed-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Deren Wu <deren.wu@mediatek.com>
+Signed-off-by: YN Chen <yn.chen@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/mediatek/mt76/mt7921/main.c | 55 +------------------
+ 1 file changed, 1 insertion(+), 54 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+index 97a0ef331ac3..bd77a04a15fb 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+@@ -223,54 +223,6 @@ static void mt7921_stop(struct ieee80211_hw *hw)
+ mt7921_mutex_release(dev);
+ }
+
+-static inline int get_free_idx(u32 mask, u8 start, u8 end)
+-{
+- return ffs(~mask & GENMASK(end, start));
+-}
+-
+-static int get_omac_idx(enum nl80211_iftype type, u64 mask)
+-{
+- int i;
+-
+- switch (type) {
+- case NL80211_IFTYPE_STATION:
+- /* prefer hw bssid slot 1-3 */
+- i = get_free_idx(mask, HW_BSSID_1, HW_BSSID_3);
+- if (i)
+- return i - 1;
+-
+- /* next, try to find a free repeater entry for the sta */
+- i = get_free_idx(mask >> REPEATER_BSSID_START, 0,
+- REPEATER_BSSID_MAX - REPEATER_BSSID_START);
+- if (i)
+- return i + 32 - 1;
+-
+- i = get_free_idx(mask, EXT_BSSID_1, EXT_BSSID_MAX);
+- if (i)
+- return i - 1;
+-
+- if (~mask & BIT(HW_BSSID_0))
+- return HW_BSSID_0;
+-
+- break;
+- case NL80211_IFTYPE_MONITOR:
+- /* ap uses hw bssid 0 and ext bssid */
+- if (~mask & BIT(HW_BSSID_0))
+- return HW_BSSID_0;
+-
+- i = get_free_idx(mask, EXT_BSSID_1, EXT_BSSID_MAX);
+- if (i)
+- return i - 1;
+-
+- break;
+- default:
+- WARN_ON(1);
+- break;
+- }
+-
+- return -1;
+-}
+-
+ static int mt7921_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+ {
+@@ -292,12 +244,7 @@ static int mt7921_add_interface(struct ieee80211_hw *hw,
+ goto out;
+ }
+
+- idx = get_omac_idx(vif->type, phy->omac_mask);
+- if (idx < 0) {
+- ret = -ENOSPC;
+- goto out;
+- }
+- mvif->mt76.omac_idx = idx;
++ mvif->mt76.omac_idx = mvif->mt76.idx;
+ mvif->phy = phy;
+ mvif->mt76.band_idx = 0;
+ mvif->mt76.wmm_idx = mvif->mt76.idx % MT7921_MAX_WMM_SETS;
+--
+2.30.2
+
--- /dev/null
+From 7bac0a08febf3b64cb87e95163129cceb0488139 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jun 2021 09:39:19 +0800
+Subject: mt76: mt7921: fix the coredump is being truncated
+
+From: Sean Wang <sean.wang@mediatek.com>
+
+[ Upstream commit 723885a6750102e5d807429b3d06aa6b0d29cc66 ]
+
+Fix the maximum size of the coredump generated with current mt7921
+firmware. Otherwise, a truncated coredump would be reported to userland
+via dev_coredumpv.
+
+Also, there is an additional error handling enhanced in the patch to avoid
+the possible invalid buffer access when the system failed to create the
+buffer to hold the coredump.
+
+Fixes: 0da3c795d07b ("mt76: mt7921: add coredump support")
+Co-developed-by: YN Chen <YN.Chen@mediatek.com>
+Signed-off-by: YN Chen <YN.Chen@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt76_connac.h | 2 +-
+ drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 9 ++++++---
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+index 63c1d1a68a70..c26cfef425ed 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+@@ -12,7 +12,7 @@
+ #define MT76_CONNAC_MAX_SCAN_MATCH 16
+
+ #define MT76_CONNAC_COREDUMP_TIMEOUT (HZ / 20)
+-#define MT76_CONNAC_COREDUMP_SZ (128 * 1024)
++#define MT76_CONNAC_COREDUMP_SZ (1300 * 1024)
+
+ enum {
+ CMD_CBW_20MHZ = IEEE80211_STA_RX_BW_20,
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+index 853db0a52181..493c2aba2f79 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+@@ -1504,7 +1504,7 @@ void mt7921_coredump_work(struct work_struct *work)
+ break;
+
+ skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
+- if (data + skb->len - dump > MT76_CONNAC_COREDUMP_SZ) {
++ if (!dump || data + skb->len - dump > MT76_CONNAC_COREDUMP_SZ) {
+ dev_kfree_skb(skb);
+ continue;
+ }
+@@ -1514,7 +1514,10 @@ void mt7921_coredump_work(struct work_struct *work)
+
+ dev_kfree_skb(skb);
+ }
+- dev_coredumpv(dev->mt76.dev, dump, MT76_CONNAC_COREDUMP_SZ,
+- GFP_KERNEL);
++
++ if (dump)
++ dev_coredumpv(dev->mt76.dev, dump, MT76_CONNAC_COREDUMP_SZ,
++ GFP_KERNEL);
++
+ mt7921_reset(&dev->mt76);
+ }
+--
+2.30.2
+
--- /dev/null
+From 0940f9246868cad82df60707e74fd1ff8c00086a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Jun 2021 13:46:03 +0200
+Subject: mt76: mt7921: wake the device before dumping power table
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 271fa685365842962f56651c9d1a33a0d0d3b30b ]
+
+Always wake the device up before dumping the single_sku power table
+otherwise the device can hang.
+
+Fixes: ea29acc97c555 ("mt76: mt7921: add dumping Tx power table")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
+index 6ee423dd4027..6602903c0d02 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
+@@ -184,7 +184,10 @@ mt7921_txpwr(struct seq_file *s, void *data)
+ struct mt7921_txpwr txpwr;
+ int ret;
+
++ mt7921_mutex_acquire(dev);
+ ret = mt7921_get_txpwr_info(dev, &txpwr);
++ mt7921_mutex_release(dev);
++
+ if (ret)
+ return ret;
+
+--
+2.30.2
+
--- /dev/null
+From 66130edb6bd63b71c651132024b6532529d3b041 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 May 2021 13:35:28 +0200
+Subject: mt76: testmode: fix memory leak in mt76_testmode_alloc_skb
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit fe2c3b1fc64ea0c7a5b2ca2f671b4572ff99baf8 ]
+
+Free all pending frames in case of failure in mt76_testmode_alloc_skb
+routine
+
+Fixes: 2601dda8faa76 ("mt76: testmode: add support to send larger packet")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/testmode.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/testmode.c b/drivers/net/wireless/mediatek/mt76/testmode.c
+index 001d0ba5f73e..f40387a866ee 100644
+--- a/drivers/net/wireless/mediatek/mt76/testmode.c
++++ b/drivers/net/wireless/mediatek/mt76/testmode.c
+@@ -158,8 +158,11 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
+ frag_len = MT_TXP_MAX_LEN;
+
+ frag = alloc_skb(frag_len, GFP_KERNEL);
+- if (!frag)
++ if (!frag) {
++ mt76_testmode_free_skb(phy);
++ dev_kfree_skb(head);
+ return -ENOMEM;
++ }
+
+ __skb_put_zero(frag, frag_len);
+ head->len += frag->len;
+--
+2.30.2
+
--- /dev/null
+From 8a908ea1f4f29dd943533b9b29e05df07d81f630 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 May 2021 13:35:30 +0200
+Subject: mt76: testmode: remove undefined behaviour in mt76_testmode_alloc_skb
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 223cea6d3c974acd393bfac2d168b2945a6cf1e5 ]
+
+Get rid of an undefined behaviour in mt76_testmode_alloc_skb routine
+allocating skb frames
+
+Fixes: 2601dda8faa76 ("mt76: testmode: add support to send larger packet")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/testmode.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/testmode.c b/drivers/net/wireless/mediatek/mt76/testmode.c
+index f40387a866ee..f614c887f323 100644
+--- a/drivers/net/wireless/mediatek/mt76/testmode.c
++++ b/drivers/net/wireless/mediatek/mt76/testmode.c
+@@ -168,12 +168,8 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
+ head->len += frag->len;
+ head->data_len += frag->len;
+
+- if (*frag_tail) {
+- (*frag_tail)->next = frag;
+- frag_tail = &frag;
+- } else {
+- *frag_tail = frag;
+- }
++ *frag_tail = frag;
++ frag_tail = &(*frag_tail)->next;
+ }
+
+ mt76_testmode_free_skb(phy);
+--
+2.30.2
+
--- /dev/null
+From d6454ca69cc95f7df4b9bd31c50203b08e9d88ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 May 2021 01:09:31 +0200
+Subject: mtd: parsers: qcom: Fix leaking of partition name
+
+From: Ansuel Smith <ansuelsmth@gmail.com>
+
+[ Upstream commit 10f3b4d79958d6f9f71588c6fa862159c83fa80f ]
+
+Add cleanup function as the name variable for the partition name was
+allocaed but never freed after the use as the add mtd function
+duplicate the name and free the pparts struct as the partition name is
+assumed to be static.
+The leak was found using kmemleak.
+
+Fixes: 803eb124e1a6 ("mtd: parsers: Add Qcom SMEM parser")
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20210525230931.30013-1-ansuelsmth@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/parsers/qcomsmempart.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/mtd/parsers/qcomsmempart.c b/drivers/mtd/parsers/qcomsmempart.c
+index d9083308f6ba..06a818cd2433 100644
+--- a/drivers/mtd/parsers/qcomsmempart.c
++++ b/drivers/mtd/parsers/qcomsmempart.c
+@@ -159,6 +159,15 @@ out_free_parts:
+ return ret;
+ }
+
++static void parse_qcomsmem_cleanup(const struct mtd_partition *pparts,
++ int nr_parts)
++{
++ int i;
++
++ for (i = 0; i < nr_parts; i++)
++ kfree(pparts[i].name);
++}
++
+ static const struct of_device_id qcomsmem_of_match_table[] = {
+ { .compatible = "qcom,smem-part" },
+ {},
+@@ -167,6 +176,7 @@ MODULE_DEVICE_TABLE(of, qcomsmem_of_match_table);
+
+ static struct mtd_part_parser mtd_parser_qcomsmem = {
+ .parse_fn = parse_qcomsmem_part,
++ .cleanup = parse_qcomsmem_cleanup,
+ .name = "qcomsmem",
+ .of_match_table = qcomsmem_of_match_table,
+ };
+--
+2.30.2
+
--- /dev/null
+From 600d115fae846c20cd756819e4fc66188b3e64df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 May 2021 11:48:50 +0000
+Subject: mtd: partitions: redboot: seek fis-index-block in the right node
+
+From: Corentin Labbe <clabbe@baylibre.com>
+
+[ Upstream commit 237960880960863fb41888763d635b384cffb104 ]
+
+fis-index-block is seeked in the master node and not in the partitions node.
+For following binding and current usage, the driver need to check the
+partitions subnode.
+
+Fixes: c0e118c8a1a3 ("mtd: partitions: Add OF support to RedBoot partitions")
+Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20210520114851.1274609-1-clabbe@baylibre.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/parsers/redboot.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/parsers/redboot.c b/drivers/mtd/parsers/redboot.c
+index 91146bdc4713..3ccd6363ee8c 100644
+--- a/drivers/mtd/parsers/redboot.c
++++ b/drivers/mtd/parsers/redboot.c
+@@ -45,6 +45,7 @@ static inline int redboot_checksum(struct fis_image_desc *img)
+ static void parse_redboot_of(struct mtd_info *master)
+ {
+ struct device_node *np;
++ struct device_node *npart;
+ u32 dirblock;
+ int ret;
+
+@@ -52,7 +53,11 @@ static void parse_redboot_of(struct mtd_info *master)
+ if (!np)
+ return;
+
+- ret = of_property_read_u32(np, "fis-index-block", &dirblock);
++ npart = of_get_child_by_name(np, "partitions");
++ if (!npart)
++ return;
++
++ ret = of_property_read_u32(npart, "fis-index-block", &dirblock);
+ if (ret)
+ return;
+
+--
+2.30.2
+
--- /dev/null
+From b887ee76dd0634127657ff8250871520e131dfe7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 May 2021 11:32:41 +0200
+Subject: mtd: rawnand: arasan: Ensure proper configuration for the asserted
+ target
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ Upstream commit b5437c7b682c9a505065b4ab4716cdc951dc3c7c ]
+
+The controller being always asserting one CS or the other, there is no
+need to actually select the right target before doing a page read/write.
+However, the anfc_select_target() helper actually also changes the
+timing configuration and clock in the case were two different NAND chips
+with different timing requirements would be used. In this situation, we
+must ensure proper configuration of the controller by calling it.
+
+As a consequence of this change, the anfc_select_target() helper is
+being moved earlier in the driver.
+
+Fixes: 88ffef1b65cf ("mtd: rawnand: arasan: Support the hardware BCH ECC engine")
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20210526093242.183847-4-miquel.raynal@bootlin.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/raw/arasan-nand-controller.c | 90 ++++++++++++-------
+ 1 file changed, 57 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/mtd/nand/raw/arasan-nand-controller.c b/drivers/mtd/nand/raw/arasan-nand-controller.c
+index 549aac00228e..390f8d719c25 100644
+--- a/drivers/mtd/nand/raw/arasan-nand-controller.c
++++ b/drivers/mtd/nand/raw/arasan-nand-controller.c
+@@ -273,6 +273,37 @@ static int anfc_pkt_len_config(unsigned int len, unsigned int *steps,
+ return 0;
+ }
+
++static int anfc_select_target(struct nand_chip *chip, int target)
++{
++ struct anand *anand = to_anand(chip);
++ struct arasan_nfc *nfc = to_anfc(chip->controller);
++ int ret;
++
++ /* Update the controller timings and the potential ECC configuration */
++ writel_relaxed(anand->timings, nfc->base + DATA_INTERFACE_REG);
++
++ /* Update clock frequency */
++ if (nfc->cur_clk != anand->clk) {
++ clk_disable_unprepare(nfc->controller_clk);
++ ret = clk_set_rate(nfc->controller_clk, anand->clk);
++ if (ret) {
++ dev_err(nfc->dev, "Failed to change clock rate\n");
++ return ret;
++ }
++
++ ret = clk_prepare_enable(nfc->controller_clk);
++ if (ret) {
++ dev_err(nfc->dev,
++ "Failed to re-enable the controller clock\n");
++ return ret;
++ }
++
++ nfc->cur_clk = anand->clk;
++ }
++
++ return 0;
++}
++
+ /*
+ * When using the embedded hardware ECC engine, the controller is in charge of
+ * feeding the engine with, first, the ECC residue present in the data array.
+@@ -401,6 +432,18 @@ static int anfc_read_page_hw_ecc(struct nand_chip *chip, u8 *buf,
+ return 0;
+ }
+
++static int anfc_sel_read_page_hw_ecc(struct nand_chip *chip, u8 *buf,
++ int oob_required, int page)
++{
++ int ret;
++
++ ret = anfc_select_target(chip, chip->cur_cs);
++ if (ret)
++ return ret;
++
++ return anfc_read_page_hw_ecc(chip, buf, oob_required, page);
++};
++
+ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
+ int oob_required, int page)
+ {
+@@ -461,6 +504,18 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
+ return ret;
+ }
+
++static int anfc_sel_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
++ int oob_required, int page)
++{
++ int ret;
++
++ ret = anfc_select_target(chip, chip->cur_cs);
++ if (ret)
++ return ret;
++
++ return anfc_write_page_hw_ecc(chip, buf, oob_required, page);
++};
++
+ /* NAND framework ->exec_op() hooks and related helpers */
+ static int anfc_parse_instructions(struct nand_chip *chip,
+ const struct nand_subop *subop,
+@@ -753,37 +808,6 @@ static const struct nand_op_parser anfc_op_parser = NAND_OP_PARSER(
+ NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)),
+ );
+
+-static int anfc_select_target(struct nand_chip *chip, int target)
+-{
+- struct anand *anand = to_anand(chip);
+- struct arasan_nfc *nfc = to_anfc(chip->controller);
+- int ret;
+-
+- /* Update the controller timings and the potential ECC configuration */
+- writel_relaxed(anand->timings, nfc->base + DATA_INTERFACE_REG);
+-
+- /* Update clock frequency */
+- if (nfc->cur_clk != anand->clk) {
+- clk_disable_unprepare(nfc->controller_clk);
+- ret = clk_set_rate(nfc->controller_clk, anand->clk);
+- if (ret) {
+- dev_err(nfc->dev, "Failed to change clock rate\n");
+- return ret;
+- }
+-
+- ret = clk_prepare_enable(nfc->controller_clk);
+- if (ret) {
+- dev_err(nfc->dev,
+- "Failed to re-enable the controller clock\n");
+- return ret;
+- }
+-
+- nfc->cur_clk = anand->clk;
+- }
+-
+- return 0;
+-}
+-
+ static int anfc_check_op(struct nand_chip *chip,
+ const struct nand_operation *op)
+ {
+@@ -1007,8 +1031,8 @@ static int anfc_init_hw_ecc_controller(struct arasan_nfc *nfc,
+ if (!anand->bch)
+ return -EINVAL;
+
+- ecc->read_page = anfc_read_page_hw_ecc;
+- ecc->write_page = anfc_write_page_hw_ecc;
++ ecc->read_page = anfc_sel_read_page_hw_ecc;
++ ecc->write_page = anfc_sel_write_page_hw_ecc;
+
+ return 0;
+ }
+--
+2.30.2
+
--- /dev/null
+From f4269ea7775ecb616ac98ade0b1fbf67de69339e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Jun 2021 20:58:14 +0800
+Subject: mtd: rawnand: marvell: add missing clk_disable_unprepare() on error
+ in marvell_nfc_resume()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit ae94c49527aa9bd3b563349adc4b5617747ca6bd ]
+
+Add clk_disable_unprepare() on error path in marvell_nfc_resume().
+
+Fixes: bd9c3f9b3c00 ("mtd: rawnand: marvell: add suspend and resume hooks")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20210601125814.3260364-1-yangyingliang@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/raw/marvell_nand.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c
+index 79da6b02e209..f83525a1ab0e 100644
+--- a/drivers/mtd/nand/raw/marvell_nand.c
++++ b/drivers/mtd/nand/raw/marvell_nand.c
+@@ -3030,8 +3030,10 @@ static int __maybe_unused marvell_nfc_resume(struct device *dev)
+ return ret;
+
+ ret = clk_prepare_enable(nfc->reg_clk);
+- if (ret < 0)
++ if (ret < 0) {
++ clk_disable_unprepare(nfc->core_clk);
+ return ret;
++ }
+
+ /*
+ * Reset nfc->selected_chip so the next command will cause the timing
+--
+2.30.2
+
--- /dev/null
+From 192f995e1d0e8515b7e185dfe8d0f9eb9989d867 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 13:27:41 +0200
+Subject: mtd: spi-nor: otp: fix access to security registers in 4 byte mode
+
+From: Michael Walle <michael@walle.cc>
+
+[ Upstream commit b97b1a769849beb6b40b740817b06f1a50e1c589 ]
+
+The security registers either take a 3 byte or a 4 byte address offset,
+depending on the address mode of the flash. Thus just leave the
+nor->addr_width as is.
+
+Fixes: cad3193fe9d1 ("mtd: spi-nor: implement OTP support for Winbond and similar flashes")
+Signed-off-by: Michael Walle <michael@walle.cc>
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>
+Acked-by: Pratyush Yadav <p.yadav@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/spi-nor/otp.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/mtd/spi-nor/otp.c b/drivers/mtd/spi-nor/otp.c
+index fcf38d260345..5c51a2c9be61 100644
+--- a/drivers/mtd/spi-nor/otp.c
++++ b/drivers/mtd/spi-nor/otp.c
+@@ -40,7 +40,6 @@ int spi_nor_otp_read_secr(struct spi_nor *nor, loff_t addr, size_t len, u8 *buf)
+ rdesc = nor->dirmap.rdesc;
+
+ nor->read_opcode = SPINOR_OP_RSECR;
+- nor->addr_width = 3;
+ nor->read_dummy = 8;
+ nor->read_proto = SNOR_PROTO_1_1_1;
+ nor->dirmap.rdesc = NULL;
+@@ -84,7 +83,6 @@ int spi_nor_otp_write_secr(struct spi_nor *nor, loff_t addr, size_t len,
+ wdesc = nor->dirmap.wdesc;
+
+ nor->program_opcode = SPINOR_OP_PSECR;
+- nor->addr_width = 3;
+ nor->write_proto = SNOR_PROTO_1_1_1;
+ nor->dirmap.wdesc = NULL;
+
+--
+2.30.2
+
--- /dev/null
+From 55865f99a5bb15342bd80a9b927ad1c706266913 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 13:27:43 +0200
+Subject: mtd: spi-nor: otp: return -EROFS if region is read-only
+
+From: Michael Walle <michael@walle.cc>
+
+[ Upstream commit 388161ca45c911f566b71716bce5ff0119fb5522 ]
+
+SPI NOR flashes will just ignore program commands if the OTP region is
+locked. Thus, a user might not notice that the intended write didn't end
+up in the flash. Return -EROFS to the user in this case. From what I can
+tell, chips/cfi_cmdset_0001.c also return this error code.
+
+One could optimize spi_nor_mtd_otp_range_is_locked() to read the status
+register only once and not for every OTP region, but for that we would
+need some more invasive changes. Given that this is
+one-time-programmable memory and the normal access mode is reading, we
+just live with the small overhead.
+
+By moving the code around a bit, we can just check the length before
+calling spi_nor_mtd_otp_range_is_locked() and avoid an underflow there
+if a len is 0. This way we don't need to take the lock either. We also
+skip the "*retlen = 0" assignment, mtdcore already takes care of that
+for us.
+
+Fixes: 069089acf88b ("mtd: spi-nor: add OTP support")
+Signed-off-by: Michael Walle <michael@walle.cc>
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
+Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/spi-nor/otp.c | 41 ++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 38 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mtd/spi-nor/otp.c b/drivers/mtd/spi-nor/otp.c
+index 5c51a2c9be61..d8e68120a4b1 100644
+--- a/drivers/mtd/spi-nor/otp.c
++++ b/drivers/mtd/spi-nor/otp.c
+@@ -238,6 +238,29 @@ out:
+ return ret;
+ }
+
++static int spi_nor_mtd_otp_range_is_locked(struct spi_nor *nor, loff_t ofs,
++ size_t len)
++{
++ const struct spi_nor_otp_ops *ops = nor->params->otp.ops;
++ unsigned int region;
++ int locked;
++
++ /*
++ * If any of the affected OTP regions are locked the entire range is
++ * considered locked.
++ */
++ for (region = spi_nor_otp_offset_to_region(nor, ofs);
++ region <= spi_nor_otp_offset_to_region(nor, ofs + len - 1);
++ region++) {
++ locked = ops->is_locked(nor, region);
++ /* take the branch it is locked or in case of an error */
++ if (locked)
++ return locked;
++ }
++
++ return 0;
++}
++
+ static int spi_nor_mtd_otp_read_write(struct mtd_info *mtd, loff_t ofs,
+ size_t total_len, size_t *retlen,
+ const u8 *buf, bool is_write)
+@@ -253,14 +276,26 @@ static int spi_nor_mtd_otp_read_write(struct mtd_info *mtd, loff_t ofs,
+ if (ofs < 0 || ofs >= spi_nor_otp_size(nor))
+ return 0;
+
++ /* don't access beyond the end */
++ total_len = min_t(size_t, total_len, spi_nor_otp_size(nor) - ofs);
++
++ if (!total_len)
++ return 0;
++
+ ret = spi_nor_lock_and_prep(nor);
+ if (ret)
+ return ret;
+
+- /* don't access beyond the end */
+- total_len = min_t(size_t, total_len, spi_nor_otp_size(nor) - ofs);
++ if (is_write) {
++ ret = spi_nor_mtd_otp_range_is_locked(nor, ofs, total_len);
++ if (ret < 0) {
++ goto out;
++ } else if (ret) {
++ ret = -EROFS;
++ goto out;
++ }
++ }
+
+- *retlen = 0;
+ while (total_len) {
+ /*
+ * The OTP regions are mapped into a contiguous area starting
+--
+2.30.2
+
--- /dev/null
+From c563ecfe7f2b65207a2cf46d139706baae70e507 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 May 2021 10:43:45 +0200
+Subject: mtd: spinand: Fix double counting of ECC stats
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ Upstream commit c93081b265735db2417f0964718516044d06b1a2 ]
+
+In the raw NAND world, ECC engines increment ecc_stats and the final
+caller is responsible for returning -EBADMSG if the verification
+failed.
+
+In the SPI-NAND world it was a bit different until now because there was
+only one possible ECC engine: the on-die one. Indeed, the
+spinand_mtd_read() call was incrementing the ecc_stats counters
+depending on the outcome of spinand_check_ecc_status() directly.
+
+So now let's split the logic like this:
+- spinand_check_ecc_status() is specific to the SPI-NAND on-die engine
+ and is kept very simple: it just returns the ECC status (bonus point:
+ the content of this helper can be overloaded).
+- spinand_ondie_ecc_finish_io_req() is the caller of
+ spinand_check_ecc_status() and will increment the counters and
+ eventually return -EBADMSG.
+- spinand_mtd_read() is not tied to the on-die ECC implementation and
+ should be able to handle results coming from other ECC engines: it has
+ the responsibility of returning the maximum number of bitflips which
+ happened during the entire operation as this is the only helper that
+ is aware that several pages may be read in a row.
+
+Fixes: 945845b54c9c ("mtd: spinand: Instantiate a SPI-NAND on-die ECC engine")
+Reported-by: YouChing Lin <ycllin@mxic.com.tw>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Tested-by: YouChing Lin <ycllin@mxic.com.tw>
+Link: https://lore.kernel.org/linux-mtd/20210527084345.208215-1-miquel.raynal@bootlin.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/spi/core.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
+index 17f63f95f4a2..54ae540bc66b 100644
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -290,6 +290,8 @@ static int spinand_ondie_ecc_finish_io_req(struct nand_device *nand,
+ {
+ struct spinand_ondie_ecc_conf *engine_conf = nand->ecc.ctx.priv;
+ struct spinand_device *spinand = nand_to_spinand(nand);
++ struct mtd_info *mtd = spinand_to_mtd(spinand);
++ int ret;
+
+ if (req->mode == MTD_OPS_RAW)
+ return 0;
+@@ -299,7 +301,13 @@ static int spinand_ondie_ecc_finish_io_req(struct nand_device *nand,
+ return 0;
+
+ /* Finish a page write: check the status, report errors/bitflips */
+- return spinand_check_ecc_status(spinand, engine_conf->status);
++ ret = spinand_check_ecc_status(spinand, engine_conf->status);
++ if (ret == -EBADMSG)
++ mtd->ecc_stats.failed++;
++ else if (ret > 0)
++ mtd->ecc_stats.corrected += ret;
++
++ return ret;
+ }
+
+ static struct nand_ecc_engine_ops spinand_ondie_ecc_engine_ops = {
+@@ -620,13 +628,10 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t from,
+ if (ret < 0 && ret != -EBADMSG)
+ break;
+
+- if (ret == -EBADMSG) {
++ if (ret == -EBADMSG)
+ ecc_failed = true;
+- mtd->ecc_stats.failed++;
+- } else {
+- mtd->ecc_stats.corrected += ret;
++ else
+ max_bitflips = max_t(unsigned int, max_bitflips, ret);
+- }
+
+ ret = 0;
+ ops->retlen += iter.req.datalen;
+--
+2.30.2
+
--- /dev/null
+From 35a3ced60085fd64c40e57d1b2459f13cd69aecb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 May 2021 00:07:55 +0200
+Subject: mwifiex: re-fix for unaligned accesses
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 8f4e3d48bb50765ab27ae5bebed2595b20de80a1 ]
+
+A patch from 2017 changed some accesses to DMA memory to use
+get_unaligned_le32() and similar interfaces, to avoid problems
+with doing unaligned accesson uncached memory.
+
+However, the change in the mwifiex_pcie_alloc_sleep_cookie_buf()
+function ended up changing the size of the access instead,
+as it operates on a pointer to u8.
+
+Change this function back to actually access the entire 32 bits.
+Note that the pointer is aligned by definition because it came
+from dma_alloc_coherent().
+
+Fixes: 92c70a958b0b ("mwifiex: fix for unaligned reads")
+Acked-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/pcie.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
+index 94228b316df1..46517515ba72 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
++++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
+@@ -1231,7 +1231,7 @@ static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
+ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
+ {
+ struct pcie_service_card *card = adapter->card;
+- u32 tmp;
++ u32 *cookie;
+
+ card->sleep_cookie_vbase = dma_alloc_coherent(&card->dev->dev,
+ sizeof(u32),
+@@ -1242,13 +1242,11 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
+ "dma_alloc_coherent failed!\n");
+ return -ENOMEM;
+ }
++ cookie = (u32 *)card->sleep_cookie_vbase;
+ /* Init val of Sleep Cookie */
+- tmp = FW_AWAKE_COOKIE;
+- put_unaligned(tmp, card->sleep_cookie_vbase);
++ *cookie = FW_AWAKE_COOKIE;
+
+- mwifiex_dbg(adapter, INFO,
+- "alloc_scook: sleep cookie=0x%x\n",
+- get_unaligned(card->sleep_cookie_vbase));
++ mwifiex_dbg(adapter, INFO, "alloc_scook: sleep cookie=0x%x\n", *cookie);
+
+ return 0;
+ }
+--
+2.30.2
+
--- /dev/null
+From c3b6fac5acac64a898f707fd95d04f0a6fd7eed5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Jun 2021 11:38:30 +0200
+Subject: net: atlantic: fix the macsec key length
+
+From: Antoine Tenart <atenart@kernel.org>
+
+[ Upstream commit d67fb4772d9a6cfd10f1109f0e7b1e6eb58c8e16 ]
+
+The key length used to store the macsec key was set to MACSEC_KEYID_LEN
+(16), which is an issue as:
+- This was never meant to be the key length.
+- The key length can be > 16.
+
+Fix this by using MACSEC_MAX_KEY_LEN instead (the max length accepted in
+uAPI).
+
+Fixes: 27736563ce32 ("net: atlantic: MACSec egress offload implementation")
+Fixes: 9ff40a751a6f ("net: atlantic: MACSec ingress offload implementation")
+Reported-by: Lior Nahmanson <liorna@nvidia.com>
+Signed-off-by: Antoine Tenart <atenart@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/aquantia/atlantic/aq_macsec.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_macsec.h b/drivers/net/ethernet/aquantia/atlantic/aq_macsec.h
+index f5fba8b8cdea..a47e2710487e 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_macsec.h
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_macsec.h
+@@ -91,7 +91,7 @@ struct aq_macsec_txsc {
+ u32 hw_sc_idx;
+ unsigned long tx_sa_idx_busy;
+ const struct macsec_secy *sw_secy;
+- u8 tx_sa_key[MACSEC_NUM_AN][MACSEC_KEYID_LEN];
++ u8 tx_sa_key[MACSEC_NUM_AN][MACSEC_MAX_KEY_LEN];
+ struct aq_macsec_tx_sc_stats stats;
+ struct aq_macsec_tx_sa_stats tx_sa_stats[MACSEC_NUM_AN];
+ };
+@@ -101,7 +101,7 @@ struct aq_macsec_rxsc {
+ unsigned long rx_sa_idx_busy;
+ const struct macsec_secy *sw_secy;
+ const struct macsec_rx_sc *sw_rxsc;
+- u8 rx_sa_key[MACSEC_NUM_AN][MACSEC_KEYID_LEN];
++ u8 rx_sa_key[MACSEC_NUM_AN][MACSEC_MAX_KEY_LEN];
+ struct aq_macsec_rx_sa_stats rx_sa_stats[MACSEC_NUM_AN];
+ };
+
+--
+2.30.2
+
--- /dev/null
+From 6235930f5a2c846b453ac3dad5269a525545b98f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 11:28:03 +0800
+Subject: net: bcmgenet: Fix attaching to PYH failed on RPi 4B
+
+From: Jian-Hong Pan <jhp@endlessos.org>
+
+[ Upstream commit b2ac9800cfe0f8da16abc4e74e003440361c112e ]
+
+The Broadcom UniMAC MDIO bus from mdio-bcm-unimac module comes too late.
+So, GENET cannot find the ethernet PHY on UniMAC MDIO bus. This leads
+GENET fail to attach the PHY as following log:
+
+bcmgenet fd580000.ethernet: GENET 5.0 EPHY: 0x0000
+...
+could not attach to PHY
+bcmgenet fd580000.ethernet eth0: failed to connect to PHY
+uart-pl011 fe201000.serial: no DMA platform data
+libphy: bcmgenet MII bus: probed
+...
+unimac-mdio unimac-mdio.-19: Broadcom UniMAC MDIO bus
+
+This patch adds the soft dependency to load mdio-bcm-unimac module
+before genet module to avoid the issue.
+
+Fixes: 9a4e79697009 ("net: bcmgenet: utilize generic Broadcom UniMAC MDIO controller driver")
+Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=213485
+Signed-off-by: Jian-Hong Pan <jhp@endlessos.org>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/genet/bcmgenet.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+index fcca023f22e5..41f7f078cd27 100644
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+@@ -4296,3 +4296,4 @@ MODULE_AUTHOR("Broadcom Corporation");
+ MODULE_DESCRIPTION("Broadcom GENET Ethernet controller driver");
+ MODULE_ALIAS("platform:bcmgenet");
+ MODULE_LICENSE("GPL");
++MODULE_SOFTDEP("pre: mdio-bcm-unimac");
+--
+2.30.2
+
--- /dev/null
+From 6cbc8325674e53ea319a184832c176a6b01cd90c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 07:24:15 +0200
+Subject: net: broadcom: bcm4908_enet: reset DMA rings sw indexes properly
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit ddeacc4f6494e07cbb6f033627926623f3e7a9d0 ]
+
+Resetting software indexes in bcm4908_dma_alloc_buf_descs() is not
+enough as it's called during device probe only. Driver resets DMA on
+every .ndo_open callback and it's required to reset indexes then.
+
+This fixes inconsistent rings state and stalled traffic after interface
+down & up sequence.
+
+Fixes: 4feffeadbcb2 ("net: broadcom: bcm4908enet: add BCM4908 controller driver")
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bcm4908_enet.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bcm4908_enet.c b/drivers/net/ethernet/broadcom/bcm4908_enet.c
+index 60d908507f51..02a569500234 100644
+--- a/drivers/net/ethernet/broadcom/bcm4908_enet.c
++++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c
+@@ -174,9 +174,6 @@ static int bcm4908_dma_alloc_buf_descs(struct bcm4908_enet *enet,
+ if (!ring->slots)
+ goto err_free_buf_descs;
+
+- ring->read_idx = 0;
+- ring->write_idx = 0;
+-
+ return 0;
+
+ err_free_buf_descs:
+@@ -304,6 +301,9 @@ static void bcm4908_enet_dma_ring_init(struct bcm4908_enet *enet,
+
+ enet_write(enet, ring->st_ram_block + ENET_DMA_CH_STATE_RAM_BASE_DESC_PTR,
+ (uint32_t)ring->dma_addr);
++
++ ring->read_idx = 0;
++ ring->write_idx = 0;
+ }
+
+ static void bcm4908_enet_dma_uninit(struct bcm4908_enet *enet)
+--
+2.30.2
+
--- /dev/null
+From c940d39126e24bf6ab4146aab7fe86c3b30b1457 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Jun 2021 11:54:38 +0300
+Subject: net: dsa: mv88e6xxx: Fix adding vlan 0
+
+From: Eldar Gasanov <eldargasanov2@gmail.com>
+
+[ Upstream commit b8b79c414eca4e9bcab645e02cb92c48db974ce9 ]
+
+8021q module adds vlan 0 to all interfaces when it starts.
+When 8021q module is loaded it isn't possible to create bond
+with mv88e6xxx interfaces, bonding module dipslay error
+"Couldn't add bond vlan ids", because it tries to add vlan 0
+to slave interfaces.
+
+There is unexpected behavior in the switch. When a PVID
+is assigned to a port the switch changes VID to PVID
+in ingress frames with VID 0 on the port. Expected
+that the switch doesn't assign PVID to tagged frames
+with VID 0. But there isn't a way to change this behavior
+in the switch.
+
+Fixes: 57e661aae6a8 ("net: dsa: mv88e6xxx: Link aggregation support")
+Signed-off-by: Eldar Gasanov <eldargasanov2@gmail.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/chip.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+index eca285aaf72f..961fa6b75cad 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -1618,9 +1618,6 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
+ struct mv88e6xxx_vtu_entry vlan;
+ int i, err;
+
+- if (!vid)
+- return -EOPNOTSUPP;
+-
+ /* DSA and CPU ports have to be members of multiple vlans */
+ if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
+ return 0;
+@@ -2109,6 +2106,9 @@ static int mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
+ u8 member;
+ int err;
+
++ if (!vlan->vid)
++ return 0;
++
+ err = mv88e6xxx_port_vlan_prepare(ds, port, vlan);
+ if (err)
+ return err;
+--
+2.30.2
+
--- /dev/null
+From a5322c21f52a261cb5fafe0e20222408723bf844 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Jun 2021 18:52:07 +0300
+Subject: net: dsa: sja1105: fix NULL pointer dereference in
+ sja1105_reload_cbs()
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit be7f62eebaff2f86c1467a2d33930a0a7a87675b ]
+
+priv->cbs is an array of priv->info->num_cbs_shapers elements of type
+struct sja1105_cbs_entry which only get allocated if CONFIG_NET_SCH_CBS
+is enabled.
+
+However, sja1105_reload_cbs() is called from sja1105_static_config_reload()
+which in turn is called for any of the items in sja1105_reset_reasons,
+therefore during the normal runtime of the driver and not just from a
+code path which can be triggered by the tc-cbs offload.
+
+The sja1105_reload_cbs() function does not contain a check whether the
+priv->cbs array is NULL or not, it just assumes it isn't and proceeds to
+iterate through the credit-based shaper elements. This leads to a NULL
+pointer dereference.
+
+The solution is to return success if the priv->cbs array has not been
+allocated, since sja1105_reload_cbs() has nothing to do.
+
+Fixes: 4d7525085a9b ("net: dsa: sja1105: offload the Credit-Based Shaper qdisc")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/sja1105/sja1105_main.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
+index b88d9ef45a1f..ebe4d33cda27 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -1798,6 +1798,12 @@ static int sja1105_reload_cbs(struct sja1105_private *priv)
+ {
+ int rc = 0, i;
+
++ /* The credit based shapers are only allocated if
++ * CONFIG_NET_SCH_CBS is enabled.
++ */
++ if (!priv->cbs)
++ return 0;
++
+ for (i = 0; i < priv->info->num_cbs_shapers; i++) {
+ struct sja1105_cbs_entry *cbs = &priv->cbs[i];
+
+--
+2.30.2
+
--- /dev/null
+From 5dd94a11c5981bdedce2d2721f34c0e5c6509818 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 17:57:31 +0300
+Subject: net: ethernet: aeroflex: fix UAF in greth_of_remove
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+[ Upstream commit e3a5de6d81d8b2199935c7eb3f7d17a50a7075b7 ]
+
+static int greth_of_remove(struct platform_device *of_dev)
+{
+...
+ struct greth_private *greth = netdev_priv(ndev);
+...
+ unregister_netdev(ndev);
+ free_netdev(ndev);
+
+ of_iounmap(&of_dev->resource[0], greth->regs, resource_size(&of_dev->resource[0]));
+...
+}
+
+greth is netdev private data, but it is used
+after free_netdev(). It can cause use-after-free when accessing greth
+pointer. So, fix it by moving free_netdev() after of_iounmap()
+call.
+
+Fixes: d4c41139df6e ("net: Add Aeroflex Gaisler 10/100/1G Ethernet MAC driver")
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/aeroflex/greth.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c
+index d77fafbc1530..c560ad06f0be 100644
+--- a/drivers/net/ethernet/aeroflex/greth.c
++++ b/drivers/net/ethernet/aeroflex/greth.c
+@@ -1539,10 +1539,11 @@ static int greth_of_remove(struct platform_device *of_dev)
+ mdiobus_unregister(greth->mdio);
+
+ unregister_netdev(ndev);
+- free_netdev(ndev);
+
+ of_iounmap(&of_dev->resource[0], greth->regs, resource_size(&of_dev->resource[0]));
+
++ free_netdev(ndev);
++
+ return 0;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From a03dd77159f26ed0556f66feebe7c930fb3ff6c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 19:14:47 +0300
+Subject: net: ethernet: ezchip: fix error handling
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+[ Upstream commit 0de449d599594f5472e00267d651615c7f2c6c1d ]
+
+As documented at drivers/base/platform.c for platform_get_irq:
+
+ * Gets an IRQ for a platform device and prints an error message if finding the
+ * IRQ fails. Device drivers should check the return value for errors so as to
+ * not pass a negative integer value to the request_irq() APIs.
+
+So, the driver should check that platform_get_irq() return value
+is _negative_, not that it's equal to zero, because -ENXIO (return
+value from request_irq() if irq was not found) will
+pass this check and it leads to passing negative irq to request_irq()
+
+Fixes: 0dd077093636 ("NET: Add ezchip ethernet driver")
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ezchip/nps_enet.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c
+index 20d2c2bb26e4..49957598301b 100644
+--- a/drivers/net/ethernet/ezchip/nps_enet.c
++++ b/drivers/net/ethernet/ezchip/nps_enet.c
+@@ -607,7 +607,7 @@ static s32 nps_enet_probe(struct platform_device *pdev)
+
+ /* Get IRQ number */
+ priv->irq = platform_get_irq(pdev, 0);
+- if (!priv->irq) {
++ if (priv->irq < 0) {
+ dev_err(dev, "failed to retrieve <irq Rx-Tx> value from device tree\n");
+ err = -ENODEV;
+ goto out_netdev;
+--
+2.30.2
+
--- /dev/null
+From 6da8a0e0f9bf655f057d25785d21b3f3470f3532 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 19:14:31 +0300
+Subject: net: ethernet: ezchip: fix UAF in nps_enet_remove
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+[ Upstream commit e4b8700e07a86e8eab6916aa5c5ba99042c34089 ]
+
+priv is netdev private data, but it is used
+after free_netdev(). It can cause use-after-free when accessing priv
+pointer. So, fix it by moving free_netdev() after netif_napi_del()
+call.
+
+Fixes: 0dd077093636 ("NET: Add ezchip ethernet driver")
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ezchip/nps_enet.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c
+index e3954d8835e7..20d2c2bb26e4 100644
+--- a/drivers/net/ethernet/ezchip/nps_enet.c
++++ b/drivers/net/ethernet/ezchip/nps_enet.c
+@@ -642,8 +642,8 @@ static s32 nps_enet_remove(struct platform_device *pdev)
+ struct nps_enet_priv *priv = netdev_priv(ndev);
+
+ unregister_netdev(ndev);
+- free_netdev(ndev);
+ netif_napi_del(&priv->napi);
++ free_netdev(ndev);
+
+ return 0;
+ }
+--
+2.30.2
+
--- /dev/null
+From 03db42461bbc141e3151285b85787ddb582d1f4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 May 2021 20:02:46 +0800
+Subject: net: ftgmac100: add missing error return code in ftgmac100_probe()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 52af13a41489d7bbc1932d17583eff6e5fffc820 ]
+
+The variables will be free on path err_phy_connect, it should
+return error code, or it will cause double free when calling
+ftgmac100_remove().
+
+Fixes: bd466c3fb5a4 ("net/faraday: Support NCSI mode")
+Fixes: 39bfab8844a0 ("net: ftgmac100: Add support for DT phy-handle property")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/faraday/ftgmac100.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
+index 04421aec2dfd..11dbbfd38770 100644
+--- a/drivers/net/ethernet/faraday/ftgmac100.c
++++ b/drivers/net/ethernet/faraday/ftgmac100.c
+@@ -1830,14 +1830,17 @@ static int ftgmac100_probe(struct platform_device *pdev)
+ if (np && of_get_property(np, "use-ncsi", NULL)) {
+ if (!IS_ENABLED(CONFIG_NET_NCSI)) {
+ dev_err(&pdev->dev, "NCSI stack not enabled\n");
++ err = -EINVAL;
+ goto err_phy_connect;
+ }
+
+ dev_info(&pdev->dev, "Using NCSI interface\n");
+ priv->use_ncsi = true;
+ priv->ndev = ncsi_register_dev(netdev, ftgmac100_ncsi_handler);
+- if (!priv->ndev)
++ if (!priv->ndev) {
++ err = -EINVAL;
+ goto err_phy_connect;
++ }
+ } else if (np && of_get_property(np, "phy-handle", NULL)) {
+ struct phy_device *phy;
+
+@@ -1856,6 +1859,7 @@ static int ftgmac100_probe(struct platform_device *pdev)
+ &ftgmac100_adjust_link);
+ if (!phy) {
+ dev_err(&pdev->dev, "Failed to connect to phy\n");
++ err = -EINVAL;
+ goto err_phy_connect;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 771e4e73807d96112e8d39c0c077b180301ac5b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 12:24:50 +0800
+Subject: net/ipv4: swap flow ports when validating source
+
+From: Miao Wang <shankerwangmiao@gmail.com>
+
+[ Upstream commit c69f114d09891adfa3e301a35d9e872b8b7b5a50 ]
+
+When doing source address validation, the flowi4 struct used for
+fib_lookup should be in the reverse direction to the given skb.
+fl4_dport and fl4_sport returned by fib4_rules_early_flow_dissect
+should thus be swapped.
+
+Fixes: 5a847a6e1477 ("net/ipv4: Initialize proto and ports in flow struct")
+Signed-off-by: Miao Wang <shankerwangmiao@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/fib_frontend.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
+index 84bb707bd88d..647bceab56c2 100644
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -371,6 +371,8 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
+ fl4.flowi4_proto = 0;
+ fl4.fl4_sport = 0;
+ fl4.fl4_dport = 0;
++ } else {
++ swap(fl4.fl4_sport, fl4.fl4_dport);
+ }
+
+ if (fib_lookup(net, &fl4, &res, 0))
+--
+2.30.2
+
--- /dev/null
+From 626a740893233b55467e42bc4a83c20326ea8d5e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Jun 2021 19:21:39 +0300
+Subject: net: lwtunnel: handle MTU calculation in forwading
+
+From: Vadim Fedorenko <vfedorenko@novek.ru>
+
+[ Upstream commit fade56410c22cacafb1be9f911a0afd3701d8366 ]
+
+Commit 14972cbd34ff ("net: lwtunnel: Handle fragmentation") moved
+fragmentation logic away from lwtunnel by carry encap headroom and
+use it in output MTU calculation. But the forwarding part was not
+covered and created difference in MTU for output and forwarding and
+further to silent drops on ipv4 forwarding path. Fix it by taking
+into account lwtunnel encap headroom.
+
+The same commit also introduced difference in how to treat RTAX_MTU
+in IPv4 and IPv6 where latter explicitly removes lwtunnel encap
+headroom from route MTU. Make IPv4 version do the same.
+
+Fixes: 14972cbd34ff ("net: lwtunnel: Handle fragmentation")
+Suggested-by: David Ahern <dsahern@gmail.com>
+Signed-off-by: Vadim Fedorenko <vfedorenko@novek.ru>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ip.h | 12 ++++++++----
+ include/net/ip6_route.h | 16 ++++++++++++----
+ net/ipv4/route.c | 3 ++-
+ 3 files changed, 22 insertions(+), 9 deletions(-)
+
+diff --git a/include/net/ip.h b/include/net/ip.h
+index e20874059f82..d9683bef8684 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -31,6 +31,7 @@
+ #include <net/flow.h>
+ #include <net/flow_dissector.h>
+ #include <net/netns/hash.h>
++#include <net/lwtunnel.h>
+
+ #define IPV4_MAX_PMTU 65535U /* RFC 2675, Section 5.1 */
+ #define IPV4_MIN_MTU 68 /* RFC 791 */
+@@ -445,22 +446,25 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst,
+
+ /* 'forwarding = true' case should always honour route mtu */
+ mtu = dst_metric_raw(dst, RTAX_MTU);
+- if (mtu)
+- return mtu;
++ if (!mtu)
++ mtu = min(READ_ONCE(dst->dev->mtu), IP_MAX_MTU);
+
+- return min(READ_ONCE(dst->dev->mtu), IP_MAX_MTU);
++ return mtu - lwtunnel_headroom(dst->lwtstate, mtu);
+ }
+
+ static inline unsigned int ip_skb_dst_mtu(struct sock *sk,
+ const struct sk_buff *skb)
+ {
++ unsigned int mtu;
++
+ if (!sk || !sk_fullsock(sk) || ip_sk_use_pmtu(sk)) {
+ bool forwarding = IPCB(skb)->flags & IPSKB_FORWARDED;
+
+ return ip_dst_mtu_maybe_forward(skb_dst(skb), forwarding);
+ }
+
+- return min(READ_ONCE(skb_dst(skb)->dev->mtu), IP_MAX_MTU);
++ mtu = min(READ_ONCE(skb_dst(skb)->dev->mtu), IP_MAX_MTU);
++ return mtu - lwtunnel_headroom(skb_dst(skb)->lwtstate, mtu);
+ }
+
+ struct dst_metrics *ip_fib_metrics_init(struct net *net, struct nlattr *fc_mx,
+diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
+index f51a118bfce8..f14149df5a65 100644
+--- a/include/net/ip6_route.h
++++ b/include/net/ip6_route.h
+@@ -265,11 +265,18 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
+
+ static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
+ {
++ int mtu;
++
+ struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ?
+ inet6_sk(skb->sk) : NULL;
+
+- return (np && np->pmtudisc >= IPV6_PMTUDISC_PROBE) ?
+- skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
++ if (np && np->pmtudisc >= IPV6_PMTUDISC_PROBE) {
++ mtu = READ_ONCE(skb_dst(skb)->dev->mtu);
++ mtu -= lwtunnel_headroom(skb_dst(skb)->lwtstate, mtu);
++ } else
++ mtu = dst_mtu(skb_dst(skb));
++
++ return mtu;
+ }
+
+ static inline bool ip6_sk_accept_pmtu(const struct sock *sk)
+@@ -317,7 +324,7 @@ static inline unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst)
+ if (dst_metric_locked(dst, RTAX_MTU)) {
+ mtu = dst_metric_raw(dst, RTAX_MTU);
+ if (mtu)
+- return mtu;
++ goto out;
+ }
+
+ mtu = IPV6_MIN_MTU;
+@@ -327,7 +334,8 @@ static inline unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst)
+ mtu = idev->cnf.mtu6;
+ rcu_read_unlock();
+
+- return mtu;
++out:
++ return mtu - lwtunnel_headroom(dst->lwtstate, mtu);
+ }
+
+ u32 ip6_mtu_from_fib6(const struct fib6_result *res,
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 6a36ac98476f..78d1e5afc452 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -1306,7 +1306,7 @@ INDIRECT_CALLABLE_SCOPE unsigned int ipv4_mtu(const struct dst_entry *dst)
+ mtu = dst_metric_raw(dst, RTAX_MTU);
+
+ if (mtu)
+- return mtu;
++ goto out;
+
+ mtu = READ_ONCE(dst->dev->mtu);
+
+@@ -1315,6 +1315,7 @@ INDIRECT_CALLABLE_SCOPE unsigned int ipv4_mtu(const struct dst_entry *dst)
+ mtu = 576;
+ }
+
++out:
+ mtu = min_t(unsigned int, mtu, IP_MAX_MTU);
+
+ return mtu - lwtunnel_headroom(dst->lwtstate, mtu);
+--
+2.30.2
+
--- /dev/null
+From 8be4e5803c33e2787453bd2b1fd88b360533eb05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Jun 2021 11:38:28 +0200
+Subject: net: macsec: fix the length used to copy the key for offloading
+
+From: Antoine Tenart <atenart@kernel.org>
+
+[ Upstream commit 1f7fe5121127e037b86592ba42ce36515ea0e3f7 ]
+
+The key length used when offloading macsec to Ethernet or PHY drivers
+was set to MACSEC_KEYID_LEN (16), which is an issue as:
+- This was never meant to be the key length.
+- The key length can be > 16.
+
+Fix this by using MACSEC_MAX_KEY_LEN to store the key (the max length
+accepted in uAPI) and secy->key_len to copy it.
+
+Fixes: 3cf3227a21d1 ("net: macsec: hardware offloading infrastructure")
+Reported-by: Lior Nahmanson <liorna@nvidia.com>
+Signed-off-by: Antoine Tenart <atenart@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/macsec.c | 4 ++--
+ include/net/macsec.h | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index 92425e1fd70c..93dc48b9b4f2 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -1819,7 +1819,7 @@ static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info)
+ ctx.sa.rx_sa = rx_sa;
+ ctx.secy = secy;
+ memcpy(ctx.sa.key, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]),
+- MACSEC_KEYID_LEN);
++ secy->key_len);
+
+ err = macsec_offload(ops->mdo_add_rxsa, &ctx);
+ if (err)
+@@ -2061,7 +2061,7 @@ static int macsec_add_txsa(struct sk_buff *skb, struct genl_info *info)
+ ctx.sa.tx_sa = tx_sa;
+ ctx.secy = secy;
+ memcpy(ctx.sa.key, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]),
+- MACSEC_KEYID_LEN);
++ secy->key_len);
+
+ err = macsec_offload(ops->mdo_add_txsa, &ctx);
+ if (err)
+diff --git a/include/net/macsec.h b/include/net/macsec.h
+index 52874cdfe226..d6fa6b97f6ef 100644
+--- a/include/net/macsec.h
++++ b/include/net/macsec.h
+@@ -241,7 +241,7 @@ struct macsec_context {
+ struct macsec_rx_sc *rx_sc;
+ struct {
+ unsigned char assoc_num;
+- u8 key[MACSEC_KEYID_LEN];
++ u8 key[MACSEC_MAX_KEY_LEN];
+ union {
+ struct macsec_rx_sa *rx_sa;
+ struct macsec_tx_sa *tx_sa;
+--
+2.30.2
+
--- /dev/null
+From 535d890eae0a0625bb4eb78efdf477f7dd0a12de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Jun 2021 15:43:28 +0200
+Subject: net: mana: Fix a memory leak in an error handling path in
+ 'mana_create_txq()'
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit b90788459cd6d140171b046f0b37fad341ade0a3 ]
+
+If this test fails we must free some resources as in all the other error
+handling paths of this function.
+
+Fixes: ca9c54d2d6a5 ("net: mana: Add a driver for Microsoft Azure Network Adapter (MANA)")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microsoft/mana/mana_en.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
+index 04d067243457..1ed25e48f616 100644
+--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
+@@ -1230,8 +1230,10 @@ static int mana_create_txq(struct mana_port_context *apc,
+
+ cq->gdma_id = cq->gdma_cq->id;
+
+- if (WARN_ON(cq->gdma_id >= gc->max_num_cqs))
+- return -EINVAL;
++ if (WARN_ON(cq->gdma_id >= gc->max_num_cqs)) {
++ err = -EINVAL;
++ goto out;
++ }
+
+ gc->cq_table[cq->gdma_id] = cq->gdma_cq;
+
+--
+2.30.2
+
--- /dev/null
+From 59afffa35f9a2db83d10109bc6f85f27a7a13ea5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 12:58:05 +0300
+Subject: net: mvpp2: Put fwnode in error case during ->probe()
+
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+
+[ Upstream commit 71f0891c84dfdc448736082ab0a00acd29853896 ]
+
+In each iteration fwnode_for_each_available_child_node() bumps a reference
+counting of a loop variable followed by dropping in on a next iteration,
+
+Since in error case the loop is broken, we have to drop a reference count
+by ourselves. Do it for port_fwnode in error case during ->probe().
+
+Fixes: 248122212f68 ("net: mvpp2: use device_*/fwnode_* APIs instead of of_*")
+Cc: Marcin Wojtas <mw@semihalf.com>
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index d39c7639cdba..b3041fe6c0ae 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -7588,6 +7588,8 @@ static int mvpp2_probe(struct platform_device *pdev)
+ return 0;
+
+ err_port_probe:
++ fwnode_handle_put(port_fwnode);
++
+ i = 0;
+ fwnode_for_each_available_child_node(fwnode, port_fwnode) {
+ if (priv->port_list[i])
+--
+2.30.2
+
--- /dev/null
+From 4aa74dd3d672bf7eba268d4fb20f57cf6ba5e75e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 19:39:27 +0300
+Subject: net: pch_gbe: Propagate error from devm_gpio_request_one()
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 9e3617a7b84512bf96c04f9cf82d1a7257d33794 ]
+
+If GPIO controller is not available yet we need to defer
+the probe of GBE until provider will become available.
+
+While here, drop GPIOF_EXPORT because it's deprecated and
+may not be available.
+
+Fixes: f1a26fdf5944 ("pch_gbe: Add MinnowBoard support")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Tested-by: Flavio Suligoi <f.suligoi@asem.it>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+index 334af49e5add..3dc29b282a88 100644
+--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
++++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+@@ -2532,9 +2532,13 @@ static int pch_gbe_probe(struct pci_dev *pdev,
+ adapter->pdev = pdev;
+ adapter->hw.back = adapter;
+ adapter->hw.reg = pcim_iomap_table(pdev)[PCH_GBE_PCI_BAR];
++
+ adapter->pdata = (struct pch_gbe_privdata *)pci_id->driver_data;
+- if (adapter->pdata && adapter->pdata->platform_init)
+- adapter->pdata->platform_init(pdev);
++ if (adapter->pdata && adapter->pdata->platform_init) {
++ ret = adapter->pdata->platform_init(pdev);
++ if (ret)
++ goto err_free_netdev;
++ }
+
+ adapter->ptp_pdev =
+ pci_get_domain_bus_and_slot(pci_domain_nr(adapter->pdev->bus),
+@@ -2629,7 +2633,7 @@ err_free_netdev:
+ */
+ static int pch_gbe_minnow_platform_init(struct pci_dev *pdev)
+ {
+- unsigned long flags = GPIOF_DIR_OUT | GPIOF_INIT_HIGH | GPIOF_EXPORT;
++ unsigned long flags = GPIOF_OUT_INIT_HIGH;
+ unsigned gpio = MINNOW_PHY_RESET_GPIO;
+ int ret;
+
+--
+2.30.2
+
--- /dev/null
+From f99881e0bd259efa994893b393464dcc9af60087 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Jun 2021 11:38:29 +0200
+Subject: net: phy: mscc: fix macsec key length
+
+From: Antoine Tenart <atenart@kernel.org>
+
+[ Upstream commit c309217f91f2d2097c2a0a832d9bff50b88c81dc ]
+
+The key length used to store the macsec key was set to MACSEC_KEYID_LEN
+(16), which is an issue as:
+- This was never meant to be the key length.
+- The key length can be > 16.
+
+Fix this by using MACSEC_MAX_KEY_LEN instead (the max length accepted in
+uAPI).
+
+Fixes: 28c5107aa904 ("net: phy: mscc: macsec support")
+Reported-by: Lior Nahmanson <liorna@nvidia.com>
+Signed-off-by: Antoine Tenart <atenart@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mscc/mscc_macsec.c | 2 +-
+ drivers/net/phy/mscc/mscc_macsec.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/phy/mscc/mscc_macsec.c b/drivers/net/phy/mscc/mscc_macsec.c
+index 10be266e48e8..b7b2521c73fb 100644
+--- a/drivers/net/phy/mscc/mscc_macsec.c
++++ b/drivers/net/phy/mscc/mscc_macsec.c
+@@ -501,7 +501,7 @@ static u32 vsc8584_macsec_flow_context_id(struct macsec_flow *flow)
+ }
+
+ /* Derive the AES key to get a key for the hash autentication */
+-static int vsc8584_macsec_derive_key(const u8 key[MACSEC_KEYID_LEN],
++static int vsc8584_macsec_derive_key(const u8 key[MACSEC_MAX_KEY_LEN],
+ u16 key_len, u8 hkey[16])
+ {
+ const u8 input[AES_BLOCK_SIZE] = {0};
+diff --git a/drivers/net/phy/mscc/mscc_macsec.h b/drivers/net/phy/mscc/mscc_macsec.h
+index 9c6d25e36de2..453304bae778 100644
+--- a/drivers/net/phy/mscc/mscc_macsec.h
++++ b/drivers/net/phy/mscc/mscc_macsec.h
+@@ -81,7 +81,7 @@ struct macsec_flow {
+ /* Highest takes precedence [0..15] */
+ u8 priority;
+
+- u8 key[MACSEC_KEYID_LEN];
++ u8 key[MACSEC_MAX_KEY_LEN];
+
+ union {
+ struct macsec_rx_sa *rx_sa;
+--
+2.30.2
+
--- /dev/null
+From 3fa3046b415c4c5095b6818ef5766e34afab167b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 11:35:26 +0200
+Subject: net: pxa168_eth: Fix a potential data race in pxa168_eth_remove
+
+From: Pavel Machek <pavel@denx.de>
+
+[ Upstream commit bd70957438f0cc4879cbdff8bbc8614bc1cddf49 ]
+
+Commit 0571a753cb07 cancelled delayed work too late, keeping small
+race. Cancel work sooner to close it completely.
+
+Signed-off-by: Pavel Machek (CIP) <pavel@denx.de>
+Fixes: 0571a753cb07 ("net: pxa168_eth: Fix a potential data race in pxa168_eth_remove")
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/pxa168_eth.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
+index e967867828d8..9b48ae4bac39 100644
+--- a/drivers/net/ethernet/marvell/pxa168_eth.c
++++ b/drivers/net/ethernet/marvell/pxa168_eth.c
+@@ -1528,6 +1528,7 @@ static int pxa168_eth_remove(struct platform_device *pdev)
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+
++ cancel_work_sync(&pep->tx_timeout_task);
+ if (pep->htpr) {
+ dma_free_coherent(pep->dev->dev.parent, HASH_ADDR_TABLE_SIZE,
+ pep->htpr, pep->htpr_dma);
+@@ -1539,7 +1540,6 @@ static int pxa168_eth_remove(struct platform_device *pdev)
+ clk_disable_unprepare(pep->clk);
+ mdiobus_unregister(pep->smi_bus);
+ mdiobus_free(pep->smi_bus);
+- cancel_work_sync(&pep->tx_timeout_task);
+ unregister_netdev(dev);
+ free_netdev(dev);
+ return 0;
+--
+2.30.2
+
--- /dev/null
+From 46dbd4369f266faeb6a123d56542eeeb8e5e5a50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 May 2021 15:58:52 +0000
+Subject: net: qrtr: ns: Fix error return code in qrtr_ns_init()
+
+From: Wei Yongjun <weiyongjun1@huawei.com>
+
+[ Upstream commit a49e72b3bda73d36664a084e47da9727a31b8095 ]
+
+Fix to return a negative error code -ENOMEM from the error handling
+case instead of 0, as done elsewhere in this function.
+
+Fixes: c6e08d6251f3 ("net: qrtr: Allocate workqueue before kernel_bind")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/qrtr/ns.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c
+index 8d00dfe8139e..1990d496fcfc 100644
+--- a/net/qrtr/ns.c
++++ b/net/qrtr/ns.c
+@@ -775,8 +775,10 @@ int qrtr_ns_init(void)
+ }
+
+ qrtr_ns.workqueue = alloc_workqueue("qrtr_ns_handler", WQ_UNBOUND, 1);
+- if (!qrtr_ns.workqueue)
++ if (!qrtr_ns.workqueue) {
++ ret = -ENOMEM;
+ goto err_sock;
++ }
+
+ qrtr_ns.sock->sk->sk_data_ready = qrtr_ns_data_ready;
+
+--
+2.30.2
+
--- /dev/null
+From b7e0ac8652b00efe8e2d3795c400a949995b1117 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Jun 2021 15:30:50 +0300
+Subject: net/sched: act_vlan: Fix modify to allow 0
+
+From: Boris Sukholitko <boris.sukholitko@broadcom.com>
+
+[ Upstream commit 9c5eee0afca09cbde6bd00f77876754aaa552970 ]
+
+Currently vlan modification action checks existence of vlan priority by
+comparing it to 0. Therefore it is impossible to modify existing vlan
+tag to have priority 0.
+
+For example, the following tc command will change the vlan id but will
+not affect vlan priority:
+
+tc filter add dev eth1 ingress matchall action vlan modify id 300 \
+ priority 0 pipe mirred egress redirect dev eth2
+
+The incoming packet on eth1:
+
+ethertype 802.1Q (0x8100), vlan 200, p 4, ethertype IPv4
+
+will be changed to:
+
+ethertype 802.1Q (0x8100), vlan 300, p 4, ethertype IPv4
+
+although the user has intended to have p == 0.
+
+The fix is to add tcfv_push_prio_exists flag to struct tcf_vlan_params
+and rely on it when deciding to set the priority.
+
+Fixes: 45a497f2d149a4a8061c (net/sched: act_vlan: Introduce TCA_VLAN_ACT_MODIFY vlan action)
+Signed-off-by: Boris Sukholitko <boris.sukholitko@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tc_act/tc_vlan.h | 1 +
+ net/sched/act_vlan.c | 7 +++++--
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/tc_act/tc_vlan.h b/include/net/tc_act/tc_vlan.h
+index f051046ba034..f94b8bc26f9e 100644
+--- a/include/net/tc_act/tc_vlan.h
++++ b/include/net/tc_act/tc_vlan.h
+@@ -16,6 +16,7 @@ struct tcf_vlan_params {
+ u16 tcfv_push_vid;
+ __be16 tcfv_push_proto;
+ u8 tcfv_push_prio;
++ bool tcfv_push_prio_exists;
+ struct rcu_head rcu;
+ };
+
+diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c
+index 1cac3c6fbb49..a108469c664f 100644
+--- a/net/sched/act_vlan.c
++++ b/net/sched/act_vlan.c
+@@ -70,7 +70,7 @@ static int tcf_vlan_act(struct sk_buff *skb, const struct tc_action *a,
+ /* replace the vid */
+ tci = (tci & ~VLAN_VID_MASK) | p->tcfv_push_vid;
+ /* replace prio bits, if tcfv_push_prio specified */
+- if (p->tcfv_push_prio) {
++ if (p->tcfv_push_prio_exists) {
+ tci &= ~VLAN_PRIO_MASK;
+ tci |= p->tcfv_push_prio << VLAN_PRIO_SHIFT;
+ }
+@@ -121,6 +121,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
+ struct tc_action_net *tn = net_generic(net, vlan_net_id);
+ struct nlattr *tb[TCA_VLAN_MAX + 1];
+ struct tcf_chain *goto_ch = NULL;
++ bool push_prio_exists = false;
+ struct tcf_vlan_params *p;
+ struct tc_vlan *parm;
+ struct tcf_vlan *v;
+@@ -189,7 +190,8 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
+ push_proto = htons(ETH_P_8021Q);
+ }
+
+- if (tb[TCA_VLAN_PUSH_VLAN_PRIORITY])
++ push_prio_exists = !!tb[TCA_VLAN_PUSH_VLAN_PRIORITY];
++ if (push_prio_exists)
+ push_prio = nla_get_u8(tb[TCA_VLAN_PUSH_VLAN_PRIORITY]);
+ break;
+ case TCA_VLAN_ACT_POP_ETH:
+@@ -241,6 +243,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
+ p->tcfv_action = action;
+ p->tcfv_push_vid = push_vid;
+ p->tcfv_push_prio = push_prio;
++ p->tcfv_push_prio_exists = push_prio_exists || action == TCA_VLAN_ACT_PUSH;
+ p->tcfv_push_proto = push_proto;
+
+ if (action == TCA_VLAN_ACT_PUSH_ETH) {
+--
+2.30.2
+
--- /dev/null
+From 6f1946f674b1e3df19090ff1b2d76100c2c2ccec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jun 2021 09:04:14 +0800
+Subject: net: sched: add barrier to ensure correct ordering for lockless qdisc
+
+From: Yunsheng Lin <linyunsheng@huawei.com>
+
+[ Upstream commit 89837eb4b2463c556a123437f242d6c2bc62ce81 ]
+
+The spin_trylock() was assumed to contain the implicit
+barrier needed to ensure the correct ordering between
+STATE_MISSED setting/clearing and STATE_MISSED checking
+in commit a90c57f2cedd ("net: sched: fix packet stuck
+problem for lockless qdisc").
+
+But it turns out that spin_trylock() only has load-acquire
+semantic, for strongly-ordered system(like x86), the compiler
+barrier implicitly contained in spin_trylock() seems enough
+to ensure the correct ordering. But for weakly-orderly system
+(like arm64), the store-release semantic is needed to ensure
+the correct ordering as clear_bit() and test_bit() is store
+operation, see queued_spin_lock().
+
+So add the explicit barrier to ensure the correct ordering
+for the above case.
+
+Fixes: a90c57f2cedd ("net: sched: fix packet stuck problem for lockless qdisc")
+Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
+Acked-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sch_generic.h | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
+index 1e625519ae96..57710303908c 100644
+--- a/include/net/sch_generic.h
++++ b/include/net/sch_generic.h
+@@ -163,6 +163,12 @@ static inline bool qdisc_run_begin(struct Qdisc *qdisc)
+ if (spin_trylock(&qdisc->seqlock))
+ goto nolock_empty;
+
++ /* Paired with smp_mb__after_atomic() to make sure
++ * STATE_MISSED checking is synchronized with clearing
++ * in pfifo_fast_dequeue().
++ */
++ smp_mb__before_atomic();
++
+ /* If the MISSED flag is set, it means other thread has
+ * set the MISSED flag before second spin_trylock(), so
+ * we can return false here to avoid multi cpus doing
+@@ -180,6 +186,12 @@ static inline bool qdisc_run_begin(struct Qdisc *qdisc)
+ */
+ set_bit(__QDISC_STATE_MISSED, &qdisc->state);
+
++ /* spin_trylock() only has load-acquire semantic, so use
++ * smp_mb__after_atomic() to ensure STATE_MISSED is set
++ * before doing the second spin_trylock().
++ */
++ smp_mb__after_atomic();
++
+ /* Retry again in case other CPU may not see the new flag
+ * after it releases the lock at the end of qdisc_run_end().
+ */
+--
+2.30.2
+
--- /dev/null
+From 8c0c13b59ffef206de2e5c822769b0b2c18b8e3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Jun 2021 23:23:48 +0300
+Subject: net: sched: fix warning in tcindex_alloc_perfect_hash
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+[ Upstream commit 3f2db250099f46988088800052cdf2332c7aba61 ]
+
+Syzbot reported warning in tcindex_alloc_perfect_hash. The problem
+was in too big cp->hash, which triggers warning in kmalloc. Since
+cp->hash comes from userspace, there is no need to warn if value
+is not correct
+
+Fixes: b9a24bb76bf6 ("net_sched: properly handle failure case of tcf_exts_init()")
+Reported-and-tested-by: syzbot+1071ad60cd7df39fdadb@syzkaller.appspotmail.com
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Acked-by: Cong Wang <cong.wang@bytedance.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/cls_tcindex.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
+index c4007b9cd16d..5b274534264c 100644
+--- a/net/sched/cls_tcindex.c
++++ b/net/sched/cls_tcindex.c
+@@ -304,7 +304,7 @@ static int tcindex_alloc_perfect_hash(struct net *net, struct tcindex_data *cp)
+ int i, err = 0;
+
+ cp->perfect = kcalloc(cp->hash, sizeof(struct tcindex_filter_result),
+- GFP_KERNEL);
++ GFP_KERNEL | __GFP_NOWARN);
+ if (!cp->perfect)
+ return -ENOMEM;
+
+--
+2.30.2
+
--- /dev/null
+From 12721790b8ed4a445ee70ffc6dcd3f307a92bbb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Jun 2021 17:02:38 +0800
+Subject: net: stmmac: Fix potential integer overflow
+
+From: Wong Vee Khee <vee.khee.wong@linux.intel.com>
+
+[ Upstream commit 52e597d3e2e6e5bfce47559eb22b955ac17b3826 ]
+
+The commit d96febedfde2 ("net: stmmac: arrange Tx tail pointer update
+to stmmac_flush_tx_descriptors") introduced the following coverity
+warning:-
+
+ 1. Unintentional integer overflow (OVERFLOW_BEFORE_WIDEN)
+ overflow_before_widen: Potentially overflowing expression
+ 'tx_q->cur_tx * desc_size' with type 'unsigned int' (32 bits,
+ unsigned) is evaluated using 32-bit arithmetic, and then used in a
+ context that expects an expression of type dma_addr_t (64 bits,
+ unsigned).
+
+Fixed this by assigning tx_tail_addr to dma_addr_t type, as dma_addr_t
+datatype is decided by CONFIG_ARCH_DMA_ADDR_T_64_BIT.
+
+Fixes: d96febedfde2 ("net: stmmac: arrange Tx tail pointer update to stmmac_flush_tx_descriptors")
+Signed-off-by: Wong Vee Khee <vee.khee.wong@linux.intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+index b6cd43eda7ac..8aa55612d094 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+@@ -75,7 +75,7 @@ struct stmmac_tx_queue {
+ unsigned int cur_tx;
+ unsigned int dirty_tx;
+ dma_addr_t dma_tx_phy;
+- u32 tx_tail_addr;
++ dma_addr_t tx_tail_addr;
+ u32 mss;
+ };
+
+--
+2.30.2
+
--- /dev/null
+From 959767ce15bb1713b5ada865f5bc27d35887e5c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 20:08:57 +0530
+Subject: net: ti: am65-cpsw-nuss: Fix crash when changing number of TX queues
+
+From: Vignesh Raghavendra <vigneshr@ti.com>
+
+[ Upstream commit ce8eb4c728ef40b554b4f3d8963f11ed44502e00 ]
+
+When changing number of TX queues using ethtool:
+
+ # ethtool -L eth0 tx 1
+ [ 135.301047] Unable to handle kernel paging request at virtual address 00000000af5d0000
+ [...]
+ [ 135.525128] Call trace:
+ [ 135.525142] dma_release_from_dev_coherent+0x2c/0xb0
+ [ 135.525148] dma_free_attrs+0x54/0xe0
+ [ 135.525156] k3_cppi_desc_pool_destroy+0x50/0xa0
+ [ 135.525164] am65_cpsw_nuss_remove_tx_chns+0x88/0xdc
+ [ 135.525171] am65_cpsw_set_channels+0x3c/0x70
+ [...]
+
+This is because k3_cppi_desc_pool_destroy() which is called after
+k3_udma_glue_release_tx_chn() in am65_cpsw_nuss_remove_tx_chns()
+references struct device that is unregistered at the end of
+k3_udma_glue_release_tx_chn()
+
+Therefore the right order is to call k3_cppi_desc_pool_destroy() and
+destroy desc pool before calling k3_udma_glue_release_tx_chn().
+Fix this throughout the driver.
+
+Fixes: 93a76530316a ("net: ethernet: ti: introduce am65x/j721e gigabit eth subsystem driver")
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/am65-cpsw-nuss.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index 6a67b026df0b..718539cdd2f2 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -1506,12 +1506,12 @@ static void am65_cpsw_nuss_free_tx_chns(void *data)
+ for (i = 0; i < common->tx_ch_num; i++) {
+ struct am65_cpsw_tx_chn *tx_chn = &common->tx_chns[i];
+
+- if (!IS_ERR_OR_NULL(tx_chn->tx_chn))
+- k3_udma_glue_release_tx_chn(tx_chn->tx_chn);
+-
+ if (!IS_ERR_OR_NULL(tx_chn->desc_pool))
+ k3_cppi_desc_pool_destroy(tx_chn->desc_pool);
+
++ if (!IS_ERR_OR_NULL(tx_chn->tx_chn))
++ k3_udma_glue_release_tx_chn(tx_chn->tx_chn);
++
+ memset(tx_chn, 0, sizeof(*tx_chn));
+ }
+ }
+@@ -1531,12 +1531,12 @@ void am65_cpsw_nuss_remove_tx_chns(struct am65_cpsw_common *common)
+
+ netif_napi_del(&tx_chn->napi_tx);
+
+- if (!IS_ERR_OR_NULL(tx_chn->tx_chn))
+- k3_udma_glue_release_tx_chn(tx_chn->tx_chn);
+-
+ if (!IS_ERR_OR_NULL(tx_chn->desc_pool))
+ k3_cppi_desc_pool_destroy(tx_chn->desc_pool);
+
++ if (!IS_ERR_OR_NULL(tx_chn->tx_chn))
++ k3_udma_glue_release_tx_chn(tx_chn->tx_chn);
++
+ memset(tx_chn, 0, sizeof(*tx_chn));
+ }
+ }
+@@ -1624,11 +1624,11 @@ static void am65_cpsw_nuss_free_rx_chns(void *data)
+
+ rx_chn = &common->rx_chns;
+
+- if (!IS_ERR_OR_NULL(rx_chn->rx_chn))
+- k3_udma_glue_release_rx_chn(rx_chn->rx_chn);
+-
+ if (!IS_ERR_OR_NULL(rx_chn->desc_pool))
+ k3_cppi_desc_pool_destroy(rx_chn->desc_pool);
++
++ if (!IS_ERR_OR_NULL(rx_chn->rx_chn))
++ k3_udma_glue_release_rx_chn(rx_chn->rx_chn);
+ }
+
+ static int am65_cpsw_nuss_init_rx_chns(struct am65_cpsw_common *common)
+--
+2.30.2
+
--- /dev/null
+From 66569dfbdcc2afeaf6458c1033da24ebd8de448e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Jun 2021 23:37:44 -0700
+Subject: net: tipc: fix FB_MTU eat two pages
+
+From: Menglong Dong <dong.menglong@zte.com.cn>
+
+[ Upstream commit 0c6de0c943dbb42831bf7502eb5c007f71e752d2 ]
+
+FB_MTU is used in 'tipc_msg_build()' to alloc smaller skb when memory
+allocation fails, which can avoid unnecessary sending failures.
+
+The value of FB_MTU now is 3744, and the data size will be:
+
+ (3744 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) + \
+ SKB_DATA_ALIGN(BUF_HEADROOM + BUF_TAILROOM + 3))
+
+which is larger than one page(4096), and two pages will be allocated.
+
+To avoid it, replace '3744' with a calculation:
+
+ (PAGE_SIZE - SKB_DATA_ALIGN(BUF_OVERHEAD) - \
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
+
+What's more, alloc_skb_fclone() will call SKB_DATA_ALIGN for data size,
+and it's not necessary to make alignment for buf_size in
+tipc_buf_acquire(). So, just remove it.
+
+Fixes: 4c94cc2d3d57 ("tipc: fall back to smaller MTU if allocation of local send skb fails")
+Signed-off-by: Menglong Dong <dong.menglong@zte.com.cn>
+Acked-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/bcast.c | 2 +-
+ net/tipc/msg.c | 17 ++++++++---------
+ net/tipc/msg.h | 3 ++-
+ 3 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
+index d4beca895992..593846d25214 100644
+--- a/net/tipc/bcast.c
++++ b/net/tipc/bcast.c
+@@ -699,7 +699,7 @@ int tipc_bcast_init(struct net *net)
+ spin_lock_init(&tipc_net(net)->bclock);
+
+ if (!tipc_link_bc_create(net, 0, 0, NULL,
+- FB_MTU,
++ one_page_mtu,
+ BCLINK_WIN_DEFAULT,
+ BCLINK_WIN_DEFAULT,
+ 0,
+diff --git a/net/tipc/msg.c b/net/tipc/msg.c
+index ce6ab54822d8..7053c22e393e 100644
+--- a/net/tipc/msg.c
++++ b/net/tipc/msg.c
+@@ -44,12 +44,15 @@
+ #define MAX_FORWARD_SIZE 1024
+ #ifdef CONFIG_TIPC_CRYPTO
+ #define BUF_HEADROOM ALIGN(((LL_MAX_HEADER + 48) + EHDR_MAX_SIZE), 16)
+-#define BUF_TAILROOM (TIPC_AES_GCM_TAG_SIZE)
++#define BUF_OVERHEAD (BUF_HEADROOM + TIPC_AES_GCM_TAG_SIZE)
+ #else
+ #define BUF_HEADROOM (LL_MAX_HEADER + 48)
+-#define BUF_TAILROOM 16
++#define BUF_OVERHEAD BUF_HEADROOM
+ #endif
+
++const int one_page_mtu = PAGE_SIZE - SKB_DATA_ALIGN(BUF_OVERHEAD) -
++ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
++
+ static unsigned int align(unsigned int i)
+ {
+ return (i + 3) & ~3u;
+@@ -69,13 +72,8 @@ static unsigned int align(unsigned int i)
+ struct sk_buff *tipc_buf_acquire(u32 size, gfp_t gfp)
+ {
+ struct sk_buff *skb;
+-#ifdef CONFIG_TIPC_CRYPTO
+- unsigned int buf_size = (BUF_HEADROOM + size + BUF_TAILROOM + 3) & ~3u;
+-#else
+- unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u;
+-#endif
+
+- skb = alloc_skb_fclone(buf_size, gfp);
++ skb = alloc_skb_fclone(BUF_OVERHEAD + size, gfp);
+ if (skb) {
+ skb_reserve(skb, BUF_HEADROOM);
+ skb_put(skb, size);
+@@ -395,7 +393,8 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset,
+ if (unlikely(!skb)) {
+ if (pktmax != MAX_MSG_SIZE)
+ return -ENOMEM;
+- rc = tipc_msg_build(mhdr, m, offset, dsz, FB_MTU, list);
++ rc = tipc_msg_build(mhdr, m, offset, dsz,
++ one_page_mtu, list);
+ if (rc != dsz)
+ return rc;
+ if (tipc_msg_assemble(list))
+diff --git a/net/tipc/msg.h b/net/tipc/msg.h
+index 5d64596ba987..64ae4c4c44f8 100644
+--- a/net/tipc/msg.h
++++ b/net/tipc/msg.h
+@@ -99,9 +99,10 @@ struct plist;
+ #define MAX_H_SIZE 60 /* Largest possible TIPC header size */
+
+ #define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE)
+-#define FB_MTU 3744
+ #define TIPC_MEDIA_INFO_OFFSET 5
+
++extern const int one_page_mtu;
++
+ struct tipc_skb_cb {
+ union {
+ struct {
+--
+2.30.2
+
--- /dev/null
+From cc089ec5461c4bc0e1ba9b279f8115644bc4c2de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Jul 2021 10:33:21 -0400
+Subject: net: wwan: Fix WWAN config symbols
+
+[ Upstream commit 89212e160b81e778f829b89743570665810e3b13 ]
+
+There is not strong reason to have both WWAN and WWAN_CORE symbols,
+Let's build the WWAN core framework when WWAN is selected, in the
+same way as for other subsystems.
+
+This fixes issue with mhi_net selecting WWAN_CORE without WWAN and
+reported by kernel test robot:
+
+Kconfig warnings: (for reference only)
+ WARNING: unmet direct dependencies detected for WWAN_CORE
+ Depends on NETDEVICES && WWAN
+ Selected by
+ - MHI_NET && NETDEVICES && NET_CORE && MHI_BUS
+
+Fixes: 9a44c1cc6388 ("net: Add a WWAN subsystem")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/Kconfig | 1 +
+ drivers/net/wwan/Kconfig | 15 ++++++---------
+ drivers/net/wwan/Makefile | 2 +-
+ 3 files changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index 74dc8e249faa..9b12a8e110f4 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -431,6 +431,7 @@ config VSOCKMON
+ config MHI_NET
+ tristate "MHI network driver"
+ depends on MHI_BUS
++ select WWAN
+ help
+ This is the network driver for MHI bus. It can be used with
+ QCOM based WWAN modems (like SDX55). Say Y or M.
+diff --git a/drivers/net/wwan/Kconfig b/drivers/net/wwan/Kconfig
+index 7ad1920120bc..e9d8a1c25e43 100644
+--- a/drivers/net/wwan/Kconfig
++++ b/drivers/net/wwan/Kconfig
+@@ -3,15 +3,9 @@
+ # Wireless WAN device configuration
+ #
+
+-menuconfig WWAN
+- bool "Wireless WAN"
+- help
+- This section contains Wireless WAN configuration for WWAN framework
+- and drivers.
+-
+-if WWAN
++menu "Wireless WAN"
+
+-config WWAN_CORE
++config WWAN
+ tristate "WWAN Driver Core"
+ help
+ Say Y here if you want to use the WWAN driver core. This driver
+@@ -20,9 +14,10 @@ config WWAN_CORE
+ To compile this driver as a module, choose M here: the module will be
+ called wwan.
+
++if WWAN
++
+ config MHI_WWAN_CTRL
+ tristate "MHI WWAN control driver for QCOM-based PCIe modems"
+- select WWAN_CORE
+ depends on MHI_BUS
+ help
+ MHI WWAN CTRL allows QCOM-based PCIe modems to expose different modem
+@@ -35,3 +30,5 @@ config MHI_WWAN_CTRL
+ called mhi_wwan_ctrl.
+
+ endif # WWAN
++
++endmenu
+diff --git a/drivers/net/wwan/Makefile b/drivers/net/wwan/Makefile
+index 556cd90958ca..289771a4f952 100644
+--- a/drivers/net/wwan/Makefile
++++ b/drivers/net/wwan/Makefile
+@@ -3,7 +3,7 @@
+ # Makefile for the Linux WWAN device drivers.
+ #
+
+-obj-$(CONFIG_WWAN_CORE) += wwan.o
++obj-$(CONFIG_WWAN) += wwan.o
+ wwan-objs += wwan_core.o
+
+ obj-$(CONFIG_MHI_WWAN_CTRL) += mhi_wwan_ctrl.o
+--
+2.30.2
+
--- /dev/null
+From e0e7e84cdaf4207f939a1dde68d9a1e301bb36e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 12:10:49 +0200
+Subject: netfilter: nf_tables: do not allow to delete table with owner by
+ handle
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit e31f072ffab0397a328b31a9589dcf9733dc9c72 ]
+
+nft_table_lookup_byhandle() also needs to validate the netlink PortID
+owner when deleting a table by handle.
+
+Fixes: 6001a930ce03 ("netfilter: nftables: introduce table ownership")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 1d62b1a83299..fcb15b8904e8 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -583,7 +583,7 @@ static struct nft_table *nft_table_lookup(const struct net *net,
+
+ static struct nft_table *nft_table_lookup_byhandle(const struct net *net,
+ const struct nlattr *nla,
+- u8 genmask)
++ u8 genmask, u32 nlpid)
+ {
+ struct nftables_pernet *nft_net;
+ struct nft_table *table;
+@@ -591,8 +591,13 @@ static struct nft_table *nft_table_lookup_byhandle(const struct net *net,
+ nft_net = nft_pernet(net);
+ list_for_each_entry(table, &nft_net->tables, list) {
+ if (be64_to_cpu(nla_get_be64(nla)) == table->handle &&
+- nft_active_genmask(table, genmask))
++ nft_active_genmask(table, genmask)) {
++ if (nft_table_has_owner(table) &&
++ nlpid && table->nlpid != nlpid)
++ return ERR_PTR(-EPERM);
++
+ return table;
++ }
+ }
+
+ return ERR_PTR(-ENOENT);
+@@ -1279,7 +1284,8 @@ static int nf_tables_deltable(struct sk_buff *skb, const struct nfnl_info *info,
+
+ if (nla[NFTA_TABLE_HANDLE]) {
+ attr = nla[NFTA_TABLE_HANDLE];
+- table = nft_table_lookup_byhandle(net, attr, genmask);
++ table = nft_table_lookup_byhandle(net, attr, genmask,
++ NETLINK_CB(skb).portid);
+ } else {
+ attr = nla[NFTA_TABLE_NAME];
+ table = nft_table_lookup(net, attr, family, genmask,
+--
+2.30.2
+
--- /dev/null
+From 7490394b9f307184cb82b7bca2da7fefdb275df2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Jun 2021 00:55:20 +0200
+Subject: netfilter: nf_tables: memleak in hw offload abort path
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 3c5e44622011b9ea21bd425875dcccfc9a158f5f ]
+
+Release flow from the abort path, this is easy to reproduce since
+b72920f6e4a9 ("netfilter: nftables: counter hardware offload support").
+If the preparation phase fails, then the abort path is exercised without
+releasing the flow rule object.
+
+unreferenced object 0xffff8881f0fa7700 (size 128):
+ comm "nft", pid 1335, jiffies 4294931120 (age 4163.740s)
+ hex dump (first 32 bytes):
+ 08 e4 de 13 82 88 ff ff 98 e4 de 13 82 88 ff ff ................
+ 48 e4 de 13 82 88 ff ff 01 00 00 00 00 00 00 00 H...............
+ backtrace:
+ [<00000000634547e7>] flow_rule_alloc+0x26/0x80
+ [<00000000c8426156>] nft_flow_rule_create+0xc9/0x3f0 [nf_tables]
+ [<0000000075ff8e46>] nf_tables_newrule+0xc79/0x10a0 [nf_tables]
+ [<00000000ba65e40e>] nfnetlink_rcv_batch+0xaac/0xf90 [nfnetlink]
+ [<00000000505c614a>] nfnetlink_rcv+0x1bb/0x1f0 [nfnetlink]
+ [<00000000eb78e1fe>] netlink_unicast+0x34b/0x480
+ [<00000000a8f72c94>] netlink_sendmsg+0x3af/0x690
+ [<000000009cb1ddf4>] sock_sendmsg+0x96/0xa0
+ [<0000000039d06e44>] ____sys_sendmsg+0x3fe/0x440
+ [<00000000137e82ca>] ___sys_sendmsg+0xd8/0x140
+ [<000000000c6bf6a6>] __sys_sendmsg+0xb3/0x130
+ [<0000000043bd6268>] do_syscall_64+0x40/0xb0
+ [<00000000afdebc2d>] entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+Remove flow rule release from the offload commit path, otherwise error
+from the offload commit phase might trigger a double-free due to the
+execution of the abort_offload -> abort. After this patch, the abort
+path takes care of releasing the flow rule.
+
+This fix also needs to move the nft_flow_rule_create() call before the
+transaction object is added otherwise the abort path might find a NULL
+pointer to the flow rule object for the NFT_CHAIN_HW_OFFLOAD case.
+
+While at it, rename BASIC-like goto tags to slightly more meaningful
+names rather than adding a new "err3" tag.
+
+Fixes: 63b48c73ff56 ("netfilter: nf_tables_offload: undo updates if transaction fails")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 51 +++++++++++++++++++------------
+ net/netfilter/nf_tables_offload.c | 17 -----------
+ 2 files changed, 31 insertions(+), 37 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index bf4d6ec9fc55..ca9ec8721e6c 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -3243,9 +3243,9 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
+ u8 genmask = nft_genmask_next(info->net);
+ struct nft_rule *rule, *old_rule = NULL;
+ struct nft_expr_info *expr_info = NULL;
++ struct nft_flow_rule *flow = NULL;
+ int family = nfmsg->nfgen_family;
+ struct net *net = info->net;
+- struct nft_flow_rule *flow;
+ struct nft_userdata *udata;
+ struct nft_table *table;
+ struct nft_chain *chain;
+@@ -3340,13 +3340,13 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
+ nla_for_each_nested(tmp, nla[NFTA_RULE_EXPRESSIONS], rem) {
+ err = -EINVAL;
+ if (nla_type(tmp) != NFTA_LIST_ELEM)
+- goto err1;
++ goto err_release_expr;
+ if (n == NFT_RULE_MAXEXPRS)
+- goto err1;
++ goto err_release_expr;
+ err = nf_tables_expr_parse(&ctx, tmp, &expr_info[n]);
+ if (err < 0) {
+ NL_SET_BAD_ATTR(extack, tmp);
+- goto err1;
++ goto err_release_expr;
+ }
+ size += expr_info[n].ops->size;
+ n++;
+@@ -3355,7 +3355,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
+ /* Check for overflow of dlen field */
+ err = -EFBIG;
+ if (size >= 1 << 12)
+- goto err1;
++ goto err_release_expr;
+
+ if (nla[NFTA_RULE_USERDATA]) {
+ ulen = nla_len(nla[NFTA_RULE_USERDATA]);
+@@ -3366,7 +3366,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
+ err = -ENOMEM;
+ rule = kzalloc(sizeof(*rule) + size + usize, GFP_KERNEL);
+ if (rule == NULL)
+- goto err1;
++ goto err_release_expr;
+
+ nft_activate_next(net, rule);
+
+@@ -3385,7 +3385,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
+ err = nf_tables_newexpr(&ctx, &expr_info[i], expr);
+ if (err < 0) {
+ NL_SET_BAD_ATTR(extack, expr_info[i].attr);
+- goto err2;
++ goto err_release_rule;
+ }
+
+ if (expr_info[i].ops->validate)
+@@ -3395,16 +3395,24 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
+ expr = nft_expr_next(expr);
+ }
+
++ if (chain->flags & NFT_CHAIN_HW_OFFLOAD) {
++ flow = nft_flow_rule_create(net, rule);
++ if (IS_ERR(flow)) {
++ err = PTR_ERR(flow);
++ goto err_release_rule;
++ }
++ }
++
+ if (info->nlh->nlmsg_flags & NLM_F_REPLACE) {
+ trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
+ if (trans == NULL) {
+ err = -ENOMEM;
+- goto err2;
++ goto err_destroy_flow_rule;
+ }
+ err = nft_delrule(&ctx, old_rule);
+ if (err < 0) {
+ nft_trans_destroy(trans);
+- goto err2;
++ goto err_destroy_flow_rule;
+ }
+
+ list_add_tail_rcu(&rule->list, &old_rule->list);
+@@ -3412,7 +3420,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
+ trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
+ if (!trans) {
+ err = -ENOMEM;
+- goto err2;
++ goto err_destroy_flow_rule;
+ }
+
+ if (info->nlh->nlmsg_flags & NLM_F_APPEND) {
+@@ -3430,21 +3438,19 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
+ kvfree(expr_info);
+ chain->use++;
+
++ if (flow)
++ nft_trans_flow_rule(trans) = flow;
++
+ if (nft_net->validate_state == NFT_VALIDATE_DO)
+ return nft_table_validate(net, table);
+
+- if (chain->flags & NFT_CHAIN_HW_OFFLOAD) {
+- flow = nft_flow_rule_create(net, rule);
+- if (IS_ERR(flow))
+- return PTR_ERR(flow);
+-
+- nft_trans_flow_rule(trans) = flow;
+- }
+-
+ return 0;
+-err2:
++
++err_destroy_flow_rule:
++ nft_flow_rule_destroy(flow);
++err_release_rule:
+ nf_tables_rule_release(&ctx, rule);
+-err1:
++err_release_expr:
+ for (i = 0; i < n; i++) {
+ if (expr_info[i].ops) {
+ module_put(expr_info[i].ops->type->owner);
+@@ -8839,11 +8845,16 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
+ nft_rule_expr_deactivate(&trans->ctx,
+ nft_trans_rule(trans),
+ NFT_TRANS_ABORT);
++ if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)
++ nft_flow_rule_destroy(nft_trans_flow_rule(trans));
+ break;
+ case NFT_MSG_DELRULE:
+ trans->ctx.chain->use++;
+ nft_clear(trans->ctx.net, nft_trans_rule(trans));
+ nft_rule_expr_activate(&trans->ctx, nft_trans_rule(trans));
++ if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)
++ nft_flow_rule_destroy(nft_trans_flow_rule(trans));
++
+ nft_trans_destroy(trans);
+ break;
+ case NFT_MSG_NEWSET:
+diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c
+index a48c5fd53a80..ec701b84844f 100644
+--- a/net/netfilter/nf_tables_offload.c
++++ b/net/netfilter/nf_tables_offload.c
+@@ -594,23 +594,6 @@ int nft_flow_rule_offload_commit(struct net *net)
+ }
+ }
+
+- list_for_each_entry(trans, &nft_net->commit_list, list) {
+- if (trans->ctx.family != NFPROTO_NETDEV)
+- continue;
+-
+- switch (trans->msg_type) {
+- case NFT_MSG_NEWRULE:
+- case NFT_MSG_DELRULE:
+- if (!(trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD))
+- continue;
+-
+- nft_flow_rule_destroy(nft_trans_flow_rule(trans));
+- break;
+- default:
+- break;
+- }
+- }
+-
+ return err;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From c995d074399c8a527b7f83cac8229a4bb5a00de9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 11:45:11 +0200
+Subject: netfilter: nf_tables: skip netlink portID validation if zero
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 534799097a777e82910f77a4f9d289c815a9a64e ]
+
+nft_table_lookup() allows us to obtain the table object by the name and
+the family. The netlink portID validation needs to be skipped for the
+dump path, since the ownership only applies to commands to update the
+given table. Skip validation if the specified netlink PortID is zero
+when calling nft_table_lookup().
+
+Fixes: 6001a930ce03 ("netfilter: nftables: introduce table ownership")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index ca9ec8721e6c..1d62b1a83299 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -571,7 +571,7 @@ static struct nft_table *nft_table_lookup(const struct net *net,
+ table->family == family &&
+ nft_active_genmask(table, genmask)) {
+ if (nft_table_has_owner(table) &&
+- table->nlpid != nlpid)
++ nlpid && table->nlpid != nlpid)
+ return ERR_PTR(-EPERM);
+
+ return table;
+--
+2.30.2
+
--- /dev/null
+From 5b69f42b5afdb6323ae60deba68e029f7022a01f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Jun 2021 01:25:14 +0200
+Subject: netfilter: nf_tables_offload: check FLOW_DISSECTOR_KEY_BASIC in VLAN
+ transfer logic
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit ea45fdf82cc90430bb7c280e5e53821e833782c5 ]
+
+The VLAN transfer logic should actually check for
+FLOW_DISSECTOR_KEY_BASIC, not FLOW_DISSECTOR_KEY_CONTROL. Moreover, do
+not fallback to case 2) .n_proto is set to 802.1q or 802.1ad, if
+FLOW_DISSECTOR_KEY_BASIC is unset.
+
+Fixes: 783003f3bb8a ("netfilter: nftables_offload: special ethertype handling for VLAN")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_offload.c | 17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c
+index ec701b84844f..b58d73a96523 100644
+--- a/net/netfilter/nf_tables_offload.c
++++ b/net/netfilter/nf_tables_offload.c
+@@ -54,15 +54,10 @@ static void nft_flow_rule_transfer_vlan(struct nft_offload_ctx *ctx,
+ struct nft_flow_rule *flow)
+ {
+ struct nft_flow_match *match = &flow->match;
+- struct nft_offload_ethertype ethertype;
+-
+- if (match->dissector.used_keys & BIT(FLOW_DISSECTOR_KEY_CONTROL) &&
+- match->key.basic.n_proto != htons(ETH_P_8021Q) &&
+- match->key.basic.n_proto != htons(ETH_P_8021AD))
+- return;
+-
+- ethertype.value = match->key.basic.n_proto;
+- ethertype.mask = match->mask.basic.n_proto;
++ struct nft_offload_ethertype ethertype = {
++ .value = match->key.basic.n_proto,
++ .mask = match->mask.basic.n_proto,
++ };
+
+ if (match->dissector.used_keys & BIT(FLOW_DISSECTOR_KEY_VLAN) &&
+ (match->key.vlan.vlan_tpid == htons(ETH_P_8021Q) ||
+@@ -76,7 +71,9 @@ static void nft_flow_rule_transfer_vlan(struct nft_offload_ctx *ctx,
+ match->dissector.offset[FLOW_DISSECTOR_KEY_CVLAN] =
+ offsetof(struct nft_flow_key, cvlan);
+ match->dissector.used_keys |= BIT(FLOW_DISSECTOR_KEY_CVLAN);
+- } else {
++ } else if (match->dissector.used_keys & BIT(FLOW_DISSECTOR_KEY_BASIC) &&
++ (match->key.basic.n_proto == htons(ETH_P_8021Q) ||
++ match->key.basic.n_proto == htons(ETH_P_8021AD))) {
+ match->key.basic.n_proto = match->key.vlan.vlan_tpid;
+ match->mask.basic.n_proto = match->mask.vlan.vlan_tpid;
+ match->key.vlan.vlan_tpid = ethertype.value;
+--
+2.30.2
+
--- /dev/null
+From 1de8270b58024bceb13a52743c57b2ef7b234131 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jun 2021 20:20:30 +0200
+Subject: netfilter: nft_exthdr: check for IPv6 packet before further
+ processing
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit cdd73cc545c0fb9b1a1f7b209f4f536e7990cff4 ]
+
+ipv6_find_hdr() does not validate that this is an IPv6 packet. Add a
+sanity check for calling ipv6_find_hdr() to make sure an IPv6 packet
+is passed for parsing.
+
+Fixes: 96518518cc41 ("netfilter: add nftables")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_exthdr.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
+index f64f0017e9a5..670dd146fb2b 100644
+--- a/net/netfilter/nft_exthdr.c
++++ b/net/netfilter/nft_exthdr.c
+@@ -42,6 +42,9 @@ static void nft_exthdr_ipv6_eval(const struct nft_expr *expr,
+ unsigned int offset = 0;
+ int err;
+
++ if (pkt->skb->protocol != htons(ETH_P_IPV6))
++ goto err;
++
+ err = ipv6_find_hdr(pkt->skb, &offset, priv->type, NULL, NULL);
+ if (priv->flags & NFT_EXTHDR_F_PRESENT) {
+ nft_reg_store8(dest, err >= 0);
+--
+2.30.2
+
--- /dev/null
+From aff14929d679b337b6cecdc1c3dd1cdecb1bab44 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jun 2021 20:20:31 +0200
+Subject: netfilter: nft_osf: check for TCP packet before further processing
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 8f518d43f89ae00b9cf5460e10b91694944ca1a8 ]
+
+The osf expression only supports for TCP packets, add a upfront sanity
+check to skip packet parsing if this is not a TCP packet.
+
+Fixes: b96af92d6eaf ("netfilter: nf_tables: implement Passive OS fingerprint module in nft_osf")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_osf.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
+index ac61f708b82d..d82677e83400 100644
+--- a/net/netfilter/nft_osf.c
++++ b/net/netfilter/nft_osf.c
+@@ -28,6 +28,11 @@ static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,
+ struct nf_osf_data data;
+ struct tcphdr _tcph;
+
++ if (pkt->tprot != IPPROTO_TCP) {
++ regs->verdict.code = NFT_BREAK;
++ return;
++ }
++
+ tcp = skb_header_pointer(skb, ip_hdrlen(skb),
+ sizeof(struct tcphdr), &_tcph);
+ if (!tcp) {
+--
+2.30.2
+
--- /dev/null
+From 763152fd29a96b21785da04f7ec29babd5c2079e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Jun 2021 19:26:56 +0200
+Subject: netfilter: nft_tproxy: restrict support to TCP and UDP transport
+ protocols
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 52f0f4e178c757b3d356087376aad8bd77271828 ]
+
+Add unfront check for TCP and UDP packets before performing further
+processing.
+
+Fixes: 4ed8eb6570a4 ("netfilter: nf_tables: Add native tproxy support")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_tproxy.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nft_tproxy.c b/net/netfilter/nft_tproxy.c
+index accef672088c..5cb4d575d47f 100644
+--- a/net/netfilter/nft_tproxy.c
++++ b/net/netfilter/nft_tproxy.c
+@@ -30,6 +30,12 @@ static void nft_tproxy_eval_v4(const struct nft_expr *expr,
+ __be16 tport = 0;
+ struct sock *sk;
+
++ if (pkt->tprot != IPPROTO_TCP &&
++ pkt->tprot != IPPROTO_UDP) {
++ regs->verdict.code = NFT_BREAK;
++ return;
++ }
++
+ hp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_hdr), &_hdr);
+ if (!hp) {
+ regs->verdict.code = NFT_BREAK;
+@@ -91,7 +97,8 @@ static void nft_tproxy_eval_v6(const struct nft_expr *expr,
+
+ memset(&taddr, 0, sizeof(taddr));
+
+- if (!pkt->tprot_set) {
++ if (pkt->tprot != IPPROTO_TCP &&
++ pkt->tprot != IPPROTO_UDP) {
+ regs->verdict.code = NFT_BREAK;
+ return;
+ }
+--
+2.30.2
+
--- /dev/null
+From d219cc2d509119142c2cb4ec4039ad5096302dc7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jun 2021 10:14:44 +0800
+Subject: netlabel: Fix memory leak in netlbl_mgmt_add_common
+
+From: Liu Shixin <liushixin2@huawei.com>
+
+[ Upstream commit b8f6b0522c298ae9267bd6584e19b942a0636910 ]
+
+Hulk Robot reported memory leak in netlbl_mgmt_add_common.
+The problem is non-freed map in case of netlbl_domhsh_add() failed.
+
+BUG: memory leak
+unreferenced object 0xffff888100ab7080 (size 96):
+ comm "syz-executor537", pid 360, jiffies 4294862456 (age 22.678s)
+ hex dump (first 32 bytes):
+ 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ fe 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ................
+ backtrace:
+ [<0000000008b40026>] netlbl_mgmt_add_common.isra.0+0xb2a/0x1b40
+ [<000000003be10950>] netlbl_mgmt_add+0x271/0x3c0
+ [<00000000c70487ed>] genl_family_rcv_msg_doit.isra.0+0x20e/0x320
+ [<000000001f2ff614>] genl_rcv_msg+0x2bf/0x4f0
+ [<0000000089045792>] netlink_rcv_skb+0x134/0x3d0
+ [<0000000020e96fdd>] genl_rcv+0x24/0x40
+ [<0000000042810c66>] netlink_unicast+0x4a0/0x6a0
+ [<000000002e1659f0>] netlink_sendmsg+0x789/0xc70
+ [<000000006e43415f>] sock_sendmsg+0x139/0x170
+ [<00000000680a73d7>] ____sys_sendmsg+0x658/0x7d0
+ [<0000000065cbb8af>] ___sys_sendmsg+0xf8/0x170
+ [<0000000019932b6c>] __sys_sendmsg+0xd3/0x190
+ [<00000000643ac172>] do_syscall_64+0x37/0x90
+ [<000000009b79d6dc>] entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+Fixes: 63c416887437 ("netlabel: Add network address selectors to the NetLabel/LSM domain mapping")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Liu Shixin <liushixin2@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlabel/netlabel_mgmt.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
+index ca52f5085989..e51ab37bbb03 100644
+--- a/net/netlabel/netlabel_mgmt.c
++++ b/net/netlabel/netlabel_mgmt.c
+@@ -76,6 +76,7 @@ static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
+ static int netlbl_mgmt_add_common(struct genl_info *info,
+ struct netlbl_audit *audit_info)
+ {
++ void *pmap = NULL;
+ int ret_val = -EINVAL;
+ struct netlbl_domaddr_map *addrmap = NULL;
+ struct cipso_v4_doi *cipsov4 = NULL;
+@@ -175,6 +176,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
+ ret_val = -ENOMEM;
+ goto add_free_addrmap;
+ }
++ pmap = map;
+ map->list.addr = addr->s_addr & mask->s_addr;
+ map->list.mask = mask->s_addr;
+ map->list.valid = 1;
+@@ -183,10 +185,8 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
+ map->def.cipso = cipsov4;
+
+ ret_val = netlbl_af4list_add(&map->list, &addrmap->list4);
+- if (ret_val != 0) {
+- kfree(map);
+- goto add_free_addrmap;
+- }
++ if (ret_val != 0)
++ goto add_free_map;
+
+ entry->family = AF_INET;
+ entry->def.type = NETLBL_NLTYPE_ADDRSELECT;
+@@ -223,6 +223,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
+ ret_val = -ENOMEM;
+ goto add_free_addrmap;
+ }
++ pmap = map;
+ map->list.addr = *addr;
+ map->list.addr.s6_addr32[0] &= mask->s6_addr32[0];
+ map->list.addr.s6_addr32[1] &= mask->s6_addr32[1];
+@@ -235,10 +236,8 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
+ map->def.calipso = calipso;
+
+ ret_val = netlbl_af6list_add(&map->list, &addrmap->list6);
+- if (ret_val != 0) {
+- kfree(map);
+- goto add_free_addrmap;
+- }
++ if (ret_val != 0)
++ goto add_free_map;
+
+ entry->family = AF_INET6;
+ entry->def.type = NETLBL_NLTYPE_ADDRSELECT;
+@@ -248,10 +247,12 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
+
+ ret_val = netlbl_domhsh_add(entry, audit_info);
+ if (ret_val != 0)
+- goto add_free_addrmap;
++ goto add_free_map;
+
+ return 0;
+
++add_free_map:
++ kfree(pmap);
+ add_free_addrmap:
+ kfree(addrmap);
+ add_doi_put_def:
+--
+2.30.2
+
--- /dev/null
+From f120f1a4123d5bc7cc447819ee68bf3da4d2a8eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jun 2021 15:02:17 +0900
+Subject: nvme-pci: fix var. type for increasing cq_head
+
+From: JK Kim <jongkang.kim2@gmail.com>
+
+[ Upstream commit a0aac973a26d1ac814b9e131e209eb39472a67ce ]
+
+nvmeq->cq_head is compared with nvmeq->q_depth and changed the value
+and cq_phase for handling the next cq db.
+
+but, nvmeq->q_depth's type is u32 and max. value is 0x10000 when
+CQP.MSQE is 0xffff and io_queue_depth is 0x10000.
+
+current temp. variable for comparing with nvmeq->q_depth is overflowed
+when previous nvmeq->cq_head is 0xffff.
+
+in this case, nvmeq->cq_phase is not updated.
+so, fix data type for temp. variable to u32.
+
+Signed-off-by: JK Kim <jongkang.kim2@gmail.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/pci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index a29b170701fc..2995e87ce776 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -1032,7 +1032,7 @@ static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx)
+
+ static inline void nvme_update_cq_head(struct nvme_queue *nvmeq)
+ {
+- u16 tmp = nvmeq->cq_head + 1;
++ u32 tmp = nvmeq->cq_head + 1;
+
+ if (tmp == nvmeq->q_depth) {
+ nvmeq->cq_head = 0;
+--
+2.30.2
+
--- /dev/null
+From 704084d64b8a1f60b45cdb9f561e9c40f64ac756 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 May 2021 11:02:34 -0500
+Subject: nvme-pci: look for StorageD3Enable on companion ACPI device instead
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit e21e0243e7b0f1c2a21d21f4d115f7b37175772a ]
+
+The documentation around the StorageD3Enable property hints that it
+should be made on the PCI device. This is where newer AMD systems set
+the property and it's required for S0i3 support.
+
+So rather than look for nodes of the root port only present on Intel
+systems, switch to the companion ACPI device for all systems.
+David Box from Intel indicated this should work on Intel as well.
+
+Link: https://lore.kernel.org/linux-nvme/YK6gmAWqaRmvpJXb@google.com/T/#m900552229fa455867ee29c33b854845fce80ba70
+Link: https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/power-management-for-storage-hardware-devices-intro
+Fixes: df4f9bc4fb9c ("nvme-pci: add support for ACPI StorageD3Enable property")
+Suggested-by: Liang Prike <Prike.Liang@amd.com>
+Acked-by: Raul E Rangel <rrangel@chromium.org>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: David E. Box <david.e.box@linux.intel.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/pci.c | 24 +-----------------------
+ 1 file changed, 1 insertion(+), 23 deletions(-)
+
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 2995e87ce776..42ad75ff1348 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -2831,10 +2831,7 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev)
+ #ifdef CONFIG_ACPI
+ static bool nvme_acpi_storage_d3(struct pci_dev *dev)
+ {
+- struct acpi_device *adev;
+- struct pci_dev *root;
+- acpi_handle handle;
+- acpi_status status;
++ struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
+ u8 val;
+
+ /*
+@@ -2842,28 +2839,9 @@ static bool nvme_acpi_storage_d3(struct pci_dev *dev)
+ * must use D3 to support deep platform power savings during
+ * suspend-to-idle.
+ */
+- root = pcie_find_root_port(dev);
+- if (!root)
+- return false;
+
+- adev = ACPI_COMPANION(&root->dev);
+ if (!adev)
+ return false;
+-
+- /*
+- * The property is defined in the PXSX device for South complex ports
+- * and in the PEGP device for North complex ports.
+- */
+- status = acpi_get_handle(adev->handle, "PXSX", &handle);
+- if (ACPI_FAILURE(status)) {
+- status = acpi_get_handle(adev->handle, "PEGP", &handle);
+- if (ACPI_FAILURE(status))
+- return false;
+- }
+-
+- if (acpi_bus_get_device(handle, &adev))
+- return false;
+-
+ if (fwnode_property_read_u8(acpi_fwnode_handle(adev), "StorageD3Enable",
+ &val))
+ return false;
+--
+2.30.2
+
--- /dev/null
+From 9a78a0324c902c1758eee3a8733ff7237b56761a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Jun 2021 15:48:16 +0300
+Subject: nvme-tcp: fix error codes in nvme_tcp_setup_ctrl()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 522af60cb2f8e3658bda1902fb7f200dcf888a5c ]
+
+These error paths currently return success but they should return
+-EOPNOTSUPP.
+
+Fixes: 73ffcefcfca0 ("nvme-tcp: check sgl supported by target")
+Fixes: 3f2304f8c6d6 ("nvme-tcp: add NVMe over TCP host driver")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/tcp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
+index 34f4b3402f7c..79a463090dd3 100644
+--- a/drivers/nvme/host/tcp.c
++++ b/drivers/nvme/host/tcp.c
+@@ -1973,11 +1973,13 @@ static int nvme_tcp_setup_ctrl(struct nvme_ctrl *ctrl, bool new)
+ return ret;
+
+ if (ctrl->icdoff) {
++ ret = -EOPNOTSUPP;
+ dev_err(ctrl->device, "icdoff is not supported!\n");
+ goto destroy_admin;
+ }
+
+ if (!(ctrl->sgls & ((1 << 0) | (1 << 1)))) {
++ ret = -EOPNOTSUPP;
+ dev_err(ctrl->device, "Mandatory sgls are not supported!\n");
+ goto destroy_admin;
+ }
+--
+2.30.2
+
--- /dev/null
+From 3a8105ebac4a2c3d4fdf54bbac165695e973e82b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 14:54:14 +0200
+Subject: nvmet-fc: do not check for invalid target port in
+ nvmet_fc_handle_fcp_rqst()
+
+From: Hannes Reinecke <hare@suse.de>
+
+[ Upstream commit 2a4a910aa4f0acc428dc8d10227c42e14ed21d10 ]
+
+When parsing a request in nvmet_fc_handle_fcp_rqst() we should not
+check for invalid target ports; if we do the command is aborted
+from the fcp layer, causing the host to assume a transport error.
+Rather we should still forward this request to the nvmet layer, which
+will then correctly fail the command with an appropriate error status.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+Reviewed-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/fc.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c
+index 19e113240fff..22b5108168a6 100644
+--- a/drivers/nvme/target/fc.c
++++ b/drivers/nvme/target/fc.c
+@@ -2510,13 +2510,6 @@ nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport,
+ u32 xfrlen = be32_to_cpu(cmdiu->data_len);
+ int ret;
+
+- /*
+- * if there is no nvmet mapping to the targetport there
+- * shouldn't be requests. just terminate them.
+- */
+- if (!tgtport->pe)
+- goto transport_error;
+-
+ /*
+ * Fused commands are currently not supported in the linux
+ * implementation.
+@@ -2544,7 +2537,8 @@ nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport,
+
+ fod->req.cmd = &fod->cmdiubuf.sqe;
+ fod->req.cqe = &fod->rspiubuf.cqe;
+- fod->req.port = tgtport->pe->port;
++ if (tgtport->pe)
++ fod->req.port = tgtport->pe->port;
+
+ /* clear any response payload */
+ memset(&fod->rspiubuf, 0, sizeof(fod->rspiubuf));
+--
+2.30.2
+
--- /dev/null
+From e2c9e4062c95ffc116a98fceded41e330de716d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 10:42:28 -0500
+Subject: objtool: Don't make .altinstructions writable
+
+From: Josh Poimboeuf <jpoimboe@redhat.com>
+
+[ Upstream commit e31694e0a7a709293319475d8001e05e31f2178c ]
+
+When objtool creates the .altinstructions section, it sets the SHF_WRITE
+flag to make the section writable -- unless the section had already been
+previously created by the kernel. The mismatch between kernel-created
+and objtool-created section flags can cause failures with external
+tooling (kpatch-build). And the section doesn't need to be writable
+anyway.
+
+Make the section flags consistent with the kernel's.
+
+Fixes: 9bc0bb50727c ("objtool/x86: Rewrite retpoline thunk calls")
+Reported-by: Joe Lawrence <joe.lawrence@redhat.com>
+Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/6c284ae89717889ea136f9f0064d914cd8329d31.1624462939.git.jpoimboe@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/objtool/arch/x86/decode.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
+index 523aa4157f80..bc821056aba9 100644
+--- a/tools/objtool/arch/x86/decode.c
++++ b/tools/objtool/arch/x86/decode.c
+@@ -684,7 +684,7 @@ static int elf_add_alternative(struct elf *elf,
+ sec = find_section_by_name(elf, ".altinstructions");
+ if (!sec) {
+ sec = elf_create_section(elf, ".altinstructions",
+- SHF_WRITE, size, 0);
++ SHF_ALLOC, size, 0);
+
+ if (!sec) {
+ WARN_ELF("elf_create_section");
+--
+2.30.2
+
--- /dev/null
+From ccb7b60fee735d8423f3a941735634d0c1f06acd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jun 2021 19:34:01 -0700
+Subject: ocfs2: fix snprintf() checking
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 54e948c60cc843b6e84dc44496edc91f51d2a28e ]
+
+The snprintf() function returns the number of bytes which would have been
+printed if the buffer was large enough. In other words it can return ">=
+remain" but this code assumes it returns "== remain".
+
+The run time impact of this bug is not very severe. The next iteration
+through the loop would trigger a WARN() when we pass a negative limit to
+snprintf(). We would then return success instead of -E2BIG.
+
+The kernel implementation of snprintf() will never return negatives so
+there is no need to check and I have deleted that dead code.
+
+Link: https://lkml.kernel.org/r/20210511135350.GV1955@kadam
+Fixes: a860f6eb4c6a ("ocfs2: sysfile interfaces for online file check")
+Fixes: 74ae4e104dfc ("ocfs2: Create stack glue sysfs files.")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Gang He <ghe@suse.com>
+Cc: Jun Piao <piaojun@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ocfs2/filecheck.c | 6 +-----
+ fs/ocfs2/stackglue.c | 8 ++------
+ 2 files changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/fs/ocfs2/filecheck.c b/fs/ocfs2/filecheck.c
+index 90b8d300c1ee..de56e6231af8 100644
+--- a/fs/ocfs2/filecheck.c
++++ b/fs/ocfs2/filecheck.c
+@@ -326,11 +326,7 @@ static ssize_t ocfs2_filecheck_attr_show(struct kobject *kobj,
+ ret = snprintf(buf + total, remain, "%lu\t\t%u\t%s\n",
+ p->fe_ino, p->fe_done,
+ ocfs2_filecheck_error(p->fe_status));
+- if (ret < 0) {
+- total = ret;
+- break;
+- }
+- if (ret == remain) {
++ if (ret >= remain) {
+ /* snprintf() didn't fit */
+ total = -E2BIG;
+ break;
+diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c
+index d50e8b8dfea4..16f1bfc407f2 100644
+--- a/fs/ocfs2/stackglue.c
++++ b/fs/ocfs2/stackglue.c
+@@ -500,11 +500,7 @@ static ssize_t ocfs2_loaded_cluster_plugins_show(struct kobject *kobj,
+ list_for_each_entry(p, &ocfs2_stack_list, sp_list) {
+ ret = snprintf(buf, remain, "%s\n",
+ p->sp_name);
+- if (ret < 0) {
+- total = ret;
+- break;
+- }
+- if (ret == remain) {
++ if (ret >= remain) {
+ /* snprintf() didn't fit */
+ total = -E2BIG;
+ break;
+@@ -531,7 +527,7 @@ static ssize_t ocfs2_active_cluster_plugin_show(struct kobject *kobj,
+ if (active_stack) {
+ ret = snprintf(buf, PAGE_SIZE, "%s\n",
+ active_stack->sp_name);
+- if (ret == PAGE_SIZE)
++ if (ret >= PAGE_SIZE)
+ ret = -E2BIG;
+ }
+ spin_unlock(&ocfs2_stack_lock);
+--
+2.30.2
+
--- /dev/null
+From f9648987cada7235f02ee9da2c6baf275a225e89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jun 2021 11:27:44 +0200
+Subject: of: Fix truncation of memory sizes on 32-bit platforms
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 2892d8a00d23d511a0591ac4b2ff3f050ae1f004 ]
+
+Variable "size" has type "phys_addr_t", which can be either 32-bit or
+64-bit on 32-bit systems, while "unsigned long" is always 32-bit on
+32-bit systems. Hence the cast in
+
+ (unsigned long)size / SZ_1M
+
+may truncate a 64-bit size to 32-bit, as casts have a higher operator
+precedence than divisions.
+
+Fix this by inverting the order of the cast and division, which should
+be safe for memory blocks smaller than 4 PiB. Note that the division is
+actually a shift, as SZ_1M is a power-of-two constant, hence there is no
+need to use div_u64().
+
+While at it, use "%lu" to format "unsigned long".
+
+Fixes: e8d9d1f5485b52ec ("drivers: of: add initialization code for static reserved memory")
+Fixes: 3f0c8206644836e4 ("drivers: of: add initialization code for dynamic reserved memory")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://lore.kernel.org/r/4a1117e72d13d26126f57be034c20dac02f1e915.1623835273.git.geert+renesas@glider.be
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/fdt.c | 8 ++++----
+ drivers/of/of_reserved_mem.c | 8 ++++----
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
+index ba17a80b8c79..cc71e0b3eed9 100644
+--- a/drivers/of/fdt.c
++++ b/drivers/of/fdt.c
+@@ -510,11 +510,11 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
+
+ if (size &&
+ early_init_dt_reserve_memory_arch(base, size, nomap) == 0)
+- pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n",
+- uname, &base, (unsigned long)size / SZ_1M);
++ pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n",
++ uname, &base, (unsigned long)(size / SZ_1M));
+ else
+- pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %ld MiB\n",
+- uname, &base, (unsigned long)size / SZ_1M);
++ pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n",
++ uname, &base, (unsigned long)(size / SZ_1M));
+
+ len -= t_len;
+ if (first) {
+diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
+index 15e2417974d6..3502ba522c39 100644
+--- a/drivers/of/of_reserved_mem.c
++++ b/drivers/of/of_reserved_mem.c
+@@ -134,9 +134,9 @@ static int __init __reserved_mem_alloc_size(unsigned long node,
+ ret = early_init_dt_alloc_reserved_memory_arch(size,
+ align, start, end, nomap, &base);
+ if (ret == 0) {
+- pr_debug("allocated memory for '%s' node: base %pa, size %ld MiB\n",
++ pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n",
+ uname, &base,
+- (unsigned long)size / SZ_1M);
++ (unsigned long)(size / SZ_1M));
+ break;
+ }
+ len -= t_len;
+@@ -146,8 +146,8 @@ static int __init __reserved_mem_alloc_size(unsigned long node,
+ ret = early_init_dt_alloc_reserved_memory_arch(size, align,
+ 0, 0, nomap, &base);
+ if (ret == 0)
+- pr_debug("allocated memory for '%s' node: base %pa, size %ld MiB\n",
+- uname, &base, (unsigned long)size / SZ_1M);
++ pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n",
++ uname, &base, (unsigned long)(size / SZ_1M));
+ }
+
+ if (base == 0) {
+--
+2.30.2
+
--- /dev/null
+From 736ce8817a719f542f945c842e008a192518b0ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 May 2021 11:24:16 +0200
+Subject: open: don't silently ignore unknown O-flags in openat2()
+
+From: Christian Brauner <christian.brauner@ubuntu.com>
+
+[ Upstream commit cfe80306a0dd6d363934913e47c3f30d71b721e5 ]
+
+The new openat2() syscall verifies that no unknown O-flag values are
+set and returns an error to userspace if they are while the older open
+syscalls like open() and openat() simply ignore unknown flag values:
+
+ #define O_FLAG_CURRENTLY_INVALID (1 << 31)
+ struct open_how how = {
+ .flags = O_RDONLY | O_FLAG_CURRENTLY_INVALID,
+ .resolve = 0,
+ };
+
+ /* fails */
+ fd = openat2(-EBADF, "/dev/null", &how, sizeof(how));
+
+ /* succeeds */
+ fd = openat(-EBADF, "/dev/null", O_RDONLY | O_FLAG_CURRENTLY_INVALID);
+
+However, openat2() silently truncates the upper 32 bits meaning:
+
+ #define O_FLAG_CURRENTLY_INVALID_LOWER32 (1 << 31)
+ #define O_FLAG_CURRENTLY_INVALID_UPPER32 (1 << 40)
+
+ struct open_how how_lowe32 = {
+ .flags = O_RDONLY | O_FLAG_CURRENTLY_INVALID_LOWER32,
+ };
+
+ struct open_how how_upper32 = {
+ .flags = O_RDONLY | O_FLAG_CURRENTLY_INVALID_UPPER32,
+ };
+
+ /* fails */
+ fd = openat2(-EBADF, "/dev/null", &how_lower32, sizeof(how_lower32));
+
+ /* succeeds */
+ fd = openat2(-EBADF, "/dev/null", &how_upper32, sizeof(how_upper32));
+
+Fix this by preventing the immediate truncation in build_open_flags().
+
+There's a snafu here though stripping FMODE_* directly from flags would
+cause the upper 32 bits to be truncated as well due to integer promotion
+rules since FMODE_* is unsigned int, O_* are signed ints (yuck).
+
+In addition, struct open_flags currently defines flags to be 32 bit
+which is reasonable. If we simply were to bump it to 64 bit we would
+need to change a lot of code preemptively which doesn't seem worth it.
+So simply add a compile-time check verifying that all currently known
+O_* flags are within the 32 bit range and fail to build if they aren't
+anymore.
+
+This change shouldn't regress old open syscalls since they silently
+truncate any unknown values anyway. It is a tiny semantic change for
+openat2() but it is very unlikely people pass ing > 32 bit unknown flags
+and the syscall is relatively new too.
+
+Link: https://lore.kernel.org/r/20210528092417.3942079-3-brauner@kernel.org
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Aleksa Sarai <cyphar@cyphar.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: linux-fsdevel@vger.kernel.org
+Reported-by: Richard Guy Briggs <rgb@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Aleksa Sarai <cyphar@cyphar.com>
+Reviewed-by: Richard Guy Briggs <rgb@redhat.com>
+Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/open.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/fs/open.c b/fs/open.c
+index e53af13b5835..53bc0573c0ec 100644
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -1002,12 +1002,20 @@ inline struct open_how build_open_how(int flags, umode_t mode)
+
+ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
+ {
+- int flags = how->flags;
++ u64 flags = how->flags;
++ u64 strip = FMODE_NONOTIFY | O_CLOEXEC;
+ int lookup_flags = 0;
+ int acc_mode = ACC_MODE(flags);
+
+- /* Must never be set by userspace */
+- flags &= ~(FMODE_NONOTIFY | O_CLOEXEC);
++ BUILD_BUG_ON_MSG(upper_32_bits(VALID_OPEN_FLAGS),
++ "struct open_flags doesn't yet handle flags > 32 bits");
++
++ /*
++ * Strip flags that either shouldn't be set by userspace like
++ * FMODE_NONOTIFY or that aren't relevant in determining struct
++ * open_flags like O_CLOEXEC.
++ */
++ flags &= ~strip;
+
+ /*
+ * Older syscalls implicitly clear all of the invalid flags or argument
+--
+2.30.2
+
--- /dev/null
+From 68e876d0b7b2225ee428902d084d1011a7df40fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Mar 2021 23:32:38 +0300
+Subject: pata_ep93xx: fix deferred probing
+
+From: Sergey Shtylyov <s.shtylyov@omprussia.ru>
+
+[ Upstream commit 5c8121262484d99bffb598f39a0df445cecd8efb ]
+
+The driver overrides the error codes returned by platform_get_irq() to
+-ENXIO, so if it returns -EPROBE_DEFER, the driver would fail the probe
+permanently instead of the deferred probing. Propagate the error code
+upstream, as it should have been done from the start...
+
+Fixes: 2fff27512600 ("PATA host controller driver for ep93xx")
+Signed-off-by: Sergey Shtylyov <s.shtylyov@omprussia.ru>
+Link: https://lore.kernel.org/r/509fda88-2e0d-2cc7-f411-695d7e94b136@omprussia.ru
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/pata_ep93xx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c
+index badab6708893..46208ececbb6 100644
+--- a/drivers/ata/pata_ep93xx.c
++++ b/drivers/ata/pata_ep93xx.c
+@@ -928,7 +928,7 @@ static int ep93xx_pata_probe(struct platform_device *pdev)
+ /* INT[3] (IRQ_EP93XX_EXT3) line connected as pull down */
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+- err = -ENXIO;
++ err = irq;
+ goto err_rel_gpio;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 85fae657d7099b197658d808924512f3e24d12db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 May 2021 23:38:54 +0300
+Subject: pata_octeon_cf: avoid WARN_ON() in ata_host_activate()
+
+From: Sergey Shtylyov <s.shtylyov@omp.ru>
+
+[ Upstream commit bfc1f378c8953e68ccdbfe0a8c20748427488b80 ]
+
+Iff platform_get_irq() fails (or returns IRQ0) and thus the polling mode
+has to be used, ata_host_activate() hits the WARN_ON() due to 'irq_handler'
+parameter being non-NULL if the polling mode is selected. Let's only set
+the pointer to the driver's IRQ handler if platform_get_irq() returns a
+valid IRQ # -- this should avoid the unnecessary WARN_ON()...
+
+Fixes: 43f01da0f279 ("MIPS/OCTEON/ata: Convert pata_octeon_cf.c to use device tree.")
+Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Link: https://lore.kernel.org/r/3a241167-f84d-1d25-5b9b-be910afbe666@omp.ru
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/pata_octeon_cf.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c
+index bd87476ab481..b5a3f710d76d 100644
+--- a/drivers/ata/pata_octeon_cf.c
++++ b/drivers/ata/pata_octeon_cf.c
+@@ -898,10 +898,11 @@ static int octeon_cf_probe(struct platform_device *pdev)
+ return -EINVAL;
+ }
+
+- irq_handler = octeon_cf_interrupt;
+ i = platform_get_irq(dma_dev, 0);
+- if (i > 0)
++ if (i > 0) {
+ irq = i;
++ irq_handler = octeon_cf_interrupt;
++ }
+ }
+ of_node_put(dma_node);
+ }
+--
+2.30.2
+
--- /dev/null
+From 69c2eabdee601e7bec9d57b1706947d674c60d47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Mar 2021 14:46:53 +0300
+Subject: pata_rb532_cf: fix deferred probing
+
+From: Sergey Shtylyov <s.shtylyov@omprussia.ru>
+
+[ Upstream commit 2d3a62fbae8e5badc2342388f65ab2191c209cc0 ]
+
+The driver overrides the error codes returned by platform_get_irq() to
+-ENOENT, so if it returns -EPROBE_DEFER, the driver would fail the probe
+permanently instead of the deferred probing. Switch to propagating the
+error code upstream, still checking/overriding IRQ0 as libata regards it
+as "no IRQ" (thus polling) anyway...
+
+Fixes: 9ec36cafe43b ("of/irq: do irq resolution in platform_get_irq")
+Signed-off-by: Sergey Shtylyov <s.shtylyov@omprussia.ru>
+Link: https://lore.kernel.org/r/771ced55-3efb-21f5-f21c-b99920aae611@omprussia.ru
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/pata_rb532_cf.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c
+index 479c4b29b856..303f8c375b3a 100644
+--- a/drivers/ata/pata_rb532_cf.c
++++ b/drivers/ata/pata_rb532_cf.c
+@@ -115,10 +115,12 @@ static int rb532_pata_driver_probe(struct platform_device *pdev)
+ }
+
+ irq = platform_get_irq(pdev, 0);
+- if (irq <= 0) {
++ if (irq < 0) {
+ dev_err(&pdev->dev, "no IRQ resource found\n");
+- return -ENOENT;
++ return irq;
+ }
++ if (!irq)
++ return -EINVAL;
+
+ gpiod = devm_gpiod_get(&pdev->dev, NULL, GPIOD_IN);
+ if (IS_ERR(gpiod)) {
+--
+2.30.2
+
--- /dev/null
+From eca4e2a694cbafb56ef9b870ed86ebb6acd0fa62 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 16:17:33 -0700
+Subject: PCI: hv: Add check for hyperv_initialized in init_hv_pci_drv()
+
+From: Haiyang Zhang <haiyangz@microsoft.com>
+
+[ Upstream commit 7d815f4afa87f2032b650ae1bba7534b550a6b8b ]
+
+Add check for hv_is_hyperv_initialized() at the top of
+init_hv_pci_drv(), so if the pci-hyperv driver is force-loaded on non
+Hyper-V platforms, the init_hv_pci_drv() will exit immediately, without
+any side effects, like assignments to hvpci_block_ops, etc.
+
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Reported-and-tested-by: Mohammad Alqayeem <mohammad.alqyeem@nutanix.com>
+Reviewed-by: Wei Liu <wei.liu@kernel.org>
+Link: https://lore.kernel.org/r/1621984653-1210-1-git-send-email-haiyangz@microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pci-hyperv.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
+index 6511648271b2..bebe3eeebc4e 100644
+--- a/drivers/pci/controller/pci-hyperv.c
++++ b/drivers/pci/controller/pci-hyperv.c
+@@ -3476,6 +3476,9 @@ static void __exit exit_hv_pci_drv(void)
+
+ static int __init init_hv_pci_drv(void)
+ {
++ if (!hv_is_hyperv_initialized())
++ return -ENODEV;
++
+ /* Set the invalid domain number's bit, so it will not be used */
+ set_bit(HVPCI_DOM_INVALID, hvpci_dom_map);
+
+--
+2.30.2
+
--- /dev/null
+From f1508e067aca083a2ee05565cd8f6cfcb280aaa1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jun 2021 09:08:49 -0700
+Subject: perf/arm-cmn: Fix invalid pointer when access dtc object sharing the
+ same IRQ number
+
+From: Tuan Phan <tuanphan@os.amperecomputing.com>
+
+[ Upstream commit 4e16f283edc289820e9b2d6f617ed8e514ee8396 ]
+
+When multiple dtcs share the same IRQ number, the irq_friend which
+used to refer to dtc object gets calculated incorrect which leads
+to invalid pointer.
+
+Fixes: 0ba64770a2f2 ("perf: Add Arm CMN-600 PMU driver")
+
+Signed-off-by: Tuan Phan <tuanphan@os.amperecomputing.com>
+Reviewed-by: Robin Murphy <robin.murphy@arm.com>
+Link: https://lore.kernel.org/r/1623946129-3290-1-git-send-email-tuanphan@os.amperecomputing.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/arm-cmn.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
+index 56a5c355701d..49016f2f505e 100644
+--- a/drivers/perf/arm-cmn.c
++++ b/drivers/perf/arm-cmn.c
+@@ -1212,7 +1212,7 @@ static int arm_cmn_init_irqs(struct arm_cmn *cmn)
+ irq = cmn->dtc[i].irq;
+ for (j = i; j--; ) {
+ if (cmn->dtc[j].irq == irq) {
+- cmn->dtc[j].irq_friend = j - i;
++ cmn->dtc[j].irq_friend = i - j;
+ goto next;
+ }
+ }
+--
+2.30.2
+
--- /dev/null
+From c78ea0f734c7f6afa1ff58104117783fd2023b0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 16:21:01 +0200
+Subject: perf: Fix task context PMU for Hetero
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit 012669c740e6e2afa8bdb95394d06676f933dd2d ]
+
+On HETEROGENEOUS hardware (ARM big.Little, Intel Alderlake etc.) each
+CPU might have a different hardware PMU. Since each such PMU is
+represented by a different struct pmu, but we only have a single HW
+task context.
+
+That means that the task context needs to switch PMU type when it
+switches CPUs.
+
+Not doing this means that ctx->pmu calls (pmu_{dis,en}able(),
+{start,commit,cancel}_txn() etc.) are called against the wrong PMU and
+things will go wobbly.
+
+Fixes: f83d2f91d259 ("perf/x86/intel: Add Alder Lake Hybrid support")
+Reported-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: Kan Liang <kan.liang@linux.intel.com>
+Link: https://lkml.kernel.org/r/YMsy7BuGT8nBTspT@hirez.programming.kicks-ass.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/events/core.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index fe88d6eea3c2..9ebac2a79467 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -3821,9 +3821,16 @@ static void perf_event_context_sched_in(struct perf_event_context *ctx,
+ struct task_struct *task)
+ {
+ struct perf_cpu_context *cpuctx;
+- struct pmu *pmu = ctx->pmu;
++ struct pmu *pmu;
+
+ cpuctx = __get_cpu_context(ctx);
++
++ /*
++ * HACK: for HETEROGENEOUS the task context might have switched to a
++ * different PMU, force (re)set the context,
++ */
++ pmu = ctx->pmu = cpuctx->ctx.pmu;
++
+ if (cpuctx->task_ctx == ctx) {
+ if (cpuctx->sched_cb_usage)
+ __perf_pmu_sched_task(cpuctx, true);
+--
+2.30.2
+
--- /dev/null
+From cc9cc7f9b7b813e974e3c73ba1f1890fbc4eae3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Jul 2021 14:20:58 -0300
+Subject: perf llvm: Return -ENOMEM when asprintf() fails
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit c435c166dcf526ac827bc964d82cc0d5e7a1fd0b ]
+
+Zhihao sent a patch but it made llvm__compile_bpf() return what
+asprintf() returns on error, which is just -1, but since this function
+returns -errno, fix it by returning -ENOMEM for this case instead.
+
+Fixes: cb76371441d098 ("perf llvm: Allow passing options to llc ...")
+Fixes: 5eab5a7ee032ac ("perf llvm: Display eBPF compiling command ...")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Reported-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Andrii Nakryiko <andrii@kernel.org>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nick Desaulniers <ndesaulniers@google.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Yu Kuai <yukuai3@huawei.com>
+Cc: clang-built-linux@googlegroups.com
+Link: http://lore.kernel.org/lkml/20210609115945.2193194-1-chengzhihao1@huawei.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/llvm-utils.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
+index 3ceaf7ef3301..cbd9b268f168 100644
+--- a/tools/perf/util/llvm-utils.c
++++ b/tools/perf/util/llvm-utils.c
+@@ -504,6 +504,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
+ goto errout;
+ }
+
++ err = -ENOMEM;
+ if (asprintf(&pipe_template, "%s -emit-llvm | %s -march=bpf %s -filetype=obj -o -",
+ template, llc_path, opts) < 0) {
+ pr_err("ERROR:\tnot enough memory to setup command line\n");
+@@ -524,6 +525,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
+
+ pr_debug("llvm compiling command template: %s\n", template);
+
++ err = -ENOMEM;
+ if (asprintf(&command_echo, "echo -n \"%s\"", template) < 0)
+ goto errout;
+
+--
+2.30.2
+
--- /dev/null
+From 58c0541de4af3b6121fac1b6014cc033cb4c2b1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 12:51:03 +0300
+Subject: perf scripting python: Fix tuple_set_u64()
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit d04c1ff0b3ddd5c0fbbe640996c8eaad279ed1c5 ]
+
+tuple_set_u64() produces a signed value instead of an unsigned value.
+That works for database export but not other cases. Rename to
+tuple_set_d64() for database export and fix tuple_set_u64().
+
+Fixes: df919b400ad3f ("perf scripting python: Extend interface to export data in a database-friendly way")
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Link: https://lore.kernel.org/r/20210525095112.1399-2-adrian.hunter@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../scripting-engines/trace-event-python.c | 146 ++++++++++--------
+ 1 file changed, 81 insertions(+), 65 deletions(-)
+
+diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
+index 4e4aa4c97ac5..3dfc543327af 100644
+--- a/tools/perf/util/scripting-engines/trace-event-python.c
++++ b/tools/perf/util/scripting-engines/trace-event-python.c
+@@ -934,7 +934,7 @@ static PyObject *tuple_new(unsigned int sz)
+ return t;
+ }
+
+-static int tuple_set_u64(PyObject *t, unsigned int pos, u64 val)
++static int tuple_set_s64(PyObject *t, unsigned int pos, s64 val)
+ {
+ #if BITS_PER_LONG == 64
+ return PyTuple_SetItem(t, pos, _PyLong_FromLong(val));
+@@ -944,6 +944,22 @@ static int tuple_set_u64(PyObject *t, unsigned int pos, u64 val)
+ #endif
+ }
+
++/*
++ * Databases support only signed 64-bit numbers, so even though we are
++ * exporting a u64, it must be as s64.
++ */
++#define tuple_set_d64 tuple_set_s64
++
++static int tuple_set_u64(PyObject *t, unsigned int pos, u64 val)
++{
++#if BITS_PER_LONG == 64
++ return PyTuple_SetItem(t, pos, PyLong_FromUnsignedLong(val));
++#endif
++#if BITS_PER_LONG == 32
++ return PyTuple_SetItem(t, pos, PyLong_FromUnsignedLongLong(val));
++#endif
++}
++
+ static int tuple_set_s32(PyObject *t, unsigned int pos, s32 val)
+ {
+ return PyTuple_SetItem(t, pos, _PyLong_FromLong(val));
+@@ -967,7 +983,7 @@ static int python_export_evsel(struct db_export *dbe, struct evsel *evsel)
+
+ t = tuple_new(2);
+
+- tuple_set_u64(t, 0, evsel->db_id);
++ tuple_set_d64(t, 0, evsel->db_id);
+ tuple_set_string(t, 1, evsel__name(evsel));
+
+ call_object(tables->evsel_handler, t, "evsel_table");
+@@ -985,7 +1001,7 @@ static int python_export_machine(struct db_export *dbe,
+
+ t = tuple_new(3);
+
+- tuple_set_u64(t, 0, machine->db_id);
++ tuple_set_d64(t, 0, machine->db_id);
+ tuple_set_s32(t, 1, machine->pid);
+ tuple_set_string(t, 2, machine->root_dir ? machine->root_dir : "");
+
+@@ -1004,9 +1020,9 @@ static int python_export_thread(struct db_export *dbe, struct thread *thread,
+
+ t = tuple_new(5);
+
+- tuple_set_u64(t, 0, thread->db_id);
+- tuple_set_u64(t, 1, machine->db_id);
+- tuple_set_u64(t, 2, main_thread_db_id);
++ tuple_set_d64(t, 0, thread->db_id);
++ tuple_set_d64(t, 1, machine->db_id);
++ tuple_set_d64(t, 2, main_thread_db_id);
+ tuple_set_s32(t, 3, thread->pid_);
+ tuple_set_s32(t, 4, thread->tid);
+
+@@ -1025,10 +1041,10 @@ static int python_export_comm(struct db_export *dbe, struct comm *comm,
+
+ t = tuple_new(5);
+
+- tuple_set_u64(t, 0, comm->db_id);
++ tuple_set_d64(t, 0, comm->db_id);
+ tuple_set_string(t, 1, comm__str(comm));
+- tuple_set_u64(t, 2, thread->db_id);
+- tuple_set_u64(t, 3, comm->start);
++ tuple_set_d64(t, 2, thread->db_id);
++ tuple_set_d64(t, 3, comm->start);
+ tuple_set_s32(t, 4, comm->exec);
+
+ call_object(tables->comm_handler, t, "comm_table");
+@@ -1046,9 +1062,9 @@ static int python_export_comm_thread(struct db_export *dbe, u64 db_id,
+
+ t = tuple_new(3);
+
+- tuple_set_u64(t, 0, db_id);
+- tuple_set_u64(t, 1, comm->db_id);
+- tuple_set_u64(t, 2, thread->db_id);
++ tuple_set_d64(t, 0, db_id);
++ tuple_set_d64(t, 1, comm->db_id);
++ tuple_set_d64(t, 2, thread->db_id);
+
+ call_object(tables->comm_thread_handler, t, "comm_thread_table");
+
+@@ -1068,8 +1084,8 @@ static int python_export_dso(struct db_export *dbe, struct dso *dso,
+
+ t = tuple_new(5);
+
+- tuple_set_u64(t, 0, dso->db_id);
+- tuple_set_u64(t, 1, machine->db_id);
++ tuple_set_d64(t, 0, dso->db_id);
++ tuple_set_d64(t, 1, machine->db_id);
+ tuple_set_string(t, 2, dso->short_name);
+ tuple_set_string(t, 3, dso->long_name);
+ tuple_set_string(t, 4, sbuild_id);
+@@ -1090,10 +1106,10 @@ static int python_export_symbol(struct db_export *dbe, struct symbol *sym,
+
+ t = tuple_new(6);
+
+- tuple_set_u64(t, 0, *sym_db_id);
+- tuple_set_u64(t, 1, dso->db_id);
+- tuple_set_u64(t, 2, sym->start);
+- tuple_set_u64(t, 3, sym->end);
++ tuple_set_d64(t, 0, *sym_db_id);
++ tuple_set_d64(t, 1, dso->db_id);
++ tuple_set_d64(t, 2, sym->start);
++ tuple_set_d64(t, 3, sym->end);
+ tuple_set_s32(t, 4, sym->binding);
+ tuple_set_string(t, 5, sym->name);
+
+@@ -1130,30 +1146,30 @@ static void python_export_sample_table(struct db_export *dbe,
+
+ t = tuple_new(24);
+
+- tuple_set_u64(t, 0, es->db_id);
+- tuple_set_u64(t, 1, es->evsel->db_id);
+- tuple_set_u64(t, 2, es->al->maps->machine->db_id);
+- tuple_set_u64(t, 3, es->al->thread->db_id);
+- tuple_set_u64(t, 4, es->comm_db_id);
+- tuple_set_u64(t, 5, es->dso_db_id);
+- tuple_set_u64(t, 6, es->sym_db_id);
+- tuple_set_u64(t, 7, es->offset);
+- tuple_set_u64(t, 8, es->sample->ip);
+- tuple_set_u64(t, 9, es->sample->time);
++ tuple_set_d64(t, 0, es->db_id);
++ tuple_set_d64(t, 1, es->evsel->db_id);
++ tuple_set_d64(t, 2, es->al->maps->machine->db_id);
++ tuple_set_d64(t, 3, es->al->thread->db_id);
++ tuple_set_d64(t, 4, es->comm_db_id);
++ tuple_set_d64(t, 5, es->dso_db_id);
++ tuple_set_d64(t, 6, es->sym_db_id);
++ tuple_set_d64(t, 7, es->offset);
++ tuple_set_d64(t, 8, es->sample->ip);
++ tuple_set_d64(t, 9, es->sample->time);
+ tuple_set_s32(t, 10, es->sample->cpu);
+- tuple_set_u64(t, 11, es->addr_dso_db_id);
+- tuple_set_u64(t, 12, es->addr_sym_db_id);
+- tuple_set_u64(t, 13, es->addr_offset);
+- tuple_set_u64(t, 14, es->sample->addr);
+- tuple_set_u64(t, 15, es->sample->period);
+- tuple_set_u64(t, 16, es->sample->weight);
+- tuple_set_u64(t, 17, es->sample->transaction);
+- tuple_set_u64(t, 18, es->sample->data_src);
++ tuple_set_d64(t, 11, es->addr_dso_db_id);
++ tuple_set_d64(t, 12, es->addr_sym_db_id);
++ tuple_set_d64(t, 13, es->addr_offset);
++ tuple_set_d64(t, 14, es->sample->addr);
++ tuple_set_d64(t, 15, es->sample->period);
++ tuple_set_d64(t, 16, es->sample->weight);
++ tuple_set_d64(t, 17, es->sample->transaction);
++ tuple_set_d64(t, 18, es->sample->data_src);
+ tuple_set_s32(t, 19, es->sample->flags & PERF_BRANCH_MASK);
+ tuple_set_s32(t, 20, !!(es->sample->flags & PERF_IP_FLAG_IN_TX));
+- tuple_set_u64(t, 21, es->call_path_id);
+- tuple_set_u64(t, 22, es->sample->insn_cnt);
+- tuple_set_u64(t, 23, es->sample->cyc_cnt);
++ tuple_set_d64(t, 21, es->call_path_id);
++ tuple_set_d64(t, 22, es->sample->insn_cnt);
++ tuple_set_d64(t, 23, es->sample->cyc_cnt);
+
+ call_object(tables->sample_handler, t, "sample_table");
+
+@@ -1167,8 +1183,8 @@ static void python_export_synth(struct db_export *dbe, struct export_sample *es)
+
+ t = tuple_new(3);
+
+- tuple_set_u64(t, 0, es->db_id);
+- tuple_set_u64(t, 1, es->evsel->core.attr.config);
++ tuple_set_d64(t, 0, es->db_id);
++ tuple_set_d64(t, 1, es->evsel->core.attr.config);
+ tuple_set_bytes(t, 2, es->sample->raw_data, es->sample->raw_size);
+
+ call_object(tables->synth_handler, t, "synth_data");
+@@ -1200,10 +1216,10 @@ static int python_export_call_path(struct db_export *dbe, struct call_path *cp)
+
+ t = tuple_new(4);
+
+- tuple_set_u64(t, 0, cp->db_id);
+- tuple_set_u64(t, 1, parent_db_id);
+- tuple_set_u64(t, 2, sym_db_id);
+- tuple_set_u64(t, 3, cp->ip);
++ tuple_set_d64(t, 0, cp->db_id);
++ tuple_set_d64(t, 1, parent_db_id);
++ tuple_set_d64(t, 2, sym_db_id);
++ tuple_set_d64(t, 3, cp->ip);
+
+ call_object(tables->call_path_handler, t, "call_path_table");
+
+@@ -1221,20 +1237,20 @@ static int python_export_call_return(struct db_export *dbe,
+
+ t = tuple_new(14);
+
+- tuple_set_u64(t, 0, cr->db_id);
+- tuple_set_u64(t, 1, cr->thread->db_id);
+- tuple_set_u64(t, 2, comm_db_id);
+- tuple_set_u64(t, 3, cr->cp->db_id);
+- tuple_set_u64(t, 4, cr->call_time);
+- tuple_set_u64(t, 5, cr->return_time);
+- tuple_set_u64(t, 6, cr->branch_count);
+- tuple_set_u64(t, 7, cr->call_ref);
+- tuple_set_u64(t, 8, cr->return_ref);
+- tuple_set_u64(t, 9, cr->cp->parent->db_id);
++ tuple_set_d64(t, 0, cr->db_id);
++ tuple_set_d64(t, 1, cr->thread->db_id);
++ tuple_set_d64(t, 2, comm_db_id);
++ tuple_set_d64(t, 3, cr->cp->db_id);
++ tuple_set_d64(t, 4, cr->call_time);
++ tuple_set_d64(t, 5, cr->return_time);
++ tuple_set_d64(t, 6, cr->branch_count);
++ tuple_set_d64(t, 7, cr->call_ref);
++ tuple_set_d64(t, 8, cr->return_ref);
++ tuple_set_d64(t, 9, cr->cp->parent->db_id);
+ tuple_set_s32(t, 10, cr->flags);
+- tuple_set_u64(t, 11, cr->parent_db_id);
+- tuple_set_u64(t, 12, cr->insn_count);
+- tuple_set_u64(t, 13, cr->cyc_count);
++ tuple_set_d64(t, 11, cr->parent_db_id);
++ tuple_set_d64(t, 12, cr->insn_count);
++ tuple_set_d64(t, 13, cr->cyc_count);
+
+ call_object(tables->call_return_handler, t, "call_return_table");
+
+@@ -1254,14 +1270,14 @@ static int python_export_context_switch(struct db_export *dbe, u64 db_id,
+
+ t = tuple_new(9);
+
+- tuple_set_u64(t, 0, db_id);
+- tuple_set_u64(t, 1, machine->db_id);
+- tuple_set_u64(t, 2, sample->time);
++ tuple_set_d64(t, 0, db_id);
++ tuple_set_d64(t, 1, machine->db_id);
++ tuple_set_d64(t, 2, sample->time);
+ tuple_set_s32(t, 3, sample->cpu);
+- tuple_set_u64(t, 4, th_out_id);
+- tuple_set_u64(t, 5, comm_out_id);
+- tuple_set_u64(t, 6, th_in_id);
+- tuple_set_u64(t, 7, comm_in_id);
++ tuple_set_d64(t, 4, th_out_id);
++ tuple_set_d64(t, 5, comm_out_id);
++ tuple_set_d64(t, 6, th_in_id);
++ tuple_set_d64(t, 7, comm_in_id);
+ tuple_set_s32(t, 8, flags);
+
+ call_object(tables->context_switch_handler, t, "context_switch");
+--
+2.30.2
+
--- /dev/null
+From 031ee620ffb7492acf660026320fcda90bbcc4e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 10:59:42 -0700
+Subject: perf/x86: Reset the dirty counter to prevent the leak for an RDPMC
+ task
+
+From: Kan Liang <kan.liang@linux.intel.com>
+
+[ Upstream commit 5471eea5d3bf850316f1064a6f57b34c444bce67 ]
+
+The counter value of a perf task may leak to another RDPMC task.
+For example, a perf stat task as below is running on CPU 0.
+
+ perf stat -e 'branches,cycles' -- taskset -c 0 ./workload
+
+In the meantime, an RDPMC task, which is also running on CPU 0, may read
+the GP counters periodically. (The RDPMC task creates a fixed event,
+but read four GP counters.)
+
+ $./rdpmc_read_all_counters
+ index 0x0 value 0x8001e5970f99
+ index 0x1 value 0x8005d750edb6
+ index 0x2 value 0x0
+ index 0x3 value 0x0
+
+ index 0x0 value 0x8002358e48a5
+ index 0x1 value 0x8006bd1e3bc9
+ index 0x2 value 0x0
+ index 0x3 value 0x0
+
+It is a potential security issue. Once the attacker knows what the other
+thread is counting. The PerfMon counter can be used as a side-channel to
+attack cryptosystems.
+
+The counter value of the perf stat task leaks to the RDPMC task because
+perf never clears the counter when it's stopped.
+
+Three methods were considered to address the issue.
+
+ - Unconditionally reset the counter in x86_pmu_del(). It can bring extra
+ overhead even when there is no RDPMC task running.
+
+ - Only reset the un-assigned dirty counters when the RDPMC task is
+ scheduled in via sched_task(). It fails for the below case.
+
+ Thread A Thread B
+
+ clone(CLONE_THREAD) --->
+ set_affine(0)
+ set_affine(1)
+ while (!event-enabled)
+ ;
+ event = perf_event_open()
+ mmap(event)
+ ioctl(event, IOC_ENABLE); --->
+ RDPMC
+
+ Counters are still leaked to the thread B.
+
+ - Only reset the un-assigned dirty counters before updating the CR4.PCE
+ bit. The method is implemented here.
+
+The dirty counter is a counter, on which the assigned event has been
+deleted, but the counter is not reset. To track the dirty counters,
+add a 'dirty' variable in the struct cpu_hw_events.
+
+The security issue can only be found with an RDPMC task. To enable the
+RDMPC, the CR4.PCE bit has to be updated. Add a
+perf_clear_dirty_counters() right before updating the CR4.PCE bit to
+clear the existing dirty counters. Only the current un-assigned dirty
+counters are reset, because the RDPMC assigned dirty counters will be
+updated soon.
+
+After applying the patch,
+
+ $ ./rdpmc_read_all_counters
+ index 0x0 value 0x0
+ index 0x1 value 0x0
+ index 0x2 value 0x0
+ index 0x3 value 0x0
+
+ index 0x0 value 0x0
+ index 0x1 value 0x0
+ index 0x2 value 0x0
+ index 0x3 value 0x0
+
+Performance
+
+The performance of a context switch only be impacted when there are two
+or more perf users and one of the users must be an RDPMC user. In other
+cases, there is no performance impact.
+
+The worst-case occurs when there are two users: the RDPMC user only
+uses one counter; while the other user uses all available counters.
+When the RDPMC task is scheduled in, all the counters, other than the
+RDPMC assigned one, have to be reset.
+
+Test results for the worst-case, using a modified lat_ctx as measured
+on an Ice Lake platform, which has 8 GP and 3 FP counters (ignoring
+SLOTS).
+
+ lat_ctx -s 128K -N 1000 processes 2
+
+Without the patch:
+ The context switch time is 4.97 us
+
+With the patch:
+ The context switch time is 5.16 us
+
+There is ~4% performance drop for the context switching time in the
+worst-case.
+
+Suggested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/1623693582-187370-1-git-send-email-kan.liang@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/core.c | 28 +++++++++++++++++++++++++++-
+ arch/x86/events/perf_event.h | 1 +
+ arch/x86/include/asm/perf_event.h | 1 +
+ arch/x86/mm/tlb.c | 10 ++++++++--
+ 4 files changed, 37 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
+index 8f71dd72ef95..1eb45139fcc6 100644
+--- a/arch/x86/events/core.c
++++ b/arch/x86/events/core.c
+@@ -1626,6 +1626,8 @@ static void x86_pmu_del(struct perf_event *event, int flags)
+ if (cpuc->txn_flags & PERF_PMU_TXN_ADD)
+ goto do_del;
+
++ __set_bit(event->hw.idx, cpuc->dirty);
++
+ /*
+ * Not a TXN, therefore cleanup properly.
+ */
+@@ -2474,6 +2476,31 @@ static int x86_pmu_event_init(struct perf_event *event)
+ return err;
+ }
+
++void perf_clear_dirty_counters(void)
++{
++ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
++ int i;
++
++ /* Don't need to clear the assigned counter. */
++ for (i = 0; i < cpuc->n_events; i++)
++ __clear_bit(cpuc->assign[i], cpuc->dirty);
++
++ if (bitmap_empty(cpuc->dirty, X86_PMC_IDX_MAX))
++ return;
++
++ for_each_set_bit(i, cpuc->dirty, X86_PMC_IDX_MAX) {
++ /* Metrics and fake events don't have corresponding HW counters. */
++ if (is_metric_idx(i) || (i == INTEL_PMC_IDX_FIXED_VLBR))
++ continue;
++ else if (i >= INTEL_PMC_IDX_FIXED)
++ wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + (i - INTEL_PMC_IDX_FIXED), 0);
++ else
++ wrmsrl(x86_pmu_event_addr(i), 0);
++ }
++
++ bitmap_zero(cpuc->dirty, X86_PMC_IDX_MAX);
++}
++
+ static void x86_pmu_event_mapped(struct perf_event *event, struct mm_struct *mm)
+ {
+ if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
+@@ -2497,7 +2524,6 @@ static void x86_pmu_event_mapped(struct perf_event *event, struct mm_struct *mm)
+
+ static void x86_pmu_event_unmapped(struct perf_event *event, struct mm_struct *mm)
+ {
+-
+ if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
+ return;
+
+diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
+index ad87cb36f7c8..2bf1c7ea2758 100644
+--- a/arch/x86/events/perf_event.h
++++ b/arch/x86/events/perf_event.h
+@@ -229,6 +229,7 @@ struct cpu_hw_events {
+ */
+ struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */
+ unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
++ unsigned long dirty[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+ int enabled;
+
+ int n_events; /* the # of events in the below arrays */
+diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
+index 544f41a179fb..8fc1b5003713 100644
+--- a/arch/x86/include/asm/perf_event.h
++++ b/arch/x86/include/asm/perf_event.h
+@@ -478,6 +478,7 @@ struct x86_pmu_lbr {
+
+ extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap);
+ extern void perf_check_microcode(void);
++extern void perf_clear_dirty_counters(void);
+ extern int x86_perf_rdpmc_index(struct perf_event *event);
+ #else
+ static inline void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap)
+diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
+index 78804680e923..cfe6b1e85fa6 100644
+--- a/arch/x86/mm/tlb.c
++++ b/arch/x86/mm/tlb.c
+@@ -14,6 +14,7 @@
+ #include <asm/nospec-branch.h>
+ #include <asm/cache.h>
+ #include <asm/apic.h>
++#include <asm/perf_event.h>
+
+ #include "mm_internal.h"
+
+@@ -404,9 +405,14 @@ static inline void cr4_update_pce_mm(struct mm_struct *mm)
+ {
+ if (static_branch_unlikely(&rdpmc_always_available_key) ||
+ (!static_branch_unlikely(&rdpmc_never_available_key) &&
+- atomic_read(&mm->context.perf_rdpmc_allowed)))
++ atomic_read(&mm->context.perf_rdpmc_allowed))) {
++ /*
++ * Clear the existing dirty counters to
++ * prevent the leak for an RDPMC task.
++ */
++ perf_clear_dirty_counters();
+ cr4_set_bits_irqsoff(X86_CR4_PCE);
+- else
++ } else
+ cr4_clear_bits_irqsoff(X86_CR4_PCE);
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 7bf40821a63e9ea5ca85b66a32a48a6df704cee5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 May 2021 09:09:30 +0200
+Subject: phy: ralink: phy-mt7621-pci: properly print pointer address
+
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+
+[ Upstream commit 652a6a2e3824ce2ebf79a2d5326940d05c4db036 ]
+
+The way of printing the pointer address for the 'port_base'
+address got into compile warnings on some architectures
+[-Wpointer-to-int-cast]. Instead of use '%08x' and cast
+to an 'unsigned int' just make use of '%px' and avoid the
+cast. To avoid not really needed driver verbosity on normal
+behaviour change also from 'dev_info' to 'dev_dbg'.
+
+Fixes: d87da32372a0 ("phy: ralink: Add PHY driver for MT7621 PCIe PHY")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20210508070930.5290-7-sergio.paracuellos@gmail.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/ralink/phy-mt7621-pci.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/phy/ralink/phy-mt7621-pci.c b/drivers/phy/ralink/phy-mt7621-pci.c
+index 2a9465f4bb3a..3b1245fc5a02 100644
+--- a/drivers/phy/ralink/phy-mt7621-pci.c
++++ b/drivers/phy/ralink/phy-mt7621-pci.c
+@@ -272,8 +272,8 @@ static struct phy *mt7621_pcie_phy_of_xlate(struct device *dev,
+
+ mt7621_phy->has_dual_port = args->args[0];
+
+- dev_info(dev, "PHY for 0x%08x (dual port = %d)\n",
+- (unsigned int)mt7621_phy->port_base, mt7621_phy->has_dual_port);
++ dev_dbg(dev, "PHY for 0x%px (dual port = %d)\n",
++ mt7621_phy->port_base, mt7621_phy->has_dual_port);
+
+ return mt7621_phy->phy;
+ }
+--
+2.30.2
+
--- /dev/null
+From cf2d6f15961f9fde8a56378393e9a48e099c9454 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Jun 2021 15:17:43 +0200
+Subject: phy: ti: dm816x: Fix the error handling path in
+ 'dm816x_usb_phy_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit f7eedcb8539ddcbb6fe7791f1b4ccf43f905c72f ]
+
+Add an error handling path in the probe to release some resources, as
+already done in the remove function.
+
+Fixes: 609adde838f4 ("phy: Add a driver for dm816x USB PHY")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/ac5136881f6bdec50be19b3bf73b3bc1b15ef1f1.1622898974.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/ti/phy-dm816x-usb.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/phy/ti/phy-dm816x-usb.c b/drivers/phy/ti/phy-dm816x-usb.c
+index 57adc08a89b2..9fe6ea6fdae5 100644
+--- a/drivers/phy/ti/phy-dm816x-usb.c
++++ b/drivers/phy/ti/phy-dm816x-usb.c
+@@ -242,19 +242,28 @@ static int dm816x_usb_phy_probe(struct platform_device *pdev)
+
+ pm_runtime_enable(phy->dev);
+ generic_phy = devm_phy_create(phy->dev, NULL, &ops);
+- if (IS_ERR(generic_phy))
+- return PTR_ERR(generic_phy);
++ if (IS_ERR(generic_phy)) {
++ error = PTR_ERR(generic_phy);
++ goto clk_unprepare;
++ }
+
+ phy_set_drvdata(generic_phy, phy);
+
+ phy_provider = devm_of_phy_provider_register(phy->dev,
+ of_phy_simple_xlate);
+- if (IS_ERR(phy_provider))
+- return PTR_ERR(phy_provider);
++ if (IS_ERR(phy_provider)) {
++ error = PTR_ERR(phy_provider);
++ goto clk_unprepare;
++ }
+
+ usb_add_phy_dev(&phy->phy);
+
+ return 0;
++
++clk_unprepare:
++ pm_runtime_disable(phy->dev);
++ clk_unprepare(phy->refclk);
++ return error;
+ }
+
+ static int dm816x_usb_phy_remove(struct platform_device *pdev)
+--
+2.30.2
+
--- /dev/null
+From 5cc55d425f0384335a7948052570c43cd2d134d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 12:50:42 +0900
+Subject: phy: uniphier-pcie: Fix updating phy parameters
+
+From: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+
+[ Upstream commit 4a90bbb478dbf18ecdec9dcf8eb708e319d24264 ]
+
+The current driver uses a value from register TEST_O as the original
+value for register TEST_I, though, the value is overwritten by "param",
+so there is a bug that the original value isn't no longer used.
+
+The value of TEST_O[7:0] should be masked with "mask", replaced with
+"param", and placed in the bitfield TESTI_DAT_MASK as new TEST_I value.
+
+Fixes: c6d9b1324159 ("phy: socionext: add PCIe PHY driver support")
+Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+Link: https://lore.kernel.org/r/1623037842-19363-1-git-send-email-hayashi.kunihiko@socionext.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/socionext/phy-uniphier-pcie.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/phy/socionext/phy-uniphier-pcie.c b/drivers/phy/socionext/phy-uniphier-pcie.c
+index e4adab375c73..6bdbd1f214dd 100644
+--- a/drivers/phy/socionext/phy-uniphier-pcie.c
++++ b/drivers/phy/socionext/phy-uniphier-pcie.c
+@@ -24,11 +24,13 @@
+ #define PORT_SEL_1 FIELD_PREP(PORT_SEL_MASK, 1)
+
+ #define PCL_PHY_TEST_I 0x2000
+-#define PCL_PHY_TEST_O 0x2004
+ #define TESTI_DAT_MASK GENMASK(13, 6)
+ #define TESTI_ADR_MASK GENMASK(5, 1)
+ #define TESTI_WR_EN BIT(0)
+
++#define PCL_PHY_TEST_O 0x2004
++#define TESTO_DAT_MASK GENMASK(7, 0)
++
+ #define PCL_PHY_RESET 0x200c
+ #define PCL_PHY_RESET_N_MNMODE BIT(8) /* =1:manual */
+ #define PCL_PHY_RESET_N BIT(0) /* =1:deasssert */
+@@ -77,11 +79,12 @@ static void uniphier_pciephy_set_param(struct uniphier_pciephy_priv *priv,
+ val = FIELD_PREP(TESTI_DAT_MASK, 1);
+ val |= FIELD_PREP(TESTI_ADR_MASK, reg);
+ uniphier_pciephy_testio_write(priv, val);
+- val = readl(priv->base + PCL_PHY_TEST_O);
++ val = readl(priv->base + PCL_PHY_TEST_O) & TESTO_DAT_MASK;
+
+ /* update value */
+- val &= ~FIELD_PREP(TESTI_DAT_MASK, mask);
+- val = FIELD_PREP(TESTI_DAT_MASK, mask & param);
++ val &= ~mask;
++ val |= mask & param;
++ val = FIELD_PREP(TESTI_DAT_MASK, val);
+ val |= FIELD_PREP(TESTI_ADR_MASK, reg);
+ uniphier_pciephy_testio_write(priv, val);
+ uniphier_pciephy_testio_write(priv, val | TESTI_WR_EN);
+--
+2.30.2
+
--- /dev/null
+From 7cebb0cc124acd75d37eee6419223811576625cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Apr 2021 14:31:00 +0200
+Subject: pinctrl: renesas: r8a7796: Add missing bias for PRESET# pin
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 2cee31cd49733e89dfedf4f68a56839fc2e42040 ]
+
+R-Car Gen3 Hardware Manual Errata for Rev. 0.52 of Nov 30, 2016, added
+the configuration bit for bias pull-down control for the PRESET# pin on
+R-Car M3-W. Add driver support for controlling pull-down on this pin.
+
+Fixes: 2d40bd24274d2577 ("pinctrl: sh-pfc: r8a7796: Add bias pinconf support")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Link: https://lore.kernel.org/r/c479de5b3f235c2f7d5faea9e7e08e6fccb135df.1619785375.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/renesas/pfc-r8a7796.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pinctrl/renesas/pfc-r8a7796.c b/drivers/pinctrl/renesas/pfc-r8a7796.c
+index 44e9d2eea484..bbb1b436ded3 100644
+--- a/drivers/pinctrl/renesas/pfc-r8a7796.c
++++ b/drivers/pinctrl/renesas/pfc-r8a7796.c
+@@ -67,6 +67,7 @@
+ PIN_NOGP_CFG(QSPI1_MOSI_IO0, "QSPI1_MOSI_IO0", fn, CFG_FLAGS), \
+ PIN_NOGP_CFG(QSPI1_SPCLK, "QSPI1_SPCLK", fn, CFG_FLAGS), \
+ PIN_NOGP_CFG(QSPI1_SSL, "QSPI1_SSL", fn, CFG_FLAGS), \
++ PIN_NOGP_CFG(PRESET_N, "PRESET#", fn, SH_PFC_PIN_CFG_PULL_DOWN),\
+ PIN_NOGP_CFG(RPC_INT_N, "RPC_INT#", fn, CFG_FLAGS), \
+ PIN_NOGP_CFG(RPC_RESET_N, "RPC_RESET#", fn, CFG_FLAGS), \
+ PIN_NOGP_CFG(RPC_WP_N, "RPC_WP#", fn, CFG_FLAGS), \
+@@ -6218,7 +6219,7 @@ static const struct pinmux_bias_reg pinmux_bias_regs[] = {
+ [ 4] = RCAR_GP_PIN(6, 29), /* USB30_OVC */
+ [ 5] = RCAR_GP_PIN(6, 30), /* GP6_30 */
+ [ 6] = RCAR_GP_PIN(6, 31), /* GP6_31 */
+- [ 7] = SH_PFC_PIN_NONE,
++ [ 7] = PIN_PRESET_N, /* PRESET# */
+ [ 8] = SH_PFC_PIN_NONE,
+ [ 9] = SH_PFC_PIN_NONE,
+ [10] = SH_PFC_PIN_NONE,
+--
+2.30.2
+
--- /dev/null
+From 9ba35ca9155f3139157a614965db412a7d6cd1e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Apr 2021 14:31:01 +0200
+Subject: pinctrl: renesas: r8a77990: JTAG pins do not have pull-down
+ capabilities
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 702a5fa2fe4d7e7f28fed92a170b540acfff9d34 ]
+
+Hence remove the SH_PFC_PIN_CFG_PULL_DOWN flags from their pin
+descriptions.
+
+Fixes: 83f6941a42a5e773 ("pinctrl: sh-pfc: r8a77990: Add bias pinconf support")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Link: https://lore.kernel.org/r/da4b2d69955840a506412f1e8099607a0da97ecc.1619785375.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/renesas/pfc-r8a77990.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/pinctrl/renesas/pfc-r8a77990.c b/drivers/pinctrl/renesas/pfc-r8a77990.c
+index d040eb3e305d..eeebbab4dd81 100644
+--- a/drivers/pinctrl/renesas/pfc-r8a77990.c
++++ b/drivers/pinctrl/renesas/pfc-r8a77990.c
+@@ -53,10 +53,10 @@
+ PIN_NOGP_CFG(FSCLKST_N, "FSCLKST_N", fn, CFG_FLAGS), \
+ PIN_NOGP_CFG(MLB_REF, "MLB_REF", fn, CFG_FLAGS), \
+ PIN_NOGP_CFG(PRESETOUT_N, "PRESETOUT_N", fn, CFG_FLAGS), \
+- PIN_NOGP_CFG(TCK, "TCK", fn, CFG_FLAGS), \
+- PIN_NOGP_CFG(TDI, "TDI", fn, CFG_FLAGS), \
+- PIN_NOGP_CFG(TMS, "TMS", fn, CFG_FLAGS), \
+- PIN_NOGP_CFG(TRST_N, "TRST_N", fn, CFG_FLAGS)
++ PIN_NOGP_CFG(TCK, "TCK", fn, SH_PFC_PIN_CFG_PULL_UP), \
++ PIN_NOGP_CFG(TDI, "TDI", fn, SH_PFC_PIN_CFG_PULL_UP), \
++ PIN_NOGP_CFG(TMS, "TMS", fn, SH_PFC_PIN_CFG_PULL_UP), \
++ PIN_NOGP_CFG(TRST_N, "TRST_N", fn, SH_PFC_PIN_CFG_PULL_UP)
+
+ /*
+ * F_() : just information
+--
+2.30.2
+
--- /dev/null
+From 125513ec8bee5d7da16dd40a14460b57c2dc3c9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Jun 2021 10:54:49 -0700
+Subject: pkt_sched: sch_qfq: fix qfq_change_class() error path
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0cd58e5c53babb9237b741dbef711f0a9eb6d3fd ]
+
+If qfq_change_class() is unable to allocate memory for qfq_aggregate,
+it frees the class that has been inserted in the class hash table,
+but does not unhash it.
+
+Defer the insertion after the problematic allocation.
+
+BUG: KASAN: use-after-free in hlist_add_head include/linux/list.h:884 [inline]
+BUG: KASAN: use-after-free in qdisc_class_hash_insert+0x200/0x210 net/sched/sch_api.c:731
+Write of size 8 at addr ffff88814a534f10 by task syz-executor.4/31478
+
+CPU: 0 PID: 31478 Comm: syz-executor.4 Not tainted 5.13.0-rc6-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:79 [inline]
+ dump_stack+0x141/0x1d7 lib/dump_stack.c:120
+ print_address_description.constprop.0.cold+0x5b/0x2f8 mm/kasan/report.c:233
+ __kasan_report mm/kasan/report.c:419 [inline]
+ kasan_report.cold+0x7c/0xd8 mm/kasan/report.c:436
+ hlist_add_head include/linux/list.h:884 [inline]
+ qdisc_class_hash_insert+0x200/0x210 net/sched/sch_api.c:731
+ qfq_change_class+0x96c/0x1990 net/sched/sch_qfq.c:489
+ tc_ctl_tclass+0x514/0xe50 net/sched/sch_api.c:2113
+ rtnetlink_rcv_msg+0x44e/0xad0 net/core/rtnetlink.c:5564
+ netlink_rcv_skb+0x153/0x420 net/netlink/af_netlink.c:2504
+ netlink_unicast_kernel net/netlink/af_netlink.c:1314 [inline]
+ netlink_unicast+0x533/0x7d0 net/netlink/af_netlink.c:1340
+ netlink_sendmsg+0x856/0xd90 net/netlink/af_netlink.c:1929
+ sock_sendmsg_nosec net/socket.c:654 [inline]
+ sock_sendmsg+0xcf/0x120 net/socket.c:674
+ ____sys_sendmsg+0x6e8/0x810 net/socket.c:2350
+ ___sys_sendmsg+0xf3/0x170 net/socket.c:2404
+ __sys_sendmsg+0xe5/0x1b0 net/socket.c:2433
+ do_syscall_64+0x3a/0xb0 arch/x86/entry/common.c:47
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+RIP: 0033:0x4665d9
+Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007fdc7b5f0188 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 000000000056bf80 RCX: 00000000004665d9
+RDX: 0000000000000000 RSI: 00000000200001c0 RDI: 0000000000000003
+RBP: 00007fdc7b5f01d0 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000002
+R13: 00007ffcf7310b3f R14: 00007fdc7b5f0300 R15: 0000000000022000
+
+Allocated by task 31445:
+ kasan_save_stack+0x1b/0x40 mm/kasan/common.c:38
+ kasan_set_track mm/kasan/common.c:46 [inline]
+ set_alloc_info mm/kasan/common.c:428 [inline]
+ ____kasan_kmalloc mm/kasan/common.c:507 [inline]
+ ____kasan_kmalloc mm/kasan/common.c:466 [inline]
+ __kasan_kmalloc+0x9b/0xd0 mm/kasan/common.c:516
+ kmalloc include/linux/slab.h:556 [inline]
+ kzalloc include/linux/slab.h:686 [inline]
+ qfq_change_class+0x705/0x1990 net/sched/sch_qfq.c:464
+ tc_ctl_tclass+0x514/0xe50 net/sched/sch_api.c:2113
+ rtnetlink_rcv_msg+0x44e/0xad0 net/core/rtnetlink.c:5564
+ netlink_rcv_skb+0x153/0x420 net/netlink/af_netlink.c:2504
+ netlink_unicast_kernel net/netlink/af_netlink.c:1314 [inline]
+ netlink_unicast+0x533/0x7d0 net/netlink/af_netlink.c:1340
+ netlink_sendmsg+0x856/0xd90 net/netlink/af_netlink.c:1929
+ sock_sendmsg_nosec net/socket.c:654 [inline]
+ sock_sendmsg+0xcf/0x120 net/socket.c:674
+ ____sys_sendmsg+0x6e8/0x810 net/socket.c:2350
+ ___sys_sendmsg+0xf3/0x170 net/socket.c:2404
+ __sys_sendmsg+0xe5/0x1b0 net/socket.c:2433
+ do_syscall_64+0x3a/0xb0 arch/x86/entry/common.c:47
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+Freed by task 31445:
+ kasan_save_stack+0x1b/0x40 mm/kasan/common.c:38
+ kasan_set_track+0x1c/0x30 mm/kasan/common.c:46
+ kasan_set_free_info+0x20/0x30 mm/kasan/generic.c:357
+ ____kasan_slab_free mm/kasan/common.c:360 [inline]
+ ____kasan_slab_free mm/kasan/common.c:325 [inline]
+ __kasan_slab_free+0xfb/0x130 mm/kasan/common.c:368
+ kasan_slab_free include/linux/kasan.h:212 [inline]
+ slab_free_hook mm/slub.c:1583 [inline]
+ slab_free_freelist_hook+0xdf/0x240 mm/slub.c:1608
+ slab_free mm/slub.c:3168 [inline]
+ kfree+0xe5/0x7f0 mm/slub.c:4212
+ qfq_change_class+0x10fb/0x1990 net/sched/sch_qfq.c:518
+ tc_ctl_tclass+0x514/0xe50 net/sched/sch_api.c:2113
+ rtnetlink_rcv_msg+0x44e/0xad0 net/core/rtnetlink.c:5564
+ netlink_rcv_skb+0x153/0x420 net/netlink/af_netlink.c:2504
+ netlink_unicast_kernel net/netlink/af_netlink.c:1314 [inline]
+ netlink_unicast+0x533/0x7d0 net/netlink/af_netlink.c:1340
+ netlink_sendmsg+0x856/0xd90 net/netlink/af_netlink.c:1929
+ sock_sendmsg_nosec net/socket.c:654 [inline]
+ sock_sendmsg+0xcf/0x120 net/socket.c:674
+ ____sys_sendmsg+0x6e8/0x810 net/socket.c:2350
+ ___sys_sendmsg+0xf3/0x170 net/socket.c:2404
+ __sys_sendmsg+0xe5/0x1b0 net/socket.c:2433
+ do_syscall_64+0x3a/0xb0 arch/x86/entry/common.c:47
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+The buggy address belongs to the object at ffff88814a534f00
+ which belongs to the cache kmalloc-128 of size 128
+The buggy address is located 16 bytes inside of
+ 128-byte region [ffff88814a534f00, ffff88814a534f80)
+The buggy address belongs to the page:
+page:ffffea0005294d00 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x14a534
+flags: 0x57ff00000000200(slab|node=1|zone=2|lastcpupid=0x7ff)
+raw: 057ff00000000200 ffffea00004fee00 0000000600000006 ffff8880110418c0
+raw: 0000000000000000 0000000000100010 00000001ffffffff 0000000000000000
+page dumped because: kasan: bad access detected
+page_owner tracks the page as allocated
+page last allocated via order 0, migratetype Unmovable, gfp_mask 0x12cc0(GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY), pid 29797, ts 604817765317, free_ts 604810151744
+ prep_new_page mm/page_alloc.c:2358 [inline]
+ get_page_from_freelist+0x1033/0x2b60 mm/page_alloc.c:3994
+ __alloc_pages+0x1b2/0x500 mm/page_alloc.c:5200
+ alloc_pages+0x18c/0x2a0 mm/mempolicy.c:2272
+ alloc_slab_page mm/slub.c:1646 [inline]
+ allocate_slab+0x2c5/0x4c0 mm/slub.c:1786
+ new_slab mm/slub.c:1849 [inline]
+ new_slab_objects mm/slub.c:2595 [inline]
+ ___slab_alloc+0x4a1/0x810 mm/slub.c:2758
+ __slab_alloc.constprop.0+0xa7/0xf0 mm/slub.c:2798
+ slab_alloc_node mm/slub.c:2880 [inline]
+ slab_alloc mm/slub.c:2922 [inline]
+ __kmalloc+0x315/0x330 mm/slub.c:4050
+ kmalloc include/linux/slab.h:561 [inline]
+ kzalloc include/linux/slab.h:686 [inline]
+ __register_sysctl_table+0x112/0x1090 fs/proc/proc_sysctl.c:1318
+ mpls_dev_sysctl_register+0x1b7/0x2d0 net/mpls/af_mpls.c:1421
+ mpls_add_dev net/mpls/af_mpls.c:1472 [inline]
+ mpls_dev_notify+0x214/0x8b0 net/mpls/af_mpls.c:1588
+ notifier_call_chain+0xb5/0x200 kernel/notifier.c:83
+ call_netdevice_notifiers_info+0xb5/0x130 net/core/dev.c:2121
+ call_netdevice_notifiers_extack net/core/dev.c:2133 [inline]
+ call_netdevice_notifiers net/core/dev.c:2147 [inline]
+ register_netdevice+0x106b/0x1500 net/core/dev.c:10312
+ veth_newlink+0x585/0xac0 drivers/net/veth.c:1547
+ __rtnl_newlink+0x1062/0x1710 net/core/rtnetlink.c:3452
+ rtnl_newlink+0x64/0xa0 net/core/rtnetlink.c:3500
+page last free stack trace:
+ reset_page_owner include/linux/page_owner.h:24 [inline]
+ free_pages_prepare mm/page_alloc.c:1298 [inline]
+ free_pcp_prepare+0x223/0x300 mm/page_alloc.c:1342
+ free_unref_page_prepare mm/page_alloc.c:3250 [inline]
+ free_unref_page+0x12/0x1d0 mm/page_alloc.c:3298
+ __vunmap+0x783/0xb60 mm/vmalloc.c:2566
+ free_work+0x58/0x70 mm/vmalloc.c:80
+ process_one_work+0x98d/0x1600 kernel/workqueue.c:2276
+ worker_thread+0x64c/0x1120 kernel/workqueue.c:2422
+ kthread+0x3b1/0x4a0 kernel/kthread.c:313
+ ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:294
+
+Memory state around the buggy address:
+ ffff88814a534e00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ffff88814a534e80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+>ffff88814a534f00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ^
+ ffff88814a534f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+ ffff88814a535000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+Fixes: 462dbc9101acd ("pkt_sched: QFQ Plus: fair-queueing service at DRR cost")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_qfq.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
+index 1db9d4a2ef5e..b692a0de1ad5 100644
+--- a/net/sched/sch_qfq.c
++++ b/net/sched/sch_qfq.c
+@@ -485,11 +485,6 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
+
+ if (cl->qdisc != &noop_qdisc)
+ qdisc_hash_add(cl->qdisc, true);
+- sch_tree_lock(sch);
+- qdisc_class_hash_insert(&q->clhash, &cl->common);
+- sch_tree_unlock(sch);
+-
+- qdisc_class_hash_grow(sch, &q->clhash);
+
+ set_change_agg:
+ sch_tree_lock(sch);
+@@ -507,8 +502,11 @@ set_change_agg:
+ }
+ if (existing)
+ qfq_deact_rm_from_agg(q, cl);
++ else
++ qdisc_class_hash_insert(&q->clhash, &cl->common);
+ qfq_add_to_agg(q, new_agg, cl);
+ sch_tree_unlock(sch);
++ qdisc_class_hash_grow(sch, &q->clhash);
+
+ *arg = (unsigned long)cl;
+ return 0;
+--
+2.30.2
+
--- /dev/null
+From 8cd076285ebb6be76522baee9c7ab2235cd40c3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Apr 2021 19:49:15 +1200
+Subject: platform/x86: asus-nb-wmi: Revert "add support for ASUS ROG Zephyrus
+ G14 and G15"
+
+From: Luke D. Jones <luke@ljones.dev>
+
+[ Upstream commit 28117f3a5c3c8375a3304af76357d5bf9cf30f0b ]
+
+The quirks added to asus-nb-wmi for the ASUS ROG Zephyrus G14 and G15 are
+wrong, they tell the asus-wmi code to use the vendor specific WMI backlight
+interface. But there is no such interface on these laptops.
+
+As a side effect, these quirks stop the acpi_video driver to register since
+they make acpi_video_get_backlight_type() return acpi_backlight_vendor,
+leaving only the native AMD backlight driver in place, which is the one we
+want. This happy coincidence is being replaced with a new quirk in
+drivers/acpi/video_detect.c which actually sets the backlight_type to
+acpi_backlight_native fixinf this properly. This reverts
+commit 13bceda68fb9 ("platform/x86: asus-nb-wmi: add support for ASUS ROG
+Zephyrus G14 and G15").
+
+Signed-off-by: Luke D. Jones <luke@ljones.dev>
+Link: https://lore.kernel.org/r/20210419074915.393433-3-luke@ljones.dev
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/asus-nb-wmi.c | 82 ------------------------------
+ 1 file changed, 82 deletions(-)
+
+diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
+index b07b1288346e..0cb927f0f301 100644
+--- a/drivers/platform/x86/asus-nb-wmi.c
++++ b/drivers/platform/x86/asus-nb-wmi.c
+@@ -110,16 +110,6 @@ static struct quirk_entry quirk_asus_forceals = {
+ .wmi_force_als_set = true,
+ };
+
+-static struct quirk_entry quirk_asus_ga401i = {
+- .wmi_backlight_power = true,
+- .wmi_backlight_set_devstate = true,
+-};
+-
+-static struct quirk_entry quirk_asus_ga502i = {
+- .wmi_backlight_power = true,
+- .wmi_backlight_set_devstate = true,
+-};
+-
+ static struct quirk_entry quirk_asus_use_kbd_dock_devid = {
+ .use_kbd_dock_devid = true,
+ };
+@@ -430,78 +420,6 @@ static const struct dmi_system_id asus_quirks[] = {
+ },
+ .driver_data = &quirk_asus_forceals,
+ },
+- {
+- .callback = dmi_matched,
+- .ident = "ASUSTeK COMPUTER INC. GA401IH",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "GA401IH"),
+- },
+- .driver_data = &quirk_asus_ga401i,
+- },
+- {
+- .callback = dmi_matched,
+- .ident = "ASUSTeK COMPUTER INC. GA401II",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "GA401II"),
+- },
+- .driver_data = &quirk_asus_ga401i,
+- },
+- {
+- .callback = dmi_matched,
+- .ident = "ASUSTeK COMPUTER INC. GA401IU",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "GA401IU"),
+- },
+- .driver_data = &quirk_asus_ga401i,
+- },
+- {
+- .callback = dmi_matched,
+- .ident = "ASUSTeK COMPUTER INC. GA401IV",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "GA401IV"),
+- },
+- .driver_data = &quirk_asus_ga401i,
+- },
+- {
+- .callback = dmi_matched,
+- .ident = "ASUSTeK COMPUTER INC. GA401IVC",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "GA401IVC"),
+- },
+- .driver_data = &quirk_asus_ga401i,
+- },
+- {
+- .callback = dmi_matched,
+- .ident = "ASUSTeK COMPUTER INC. GA502II",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "GA502II"),
+- },
+- .driver_data = &quirk_asus_ga502i,
+- },
+- {
+- .callback = dmi_matched,
+- .ident = "ASUSTeK COMPUTER INC. GA502IU",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "GA502IU"),
+- },
+- .driver_data = &quirk_asus_ga502i,
+- },
+- {
+- .callback = dmi_matched,
+- .ident = "ASUSTeK COMPUTER INC. GA502IV",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "GA502IV"),
+- },
+- .driver_data = &quirk_asus_ga502i,
+- },
+ {
+ .callback = dmi_matched,
+ .ident = "Asus Transformer T100TA / T100HA / T100CHI",
+--
+2.30.2
+
--- /dev/null
+From 94674689f7ebebdb08fb5e3a6eadde1cede480f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Apr 2021 19:49:14 +1200
+Subject: platform/x86: asus-nb-wmi: Revert "Drop duplicate DMI quirk
+ structures"
+
+From: Luke D. Jones <luke@ljones.dev>
+
+[ Upstream commit 98c0c85b1040db24f0d04d3e1d315c6c7b05cc07 ]
+
+This is a preparation revert for reverting the "add support for ASUS ROG
+Zephyrus G14 and G15" change. This reverts
+commit 67186653c903 ("platform/x86: asus-nb-wmi: Drop duplicate DMI quirk
+structures")
+
+Signed-off-by: Luke D. Jones <luke@ljones.dev>
+Link: https://lore.kernel.org/r/20210419074915.393433-2-luke@ljones.dev
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/asus-nb-wmi.c | 23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
+index d41d7ad14be0..b07b1288346e 100644
+--- a/drivers/platform/x86/asus-nb-wmi.c
++++ b/drivers/platform/x86/asus-nb-wmi.c
+@@ -110,7 +110,12 @@ static struct quirk_entry quirk_asus_forceals = {
+ .wmi_force_als_set = true,
+ };
+
+-static struct quirk_entry quirk_asus_vendor_backlight = {
++static struct quirk_entry quirk_asus_ga401i = {
++ .wmi_backlight_power = true,
++ .wmi_backlight_set_devstate = true,
++};
++
++static struct quirk_entry quirk_asus_ga502i = {
+ .wmi_backlight_power = true,
+ .wmi_backlight_set_devstate = true,
+ };
+@@ -432,7 +437,7 @@ static const struct dmi_system_id asus_quirks[] = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "GA401IH"),
+ },
+- .driver_data = &quirk_asus_vendor_backlight,
++ .driver_data = &quirk_asus_ga401i,
+ },
+ {
+ .callback = dmi_matched,
+@@ -441,7 +446,7 @@ static const struct dmi_system_id asus_quirks[] = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "GA401II"),
+ },
+- .driver_data = &quirk_asus_vendor_backlight,
++ .driver_data = &quirk_asus_ga401i,
+ },
+ {
+ .callback = dmi_matched,
+@@ -450,7 +455,7 @@ static const struct dmi_system_id asus_quirks[] = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "GA401IU"),
+ },
+- .driver_data = &quirk_asus_vendor_backlight,
++ .driver_data = &quirk_asus_ga401i,
+ },
+ {
+ .callback = dmi_matched,
+@@ -459,7 +464,7 @@ static const struct dmi_system_id asus_quirks[] = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "GA401IV"),
+ },
+- .driver_data = &quirk_asus_vendor_backlight,
++ .driver_data = &quirk_asus_ga401i,
+ },
+ {
+ .callback = dmi_matched,
+@@ -468,7 +473,7 @@ static const struct dmi_system_id asus_quirks[] = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "GA401IVC"),
+ },
+- .driver_data = &quirk_asus_vendor_backlight,
++ .driver_data = &quirk_asus_ga401i,
+ },
+ {
+ .callback = dmi_matched,
+@@ -477,7 +482,7 @@ static const struct dmi_system_id asus_quirks[] = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "GA502II"),
+ },
+- .driver_data = &quirk_asus_vendor_backlight,
++ .driver_data = &quirk_asus_ga502i,
+ },
+ {
+ .callback = dmi_matched,
+@@ -486,7 +491,7 @@ static const struct dmi_system_id asus_quirks[] = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "GA502IU"),
+ },
+- .driver_data = &quirk_asus_vendor_backlight,
++ .driver_data = &quirk_asus_ga502i,
+ },
+ {
+ .callback = dmi_matched,
+@@ -495,7 +500,7 @@ static const struct dmi_system_id asus_quirks[] = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "GA502IV"),
+ },
+- .driver_data = &quirk_asus_vendor_backlight,
++ .driver_data = &quirk_asus_ga502i,
+ },
+ {
+ .callback = dmi_matched,
+--
+2.30.2
+
--- /dev/null
+From 07d930ff0962be4e62a4d517b5b00cd8db494eed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Jun 2021 18:05:48 +0800
+Subject: platform/x86: toshiba_acpi: Fix missing error code in
+ toshiba_acpi_setup_keyboard()
+
+From: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
+
+[ Upstream commit 28e367127718a9cb85d615a71e152f7acee41bfc ]
+
+The error code is missing in this code scenario, add the error code
+'-EINVAL' to the return value 'error'.
+
+Eliminate the follow smatch warning:
+
+drivers/platform/x86/toshiba_acpi.c:2834 toshiba_acpi_setup_keyboard()
+warn: missing error code 'error'.
+
+Reported-by: Abaci Robot <abaci@linux.alibaba.com>
+Signed-off-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
+Link: https://lore.kernel.org/r/1622628348-87035-1-git-send-email-jiapeng.chong@linux.alibaba.com
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/toshiba_acpi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
+index fa7232ad8c39..352508d30467 100644
+--- a/drivers/platform/x86/toshiba_acpi.c
++++ b/drivers/platform/x86/toshiba_acpi.c
+@@ -2831,6 +2831,7 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
+
+ if (!dev->info_supported && !dev->system_event_supported) {
+ pr_warn("No hotkey query interface found\n");
++ error = -EINVAL;
+ goto err_remove_filter;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From c4184b630177617bb4c1a514a30d73f0e5e816c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 20:57:44 +0200
+Subject: platform/x86: touchscreen_dmi: Add an extra entry for the upside down
+ Goodix touchscreen on Teclast X89 tablets
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit a22e3803f2a4d947ff0083a9448a169269ea0f62 ]
+
+Teclast X89 tablets come in 2 versions, with Windows pre-installed and with
+Android pre-installed. These 2 versions have different DMI strings.
+
+Add a match for the DMI strings used by the Android version BIOS.
+
+Note the Android version BIOS has a bug in the DSDT where no IRQ is
+provided, so for the touchscreen to work a DSDT override fixing this
+is necessary as well.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20210504185746.175461-4-hdegoede@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/touchscreen_dmi.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c
+index b452865da2a1..8b9926a9db7e 100644
+--- a/drivers/platform/x86/touchscreen_dmi.c
++++ b/drivers/platform/x86/touchscreen_dmi.c
+@@ -1347,6 +1347,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
+ DMI_MATCH(DMI_BOARD_NAME, "X3 Plus"),
+ },
+ },
++ {
++ /* Teclast X89 (Android version / BIOS) */
++ .driver_data = (void *)&gdix1001_00_upside_down_data,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "WISKY"),
++ DMI_MATCH(DMI_BOARD_NAME, "3G062i"),
++ },
++ },
+ {
+ /* Teclast X89 (Windows version / BIOS) */
+ .driver_data = (void *)&gdix1001_01_upside_down_data,
+--
+2.30.2
+
--- /dev/null
+From 6ef00eb6215e03bacbc72711debd6e5ac534de00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 May 2021 20:57:45 +0200
+Subject: platform/x86: touchscreen_dmi: Add info for the Goodix GT912 panel of
+ TM800A550L tablets
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit fcd8cf0e3e48f4c66af82c8e799c37cb0cccffe0 ]
+
+The Bay Trail Glavey TM800A550L tablet, which ships with Android installed
+from the factory, uses a GT912 touchscreen controller which needs to have
+its firmware uploaded by the OS to work (this is a first for a x86 based
+device with a Goodix touchscreen controller).
+
+Add a touchscreen_dmi entry for this which specifies the filenames
+to use for the firmware and config files needed for this.
+
+Note this matches on a GDIX1001 ACPI HID, while the original DSDT uses
+a HID of GODX0911. For the touchscreen to work on these devices a DSDT
+override is necessary to fix a missing IRQ and broken GPIO settings in
+the ACPI-resources for the touchscreen. This override also changes the
+HID to the standard GDIX1001 id typically used for Goodix touchscreens.
+The DSDT override is available here:
+https://fedorapeople.org/~jwrdegoede/glavey-tm800a550l-dsdt-override/
+
+Reviewed-by: Bastien Nocera <hadess@hadess.net>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20210504185746.175461-5-hdegoede@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/touchscreen_dmi.c | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c
+index 8b9926a9db7e..424cf2a84744 100644
+--- a/drivers/platform/x86/touchscreen_dmi.c
++++ b/drivers/platform/x86/touchscreen_dmi.c
+@@ -316,6 +316,18 @@ static const struct ts_dmi_data gdix1001_01_upside_down_data = {
+ .properties = gdix1001_upside_down_props,
+ };
+
++static const struct property_entry glavey_tm800a550l_props[] = {
++ PROPERTY_ENTRY_STRING("firmware-name", "gt912-glavey-tm800a550l.fw"),
++ PROPERTY_ENTRY_STRING("goodix,config-name", "gt912-glavey-tm800a550l.cfg"),
++ PROPERTY_ENTRY_U32("goodix,main-clk", 54),
++ { }
++};
++
++static const struct ts_dmi_data glavey_tm800a550l_data = {
++ .acpi_name = "GDIX1001:00",
++ .properties = glavey_tm800a550l_props,
++};
++
+ static const struct property_entry gp_electronic_t701_props[] = {
+ PROPERTY_ENTRY_U32("touchscreen-size-x", 960),
+ PROPERTY_ENTRY_U32("touchscreen-size-y", 640),
+@@ -1055,6 +1067,15 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "eSTAR BEAUTY HD Intel Quad core"),
+ },
+ },
++ { /* Glavey TM800A550L */
++ .driver_data = (void *)&glavey_tm800a550l_data,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
++ DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
++ /* Above strings are too generic, also match on BIOS version */
++ DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"),
++ },
++ },
+ {
+ /* GP-electronic T701 */
+ .driver_data = (void *)&gp_electronic_t701_data,
+--
+2.30.2
+
--- /dev/null
+From 96f59e3a9597436fe6d2660dfcd25ad0f7081757 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 May 2021 14:48:43 +0800
+Subject: PM / devfreq: Add missing error code in devfreq_add_device()
+
+From: YueHaibing <yuehaibing@huawei.com>
+
+[ Upstream commit 18b380ed61f892ed06838d1f1a5124d966292ed3 ]
+
+Set err code in the error path before jumping to the end of the function.
+
+Fixes: 4dc3bab8687f ("PM / devfreq: Add support delayed timer for polling mode")
+Signed-off-by: YueHaibing <yuehaibing@huawei.com>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/devfreq/devfreq.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
+index fe08c46642f7..28f3e0ba6cdd 100644
+--- a/drivers/devfreq/devfreq.c
++++ b/drivers/devfreq/devfreq.c
+@@ -823,6 +823,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
+ if (devfreq->profile->timer < 0
+ || devfreq->profile->timer >= DEVFREQ_TIMER_NUM) {
+ mutex_unlock(&devfreq->lock);
++ err = -EINVAL;
+ goto err_dev;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 8e4c5eff670696b52c56130ed8980244de88dca1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jun 2021 15:05:43 +0900
+Subject: PM / devfreq: passive: Fix get_target_freq when not using
+ required-opp
+
+From: Chanwoo Choi <cw00.choi@samsung.com>
+
+[ Upstream commit 8c37d01e1a86073d15ea7084390fba58d9a1665f ]
+
+The 86ad9a24f21e ("PM / devfreq: Add required OPPs support to passive governor")
+supported the required-opp property for using devfreq passive governor.
+But, 86ad9a24f21e has caused the problem on use-case when required-opp
+is not used such as exynos-bus.c devfreq driver. So that fix the
+get_target_freq of passive governor for supporting the case of when
+required-opp is not used.
+
+Fixes: 86ad9a24f21e ("PM / devfreq: Add required OPPs support to passive governor")
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/devfreq/governor_passive.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c
+index b094132bd20b..fc09324a03e0 100644
+--- a/drivers/devfreq/governor_passive.c
++++ b/drivers/devfreq/governor_passive.c
+@@ -65,7 +65,7 @@ static int devfreq_passive_get_target_freq(struct devfreq *devfreq,
+ dev_pm_opp_put(p_opp);
+
+ if (IS_ERR(opp))
+- return PTR_ERR(opp);
++ goto no_required_opp;
+
+ *freq = dev_pm_opp_get_freq(opp);
+ dev_pm_opp_put(opp);
+@@ -73,6 +73,7 @@ static int devfreq_passive_get_target_freq(struct devfreq *devfreq,
+ return 0;
+ }
+
++no_required_opp:
+ /*
+ * Get the OPP table's index of decided frequency by governor
+ * of parent device.
+--
+2.30.2
+
--- /dev/null
+From 72ebd00e0eca461aa3bc8fd214c8097367aa5631 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 15:30:36 +1000
+Subject: powerpc/64s: Fix copy-paste data exposure into newly created tasks
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+[ Upstream commit f35d2f249ef05b9671e7898f09ad89aa78f99122 ]
+
+copy-paste contains implicit "copy buffer" state that can contain
+arbitrary user data (if the user process executes a copy instruction).
+This could be snooped by another process if a context switch hits while
+the state is live. So cp_abort is executed on context switch to clear
+out possible sensitive data and prevent the leak.
+
+cp_abort is done after the low level _switch(), which means it is never
+reached by newly created tasks, so they could snoop on this buffer
+between their first and second context switch.
+
+Fix this by doing the cp_abort before calling _switch. Add some
+comments which should make the issue harder to miss.
+
+Fixes: 07d2a628bc000 ("powerpc/64s: Avoid cpabort in context switch when possible")
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20210622053036.474678-1-npiggin@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/process.c | 48 +++++++++++++++++++++++------------
+ 1 file changed, 32 insertions(+), 16 deletions(-)
+
+diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
+index 89e34aa273e2..1138f035ce74 100644
+--- a/arch/powerpc/kernel/process.c
++++ b/arch/powerpc/kernel/process.c
+@@ -1213,6 +1213,19 @@ struct task_struct *__switch_to(struct task_struct *prev,
+ __flush_tlb_pending(batch);
+ batch->active = 0;
+ }
++
++ /*
++ * On POWER9 the copy-paste buffer can only paste into
++ * foreign real addresses, so unprivileged processes can not
++ * see the data or use it in any way unless they have
++ * foreign real mappings. If the new process has the foreign
++ * real address mappings, we must issue a cp_abort to clear
++ * any state and prevent snooping, corruption or a covert
++ * channel. ISA v3.1 supports paste into local memory.
++ */
++ if (new->mm && (cpu_has_feature(CPU_FTR_ARCH_31) ||
++ atomic_read(&new->mm->context.vas_windows)))
++ asm volatile(PPC_CP_ABORT);
+ #endif /* CONFIG_PPC_BOOK3S_64 */
+
+ #ifdef CONFIG_PPC_ADV_DEBUG_REGS
+@@ -1261,30 +1274,33 @@ struct task_struct *__switch_to(struct task_struct *prev,
+ #endif
+ last = _switch(old_thread, new_thread);
+
++ /*
++ * Nothing after _switch will be run for newly created tasks,
++ * because they switch directly to ret_from_fork/ret_from_kernel_thread
++ * etc. Code added here should have a comment explaining why that is
++ * okay.
++ */
++
+ #ifdef CONFIG_PPC_BOOK3S_64
++ /*
++ * This applies to a process that was context switched while inside
++ * arch_enter_lazy_mmu_mode(), to re-activate the batch that was
++ * deactivated above, before _switch(). This will never be the case
++ * for new tasks.
++ */
+ if (current_thread_info()->local_flags & _TLF_LAZY_MMU) {
+ current_thread_info()->local_flags &= ~_TLF_LAZY_MMU;
+ batch = this_cpu_ptr(&ppc64_tlb_batch);
+ batch->active = 1;
+ }
+
+- if (current->thread.regs) {
++ /*
++ * Math facilities are masked out of the child MSR in copy_thread.
++ * A new task does not need to restore_math because it will
++ * demand fault them.
++ */
++ if (current->thread.regs)
+ restore_math(current->thread.regs);
+-
+- /*
+- * On POWER9 the copy-paste buffer can only paste into
+- * foreign real addresses, so unprivileged processes can not
+- * see the data or use it in any way unless they have
+- * foreign real mappings. If the new process has the foreign
+- * real address mappings, we must issue a cp_abort to clear
+- * any state and prevent snooping, corruption or a covert
+- * channel. ISA v3.1 supports paste into local memory.
+- */
+- if (current->mm &&
+- (cpu_has_feature(CPU_FTR_ARCH_31) ||
+- atomic_read(¤t->mm->context.vas_windows)))
+- asm volatile(PPC_CP_ABORT);
+- }
+ #endif /* CONFIG_PPC_BOOK3S_64 */
+
+ return last;
+--
+2.30.2
+
--- /dev/null
+From 86c2e00d53230df19f68e2f39414a88f81c7b435 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 17:46:13 +1000
+Subject: powerpc/64s: fix hash page fault interrupt handler
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+[ Upstream commit 5567b1ee29b7a83e8c01d99d34b5bbd306ce0bcf ]
+
+The early bad fault or key fault test in do_hash_fault() ends up calling
+into ___do_page_fault without having gone through an interrupt handler
+wrapper (except the initial _RAW one). This can end up calling local irq
+functions while the interrupt has not been reconciled, which will likely
+cause crashes and it trips up on a later patch that adds more assertions.
+
+pkey_exec_prot from selftests causes this path to be executed.
+
+There is no real reason to run the in_nmi() test should be performed
+before the key fault check. In fact if a perf interrupt in the hash
+fault code did a stack walk that was made to take a key fault somehow
+then running ___do_page_fault could possibly cause another hash fault
+causing problems. Move the in_nmi() test first, and then do everything
+else inside the regular interrupt handler function.
+
+Fixes: 3a96570ffceb ("powerpc: convert interrupt handlers to use wrappers")
+Reported-by: Sachin Sant <sachinp@linux.vnet.ibm.com>
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Tested-by: Sachin Sant <sachinp@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20210630074621.2109197-2-npiggin@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/mm/book3s64/hash_utils.c | 24 +++++++++++-------------
+ 1 file changed, 11 insertions(+), 13 deletions(-)
+
+diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c
+index 96d9aa164007..ac5720371c0d 100644
+--- a/arch/powerpc/mm/book3s64/hash_utils.c
++++ b/arch/powerpc/mm/book3s64/hash_utils.c
+@@ -1522,8 +1522,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap,
+ }
+ EXPORT_SYMBOL_GPL(hash_page);
+
+-DECLARE_INTERRUPT_HANDLER_RET(__do_hash_fault);
+-DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault)
++DECLARE_INTERRUPT_HANDLER(__do_hash_fault);
++DEFINE_INTERRUPT_HANDLER(__do_hash_fault)
+ {
+ unsigned long ea = regs->dar;
+ unsigned long dsisr = regs->dsisr;
+@@ -1533,6 +1533,11 @@ DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault)
+ unsigned int region_id;
+ long err;
+
++ if (unlikely(dsisr & (DSISR_BAD_FAULT_64S | DSISR_KEYFAULT))) {
++ hash__do_page_fault(regs);
++ return;
++ }
++
+ region_id = get_region_id(ea);
+ if ((region_id == VMALLOC_REGION_ID) || (region_id == IO_REGION_ID))
+ mm = &init_mm;
+@@ -1571,9 +1576,10 @@ DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault)
+ bad_page_fault(regs, SIGBUS);
+ }
+ err = 0;
+- }
+
+- return err;
++ } else if (err) {
++ hash__do_page_fault(regs);
++ }
+ }
+
+ /*
+@@ -1582,13 +1588,6 @@ DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault)
+ */
+ DEFINE_INTERRUPT_HANDLER_RAW(do_hash_fault)
+ {
+- unsigned long dsisr = regs->dsisr;
+-
+- if (unlikely(dsisr & (DSISR_BAD_FAULT_64S | DSISR_KEYFAULT))) {
+- hash__do_page_fault(regs);
+- return 0;
+- }
+-
+ /*
+ * If we are in an "NMI" (e.g., an interrupt when soft-disabled), then
+ * don't call hash_page, just fail the fault. This is required to
+@@ -1607,8 +1606,7 @@ DEFINE_INTERRUPT_HANDLER_RAW(do_hash_fault)
+ return 0;
+ }
+
+- if (__do_hash_fault(regs))
+- hash__do_page_fault(regs);
++ __do_hash_fault(regs);
+
+ return 0;
+ }
+--
+2.30.2
+
--- /dev/null
+From f396f330787ec87d35767a2aa09b41ca41eef76f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 17:46:17 +1000
+Subject: powerpc/64s/interrupt: preserve regs->softe for NMI interrupts
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+[ Upstream commit 1b0482229c302a3c6afd00d6b3bf0169cf279b44 ]
+
+If an NMI interrupt hits in an implicit soft-masked region, regs->softe
+is modified to reflect that. This may not be necessary for correctness
+at the moment, but it is less surprising and it's unhelpful when
+debugging or adding checks.
+
+Make sure this is changed back to how it was found before returning.
+
+Fixes: 4ec5feec1ad0 ("powerpc/64s: Make NMI record implicitly soft-masked code as irqs disabled")
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20210630074621.2109197-6-npiggin@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/interrupt.h | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
+index 59f704408d65..a26aad41ef3e 100644
+--- a/arch/powerpc/include/asm/interrupt.h
++++ b/arch/powerpc/include/asm/interrupt.h
+@@ -186,6 +186,7 @@ struct interrupt_nmi_state {
+ u8 irq_soft_mask;
+ u8 irq_happened;
+ u8 ftrace_enabled;
++ u64 softe;
+ #endif
+ };
+
+@@ -211,6 +212,7 @@ static inline void interrupt_nmi_enter_prepare(struct pt_regs *regs, struct inte
+ #ifdef CONFIG_PPC64
+ state->irq_soft_mask = local_paca->irq_soft_mask;
+ state->irq_happened = local_paca->irq_happened;
++ state->softe = regs->softe;
+
+ /*
+ * Set IRQS_ALL_DISABLED unconditionally so irqs_disabled() does
+@@ -263,6 +265,7 @@ static inline void interrupt_nmi_exit_prepare(struct pt_regs *regs, struct inter
+
+ /* Check we didn't change the pending interrupt mask. */
+ WARN_ON_ONCE((state->irq_happened | PACA_IRQ_HARD_DIS) != local_paca->irq_happened);
++ regs->softe = state->softe;
+ local_paca->irq_happened = state->irq_happened;
+ local_paca->irq_soft_mask = state->irq_soft_mask;
+ #endif
+--
+2.30.2
+
--- /dev/null
+From 23f82786b7f5049717d37369277bb48a8566f69a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 23:05:14 +1000
+Subject: powerpc: Fix is_kvm_guest() / kvm_para_available()
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit 95839225639ba7c3d8d7231b542728dcf222bf2d ]
+
+Commit a21d1becaa3f ("powerpc: Reintroduce is_kvm_guest() as a fast-path
+check") added is_kvm_guest() and changed kvm_para_available() to use it.
+
+is_kvm_guest() checks a static key, kvm_guest, and that static key is
+set in check_kvm_guest().
+
+The problem is check_kvm_guest() is only called on pseries, and even
+then only in some configurations. That means is_kvm_guest() always
+returns false on all non-pseries and some pseries depending on
+configuration. That's a bug.
+
+For PR KVM guests this is noticable because they no longer do live
+patching of themselves, which can be detected by the omission of a
+message in dmesg such as:
+
+ KVM: Live patching for a fast VM worked
+
+To fix it make check_kvm_guest() an initcall, to ensure it's always
+called at boot. It needs to be core so that it runs before
+kvm_guest_init() which is postcore. To be an initcall it needs to return
+int, where 0 means success, so update that.
+
+We still call it manually in pSeries_smp_probe(), because that runs
+before init calls are run.
+
+Fixes: a21d1becaa3f ("powerpc: Reintroduce is_kvm_guest() as a fast-path check")
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20210623130514.2543232-1-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/kvm_guest.h | 4 ++--
+ arch/powerpc/kernel/firmware.c | 10 ++++++----
+ arch/powerpc/platforms/pseries/smp.c | 4 +++-
+ 3 files changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/kvm_guest.h b/arch/powerpc/include/asm/kvm_guest.h
+index 2fca299f7e19..c63105d2c9e7 100644
+--- a/arch/powerpc/include/asm/kvm_guest.h
++++ b/arch/powerpc/include/asm/kvm_guest.h
+@@ -16,10 +16,10 @@ static inline bool is_kvm_guest(void)
+ return static_branch_unlikely(&kvm_guest);
+ }
+
+-bool check_kvm_guest(void);
++int check_kvm_guest(void);
+ #else
+ static inline bool is_kvm_guest(void) { return false; }
+-static inline bool check_kvm_guest(void) { return false; }
++static inline int check_kvm_guest(void) { return 0; }
+ #endif
+
+ #endif /* _ASM_POWERPC_KVM_GUEST_H_ */
+diff --git a/arch/powerpc/kernel/firmware.c b/arch/powerpc/kernel/firmware.c
+index c9e2819b095a..c7022c41cc31 100644
+--- a/arch/powerpc/kernel/firmware.c
++++ b/arch/powerpc/kernel/firmware.c
+@@ -23,18 +23,20 @@ EXPORT_SYMBOL_GPL(powerpc_firmware_features);
+
+ #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_KVM_GUEST)
+ DEFINE_STATIC_KEY_FALSE(kvm_guest);
+-bool check_kvm_guest(void)
++int __init check_kvm_guest(void)
+ {
+ struct device_node *hyper_node;
+
+ hyper_node = of_find_node_by_path("/hypervisor");
+ if (!hyper_node)
+- return false;
++ return 0;
+
+ if (!of_device_is_compatible(hyper_node, "linux,kvm"))
+- return false;
++ return 0;
+
+ static_branch_enable(&kvm_guest);
+- return true;
++
++ return 0;
+ }
++core_initcall(check_kvm_guest); // before kvm_guest_init()
+ #endif
+diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
+index c70b4be9f0a5..096629f54576 100644
+--- a/arch/powerpc/platforms/pseries/smp.c
++++ b/arch/powerpc/platforms/pseries/smp.c
+@@ -211,7 +211,9 @@ static __init void pSeries_smp_probe(void)
+ if (!cpu_has_feature(CPU_FTR_SMT))
+ return;
+
+- if (check_kvm_guest()) {
++ check_kvm_guest();
++
++ if (is_kvm_guest()) {
+ /*
+ * KVM emulates doorbells by disabling FSCR[MSGP] so msgsndp
+ * faults to the hypervisor which then reads the instruction
+--
+2.30.2
+
--- /dev/null
+From fdfa88bf933dd6af1bf2c41d74bcd88e6d433277 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 14:12:45 +1000
+Subject: powerpc: Offline CPU in stop_this_cpu()
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+[ Upstream commit bab26238bbd44d5a4687c0a64fd2c7f2755ea937 ]
+
+printk_safe_flush_on_panic() has special lock breaking code for the case
+where we panic()ed with the console lock held. It relies on panic IPI
+causing other CPUs to mark themselves offline.
+
+Do as most other architectures do.
+
+This effectively reverts commit de6e5d38417e ("powerpc: smp_send_stop do
+not offline stopped CPUs"), unfortunately it may result in some false
+positive warnings, but the alternative is more situations where we can
+crash without getting messages out.
+
+Fixes: de6e5d38417e ("powerpc: smp_send_stop do not offline stopped CPUs")
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20210623041245.865134-1-npiggin@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/smp.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
+index 6c6e4d934d86..df6b468976d5 100644
+--- a/arch/powerpc/kernel/smp.c
++++ b/arch/powerpc/kernel/smp.c
+@@ -619,6 +619,8 @@ static void nmi_stop_this_cpu(struct pt_regs *regs)
+ /*
+ * IRQs are already hard disabled by the smp_handle_nmi_ipi.
+ */
++ set_cpu_online(smp_processor_id(), false);
++
+ spin_begin();
+ while (1)
+ spin_cpu_relax();
+@@ -634,6 +636,15 @@ void smp_send_stop(void)
+ static void stop_this_cpu(void *dummy)
+ {
+ hard_irq_disable();
++
++ /*
++ * Offlining CPUs in stop_this_cpu can result in scheduler warnings,
++ * (see commit de6e5d38417e), but printk_safe_flush_on_panic() wants
++ * to know other CPUs are offline before it breaks locks to flush
++ * printk buffers, in case we panic()ed while holding the lock.
++ */
++ set_cpu_online(smp_processor_id(), false);
++
+ spin_begin();
+ while (1)
+ spin_cpu_relax();
+--
+2.30.2
+
--- /dev/null
+From 725d682c20c198c79e4f1401d1f1f685b0d08159 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 May 2021 14:53:49 +0530
+Subject: powerpc/papr_scm: Make 'perf_stats' invisible if perf-stats
+ unavailable
+
+From: Vaibhav Jain <vaibhav@linux.ibm.com>
+
+[ Upstream commit ed78f56e1271f108e8af61baeba383dcd77adbec ]
+
+In case performance stats for an nvdimm are not available, reading the
+'perf_stats' sysfs file returns an -ENOENT error. A better approach is
+to make the 'perf_stats' file entirely invisible to indicate that
+performance stats for an nvdimm are unavailable.
+
+So this patch updates 'papr_nd_attribute_group' to add a 'is_visible'
+callback implemented as newly introduced 'papr_nd_attribute_visible()'
+that returns an appropriate mode in case performance stats aren't
+supported in a given nvdimm.
+
+Also the initialization of 'papr_scm_priv.stat_buffer_len' is moved
+from papr_scm_nvdimm_init() to papr_scm_probe() so that it value is
+available when 'papr_nd_attribute_visible()' is called during nvdimm
+initialization.
+
+Even though 'perf_stats' attribute is available since v5.9, there are
+no known user-space tools/scripts that are dependent on presence of its
+sysfs file. Hence I dont expect any user-space breakage with this
+patch.
+
+Fixes: 2d02bf835e57 ("powerpc/papr_scm: Fetch nvdimm performance stats from PHYP")
+Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20210513092349.285021-1-vaibhav@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/ABI/testing/sysfs-bus-papr-pmem | 8 +++--
+ arch/powerpc/platforms/pseries/papr_scm.c | 35 +++++++++++++------
+ 2 files changed, 29 insertions(+), 14 deletions(-)
+
+diff --git a/Documentation/ABI/testing/sysfs-bus-papr-pmem b/Documentation/ABI/testing/sysfs-bus-papr-pmem
+index 92e2db0e2d3d..95254cec92bf 100644
+--- a/Documentation/ABI/testing/sysfs-bus-papr-pmem
++++ b/Documentation/ABI/testing/sysfs-bus-papr-pmem
+@@ -39,9 +39,11 @@ KernelVersion: v5.9
+ Contact: linuxppc-dev <linuxppc-dev@lists.ozlabs.org>, nvdimm@lists.linux.dev,
+ Description:
+ (RO) Report various performance stats related to papr-scm NVDIMM
+- device. Each stat is reported on a new line with each line
+- composed of a stat-identifier followed by it value. Below are
+- currently known dimm performance stats which are reported:
++ device. This attribute is only available for NVDIMM devices
++ that support reporting NVDIMM performance stats. Each stat is
++ reported on a new line with each line composed of a
++ stat-identifier followed by it value. Below are currently known
++ dimm performance stats which are reported:
+
+ * "CtlResCt" : Controller Reset Count
+ * "CtlResTm" : Controller Reset Elapsed Time
+diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
+index 8335e13836db..d34e6eb4be0d 100644
+--- a/arch/powerpc/platforms/pseries/papr_scm.c
++++ b/arch/powerpc/platforms/pseries/papr_scm.c
+@@ -901,6 +901,20 @@ static ssize_t flags_show(struct device *dev,
+ }
+ DEVICE_ATTR_RO(flags);
+
++static umode_t papr_nd_attribute_visible(struct kobject *kobj,
++ struct attribute *attr, int n)
++{
++ struct device *dev = kobj_to_dev(kobj);
++ struct nvdimm *nvdimm = to_nvdimm(dev);
++ struct papr_scm_priv *p = nvdimm_provider_data(nvdimm);
++
++ /* For if perf-stats not available remove perf_stats sysfs */
++ if (attr == &dev_attr_perf_stats.attr && p->stat_buffer_len == 0)
++ return 0;
++
++ return attr->mode;
++}
++
+ /* papr_scm specific dimm attributes */
+ static struct attribute *papr_nd_attributes[] = {
+ &dev_attr_flags.attr,
+@@ -910,6 +924,7 @@ static struct attribute *papr_nd_attributes[] = {
+
+ static struct attribute_group papr_nd_attribute_group = {
+ .name = "papr",
++ .is_visible = papr_nd_attribute_visible,
+ .attrs = papr_nd_attributes,
+ };
+
+@@ -925,7 +940,6 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p)
+ struct nd_region_desc ndr_desc;
+ unsigned long dimm_flags;
+ int target_nid, online_nid;
+- ssize_t stat_size;
+
+ p->bus_desc.ndctl = papr_scm_ndctl;
+ p->bus_desc.module = THIS_MODULE;
+@@ -1010,16 +1024,6 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p)
+ list_add_tail(&p->region_list, &papr_nd_regions);
+ mutex_unlock(&papr_ndr_lock);
+
+- /* Try retriving the stat buffer and see if its supported */
+- stat_size = drc_pmem_query_stats(p, NULL, 0);
+- if (stat_size > 0) {
+- p->stat_buffer_len = stat_size;
+- dev_dbg(&p->pdev->dev, "Max perf-stat size %lu-bytes\n",
+- p->stat_buffer_len);
+- } else {
+- dev_info(&p->pdev->dev, "Dimm performance stats unavailable\n");
+- }
+-
+ return 0;
+
+ err: nvdimm_bus_unregister(p->bus);
+@@ -1097,6 +1101,7 @@ static int papr_scm_probe(struct platform_device *pdev)
+ struct papr_scm_priv *p;
+ u8 uuid_raw[UUID_SIZE];
+ const char *uuid_str;
++ ssize_t stat_size;
+ uuid_t uuid;
+ int rc;
+
+@@ -1181,6 +1186,14 @@ static int papr_scm_probe(struct platform_device *pdev)
+ p->res.name = pdev->name;
+ p->res.flags = IORESOURCE_MEM;
+
++ /* Try retrieving the stat buffer and see if its supported */
++ stat_size = drc_pmem_query_stats(p, NULL, 0);
++ if (stat_size > 0) {
++ p->stat_buffer_len = stat_size;
++ dev_dbg(&p->pdev->dev, "Max perf-stat size %lu-bytes\n",
++ p->stat_buffer_len);
++ }
++
+ rc = papr_scm_nvdimm_init(p);
+ if (rc)
+ goto err2;
+--
+2.30.2
+
--- /dev/null
+From 004b9ba25642910054661d5a8821785107b1c2e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jun 2021 16:43:03 +0300
+Subject: powerpc/papr_scm: Properly handle UUID types and API
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 0e8554b5d7801b0aebc6c348a0a9f7706aa17b3b ]
+
+Parse to and export from UUID own type, before dereferencing.
+This also fixes wrong comment (Little Endian UUID is something else)
+and should eliminate the direct strict types assignments.
+
+Fixes: 43001c52b603 ("powerpc/papr_scm: Use ibm,unit-guid as the iset cookie")
+Fixes: 259a948c4ba1 ("powerpc/pseries/scm: Use a specific endian format for storing uuid from the device tree")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20210616134303.58185-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/pseries/papr_scm.c | 27 +++++++++++++++--------
+ 1 file changed, 18 insertions(+), 9 deletions(-)
+
+diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
+index ef26fe40efb0..8335e13836db 100644
+--- a/arch/powerpc/platforms/pseries/papr_scm.c
++++ b/arch/powerpc/platforms/pseries/papr_scm.c
+@@ -18,6 +18,7 @@
+ #include <asm/plpar_wrappers.h>
+ #include <asm/papr_pdsm.h>
+ #include <asm/mce.h>
++#include <asm/unaligned.h>
+
+ #define BIND_ANY_ADDR (~0ul)
+
+@@ -1094,8 +1095,9 @@ static int papr_scm_probe(struct platform_device *pdev)
+ u32 drc_index, metadata_size;
+ u64 blocks, block_size;
+ struct papr_scm_priv *p;
++ u8 uuid_raw[UUID_SIZE];
+ const char *uuid_str;
+- u64 uuid[2];
++ uuid_t uuid;
+ int rc;
+
+ /* check we have all the required DT properties */
+@@ -1138,16 +1140,23 @@ static int papr_scm_probe(struct platform_device *pdev)
+ p->hcall_flush_required = of_property_read_bool(dn, "ibm,hcall-flush-required");
+
+ /* We just need to ensure that set cookies are unique across */
+- uuid_parse(uuid_str, (uuid_t *) uuid);
++ uuid_parse(uuid_str, &uuid);
++
+ /*
+- * cookie1 and cookie2 are not really little endian
+- * we store a little endian representation of the
+- * uuid str so that we can compare this with the label
+- * area cookie irrespective of the endian config with which
+- * the kernel is built.
++ * The cookie1 and cookie2 are not really little endian.
++ * We store a raw buffer representation of the
++ * uuid string so that we can compare this with the label
++ * area cookie irrespective of the endian configuration
++ * with which the kernel is built.
++ *
++ * Historically we stored the cookie in the below format.
++ * for a uuid string 72511b67-0b3b-42fd-8d1d-5be3cae8bcaa
++ * cookie1 was 0xfd423b0b671b5172
++ * cookie2 was 0xaabce8cae35b1d8d
+ */
+- p->nd_set.cookie1 = cpu_to_le64(uuid[0]);
+- p->nd_set.cookie2 = cpu_to_le64(uuid[1]);
++ export_uuid(uuid_raw, &uuid);
++ p->nd_set.cookie1 = get_unaligned_le64(&uuid_raw[0]);
++ p->nd_set.cookie2 = get_unaligned_le64(&uuid_raw[8]);
+
+ /* might be zero */
+ p->metadata_size = metadata_size;
+--
+2.30.2
+
--- /dev/null
+From be3c780c4c0c70ace54147212c7e44fff8f033fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 May 2021 00:03:55 +1000
+Subject: powerpc/powernv: Fix machine check reporting of async store errors
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+[ Upstream commit 3729e0ec59a20825bd4c8c70996b2df63915e1dd ]
+
+POWER9 and POWER10 asynchronous machine checks due to stores have their
+cause reported in SRR1 but SRR1[42] is set, which in other cases
+indicates DSISR cause.
+
+Check for these cases and clear SRR1[42], so the cause matching uses
+the i-side (SRR1) table.
+
+Fixes: 7b9f71f974a1 ("powerpc/64s: POWER9 machine check handler")
+Fixes: 201220bb0e8c ("powerpc/powernv: Machine check handler for POWER10")
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20210517140355.2325406-1-npiggin@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/mce_power.c | 48 +++++++++++++++++++++++++++------
+ 1 file changed, 40 insertions(+), 8 deletions(-)
+
+diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c
+index 667104d4c455..2fff886c549d 100644
+--- a/arch/powerpc/kernel/mce_power.c
++++ b/arch/powerpc/kernel/mce_power.c
+@@ -481,12 +481,11 @@ static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr,
+ return -1;
+ }
+
+-static int mce_handle_ierror(struct pt_regs *regs,
++static int mce_handle_ierror(struct pt_regs *regs, unsigned long srr1,
+ const struct mce_ierror_table table[],
+ struct mce_error_info *mce_err, uint64_t *addr,
+ uint64_t *phys_addr)
+ {
+- uint64_t srr1 = regs->msr;
+ int handled = 0;
+ int i;
+
+@@ -695,19 +694,19 @@ static long mce_handle_ue_error(struct pt_regs *regs,
+ }
+
+ static long mce_handle_error(struct pt_regs *regs,
++ unsigned long srr1,
+ const struct mce_derror_table dtable[],
+ const struct mce_ierror_table itable[])
+ {
+ struct mce_error_info mce_err = { 0 };
+ uint64_t addr, phys_addr = ULONG_MAX;
+- uint64_t srr1 = regs->msr;
+ long handled;
+
+ if (SRR1_MC_LOADSTORE(srr1))
+ handled = mce_handle_derror(regs, dtable, &mce_err, &addr,
+ &phys_addr);
+ else
+- handled = mce_handle_ierror(regs, itable, &mce_err, &addr,
++ handled = mce_handle_ierror(regs, srr1, itable, &mce_err, &addr,
+ &phys_addr);
+
+ if (!handled && mce_err.error_type == MCE_ERROR_TYPE_UE)
+@@ -723,16 +722,20 @@ long __machine_check_early_realmode_p7(struct pt_regs *regs)
+ /* P7 DD1 leaves top bits of DSISR undefined */
+ regs->dsisr &= 0x0000ffff;
+
+- return mce_handle_error(regs, mce_p7_derror_table, mce_p7_ierror_table);
++ return mce_handle_error(regs, regs->msr,
++ mce_p7_derror_table, mce_p7_ierror_table);
+ }
+
+ long __machine_check_early_realmode_p8(struct pt_regs *regs)
+ {
+- return mce_handle_error(regs, mce_p8_derror_table, mce_p8_ierror_table);
++ return mce_handle_error(regs, regs->msr,
++ mce_p8_derror_table, mce_p8_ierror_table);
+ }
+
+ long __machine_check_early_realmode_p9(struct pt_regs *regs)
+ {
++ unsigned long srr1 = regs->msr;
++
+ /*
+ * On POWER9 DD2.1 and below, it's possible to get a machine check
+ * caused by a paste instruction where only DSISR bit 25 is set. This
+@@ -746,10 +749,39 @@ long __machine_check_early_realmode_p9(struct pt_regs *regs)
+ if (SRR1_MC_LOADSTORE(regs->msr) && regs->dsisr == 0x02000000)
+ return 1;
+
+- return mce_handle_error(regs, mce_p9_derror_table, mce_p9_ierror_table);
++ /*
++ * Async machine check due to bad real address from store or foreign
++ * link time out comes with the load/store bit (PPC bit 42) set in
++ * SRR1, but the cause comes in SRR1 not DSISR. Clear bit 42 so we're
++ * directed to the ierror table so it will find the cause (which
++ * describes it correctly as a store error).
++ */
++ if (SRR1_MC_LOADSTORE(srr1) &&
++ ((srr1 & 0x081c0000) == 0x08140000 ||
++ (srr1 & 0x081c0000) == 0x08180000)) {
++ srr1 &= ~PPC_BIT(42);
++ }
++
++ return mce_handle_error(regs, srr1,
++ mce_p9_derror_table, mce_p9_ierror_table);
+ }
+
+ long __machine_check_early_realmode_p10(struct pt_regs *regs)
+ {
+- return mce_handle_error(regs, mce_p10_derror_table, mce_p10_ierror_table);
++ unsigned long srr1 = regs->msr;
++
++ /*
++ * Async machine check due to bad real address from store comes with
++ * the load/store bit (PPC bit 42) set in SRR1, but the cause comes in
++ * SRR1 not DSISR. Clear bit 42 so we're directed to the ierror table
++ * so it will find the cause (which describes it correctly as a store
++ * error).
++ */
++ if (SRR1_MC_LOADSTORE(srr1) &&
++ (srr1 & 0x081c0000) == 0x08140000) {
++ srr1 &= ~PPC_BIT(42);
++ }
++
++ return mce_handle_error(regs, srr1,
++ mce_p10_derror_table, mce_p10_ierror_table);
+ }
+--
+2.30.2
+
--- /dev/null
+From 4274968d5d147a5ea633b04f31df887d1ab60e52 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Jun 2021 08:29:34 +0800
+Subject: psi: Fix race between psi_trigger_create/destroy
+
+From: Zhaoyang Huang <zhaoyang.huang@unisoc.com>
+
+[ Upstream commit 8f91efd870ea5d8bc10b0fcc9740db51cd4c0c83 ]
+
+Race detected between psi_trigger_destroy/create as shown below, which
+cause panic by accessing invalid psi_system->poll_wait->wait_queue_entry
+and psi_system->poll_timer->entry->next. Under this modification, the
+race window is removed by initialising poll_wait and poll_timer in
+group_init which are executed only once at beginning.
+
+ psi_trigger_destroy() psi_trigger_create()
+
+ mutex_lock(trigger_lock);
+ rcu_assign_pointer(poll_task, NULL);
+ mutex_unlock(trigger_lock);
+ mutex_lock(trigger_lock);
+ if (!rcu_access_pointer(group->poll_task)) {
+ timer_setup(poll_timer, poll_timer_fn, 0);
+ rcu_assign_pointer(poll_task, task);
+ }
+ mutex_unlock(trigger_lock);
+
+ synchronize_rcu();
+ del_timer_sync(poll_timer); <-- poll_timer has been reinitialized by
+ psi_trigger_create()
+
+So, trigger_lock/RCU correctly protects destruction of
+group->poll_task but misses this race affecting poll_timer and
+poll_wait.
+
+Fixes: 461daba06bdc ("psi: eliminate kthread_worker from psi trigger scheduling mechanism")
+Co-developed-by: ziwei.dai <ziwei.dai@unisoc.com>
+Signed-off-by: ziwei.dai <ziwei.dai@unisoc.com>
+Co-developed-by: ke.wang <ke.wang@unisoc.com>
+Signed-off-by: ke.wang <ke.wang@unisoc.com>
+Signed-off-by: Zhaoyang Huang <zhaoyang.huang@unisoc.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Suren Baghdasaryan <surenb@google.com>
+Acked-by: Johannes Weiner <hannes@cmpxchg.org>
+Link: https://lkml.kernel.org/r/1623371374-15664-1-git-send-email-huangzhaoyang@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/psi.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c
+index cc25a3cff41f..58b36d17a09a 100644
+--- a/kernel/sched/psi.c
++++ b/kernel/sched/psi.c
+@@ -182,6 +182,8 @@ struct psi_group psi_system = {
+
+ static void psi_avgs_work(struct work_struct *work);
+
++static void poll_timer_fn(struct timer_list *t);
++
+ static void group_init(struct psi_group *group)
+ {
+ int cpu;
+@@ -201,6 +203,8 @@ static void group_init(struct psi_group *group)
+ memset(group->polling_total, 0, sizeof(group->polling_total));
+ group->polling_next_update = ULLONG_MAX;
+ group->polling_until = 0;
++ init_waitqueue_head(&group->poll_wait);
++ timer_setup(&group->poll_timer, poll_timer_fn, 0);
+ rcu_assign_pointer(group->poll_task, NULL);
+ }
+
+@@ -1157,9 +1161,7 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group,
+ return ERR_CAST(task);
+ }
+ atomic_set(&group->poll_wakeup, 0);
+- init_waitqueue_head(&group->poll_wait);
+ wake_up_process(task);
+- timer_setup(&group->poll_timer, poll_timer_fn, 0);
+ rcu_assign_pointer(group->poll_task, task);
+ }
+
+@@ -1211,6 +1213,7 @@ static void psi_trigger_destroy(struct kref *ref)
+ group->poll_task,
+ lockdep_is_held(&group->trigger_lock));
+ rcu_assign_pointer(group->poll_task, NULL);
++ del_timer(&group->poll_timer);
+ }
+ }
+
+@@ -1223,17 +1226,14 @@ static void psi_trigger_destroy(struct kref *ref)
+ */
+ synchronize_rcu();
+ /*
+- * Destroy the kworker after releasing trigger_lock to prevent a
++ * Stop kthread 'psimon' after releasing trigger_lock to prevent a
+ * deadlock while waiting for psi_poll_work to acquire trigger_lock
+ */
+ if (task_to_destroy) {
+ /*
+ * After the RCU grace period has expired, the worker
+ * can no longer be found through group->poll_task.
+- * But it might have been already scheduled before
+- * that - deschedule it cleanly before destroying it.
+ */
+- del_timer_sync(&group->poll_timer);
+ kthread_stop(task_to_destroy);
+ }
+ kfree(t);
+--
+2.30.2
+
--- /dev/null
+From c84cc8f060b2f147a48268101f10853c5f582e45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 13:20:12 +0100
+Subject: random32: Fix implicit truncation warning in prandom_seed_state()
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit d327ea15a305024ef0085252fa3657bbb1ce25f5 ]
+
+sparse generates the following warning:
+
+ include/linux/prandom.h:114:45: sparse: sparse: cast truncates bits from
+ constant value
+
+This is because the 64-bit seed value is manipulated and then placed in a
+u32, causing an implicit cast and truncation. A forced cast to u32 doesn't
+prevent this warning, which is reasonable because a typecast doesn't prove
+that truncation was expected.
+
+Logical-AND the value with 0xffffffff to make explicit that truncation to
+32-bit is intended.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Reviewed-by: Petr Mladek <pmladek@suse.com>
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Link: https://lore.kernel.org/r/20210525122012.6336-3-rf@opensource.cirrus.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/prandom.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/prandom.h b/include/linux/prandom.h
+index bbf4b4ad61df..056d31317e49 100644
+--- a/include/linux/prandom.h
++++ b/include/linux/prandom.h
+@@ -111,7 +111,7 @@ static inline u32 __seed(u32 x, u32 m)
+ */
+ static inline void prandom_seed_state(struct rnd_state *state, u64 seed)
+ {
+- u32 i = (seed >> 32) ^ (seed << 10) ^ seed;
++ u32 i = ((seed >> 32) ^ (seed << 10) ^ seed) & 0xffffffffUL;
+
+ state->s1 = __seed(i, 2U);
+ state->s2 = __seed(i, 8U);
+--
+2.30.2
+
--- /dev/null
+From 2e231820362b55b45cbab42234630b12199b5a5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Mar 2021 10:59:05 -0700
+Subject: rcu: Invoke rcu_spawn_core_kthreads() from rcu_spawn_gp_kthread()
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit 8e4b1d2bc198e34b48fc7cc3a3c5a2fcb269e271 ]
+
+Currently, rcu_spawn_core_kthreads() is invoked via an early_initcall(),
+which works, except that rcu_spawn_gp_kthread() is also invoked via an
+early_initcall() and rcu_spawn_core_kthreads() relies on adjustments to
+kthread_prio that are carried out by rcu_spawn_gp_kthread(). There is
+no guaranttee of ordering among early_initcall() handlers, and thus no
+guarantee that kthread_prio will be properly checked and range-limited
+at the time that rcu_spawn_core_kthreads() needs it.
+
+In most cases, this bug is harmless. After all, the only reason that
+rcu_spawn_gp_kthread() adjusts the value of kthread_prio is if the user
+specified a nonsensical value for this boot parameter, which experience
+indicates is rare.
+
+Nevertheless, a bug is a bug. This commit therefore causes the
+rcu_spawn_core_kthreads() function to be invoked directly from
+rcu_spawn_gp_kthread() after any needed adjustments to kthread_prio have
+been carried out.
+
+Fixes: 48d07c04b4cc ("rcu: Enable elimination of Tree-RCU softirq processing")
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/tree.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index 8e78b2430c16..9a1396a70c52 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -2911,7 +2911,6 @@ static int __init rcu_spawn_core_kthreads(void)
+ "%s: Could not start rcuc kthread, OOM is now expected behavior\n", __func__);
+ return 0;
+ }
+-early_initcall(rcu_spawn_core_kthreads);
+
+ /*
+ * Handle any core-RCU processing required by a call_rcu() invocation.
+@@ -4472,6 +4471,7 @@ static int __init rcu_spawn_gp_kthread(void)
+ wake_up_process(t);
+ rcu_spawn_nocb_kthreads();
+ rcu_spawn_boost_kthreads();
++ rcu_spawn_core_kthreads();
+ return 0;
+ }
+ early_initcall(rcu_spawn_gp_kthread);
+--
+2.30.2
+
--- /dev/null
+From 86de2940e742d288a3508848cce10445e1cec316 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 16:13:27 +0200
+Subject: RDMA/cma: Fix incorrect Packet Lifetime calculation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Håkon Bugge <haakon.bugge@oracle.com>
+
+[ Upstream commit e84045eab69c625bc0b0bf24d8e05bc65da1eed1 ]
+
+An approximation for the PacketLifeTime is half the local ACK timeout.
+The encoding for both timers are logarithmic.
+
+If the local ACK timeout is set, but zero, it means the timer is
+disabled. In this case, we choose the CMA_IBOE_PACKET_LIFETIME value,
+since 50% of infinite makes no sense.
+
+Before this commit, the PacketLifeTime became 255 if local ACK
+timeout was zero (not running).
+
+Fixed by explicitly testing for timeout being zero.
+
+Fixes: e1ee1e62bec4 ("RDMA/cma: Use ACK timeout for RoCE packetLifeTime")
+Link: https://lore.kernel.org/r/1624371207-26710-1-git-send-email-haakon.bugge@oracle.com
+Signed-off-by: Håkon Bugge <haakon.bugge@oracle.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cma.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index a5ec61ac11cc..8bbffa04fb48 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -3096,8 +3096,10 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
+ * as a reasonable approximation for RoCE networks.
+ */
+ mutex_lock(&id_priv->qp_mutex);
+- route->path_rec->packet_life_time = id_priv->timeout_set ?
+- id_priv->timeout - 1 : CMA_IBOE_PACKET_LIFETIME;
++ if (id_priv->timeout_set && id_priv->timeout)
++ route->path_rec->packet_life_time = id_priv->timeout - 1;
++ else
++ route->path_rec->packet_life_time = CMA_IBOE_PACKET_LIFETIME;
+ mutex_unlock(&id_priv->qp_mutex);
+
+ if (!route->path_rec->mtu) {
+--
+2.30.2
+
--- /dev/null
+From a359b1d5997d318090a28f563f10f125a041b0e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 15:39:57 +0200
+Subject: RDMA/cma: Protect RMW with qp_mutex
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Håkon Bugge <haakon.bugge@oracle.com>
+
+[ Upstream commit ca0c448d2b9f43e3175835d536853854ef544e22 ]
+
+The struct rdma_id_private contains three bit-fields, tos_set,
+timeout_set, and min_rnr_timer_set. These are set by accessor functions
+without any synchronization. If two or all accessor functions are invoked
+in close proximity in time, there will be Read-Modify-Write from several
+contexts to the same variable, and the result will be intermittent.
+
+Fixed by protecting the bit-fields by the qp_mutex in the accessor
+functions.
+
+The consumer of timeout_set and min_rnr_timer_set is in
+rdma_init_qp_attr(), which is called with qp_mutex held for connected
+QPs. Explicit locking is added for the consumers of tos and tos_set.
+
+This commit depends on ("RDMA/cma: Remove unnecessary INIT->INIT
+transition"), since the call to rdma_init_qp_attr() from
+cma_init_conn_qp() does not hold the qp_mutex.
+
+Fixes: 2c1619edef61 ("IB/cma: Define option to set ack timeout and pack tos_set")
+Fixes: 3aeffc46afde ("IB/cma: Introduce rdma_set_min_rnr_timer()")
+Link: https://lore.kernel.org/r/1624369197-24578-3-git-send-email-haakon.bugge@oracle.com
+Signed-off-by: Håkon Bugge <haakon.bugge@oracle.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cma.c | 20 +++++++++++++++++++-
+ 1 file changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index ab148a696c0c..a5ec61ac11cc 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -2472,8 +2472,10 @@ static int cma_iw_listen(struct rdma_id_private *id_priv, int backlog)
+ if (IS_ERR(id))
+ return PTR_ERR(id);
+
++ mutex_lock(&id_priv->qp_mutex);
+ id->tos = id_priv->tos;
+ id->tos_set = id_priv->tos_set;
++ mutex_unlock(&id_priv->qp_mutex);
+ id->afonly = id_priv->afonly;
+ id_priv->cm_id.iw = id;
+
+@@ -2534,8 +2536,10 @@ static int cma_listen_on_dev(struct rdma_id_private *id_priv,
+ cma_id_get(id_priv);
+ dev_id_priv->internal_id = 1;
+ dev_id_priv->afonly = id_priv->afonly;
++ mutex_lock(&id_priv->qp_mutex);
+ dev_id_priv->tos_set = id_priv->tos_set;
+ dev_id_priv->tos = id_priv->tos;
++ mutex_unlock(&id_priv->qp_mutex);
+
+ ret = rdma_listen(&dev_id_priv->id, id_priv->backlog);
+ if (ret)
+@@ -2582,8 +2586,10 @@ void rdma_set_service_type(struct rdma_cm_id *id, int tos)
+ struct rdma_id_private *id_priv;
+
+ id_priv = container_of(id, struct rdma_id_private, id);
++ mutex_lock(&id_priv->qp_mutex);
+ id_priv->tos = (u8) tos;
+ id_priv->tos_set = true;
++ mutex_unlock(&id_priv->qp_mutex);
+ }
+ EXPORT_SYMBOL(rdma_set_service_type);
+
+@@ -2610,8 +2616,10 @@ int rdma_set_ack_timeout(struct rdma_cm_id *id, u8 timeout)
+ return -EINVAL;
+
+ id_priv = container_of(id, struct rdma_id_private, id);
++ mutex_lock(&id_priv->qp_mutex);
+ id_priv->timeout = timeout;
+ id_priv->timeout_set = true;
++ mutex_unlock(&id_priv->qp_mutex);
+
+ return 0;
+ }
+@@ -2647,8 +2655,10 @@ int rdma_set_min_rnr_timer(struct rdma_cm_id *id, u8 min_rnr_timer)
+ return -EINVAL;
+
+ id_priv = container_of(id, struct rdma_id_private, id);
++ mutex_lock(&id_priv->qp_mutex);
+ id_priv->min_rnr_timer = min_rnr_timer;
+ id_priv->min_rnr_timer_set = true;
++ mutex_unlock(&id_priv->qp_mutex);
+
+ return 0;
+ }
+@@ -3034,8 +3044,11 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
+
+ u8 default_roce_tos = id_priv->cma_dev->default_roce_tos[id_priv->id.port_num -
+ rdma_start_port(id_priv->cma_dev->device)];
+- u8 tos = id_priv->tos_set ? id_priv->tos : default_roce_tos;
++ u8 tos;
+
++ mutex_lock(&id_priv->qp_mutex);
++ tos = id_priv->tos_set ? id_priv->tos : default_roce_tos;
++ mutex_unlock(&id_priv->qp_mutex);
+
+ work = kzalloc(sizeof *work, GFP_KERNEL);
+ if (!work)
+@@ -3082,8 +3095,10 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
+ * PacketLifeTime = local ACK timeout/2
+ * as a reasonable approximation for RoCE networks.
+ */
++ mutex_lock(&id_priv->qp_mutex);
+ route->path_rec->packet_life_time = id_priv->timeout_set ?
+ id_priv->timeout - 1 : CMA_IBOE_PACKET_LIFETIME;
++ mutex_unlock(&id_priv->qp_mutex);
+
+ if (!route->path_rec->mtu) {
+ ret = -EINVAL;
+@@ -4107,8 +4122,11 @@ static int cma_connect_iw(struct rdma_id_private *id_priv,
+ if (IS_ERR(cm_id))
+ return PTR_ERR(cm_id);
+
++ mutex_lock(&id_priv->qp_mutex);
+ cm_id->tos = id_priv->tos;
+ cm_id->tos_set = id_priv->tos_set;
++ mutex_unlock(&id_priv->qp_mutex);
++
+ id_priv->cm_id.iw = cm_id;
+
+ memcpy(&cm_id->local_addr, cma_src_addr(id_priv),
+--
+2.30.2
+
--- /dev/null
+From d57fd56add3357d5db7ccbc5434dc3d710bf364e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Jun 2021 09:49:33 +0300
+Subject: RDMA/core: Always release restrack object
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit 3d8287544223a3d2f37981c1f9ffd94d0b5e9ffc ]
+
+Change location of rdma_restrack_del() to fix the bug where
+task_struct was acquired but not released, causing to resource leak.
+
+ ucma_create_id() {
+ ucma_alloc_ctx();
+ rdma_create_user_id() {
+ rdma_restrack_new();
+ rdma_restrack_set_name() {
+ rdma_restrack_attach_task.part.0(); <--- task_struct was gotten
+ }
+ }
+ ucma_destroy_private_ctx() {
+ ucma_put_ctx();
+ rdma_destroy_id() {
+ _destroy_id() <--- id_priv was freed
+ }
+ }
+ }
+
+Fixes: 889d916b6f8a ("RDMA/core: Don't access cm_id after its destruction")
+Link: https://lore.kernel.org/r/073ec27acb943ca8b6961663c47c5abe78a5c8cc.1624948948.git.leonro@nvidia.com
+Reported-by: Pavel Skripkin <paskripkin@gmail.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cma.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index 8bbffa04fb48..ad9a9ba5f00d 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -1852,6 +1852,7 @@ static void _destroy_id(struct rdma_id_private *id_priv,
+ {
+ cma_cancel_operation(id_priv, state);
+
++ rdma_restrack_del(&id_priv->res);
+ if (id_priv->cma_dev) {
+ if (rdma_cap_ib_cm(id_priv->id.device, 1)) {
+ if (id_priv->cm_id.ib)
+@@ -1861,7 +1862,6 @@ static void _destroy_id(struct rdma_id_private *id_priv,
+ iw_destroy_cm_id(id_priv->cm_id.iw);
+ }
+ cma_leave_mc_groups(id_priv);
+- rdma_restrack_del(&id_priv->res);
+ cma_release_dev(id_priv);
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 5e709e7fc2c4556bc300f0c1d5c02a162718fe5e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 May 2021 11:37:31 +0300
+Subject: RDMA/core: Sanitize WQ state received from the userspace
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit f97442887275d11c88c2899e720fe945c1f61488 ]
+
+The mlx4 and mlx5 implemented differently the WQ input checks. Instead of
+duplicating mlx4 logic in the mlx5, let's prepare the input in the central
+place.
+
+The mlx5 implementation didn't check for validity of state input. It is
+not real bug because our FW checked that, but still worth to fix.
+
+Fixes: f213c0527210 ("IB/uverbs: Add WQ support")
+Link: https://lore.kernel.org/r/ac41ad6a81b095b1a8ad453dcf62cf8d3c5da779.1621413310.git.leonro@nvidia.com
+Reported-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/uverbs_cmd.c | 21 +++++++++++++++++++--
+ drivers/infiniband/hw/mlx4/qp.c | 9 ++-------
+ drivers/infiniband/hw/mlx5/qp.c | 6 ++----
+ 3 files changed, 23 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
+index 64e4be1cbec7..a1d1deca7c06 100644
+--- a/drivers/infiniband/core/uverbs_cmd.c
++++ b/drivers/infiniband/core/uverbs_cmd.c
+@@ -3034,12 +3034,29 @@ static int ib_uverbs_ex_modify_wq(struct uverbs_attr_bundle *attrs)
+ if (!wq)
+ return -EINVAL;
+
+- wq_attr.curr_wq_state = cmd.curr_wq_state;
+- wq_attr.wq_state = cmd.wq_state;
+ if (cmd.attr_mask & IB_WQ_FLAGS) {
+ wq_attr.flags = cmd.flags;
+ wq_attr.flags_mask = cmd.flags_mask;
+ }
++
++ if (cmd.attr_mask & IB_WQ_CUR_STATE) {
++ if (cmd.curr_wq_state > IB_WQS_ERR)
++ return -EINVAL;
++
++ wq_attr.curr_wq_state = cmd.curr_wq_state;
++ } else {
++ wq_attr.curr_wq_state = wq->state;
++ }
++
++ if (cmd.attr_mask & IB_WQ_STATE) {
++ if (cmd.wq_state > IB_WQS_ERR)
++ return -EINVAL;
++
++ wq_attr.wq_state = cmd.wq_state;
++ } else {
++ wq_attr.wq_state = wq_attr.curr_wq_state;
++ }
++
+ ret = wq->device->ops.modify_wq(wq, &wq_attr, cmd.attr_mask,
+ &attrs->driver_udata);
+ rdma_lookup_put_uobject(&wq->uobject->uevent.uobject,
+diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
+index 92ddbcc00eb2..2ae22bf50016 100644
+--- a/drivers/infiniband/hw/mlx4/qp.c
++++ b/drivers/infiniband/hw/mlx4/qp.c
+@@ -4251,13 +4251,8 @@ int mlx4_ib_modify_wq(struct ib_wq *ibwq, struct ib_wq_attr *wq_attr,
+ if (wq_attr_mask & IB_WQ_FLAGS)
+ return -EOPNOTSUPP;
+
+- cur_state = wq_attr_mask & IB_WQ_CUR_STATE ? wq_attr->curr_wq_state :
+- ibwq->state;
+- new_state = wq_attr_mask & IB_WQ_STATE ? wq_attr->wq_state : cur_state;
+-
+- if (cur_state < IB_WQS_RESET || cur_state > IB_WQS_ERR ||
+- new_state < IB_WQS_RESET || new_state > IB_WQS_ERR)
+- return -EINVAL;
++ cur_state = wq_attr->curr_wq_state;
++ new_state = wq_attr->wq_state;
+
+ if ((new_state == IB_WQS_RDY) && (cur_state == IB_WQS_ERR))
+ return -EINVAL;
+diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
+index 9282eb10bfae..5851486c0d93 100644
+--- a/drivers/infiniband/hw/mlx5/qp.c
++++ b/drivers/infiniband/hw/mlx5/qp.c
+@@ -5309,10 +5309,8 @@ int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,
+
+ rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx);
+
+- curr_wq_state = (wq_attr_mask & IB_WQ_CUR_STATE) ?
+- wq_attr->curr_wq_state : wq->state;
+- wq_state = (wq_attr_mask & IB_WQ_STATE) ?
+- wq_attr->wq_state : curr_wq_state;
++ curr_wq_state = wq_attr->curr_wq_state;
++ wq_state = wq_attr->wq_state;
+ if (curr_wq_state == IB_WQS_ERR)
+ curr_wq_state = MLX5_RQC_STATE_ERR;
+ if (wq_state == IB_WQS_ERR)
+--
+2.30.2
+
--- /dev/null
+From d206951ea39735c8ae2f38bbd692cfb892f1f524 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Jun 2021 16:00:36 +0800
+Subject: RDMA/hns: Add a check to ensure integer mtu is positive
+
+From: Weihang Li <liweihang@huawei.com>
+
+[ Upstream commit fe331da0f210c60342b042a03fe53f1b564b412b ]
+
+GCC may reports an running time assert error when a value calculated from
+ib_mtu_enum_to_int() is using as 'val' in FIELD_PREDP:
+
+include/linux/compiler_types.h:328:38: error: call to
+'__compiletime_assert_1524' declared with attribute error: FIELD_PREP:
+value too large for the field
+
+So a check is added about whether integer mtu from ib_mtu_enum_to_int() is
+negative to avoid this warning.
+
+Link: https://lore.kernel.org/r/1624262443-24528-3-git-send-email-liweihang@huawei.com
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Weihang Li <liweihang@huawei.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index cd58becf1baf..f074e2e5a5c8 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -4499,12 +4499,13 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
+ struct ib_device *ibdev = &hr_dev->ib_dev;
+ dma_addr_t trrl_ba;
+ dma_addr_t irrl_ba;
+- enum ib_mtu mtu;
++ enum ib_mtu ib_mtu;
+ u8 lp_pktn_ini;
+ u64 *mtts;
+ u8 *dmac;
+ u8 *smac;
+ u32 port;
++ int mtu;
+ int ret;
+
+ ret = config_qp_rq_buf(hr_dev, hr_qp, context, qpc_mask);
+@@ -4588,19 +4589,23 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
+ roce_set_field(qpc_mask->byte_52_udpspn_dmac, V2_QPC_BYTE_52_DMAC_M,
+ V2_QPC_BYTE_52_DMAC_S, 0);
+
+- mtu = get_mtu(ibqp, attr);
+- hr_qp->path_mtu = mtu;
++ ib_mtu = get_mtu(ibqp, attr);
++ hr_qp->path_mtu = ib_mtu;
++
++ mtu = ib_mtu_enum_to_int(ib_mtu);
++ if (WARN_ON(mtu < 0))
++ return -EINVAL;
+
+ if (attr_mask & IB_QP_PATH_MTU) {
+ roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M,
+- V2_QPC_BYTE_24_MTU_S, mtu);
++ V2_QPC_BYTE_24_MTU_S, ib_mtu);
+ roce_set_field(qpc_mask->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M,
+ V2_QPC_BYTE_24_MTU_S, 0);
+ }
+
+ #define MAX_LP_MSG_LEN 65536
+ /* MTU * (2 ^ LP_PKTN_INI) shouldn't be bigger than 64KB */
+- lp_pktn_ini = ilog2(MAX_LP_MSG_LEN / ib_mtu_enum_to_int(mtu));
++ lp_pktn_ini = ilog2(MAX_LP_MSG_LEN / mtu);
+
+ roce_set_field(context->byte_56_dqpn_err, V2_QPC_BYTE_56_LP_PKTN_INI_M,
+ V2_QPC_BYTE_56_LP_PKTN_INI_S, lp_pktn_ini);
+--
+2.30.2
+
--- /dev/null
+From d82f2f91e0faaea41556ea6f6fcf169744b70f98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 20:16:03 +0800
+Subject: RDMA/hns: Add window selection field of congestion control
+
+From: Yixing Liu <liuyixing1@huawei.com>
+
+[ Upstream commit 7ae61c5f16671ecaf23526feb6892c8249d0c2d7 ]
+
+The window selection field is necessary for congestion control of HIP09,
+it is got from firmware and then filled into QPC. Some algorithms need it
+to decide whether to limit the number of windows.
+
+Fixes: f91696f2f053 ("RDMA/hns: Support congestion control type selection according to the FW")
+Link: https://lore.kernel.org/r/1624364163-44185-1-git-send-email-liweihang@huawei.com
+Signed-off-by: Yixing Liu <liuyixing1@huawei.com>
+Signed-off-by: Weihang Li <liweihang@huawei.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 12 ++++++++++++
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 2 ++
+ 2 files changed, 14 insertions(+)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index f074e2e5a5c8..dcbe5e28a4f7 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -4777,6 +4777,11 @@ enum {
+ DIP_VALID,
+ };
+
++enum {
++ WND_LIMIT,
++ WND_UNLIMIT,
++};
++
+ static int check_cong_type(struct ib_qp *ibqp,
+ struct hns_roce_congestion_algorithm *cong_alg)
+ {
+@@ -4788,21 +4793,25 @@ static int check_cong_type(struct ib_qp *ibqp,
+ cong_alg->alg_sel = CONG_DCQCN;
+ cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL;
+ cong_alg->dip_vld = DIP_INVALID;
++ cong_alg->wnd_mode_sel = WND_LIMIT;
+ break;
+ case CONG_TYPE_LDCP:
+ cong_alg->alg_sel = CONG_WINDOW;
+ cong_alg->alg_sub_sel = CONG_LDCP;
+ cong_alg->dip_vld = DIP_INVALID;
++ cong_alg->wnd_mode_sel = WND_UNLIMIT;
+ break;
+ case CONG_TYPE_HC3:
+ cong_alg->alg_sel = CONG_WINDOW;
+ cong_alg->alg_sub_sel = CONG_HC3;
+ cong_alg->dip_vld = DIP_INVALID;
++ cong_alg->wnd_mode_sel = WND_LIMIT;
+ break;
+ case CONG_TYPE_DIP:
+ cong_alg->alg_sel = CONG_DCQCN;
+ cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL;
+ cong_alg->dip_vld = DIP_VALID;
++ cong_alg->wnd_mode_sel = WND_LIMIT;
+ break;
+ default:
+ ibdev_err(&hr_dev->ib_dev,
+@@ -4843,6 +4852,9 @@ static int fill_cong_field(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
+ hr_reg_write(&qpc_mask->ext, QPCEX_CONG_ALG_SUB_SEL, 0);
+ hr_reg_write(&context->ext, QPCEX_DIP_CTX_IDX_VLD, cong_field.dip_vld);
+ hr_reg_write(&qpc_mask->ext, QPCEX_DIP_CTX_IDX_VLD, 0);
++ hr_reg_write(&context->ext, QPCEX_SQ_RQ_NOT_FORBID_EN,
++ cong_field.wnd_mode_sel);
++ hr_reg_clear(&qpc_mask->ext, QPCEX_SQ_RQ_NOT_FORBID_EN);
+
+ /* if dip is disabled, there is no need to set dip idx */
+ if (cong_field.dip_vld == 0)
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+index 028bc41cb45c..23cf2f6bc7a5 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+@@ -964,6 +964,7 @@ struct hns_roce_v2_qp_context {
+ #define QPCEX_CONG_ALG_SUB_SEL QPCEX_FIELD_LOC(1, 1)
+ #define QPCEX_DIP_CTX_IDX_VLD QPCEX_FIELD_LOC(2, 2)
+ #define QPCEX_DIP_CTX_IDX QPCEX_FIELD_LOC(22, 3)
++#define QPCEX_SQ_RQ_NOT_FORBID_EN QPCEX_FIELD_LOC(23, 23)
+ #define QPCEX_STASH QPCEX_FIELD_LOC(82, 82)
+
+ #define V2_QP_RWE_S 1 /* rdma write enable */
+@@ -1643,6 +1644,7 @@ struct hns_roce_congestion_algorithm {
+ u8 alg_sel;
+ u8 alg_sub_sel;
+ u8 dip_vld;
++ u8 wnd_mode_sel;
+ };
+
+ #define V2_QUERY_PF_CAPS_D_CEQ_DEPTH_S 0
+--
+2.30.2
+
--- /dev/null
+From 9b92dbc2605440861dc6d6e3d6f71c528ea32553 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Jun 2021 14:14:49 +0800
+Subject: RDMA/hns: Clear extended doorbell info before using
+
+From: Xi Wang <wangxi11@huawei.com>
+
+[ Upstream commit 7e78dd816e458fbc2928a068d70009178d5d070d ]
+
+Both of HIP08 and HIP09 require the extended doorbell information to be
+cleared before being used.
+
+Fixes: 6b63597d3540 ("RDMA/hns: Add TSQ link table support")
+Link: https://lore.kernel.org/r/1623392089-35639-1-git-send-email-liweihang@huawei.com
+Signed-off-by: Xi Wang <wangxi11@huawei.com>
+Signed-off-by: Weihang Li <liweihang@huawei.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 21 +++++++++++++++++++++
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 1 +
+ 2 files changed, 22 insertions(+)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index d7289b6587f1..78f3e05cc1f5 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -1619,6 +1619,22 @@ static void hns_roce_function_clear(struct hns_roce_dev *hr_dev)
+ }
+ }
+
++static int hns_roce_clear_extdb_list_info(struct hns_roce_dev *hr_dev)
++{
++ struct hns_roce_cmq_desc desc;
++ int ret;
++
++ hns_roce_cmq_setup_basic_desc(&desc, HNS_ROCE_OPC_CLEAR_EXTDB_LIST_INFO,
++ false);
++ ret = hns_roce_cmq_send(hr_dev, &desc, 1);
++ if (ret)
++ ibdev_err(&hr_dev->ib_dev,
++ "failed to clear extended doorbell info, ret = %d.\n",
++ ret);
++
++ return ret;
++}
++
+ static int hns_roce_query_fw_ver(struct hns_roce_dev *hr_dev)
+ {
+ struct hns_roce_query_fw_info *resp;
+@@ -2732,6 +2748,11 @@ static int hns_roce_v2_init(struct hns_roce_dev *hr_dev)
+ struct hns_roce_v2_priv *priv = hr_dev->priv;
+ int ret;
+
++ /* The hns ROCEE requires the extdb info to be cleared before using */
++ ret = hns_roce_clear_extdb_list_info(hr_dev);
++ if (ret)
++ return ret;
++
+ ret = get_hem_table(hr_dev);
+ if (ret)
+ return ret;
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+index a2100a629859..028bc41cb45c 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+@@ -248,6 +248,7 @@ enum hns_roce_opcode_type {
+ HNS_ROCE_OPC_CLR_SCCC = 0x8509,
+ HNS_ROCE_OPC_QUERY_SCCC = 0x850a,
+ HNS_ROCE_OPC_RESET_SCCC = 0x850b,
++ HNS_ROCE_OPC_CLEAR_EXTDB_LIST_INFO = 0x850d,
+ HNS_ROCE_OPC_QUERY_VF_RES = 0x850e,
+ HNS_ROCE_OPC_CFG_GMV_TBL = 0x850f,
+ HNS_ROCE_OPC_CFG_GMV_BT = 0x8510,
+--
+2.30.2
+
--- /dev/null
+From b2a9a6f0b6cb4346c9574f48fb33c3cedf327c0a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 18:10:12 +0800
+Subject: RDMA/hns: Fix uninitialized variable
+
+From: Yixing Liu <liuyixing1@huawei.com>
+
+[ Upstream commit 2a38c0f10e6d7d28e06ff1eb1f350804c4850275 ]
+
+A random value will be returned if the condition below is not met, so it
+needs to be initialized.
+
+Fixes: 9ea9a53ea93b ("RDMA/hns: Add mapped page count checking for MTR")
+Link: https://lore.kernel.org/r/1624011020-16992-3-git-send-email-liweihang@huawei.com
+Signed-off-by: Yixing Liu <liuyixing1@huawei.com>
+Signed-off-by: Weihang Li <liweihang@huawei.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_mr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
+index 79b3c3023fe7..b8454dcb0318 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
++++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
+@@ -776,7 +776,7 @@ int hns_roce_mtr_map(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
+ struct ib_device *ibdev = &hr_dev->ib_dev;
+ struct hns_roce_buf_region *r;
+ unsigned int i, mapped_cnt;
+- int ret;
++ int ret = 0;
+
+ /*
+ * Only use the first page address as root ba when hopnum is 0, this
+--
+2.30.2
+
--- /dev/null
+From dd48a5caead0afdfa61d496a4b40c868f3518c7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 17:29:53 +0800
+Subject: RDMA/hns: Fix wrong timer context buffer page size
+
+From: Xi Wang <wangxi11@huawei.com>
+
+[ Upstream commit 5e6370d7cc75134b0eb5b15916aab40b628db9e1 ]
+
+The HEM page size for QPC timer and CQC timer is always 4K and there's no
+need to calculate a different size by the hns driver, otherwise the ROCEE
+may access an invalid address.
+
+Fixes: 719d13415f59 ("RDMA/hns: Remove duplicated hem page size config code")
+Link: https://lore.kernel.org/r/1621589395-2435-4-git-send-email-liweihang@huawei.com
+Signed-off-by: Xi Wang <wangxi11@huawei.com>
+Signed-off-by: Weihang Li <liweihang@huawei.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 49bb4f51466c..d7289b6587f1 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -2092,12 +2092,6 @@ static void set_hem_page_size(struct hns_roce_dev *hr_dev)
+ calc_pg_sz(caps->max_cqes, caps->cqe_sz, caps->cqe_hop_num,
+ 1, &caps->cqe_buf_pg_sz, &caps->cqe_ba_pg_sz, HEM_TYPE_CQE);
+
+- if (caps->cqc_timer_entry_sz)
+- calc_pg_sz(caps->num_cqc_timer, caps->cqc_timer_entry_sz,
+- caps->cqc_timer_hop_num, caps->cqc_timer_bt_num,
+- &caps->cqc_timer_buf_pg_sz,
+- &caps->cqc_timer_ba_pg_sz, HEM_TYPE_CQC_TIMER);
+-
+ /* SRQ */
+ if (caps->flags & HNS_ROCE_CAP_FLAG_SRQ) {
+ calc_pg_sz(caps->num_srqs, caps->srqc_entry_sz,
+--
+2.30.2
+
--- /dev/null
+From b0c61374bd37c08d48bc95fcb072ee2d64f76f00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 18:10:11 +0800
+Subject: RDMA/hns: Force rewrite inline flag of WQE
+
+From: Lang Cheng <chenglang@huawei.com>
+
+[ Upstream commit e13026578b727becf2614f34a4f35e7f0ed21be1 ]
+
+When a non-inline WR reuses a WQE that was used for inline last time, the
+remaining inline flag should be cleared.
+
+Fixes: 62490fd5a865 ("RDMA/hns: Avoid unnecessary memset on WQEs in post_send")
+Link: https://lore.kernel.org/r/1624011020-16992-2-git-send-email-liweihang@huawei.com
+Signed-off-by: Lang Cheng <chenglang@huawei.com>
+Signed-off-by: Weihang Li <liweihang@huawei.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 78f3e05cc1f5..cd58becf1baf 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -274,8 +274,6 @@ static int set_rc_inl(struct hns_roce_qp *qp, const struct ib_send_wr *wr,
+
+ dseg += sizeof(struct hns_roce_v2_rc_send_wqe);
+
+- roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_INLINE_S, 1);
+-
+ if (msg_len <= HNS_ROCE_V2_MAX_RC_INL_INN_SZ) {
+ roce_set_bit(rc_sq_wqe->byte_20,
+ V2_RC_SEND_WQE_BYTE_20_INL_TYPE_S, 0);
+@@ -320,6 +318,8 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr,
+ V2_RC_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_S,
+ (*sge_ind) & (qp->sge.sge_cnt - 1));
+
++ roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_INLINE_S,
++ !!(wr->send_flags & IB_SEND_INLINE));
+ if (wr->send_flags & IB_SEND_INLINE)
+ return set_rc_inl(qp, wr, rc_sq_wqe, sge_ind);
+
+--
+2.30.2
+
--- /dev/null
+From 11f60b63a02bb885c4dfe6a23c6c84fec57f76ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Apr 2021 15:12:30 +0800
+Subject: RDMA/hns: Remove the condition of light load for posting DWQE
+
+From: Yixian Liu <liuyixian@huawei.com>
+
+[ Upstream commit 591f762b2750c628df9412d1c795b56e83a34b3e ]
+
+Even in the case of heavy load, direct WQE can still be posted. The
+hardware will decide whether to drop the DWQE or not. Thus, the limit
+needs to be removed.
+
+Fixes: 01584a5edcc4 ("RDMA/hns: Add support of direct wqe")
+Link: https://lore.kernel.org/r/1619593950-29414-1-git-send-email-liweihang@huawei.com
+Signed-off-by: Yixian Liu <liuyixian@huawei.com>
+Signed-off-by: Weihang Li <liweihang@huawei.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 7652dafe32ec..49bb4f51466c 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -791,8 +791,7 @@ out:
+ qp->sq.head += nreq;
+ qp->next_sge = sge_idx;
+
+- if (nreq == 1 && qp->sq.head == qp->sq.tail + 1 &&
+- (qp->en_flags & HNS_ROCE_QP_CAP_DIRECT_WQE))
++ if (nreq == 1 && (qp->en_flags & HNS_ROCE_QP_CAP_DIRECT_WQE))
+ write_dwqe(hr_dev, qp, wqe);
+ else
+ update_sq_db(hr_dev, qp);
+--
+2.30.2
+
--- /dev/null
+From 931962668271b2e592196f8b449f9f79b674a44c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Jun 2021 11:51:38 +0300
+Subject: RDMA/mlx5: Don't access NULL-cleared mpi pointer
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit 4a754d7637026b42b0c9ba5787ad5ee3bc2ff77f ]
+
+The "dev->port[i].mp.mpi" is set to NULL during mlx5_ib_unbind_slave_port()
+execution, however that field is needed to add device to unaffiliated list.
+
+Such flow causes to the following kernel panic while unloading mlx5_ib
+module in multi-port mode, hence the device should be added to the list
+prior to unbind call.
+
+ RPC: Unregistered rdma transport module.
+ RPC: Unregistered rdma backchannel transport module.
+ BUG: kernel NULL pointer dereference, address: 0000000000000000
+ #PF: supervisor write access in kernel mode
+ #PF: error_code(0x0002) - not-present page
+ PGD 0 P4D 0
+ Oops: 0002 [#1] SMP NOPTI
+ CPU: 4 PID: 1904 Comm: modprobe Not tainted 5.13.0-rc7_for_upstream_min_debug_2021_06_24_12_08 #1
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
+ RIP: 0010:mlx5_ib_cleanup_multiport_master+0x18b/0x2d0 [mlx5_ib]
+ Code: 00 04 0f 85 c4 00 00 00 48 89 df e8 ef fa ff ff 48 8b 83 40 0d 00 00 48 8b 15 b9 e8 05 00 4a 8b 44 28 20 48 89 05 ad e8 05 00 <48> c7 00 d0 57 c5 a0 48 89 50 08 48 89 02 39 ab 88 0a 00 00 0f 86
+ RSP: 0018:ffff888116ee3df8 EFLAGS: 00010296
+ RAX: 0000000000000000 RBX: ffff8881154f6000 RCX: 0000000000000080
+ RDX: ffffffffa0c557d0 RSI: ffff88810b69d200 RDI: 000000000002d8a0
+ RBP: 0000000000000002 R08: ffff888110780408 R09: 0000000000000000
+ R10: ffff88812452e1c0 R11: fffffffffff7e028 R12: 0000000000000000
+ R13: 0000000000000080 R14: ffff888102c58000 R15: 0000000000000000
+ FS: 00007f884393a740(0000) GS:ffff8882f5a00000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 0000000000000000 CR3: 00000001249f6004 CR4: 0000000000370ea0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+ Call Trace:
+ mlx5_ib_stage_init_cleanup+0x16/0xd0 [mlx5_ib]
+ __mlx5_ib_remove+0x33/0x90 [mlx5_ib]
+ mlx5r_remove+0x22/0x30 [mlx5_ib]
+ auxiliary_bus_remove+0x18/0x30
+ __device_release_driver+0x177/0x220
+ driver_detach+0xc4/0x100
+ bus_remove_driver+0x58/0xd0
+ auxiliary_driver_unregister+0x12/0x20
+ mlx5_ib_cleanup+0x13/0x897 [mlx5_ib]
+ __x64_sys_delete_module+0x154/0x230
+ ? exit_to_user_mode_prepare+0x104/0x140
+ do_syscall_64+0x3f/0x80
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+ RIP: 0033:0x7f8842e095c7
+ Code: 73 01 c3 48 8b 0d d9 48 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 b8 b0 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d a9 48 2c 00 f7 d8 64 89 01 48
+ RSP: 002b:00007ffc68f6e758 EFLAGS: 00000206 ORIG_RAX: 00000000000000b0
+ RAX: ffffffffffffffda RBX: 00005638207929c0 RCX: 00007f8842e095c7
+ RDX: 0000000000000000 RSI: 0000000000000800 RDI: 0000563820792a28
+ RBP: 00005638207929c0 R08: 00007ffc68f6d701 R09: 0000000000000000
+ R10: 00007f8842e82880 R11: 0000000000000206 R12: 0000563820792a28
+ R13: 0000000000000001 R14: 0000563820792a28 R15: 00007ffc68f6fb40
+ Modules linked in: xt_MASQUERADE nf_conntrack_netlink nfnetlink iptable_nat xt_addrtype xt_conntrack nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 br_netfilter overlay rdma_ucm ib_iser libiscsi scsi_transport_iscsi rdma_cm iw_cm ib_ipoib ib_cm ib_umad mlx5_ib(-) mlx4_ib ib_uverbs ib_core mlx4_en mlx4_core mlx5_core ptp pps_core [last unloaded: rpcrdma]
+ CR2: 0000000000000000
+ ---[ end trace a0bb7e20804e9e9b ]---
+
+Fixes: 7ce6095e3bff ("RDMA/mlx5: Don't add slave port to unaffiliated list")
+Link: https://lore.kernel.org/r/899ac1b33a995be5ec0e16a4765c4e43c2b1ba5b.1624956444.git.leonro@nvidia.com
+Reviewed-by: Itay Aveksis <itayav@nvidia.com>
+Reviewed-by: Maor Gottlieb <maorg@nvidia.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/main.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
+index 3f347515a38d..cca7296b12d0 100644
+--- a/drivers/infiniband/hw/mlx5/main.c
++++ b/drivers/infiniband/hw/mlx5/main.c
+@@ -3325,9 +3325,10 @@ static void mlx5_ib_cleanup_multiport_master(struct mlx5_ib_dev *dev)
+ } else {
+ mlx5_ib_dbg(dev, "unbinding port_num: %u\n",
+ i + 1);
+- mlx5_ib_unbind_slave_port(dev, dev->port[i].mp.mpi);
+ list_add_tail(&dev->port[i].mp.mpi->list,
+ &mlx5_ib_unaffiliated_port_list);
++ mlx5_ib_unbind_slave_port(dev,
++ dev->port[i].mp.mpi);
+ }
+ }
+ }
+--
+2.30.2
+
--- /dev/null
+From 77b577e1379b46bfb6a5b59a5e20f7aa1ecd5996 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 May 2021 19:04:44 +0300
+Subject: RDMA/mlx5: Don't add slave port to unaffiliated list
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit 7ce6095e3bff8e20ce018b050960b527e298f7df ]
+
+The mlx5_ib_bind_slave_port() doesn't remove multiport device from the
+unaffiliated list, but mlx5_ib_unbind_slave_port() did it. This unbalanced
+flow caused to the situation where mlx5_ib_unaffiliated_port_list was
+changed during iteration.
+
+Fixes: 32f69e4be269 ("{net, IB}/mlx5: Manage port association for multiport RoCE")
+Link: https://lore.kernel.org/r/2726e6603b1e6ecfe76aa5a12a063af72173bcf7.1622477058.git.leonro@nvidia.com
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
+index 644d5d0ac544..3f347515a38d 100644
+--- a/drivers/infiniband/hw/mlx5/main.c
++++ b/drivers/infiniband/hw/mlx5/main.c
+@@ -3178,8 +3178,6 @@ static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev,
+
+ port->mp.mpi = NULL;
+
+- list_add_tail(&mpi->list, &mlx5_ib_unaffiliated_port_list);
+-
+ spin_unlock(&port->mp.mpi_lock);
+
+ err = mlx5_nic_vport_unaffiliate_multiport(mpi->mdev);
+@@ -3328,6 +3326,8 @@ static void mlx5_ib_cleanup_multiport_master(struct mlx5_ib_dev *dev)
+ mlx5_ib_dbg(dev, "unbinding port_num: %u\n",
+ i + 1);
+ mlx5_ib_unbind_slave_port(dev, dev->port[i].mp.mpi);
++ list_add_tail(&dev->port[i].mp.mpi->list,
++ &mlx5_ib_unaffiliated_port_list);
+ }
+ }
+ }
+--
+2.30.2
+
--- /dev/null
+From 6f2c49517daf7b60c9a3f321727965309baa62a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 May 2021 13:30:17 +0200
+Subject: RDMA/rtrs-clt: Check if the queue_depth has changed during a
+ reconnection
+
+From: Md Haris Iqbal <haris.iqbal@cloud.ionos.com>
+
+[ Upstream commit 5b73b799c25c68a4703cd6c5ac4518006d9865b8 ]
+
+The queue_depth is a module parameter for rtrs_server. It is used on the
+client side to determing the queue_depth of the request queue for the RNBD
+virtual block device.
+
+During a reconnection event for an already mapped device, in case the
+rtrs_server module queue_depth has changed, fail the reconnect attempt.
+
+Also stop further auto reconnection attempts. A manual reconnect via
+sysfs has to be triggerred.
+
+Fixes: 6a98d71daea18 ("RDMA/rtrs: client: main functionality")
+Link: https://lore.kernel.org/r/20210528113018.52290-20-jinpu.wang@ionos.com
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Signed-off-by: Gioh Kim <gi-oh.kim@ionos.com>
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-clt.c | 19 +++++++++++++++----
+ 1 file changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+index a563c9b9d52c..d4d54189c878 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+@@ -1791,7 +1791,19 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con,
+ queue_depth);
+ return -ECONNRESET;
+ }
+- if (!sess->rbufs || sess->queue_depth < queue_depth) {
++ if (sess->queue_depth > 0 && queue_depth != sess->queue_depth) {
++ rtrs_err(clt, "Error: queue depth changed\n");
++
++ /*
++ * Stop any more reconnection attempts
++ */
++ sess->reconnect_attempts = -1;
++ rtrs_err(clt,
++ "Disabling auto-reconnect. Trigger a manual reconnect after issue is resolved\n");
++ return -ECONNRESET;
++ }
++
++ if (!sess->rbufs) {
+ kfree(sess->rbufs);
+ sess->rbufs = kcalloc(queue_depth, sizeof(*sess->rbufs),
+ GFP_KERNEL);
+@@ -1805,7 +1817,7 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con,
+ sess->chunk_size = sess->max_io_size + sess->max_hdr_size;
+
+ /*
+- * Global queue depth and IO size is always a minimum.
++ * Global IO size is always a minimum.
+ * If while a reconnection server sends us a value a bit
+ * higher - client does not care and uses cached minimum.
+ *
+@@ -1813,8 +1825,7 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con,
+ * connections in parallel, use lock.
+ */
+ mutex_lock(&clt->paths_mutex);
+- clt->queue_depth = min_not_zero(sess->queue_depth,
+- clt->queue_depth);
++ clt->queue_depth = sess->queue_depth;
+ clt->max_io_size = min_not_zero(sess->max_io_size,
+ clt->max_io_size);
+ mutex_unlock(&clt->paths_mutex);
+--
+2.30.2
+
--- /dev/null
+From 00c3968a10816269aa7ae3e22ef9ca9aed509d37 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 May 2021 13:30:10 +0200
+Subject: RDMA/rtrs-clt: Check state of the rtrs_clt_sess before reading its
+ stats
+
+From: Md Haris Iqbal <haris.iqbal@cloud.ionos.com>
+
+[ Upstream commit 41db63a7efe1c8c2dd282c1849a6ebfbbedbaf67 ]
+
+When get_next_path_min_inflight is called to select the next path, it
+iterates over the list of available rtrs_clt_sess (paths). It then reads
+the number of inflight IOs for that path to select one which has the least
+inflight IO.
+
+But it may so happen that rtrs_clt_sess (path) is no longer in the
+connected state because closing or error recovery paths can change the status
+of the rtrs_clt_Sess.
+
+For example, the client sent the heart-beat and did not get the
+response, it would change the session status and stop IO processing.
+The added checking of this patch can prevent accessing the broken path
+and generating duplicated error messages.
+
+It is ok if the status is changed after checking the status because
+the error recovery path does not free memory and only tries to
+reconnection. And also it is ok if the session is closed after checking
+the status because closing the session changes the session status and
+flush all IO beforing free memory. If the session is being accessed for
+IO processing, the closing session will wait.
+
+Fixes: 6a98d71daea18 ("RDMA/rtrs: client: main functionality")
+Link: https://lore.kernel.org/r/20210528113018.52290-13-jinpu.wang@ionos.com
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Reviewed-by: Gioh Kim <gi-oh.kim@ionos.com>
+Signed-off-by: Gioh Kim <gi-oh.kim@ionos.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-clt.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+index 0a794d748a7a..a563c9b9d52c 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+@@ -814,6 +814,9 @@ static struct rtrs_clt_sess *get_next_path_min_inflight(struct path_it *it)
+ int inflight;
+
+ list_for_each_entry_rcu(sess, &clt->paths_list, s.entry) {
++ if (unlikely(READ_ONCE(sess->state) != RTRS_CLT_CONNECTED))
++ continue;
++
+ if (unlikely(!list_empty(raw_cpu_ptr(sess->mp_skip_entry))))
+ continue;
+
+--
+2.30.2
+
--- /dev/null
+From 3c569ef9db53433a71fe187647d9fda87ec64768 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 May 2021 13:30:18 +0200
+Subject: RDMA/rtrs-clt: Fix memory leak of not-freed sess->stats and
+ stats->pcpu_stats
+
+From: Gioh Kim <gi-oh.kim@cloud.ionos.com>
+
+[ Upstream commit 7ecd7e290bee0ab9cf75b79a367a4cc113cf8292 ]
+
+sess->stats and sess->stats->pcpu_stats objects are freed
+when sysfs entry is removed. If something wrong happens and
+session is closed before sysfs entry is created,
+sess->stats and sess->stats->pcpu_stats objects are not freed.
+
+This patch adds freeing of them at three places:
+1. When client uses wrong address and session creation fails.
+2. When client fails to create a sysfs entry.
+3. When client adds wrong address via sysfs add_path.
+
+Fixes: 215378b838df0 ("RDMA/rtrs: client: sysfs interface functions")
+Link: https://lore.kernel.org/r/20210528113018.52290-21-jinpu.wang@ionos.com
+Signed-off-by: Gioh Kim <gi-oh.kim@ionos.com>
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-clt.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+index d4d54189c878..ed7cf25a65c2 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+@@ -2776,6 +2776,8 @@ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops,
+ if (err) {
+ list_del_rcu(&sess->s.entry);
+ rtrs_clt_close_conns(sess, true);
++ free_percpu(sess->stats->pcpu_stats);
++ kfree(sess->stats);
+ free_sess(sess);
+ goto close_all_sess;
+ }
+@@ -2784,6 +2786,8 @@ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops,
+ if (err) {
+ list_del_rcu(&sess->s.entry);
+ rtrs_clt_close_conns(sess, true);
++ free_percpu(sess->stats->pcpu_stats);
++ kfree(sess->stats);
+ free_sess(sess);
+ goto close_all_sess;
+ }
+@@ -3066,6 +3070,8 @@ int rtrs_clt_create_path_from_sysfs(struct rtrs_clt *clt,
+ close_sess:
+ rtrs_clt_remove_path_from_arr(sess);
+ rtrs_clt_close_conns(sess, true);
++ free_percpu(sess->stats->pcpu_stats);
++ kfree(sess->stats);
+ free_sess(sess);
+
+ return err;
+--
+2.30.2
+
--- /dev/null
+From e5803335e344f9ce1bb9181d80eac046ef1af691 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 May 2021 13:30:13 +0200
+Subject: RDMA/rtrs: Do not reset hb_missed_max after re-connection
+
+From: Gioh Kim <gi-oh.kim@cloud.ionos.com>
+
+[ Upstream commit 64bce1ee978491a779eb31098b21c57d4e431d6a ]
+
+When re-connecting, it resets hb_missed_max to 0.
+Before the first re-connecting, client will trigger re-connection
+when it gets hb-ack more than 5 times. But after the first
+re-connecting, clients will do re-connection whenever it does
+not get hb-ack because hb_missed_max is 0.
+
+There is no need to reset hb_missed_max when re-connecting.
+hb_missed_max should be kept until closing the session.
+
+Fixes: c0894b3ea69d3 ("RDMA/rtrs: core: lib functions shared between client and server modules")
+Link: https://lore.kernel.org/r/20210528113018.52290-16-jinpu.wang@ionos.com
+Signed-off-by: Gioh Kim <gi-oh.kim@ionos.com>
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c
+index a7847282a2eb..4e602e40f623 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs.c
+@@ -376,7 +376,6 @@ void rtrs_stop_hb(struct rtrs_sess *sess)
+ {
+ cancel_delayed_work_sync(&sess->hb_dwork);
+ sess->hb_missed_cnt = 0;
+- sess->hb_missed_max = 0;
+ }
+ EXPORT_SYMBOL_GPL(rtrs_stop_hb);
+
+--
+2.30.2
+
--- /dev/null
+From 61a6ccc4bd9ecfd53ce3f2671aa7ad3003155850 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 May 2021 13:30:15 +0200
+Subject: RDMA/rtrs-srv: Fix memory leak of unfreed rtrs_srv_stats object
+
+From: Gioh Kim <gi-oh.kim@cloud.ionos.com>
+
+[ Upstream commit 2371c40354509746e4a4dad09a752e027a30f148 ]
+
+When closing a session, currently the rtrs_srv_stats object in the
+closing session is freed by kobject release. But if it failed
+to create a session by various reasons, it must free the rtrs_srv_stats
+object directly because kobject is not created yet.
+
+This problem is found by kmemleak as below:
+
+1. One client machine maps /dev/nullb0 with session name 'bla':
+root@test1:~# echo "sessname=bla path=ip:192.168.122.190 \
+device_path=/dev/nullb0" > /sys/devices/virtual/rnbd-client/ctl/map_device
+
+2. Another machine failed to create a session with the same name 'bla':
+root@test2:~# echo "sessname=bla path=ip:192.168.122.190 \
+device_path=/dev/nullb1" > /sys/devices/virtual/rnbd-client/ctl/map_device
+-bash: echo: write error: Connection reset by peer
+
+3. The kmemleak on server machine reported an error:
+unreferenced object 0xffff888033cdc800 (size 128):
+ comm "kworker/2:1", pid 83, jiffies 4295086585 (age 2508.680s)
+ hex dump (first 32 bytes):
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ backtrace:
+ [<00000000a72903b2>] __alloc_sess+0x1d4/0x1250 [rtrs_server]
+ [<00000000d1e5321e>] rtrs_srv_rdma_cm_handler+0xc31/0xde0 [rtrs_server]
+ [<00000000bb2f6e7e>] cma_ib_req_handler+0xdc5/0x2b50 [rdma_cm]
+ [<00000000e896235d>] cm_process_work+0x2d/0x100 [ib_cm]
+ [<00000000b6866c5f>] cm_req_handler+0x11bc/0x1c40 [ib_cm]
+ [<000000005f5dd9aa>] cm_work_handler+0xe65/0x3cf2 [ib_cm]
+ [<00000000610151e7>] process_one_work+0x4bc/0x980
+ [<00000000541e0f77>] worker_thread+0x78/0x5c0
+ [<00000000423898ca>] kthread+0x191/0x1e0
+ [<000000005a24b239>] ret_from_fork+0x3a/0x50
+
+Fixes: 39c2d639ca183 ("RDMA/rtrs-srv: Set .release function for rtrs srv device during device init")
+Link: https://lore.kernel.org/r/20210528113018.52290-18-jinpu.wang@ionos.com
+Signed-off-by: Gioh Kim <gi-oh.kim@ionos.com>
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-srv.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+index 0fa116cabc44..62f59ccb327c 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+@@ -1481,6 +1481,7 @@ static void free_sess(struct rtrs_srv_sess *sess)
+ kobject_del(&sess->kobj);
+ kobject_put(&sess->kobj);
+ } else {
++ kfree(sess->stats);
+ kfree(sess);
+ }
+ }
+--
+2.30.2
+
--- /dev/null
+From e0599a4de21dc0fafe3e43921c718c6546df1dbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 May 2021 13:30:16 +0200
+Subject: RDMA/rtrs-srv: Fix memory leak when having multiple sessions
+
+From: Jack Wang <jinpu.wang@cloud.ionos.com>
+
+[ Upstream commit 6bb97a2c1aa5278a30d49abb6186d50c34c207e2 ]
+
+Gioh notice memory leak below
+unreferenced object 0xffff8880acda2000 (size 2048):
+ comm "kworker/4:1", pid 77, jiffies 4295062871 (age 1270.730s)
+ hex dump (first 32 bytes):
+ 00 20 da ac 80 88 ff ff 00 20 da ac 80 88 ff ff . ....... ......
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ backtrace:
+ [<00000000e85d85b5>] rtrs_srv_rdma_cm_handler+0x8e5/0xa90 [rtrs_server]
+ [<00000000e31a988a>] cma_ib_req_handler+0xdc5/0x2b50 [rdma_cm]
+ [<000000000eb02c5b>] cm_process_work+0x2d/0x100 [ib_cm]
+ [<00000000e1650ca9>] cm_req_handler+0x11bc/0x1c40 [ib_cm]
+ [<000000009c28818b>] cm_work_handler+0xe65/0x3cf2 [ib_cm]
+ [<000000002b53eaa1>] process_one_work+0x4bc/0x980
+ [<00000000da3499fb>] worker_thread+0x78/0x5c0
+ [<00000000167127a4>] kthread+0x191/0x1e0
+ [<0000000060802104>] ret_from_fork+0x3a/0x50
+unreferenced object 0xffff88806d595d90 (size 8):
+ comm "kworker/4:1H", pid 131, jiffies 4295062972 (age 1269.720s)
+ hex dump (first 8 bytes):
+ 62 6c 61 00 6b 6b 6b a5 bla.kkk.
+ backtrace:
+ [<000000004447d253>] kstrdup+0x2e/0x60
+ [<0000000047259793>] kobject_set_name_vargs+0x2f/0xb0
+ [<00000000c2ee3bc8>] dev_set_name+0xab/0xe0
+ [<000000002b6bdfb1>] rtrs_srv_create_sess_files+0x260/0x290 [rtrs_server]
+ [<0000000075d87bd7>] rtrs_srv_info_req_done+0x71b/0x960 [rtrs_server]
+ [<00000000ccdf1bb5>] __ib_process_cq+0x94/0x100 [ib_core]
+ [<00000000cbcb60cb>] ib_cq_poll_work+0x32/0xc0 [ib_core]
+ [<000000002b53eaa1>] process_one_work+0x4bc/0x980
+ [<00000000da3499fb>] worker_thread+0x78/0x5c0
+ [<00000000167127a4>] kthread+0x191/0x1e0
+ [<0000000060802104>] ret_from_fork+0x3a/0x50
+unreferenced object 0xffff88806d6bb100 (size 256):
+ comm "kworker/4:1H", pid 131, jiffies 4295062972 (age 1269.720s)
+ hex dump (first 32 bytes):
+ 00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00 .....N..........
+ ff ff ff ff ff ff ff ff 00 59 4d 86 ff ff ff ff .........YM.....
+ backtrace:
+ [<00000000a18a11e4>] device_add+0x74d/0xa00
+ [<00000000a915b95f>] rtrs_srv_create_sess_files.cold+0x49/0x1fe [rtrs_server]
+ [<0000000075d87bd7>] rtrs_srv_info_req_done+0x71b/0x960 [rtrs_server]
+ [<00000000ccdf1bb5>] __ib_process_cq+0x94/0x100 [ib_core]
+ [<00000000cbcb60cb>] ib_cq_poll_work+0x32/0xc0 [ib_core]
+ [<000000002b53eaa1>] process_one_work+0x4bc/0x980
+ [<00000000da3499fb>] worker_thread+0x78/0x5c0
+ [<00000000167127a4>] kthread+0x191/0x1e0
+ [<0000000060802104>] ret_from_fork+0x3a/0x50
+
+The problem is we increase device refcount by get_device in process_info_req
+for each path, but only does put_deice for last path, which lead to
+memory leak.
+
+To fix it, it also calls put_device when dev_ref is not 0.
+
+Fixes: e2853c49477d1 ("RDMA/rtrs-srv-sysfs: fix missing put_device")
+Link: https://lore.kernel.org/r/20210528113018.52290-19-jinpu.wang@ionos.com
+Signed-off-by: Gioh Kim <gi-oh.kim@ionos.com>
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c b/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c
+index a9288175fbb5..20efd44297fb 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c
+@@ -208,6 +208,7 @@ rtrs_srv_destroy_once_sysfs_root_folders(struct rtrs_srv_sess *sess)
+ device_del(&srv->dev);
+ put_device(&srv->dev);
+ } else {
++ put_device(&srv->dev);
+ mutex_unlock(&srv->paths_mutex);
+ }
+ }
+--
+2.30.2
+
--- /dev/null
+From bc9ab396f27c4f67e7265e481cbacde810af8b3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 11:03:33 +0200
+Subject: RDMA/rtrs-srv: Set minimal max_send_wr and max_recv_wr
+
+From: Jack Wang <jinpu.wang@cloud.ionos.com>
+
+[ Upstream commit 5e91eabf66c854f16ca2e954e5c68939bc81601e ]
+
+Currently rtrs when create_qp use a coarse numbers (bigger in general),
+which leads to hardware create more resources which only waste memory with
+no benefits.
+
+For max_send_wr, we don't really need alway max_qp_wr size when creating
+qp, reduce it to cq_size.
+
+For max_recv_wr, cq_size is enough.
+
+With the patch when sess_queue_depth=128, per session (2 paths) memory
+consumption reduced from 188 MB to 65MB
+
+When always_invalidate is enabled, we need send more wr, so treat it
+special.
+
+Fixes: 9cb837480424e ("RDMA/rtrs: server: main functionality")
+Link: https://lore.kernel.org/r/20210614090337.29557-2-jinpu.wang@ionos.com
+Signed-off-by: Jack Wang <jinpu.wang@cloud.ionos.com>
+Reviewed-by: Md Haris Iqbal <haris.iqbal@cloud.ionos.com>
+Signed-off-by: Gioh Kim <gi-oh.kim@ionos.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-srv.c | 38 +++++++++++++++++---------
+ 1 file changed, 25 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+index 62f59ccb327c..8a9099684b8e 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+@@ -1605,7 +1605,7 @@ static int create_con(struct rtrs_srv_sess *sess,
+ struct rtrs_sess *s = &sess->s;
+ struct rtrs_srv_con *con;
+
+- u32 cq_size, wr_queue_size;
++ u32 cq_size, max_send_wr, max_recv_wr, wr_limit;
+ int err, cq_vector;
+
+ con = kzalloc(sizeof(*con), GFP_KERNEL);
+@@ -1626,30 +1626,42 @@ static int create_con(struct rtrs_srv_sess *sess,
+ * All receive and all send (each requiring invalidate)
+ * + 2 for drain and heartbeat
+ */
+- wr_queue_size = SERVICE_CON_QUEUE_DEPTH * 3 + 2;
+- cq_size = wr_queue_size;
++ max_send_wr = SERVICE_CON_QUEUE_DEPTH * 2 + 2;
++ max_recv_wr = SERVICE_CON_QUEUE_DEPTH + 2;
++ cq_size = max_send_wr + max_recv_wr;
+ } else {
+- /*
+- * If we have all receive requests posted and
+- * all write requests posted and each read request
+- * requires an invalidate request + drain
+- * and qp gets into error state.
+- */
+- cq_size = srv->queue_depth * 3 + 1;
+ /*
+ * In theory we might have queue_depth * 32
+ * outstanding requests if an unsafe global key is used
+ * and we have queue_depth read requests each consisting
+ * of 32 different addresses. div 3 for mlx5.
+ */
+- wr_queue_size = sess->s.dev->ib_dev->attrs.max_qp_wr / 3;
++ wr_limit = sess->s.dev->ib_dev->attrs.max_qp_wr / 3;
++ /* when always_invlaidate enalbed, we need linv+rinv+mr+imm */
++ if (always_invalidate)
++ max_send_wr =
++ min_t(int, wr_limit,
++ srv->queue_depth * (1 + 4) + 1);
++ else
++ max_send_wr =
++ min_t(int, wr_limit,
++ srv->queue_depth * (1 + 2) + 1);
++
++ max_recv_wr = srv->queue_depth + 1;
++ /*
++ * If we have all receive requests posted and
++ * all write requests posted and each read request
++ * requires an invalidate request + drain
++ * and qp gets into error state.
++ */
++ cq_size = max_send_wr + max_recv_wr;
+ }
+- atomic_set(&con->sq_wr_avail, wr_queue_size);
++ atomic_set(&con->sq_wr_avail, max_send_wr);
+ cq_vector = rtrs_srv_get_next_cq_vector(sess);
+
+ /* TODO: SOFTIRQ can be faster, but be careful with softirq context */
+ err = rtrs_cq_qp_create(&sess->s, &con->c, 1, cq_vector, cq_size,
+- wr_queue_size, wr_queue_size,
++ max_send_wr, max_recv_wr,
+ IB_POLL_WORKQUEUE);
+ if (err) {
+ rtrs_err(s, "rtrs_cq_qp_create(), err: %d\n", err);
+--
+2.30.2
+
--- /dev/null
+From 1a0444ca07c2fde3433c1a54e87536f87aa1684b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Jun 2021 12:01:12 +0300
+Subject: RDMA/rxe: Fix failure during driver load
+
+From: Kamal Heib <kamalheib1@gmail.com>
+
+[ Upstream commit 32a25f2ea690dfaace19f7a3a916f5d7e1ddafe8 ]
+
+To avoid the following failure when trying to load the rdma_rxe module
+while IPv6 is disabled, add a check for EAFNOSUPPORT and ignore the
+failure, also delete the needless debug print from rxe_setup_udp_tunnel().
+
+$ modprobe rdma_rxe
+modprobe: ERROR: could not insert 'rdma_rxe': Operation not permitted
+
+Fixes: dfdd6158ca2c ("IB/rxe: Fix kernel panic in udp_setup_tunnel")
+Link: https://lore.kernel.org/r/20210603090112.36341-1-kamalheib1@gmail.com
+Reported-by: Yi Zhang <yi.zhang@redhat.com>
+Signed-off-by: Kamal Heib <kamalheib1@gmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_net.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c
+index 01662727dca0..fc1ba4904279 100644
+--- a/drivers/infiniband/sw/rxe/rxe_net.c
++++ b/drivers/infiniband/sw/rxe/rxe_net.c
+@@ -207,10 +207,8 @@ static struct socket *rxe_setup_udp_tunnel(struct net *net, __be16 port,
+
+ /* Create UDP socket */
+ err = udp_sock_create(net, &udp_cfg, &sock);
+- if (err < 0) {
+- pr_err("failed to create udp socket. err = %d\n", err);
++ if (err < 0)
+ return ERR_PTR(err);
+- }
+
+ tnl_cfg.encap_type = 1;
+ tnl_cfg.encap_rcv = rxe_udp_encap_recv;
+@@ -619,6 +617,12 @@ static int rxe_net_ipv6_init(void)
+
+ recv_sockets.sk6 = rxe_setup_udp_tunnel(&init_net,
+ htons(ROCE_V2_UDP_DPORT), true);
++ if (PTR_ERR(recv_sockets.sk6) == -EAFNOSUPPORT) {
++ recv_sockets.sk6 = NULL;
++ pr_warn("IPv6 is not supported, can not create a UDPv6 socket\n");
++ return 0;
++ }
++
+ if (IS_ERR(recv_sockets.sk6)) {
+ recv_sockets.sk6 = NULL;
+ pr_err("Failed to create IPv6 UDP tunnel\n");
+--
+2.30.2
+
--- /dev/null
+From 8c45a8af17bcff87af2c55cd4468c575c2760117 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Jun 2021 18:05:59 -0500
+Subject: RDMA/rxe: Fix qp reference counting for atomic ops
+
+From: Bob Pearson <rpearsonhpe@gmail.com>
+
+[ Upstream commit 15ae1375ea91ae2dee6f12d71a79d8c0a10a30bf ]
+
+Currently the rdma_rxe driver attempts to protect atomic responder
+resources by taking a reference to the qp which is only freed when the
+resource is recycled for a new read or atomic operation. This means that
+in normal circumstances there is almost always an extra qp reference once
+an atomic operation has been executed which prevents cleaning up the qp
+and associated pd and cqs when the qp is destroyed.
+
+This patch removes the call to rxe_add_ref() in send_atomic_ack() and the
+call to rxe_drop_ref() in free_rd_atomic_resource(). If the qp is
+destroyed while a peer is retrying an atomic op it will cause the
+operation to fail which is acceptable.
+
+Link: https://lore.kernel.org/r/20210604230558.4812-1-rpearsonhpe@gmail.com
+Reported-by: Zhu Yanjun <zyjzyj2000@gmail.com>
+Fixes: 86af61764151 ("IB/rxe: remove unnecessary skb_clone")
+Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_qp.c | 1 -
+ drivers/infiniband/sw/rxe/rxe_resp.c | 2 --
+ 2 files changed, 3 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index b0f350d674fd..93a41ebda1a8 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -136,7 +136,6 @@ static void free_rd_atomic_resources(struct rxe_qp *qp)
+ void free_rd_atomic_resource(struct rxe_qp *qp, struct resp_res *res)
+ {
+ if (res->type == RXE_ATOMIC_MASK) {
+- rxe_drop_ref(qp);
+ kfree_skb(res->atomic.skb);
+ } else if (res->type == RXE_READ_MASK) {
+ if (res->read.mr)
+diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
+index 2b220659bddb..39dc39be586e 100644
+--- a/drivers/infiniband/sw/rxe/rxe_resp.c
++++ b/drivers/infiniband/sw/rxe/rxe_resp.c
+@@ -966,8 +966,6 @@ static int send_atomic_ack(struct rxe_qp *qp, struct rxe_pkt_info *pkt,
+ goto out;
+ }
+
+- rxe_add_ref(qp);
+-
+ res = &qp->resp.resources[qp->resp.res_head];
+ free_rd_atomic_resource(qp, res);
+ rxe_advance_resp_resource(qp);
+--
+2.30.2
+
--- /dev/null
+From 03a76211ff0f0d5d952002bf661d1766e5a8c2f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 May 2021 21:12:10 -0700
+Subject: RDMA/srp: Fix a recently introduced memory leak
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 7ec2e27a3afff64c96bfe7a77685c33619db84be ]
+
+Only allocate a memory registration list if it will be used and if it will
+be freed.
+
+Link: https://lore.kernel.org/r/20210524041211.9480-5-bvanassche@acm.org
+Reviewed-by: Max Gurtovoy <maxg@mellanox.com>
+Fixes: f273ad4f8d90 ("RDMA/srp: Remove support for FMR memory registration")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/srp/ib_srp.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
+index 31f8aa2c40ed..168705c88e2f 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.c
++++ b/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -998,7 +998,6 @@ static int srp_alloc_req_data(struct srp_rdma_ch *ch)
+ struct srp_device *srp_dev = target->srp_host->srp_dev;
+ struct ib_device *ibdev = srp_dev->dev;
+ struct srp_request *req;
+- void *mr_list;
+ dma_addr_t dma_addr;
+ int i, ret = -ENOMEM;
+
+@@ -1009,12 +1008,12 @@ static int srp_alloc_req_data(struct srp_rdma_ch *ch)
+
+ for (i = 0; i < target->req_ring_size; ++i) {
+ req = &ch->req_ring[i];
+- mr_list = kmalloc_array(target->mr_per_cmd, sizeof(void *),
+- GFP_KERNEL);
+- if (!mr_list)
+- goto out;
+- if (srp_dev->use_fast_reg)
+- req->fr_list = mr_list;
++ if (srp_dev->use_fast_reg) {
++ req->fr_list = kmalloc_array(target->mr_per_cmd,
++ sizeof(void *), GFP_KERNEL);
++ if (!req->fr_list)
++ goto out;
++ }
+ req->indirect_desc = kmalloc(target->indirect_size, GFP_KERNEL);
+ if (!req->indirect_desc)
+ goto out;
+--
+2.30.2
+
--- /dev/null
+From 944754ace37ecb2a6aa43d967e5e1e898d8d5027 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 May 2021 17:14:27 -0700
+Subject: regulator: bd71815: add select to fix build
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 5ba3747dbc9ade2d22a8f5bff3c928cb41d35030 ]
+
+Mend the Kconfig for REGULATOR_BD71815 to prevent build errors:
+
+riscv32-linux-ld: drivers/regulator/bd71815-regulator.o: in function `.L0 ':
+regulator.c:289: undefined reference to `rohm_regulator_set_dvs_levels'
+riscv32-linux-ld: drivers/regulator/bd71815-regulator.c:370: undefined reference to `rohm_regulator_set_dvs_levels'
+
+Fixes: 1aad39001e85 ("regulator: Support ROHM BD71815 regulators")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
+Cc: Lee Jones <lee.jones@linaro.org>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Liam Girdwood <lgirdwood@gmail.com>
+Reviewed-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
+Link: https://lore.kernel.org/r/20210523001427.13500-1-rdunlap@infradead.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
+index 3e7a38525cb3..fc9e8f589d16 100644
+--- a/drivers/regulator/Kconfig
++++ b/drivers/regulator/Kconfig
+@@ -207,6 +207,7 @@ config REGULATOR_BD70528
+ config REGULATOR_BD71815
+ tristate "ROHM BD71815 Power Regulator"
+ depends on MFD_ROHM_BD71828
++ select REGULATOR_ROHM
+ help
+ This driver supports voltage regulators on ROHM BD71815 PMIC.
+ This will enable support for the software controllable buck
+--
+2.30.2
+
--- /dev/null
+From af07bc19b09dd9f676cc6466066c178998906b90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Jun 2021 08:43:04 +0300
+Subject: regulator: bd9576: Fix the driver name in id table
+
+From: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
+
+[ Upstream commit e71e7d3df7eb712fc29b609bd712a63d60b81b5f ]
+
+Driver name was changed in MFD cell:
+https://lore.kernel.org/lkml/560b9748094392493ebf7af11b6cc558776c4fd5.1613031055.git.matti.vaittinen@fi.rohmeurope.com/
+Fix the ID table to match this.
+
+Fixes: b1b3ced38979 ("mfd: Support ROHM BD9576MUF and BD9573MUF")
+Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
+Link: https://lore.kernel.org/r/e0483149333626b3bea298f305cf2809429d1822.1622628334.git.matti.vaittinen@fi.rohmeurope.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/bd9576-regulator.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/regulator/bd9576-regulator.c b/drivers/regulator/bd9576-regulator.c
+index 204a2da054f5..cdf30481a582 100644
+--- a/drivers/regulator/bd9576-regulator.c
++++ b/drivers/regulator/bd9576-regulator.c
+@@ -312,8 +312,8 @@ static int bd957x_probe(struct platform_device *pdev)
+ }
+
+ static const struct platform_device_id bd957x_pmic_id[] = {
+- { "bd9573-pmic", ROHM_CHIP_TYPE_BD9573 },
+- { "bd9576-pmic", ROHM_CHIP_TYPE_BD9576 },
++ { "bd9573-regulator", ROHM_CHIP_TYPE_BD9573 },
++ { "bd9576-regulator", ROHM_CHIP_TYPE_BD9576 },
+ { },
+ };
+ MODULE_DEVICE_TABLE(platform, bd957x_pmic_id);
+--
+2.30.2
+
--- /dev/null
+From c7ef170170cb8eac41e93e21dfff4082d4cc06c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 22:14:11 +0800
+Subject: regulator: da9052: Ensure enough delay time for .set_voltage_time_sel
+
+From: Axel Lin <axel.lin@ingics.com>
+
+[ Upstream commit a336dc8f683e5be794186b5643cd34cb28dd2c53 ]
+
+Use DIV_ROUND_UP to prevent truncation by integer division issue.
+This ensures we return enough delay time.
+
+Also fix returning negative value when new_sel < old_sel.
+
+Signed-off-by: Axel Lin <axel.lin@ingics.com>
+Link: https://lore.kernel.org/r/20210618141412.4014912-1-axel.lin@ingics.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/da9052-regulator.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c
+index e18d291c7f21..23fa429ebe76 100644
+--- a/drivers/regulator/da9052-regulator.c
++++ b/drivers/regulator/da9052-regulator.c
+@@ -250,7 +250,8 @@ static int da9052_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
+ case DA9052_ID_BUCK3:
+ case DA9052_ID_LDO2:
+ case DA9052_ID_LDO3:
+- ret = (new_sel - old_sel) * info->step_uV / 6250;
++ ret = DIV_ROUND_UP(abs(new_sel - old_sel) * info->step_uV,
++ 6250);
+ break;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 60e87061ae2b87b71e6c5e80808dfbca4a6a6964 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 20:40:16 +0800
+Subject: regulator: fan53555: Fix missing slew_reg/mask/shift settings for
+ FAN53526
+
+From: Axel Lin <axel.lin@ingics.com>
+
+[ Upstream commit 30b38b805b36c03db3703ef62397111c783b5f3b ]
+
+The di->slew_reg/di->slew_mask/di->slew_shift was not set in current code,
+fix it.
+
+Fixes: f2a9eb975ab2 ("regulator: fan53555: Add support for FAN53526")
+Signed-off-by: Axel Lin <axel.lin@ingics.com>
+Link: https://lore.kernel.org/r/20210525124017.2550029-1-axel.lin@ingics.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/fan53555.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c
+index 26f06f685b1b..b2ee38c5b573 100644
+--- a/drivers/regulator/fan53555.c
++++ b/drivers/regulator/fan53555.c
+@@ -293,6 +293,9 @@ static int fan53526_voltages_setup_fairchild(struct fan53555_device_info *di)
+ return -EINVAL;
+ }
+
++ di->slew_reg = FAN53555_CONTROL;
++ di->slew_mask = CTL_SLEW_MASK;
++ di->slew_shift = CTL_SLEW_SHIFT;
+ di->vsel_count = FAN53526_NVOLTAGES;
+
+ return 0;
+--
+2.30.2
+
--- /dev/null
+From c539771cd53879d64b3bddbe7c26fdc428c098a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 22:29:07 +0800
+Subject: regulator: fan53880: Fix vsel_mask setting for FAN53880_BUCK
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Axel Lin <axel.lin@ingics.com>
+
+[ Upstream commit 2e11737a772b95c6587df73f216eec1762431432 ]
+
+According to the datasheet:
+REGISTER DETAILS − 0x02 BUCK, BUCK_OUT is BIT0 ~ BIT7.
+
+So vsel_mask for FAN53880_BUCK should be 0xFF.
+
+Fixes: e6dea51e2d41 ("regulator: fan53880: Add initial support")
+Signed-off-by: Axel Lin <axel.lin@ingics.com>
+Link: https://lore.kernel.org/r/20210607142907.1599905-1-axel.lin@ingics.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/fan53880.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/regulator/fan53880.c b/drivers/regulator/fan53880.c
+index 1684faf82ed2..94f02f3099dd 100644
+--- a/drivers/regulator/fan53880.c
++++ b/drivers/regulator/fan53880.c
+@@ -79,7 +79,7 @@ static const struct regulator_desc fan53880_regulators[] = {
+ .n_linear_ranges = 2,
+ .n_voltages = 0xf8,
+ .vsel_reg = FAN53880_BUCKVOUT,
+- .vsel_mask = 0x7f,
++ .vsel_mask = 0xff,
+ .enable_reg = FAN53880_ENABLE,
+ .enable_mask = 0x10,
+ .enable_time = 480,
+--
+2.30.2
+
--- /dev/null
+From 9f576451b38aa5ff5a473190f4a63284219b6475 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Jun 2021 20:34:23 +0800
+Subject: regulator: hi6421v600: Fix setting idle mode
+
+From: Axel Lin <axel.lin@ingics.com>
+
+[ Upstream commit 57c045bc727001c43b6a65adb0418aa7b3e6dbd0 ]
+
+commit db27f8294cd7 changed eco_mode << (ffs(sreg->eco_mode_mask) - 1)
+to sreg->eco_mode_mask << (ffs(sreg->eco_mode_mask) - 1) which is wrong.
+Fix it by simply set val = sreg->eco_mode_mask.
+
+In additional, sreg->eco_mode_mask can be 0 (LDO3, LDO33, LDO34).
+Return -EINVAL if idle mode is not supported when sreg->eco_mode_mask is 0.
+
+While at it, also use unsigned int for reg_val/val which is the expected
+type for regmap_read and regmap_update_bits.
+
+Fixes: db27f8294cd7 ("staging: regulator: hi6421v600-regulator: use shorter names for OF properties")
+Signed-off-by: Axel Lin <axel.lin@ingics.com>
+Link: https://lore.kernel.org/r/20210619123423.4091429-1-axel.lin@ingics.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/hi6421v600-regulator.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/regulator/hi6421v600-regulator.c b/drivers/regulator/hi6421v600-regulator.c
+index d6340bb49296..d1e9406b2e3e 100644
+--- a/drivers/regulator/hi6421v600-regulator.c
++++ b/drivers/regulator/hi6421v600-regulator.c
+@@ -129,7 +129,7 @@ static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev)
+ {
+ struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev);
+ struct hi6421_spmi_pmic *pmic = sreg->pmic;
+- u32 reg_val;
++ unsigned int reg_val;
+
+ regmap_read(pmic->regmap, rdev->desc->enable_reg, ®_val);
+
+@@ -144,14 +144,17 @@ static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev,
+ {
+ struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev);
+ struct hi6421_spmi_pmic *pmic = sreg->pmic;
+- u32 val;
++ unsigned int val;
+
+ switch (mode) {
+ case REGULATOR_MODE_NORMAL:
+ val = 0;
+ break;
+ case REGULATOR_MODE_IDLE:
+- val = sreg->eco_mode_mask << (ffs(sreg->eco_mode_mask) - 1);
++ if (!sreg->eco_mode_mask)
++ return -EINVAL;
++
++ val = sreg->eco_mode_mask;
+ break;
+ default:
+ return -EINVAL;
+--
+2.30.2
+
--- /dev/null
+From d099528688c856a3e228e9f94b38d18e21d0d6f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Jun 2021 21:27:15 +0800
+Subject: regulator: hi655x: Fix pass wrong pointer to config.driver_data
+
+From: Axel Lin <axel.lin@ingics.com>
+
+[ Upstream commit 61eb1b24f9e4f4e0725aa5f8164a932c933f3339 ]
+
+Current code sets config.driver_data to a zero initialized regulator
+which is obviously wrong. Fix it.
+
+Fixes: 4618119b9be5 ("regulator: hi655x: enable regulator for hi655x PMIC")
+Signed-off-by: Axel Lin <axel.lin@ingics.com>
+Link: https://lore.kernel.org/r/20210620132715.60215-1-axel.lin@ingics.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/hi655x-regulator.c | 16 +++++-----------
+ 1 file changed, 5 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/regulator/hi655x-regulator.c b/drivers/regulator/hi655x-regulator.c
+index 68cdb173196d..556bb73f3329 100644
+--- a/drivers/regulator/hi655x-regulator.c
++++ b/drivers/regulator/hi655x-regulator.c
+@@ -72,7 +72,7 @@ enum hi655x_regulator_id {
+ static int hi655x_is_enabled(struct regulator_dev *rdev)
+ {
+ unsigned int value = 0;
+- struct hi655x_regulator *regulator = rdev_get_drvdata(rdev);
++ const struct hi655x_regulator *regulator = rdev_get_drvdata(rdev);
+
+ regmap_read(rdev->regmap, regulator->status_reg, &value);
+ return (value & rdev->desc->enable_mask);
+@@ -80,7 +80,7 @@ static int hi655x_is_enabled(struct regulator_dev *rdev)
+
+ static int hi655x_disable(struct regulator_dev *rdev)
+ {
+- struct hi655x_regulator *regulator = rdev_get_drvdata(rdev);
++ const struct hi655x_regulator *regulator = rdev_get_drvdata(rdev);
+
+ return regmap_write(rdev->regmap, regulator->disable_reg,
+ rdev->desc->enable_mask);
+@@ -169,7 +169,6 @@ static const struct hi655x_regulator regulators[] = {
+ static int hi655x_regulator_probe(struct platform_device *pdev)
+ {
+ unsigned int i;
+- struct hi655x_regulator *regulator;
+ struct hi655x_pmic *pmic;
+ struct regulator_config config = { };
+ struct regulator_dev *rdev;
+@@ -180,22 +179,17 @@ static int hi655x_regulator_probe(struct platform_device *pdev)
+ return -ENODEV;
+ }
+
+- regulator = devm_kzalloc(&pdev->dev, sizeof(*regulator), GFP_KERNEL);
+- if (!regulator)
+- return -ENOMEM;
+-
+- platform_set_drvdata(pdev, regulator);
+-
+ config.dev = pdev->dev.parent;
+ config.regmap = pmic->regmap;
+- config.driver_data = regulator;
+ for (i = 0; i < ARRAY_SIZE(regulators); i++) {
++ config.driver_data = (void *) ®ulators[i];
++
+ rdev = devm_regulator_register(&pdev->dev,
+ ®ulators[i].rdesc,
+ &config);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "failed to register regulator %s\n",
+- regulator->rdesc.name);
++ regulators[i].rdesc.name);
+ return PTR_ERR(rdev);
+ }
+ }
+--
+2.30.2
+
--- /dev/null
+From b234761dfe76d9f1f08aef8cf14e095d5bfc92ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jun 2021 21:29:34 +0800
+Subject: regulator: mt6315: Fix checking return value of
+ devm_regmap_init_spmi_ext
+
+From: Axel Lin <axel.lin@ingics.com>
+
+[ Upstream commit 70d654ea3de937d7754c107bb8eeb20e30262c89 ]
+
+devm_regmap_init_spmi_ext() returns ERR_PTR() on error.
+
+Signed-off-by: Axel Lin <axel.lin@ingics.com>
+Link: https://lore.kernel.org/r/20210615132934.3453965-1-axel.lin@ingics.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/mt6315-regulator.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/regulator/mt6315-regulator.c b/drivers/regulator/mt6315-regulator.c
+index 6b8be52c3772..7514702f78cf 100644
+--- a/drivers/regulator/mt6315-regulator.c
++++ b/drivers/regulator/mt6315-regulator.c
+@@ -223,8 +223,8 @@ static int mt6315_regulator_probe(struct spmi_device *pdev)
+ int i;
+
+ regmap = devm_regmap_init_spmi_ext(pdev, &mt6315_regmap_config);
+- if (!regmap)
+- return -ENODEV;
++ if (IS_ERR(regmap))
++ return PTR_ERR(regmap);
+
+ chip = devm_kzalloc(dev, sizeof(struct mt6315_chip), GFP_KERNEL);
+ if (!chip)
+--
+2.30.2
+
--- /dev/null
+From 666826154787fe91efc424387730743f326801a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 12:56:09 +0800
+Subject: regulator: mt6358: Fix vdram2 .vsel_mask
+
+From: Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
+
+[ Upstream commit 50c9462edcbf900f3d5097ca3ad60171346124de ]
+
+The valid vsel value are 0 and 12, so the .vsel_mask should be 0xf.
+
+Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
+Reviewed-by: Axel Lin <axel.lin@ingics.com>
+Link: https://lore.kernel.org/r/1624424169-510-1-git-send-email-hsin-hsiung.wang@mediatek.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/mt6358-regulator.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c
+index 13cb6ac9a892..1d4eb5dc4fac 100644
+--- a/drivers/regulator/mt6358-regulator.c
++++ b/drivers/regulator/mt6358-regulator.c
+@@ -457,7 +457,7 @@ static struct mt6358_regulator_info mt6358_regulators[] = {
+ MT6358_REG_FIXED("ldo_vaud28", VAUD28,
+ MT6358_LDO_VAUD28_CON0, 0, 2800000),
+ MT6358_LDO("ldo_vdram2", VDRAM2, vdram2_voltages, vdram2_idx,
+- MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0x10, 0),
++ MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0xf, 0),
+ MT6358_LDO("ldo_vsim1", VSIM1, vsim_voltages, vsim_idx,
+ MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00, 8),
+ MT6358_LDO("ldo_vibr", VIBR, vibr_voltages, vibr_idx,
+--
+2.30.2
+
--- /dev/null
+From 6cad5e040e3b87b74227eed7d952038cc9371beb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jun 2021 10:47:11 +0530
+Subject: regulator: qcom-rpmh: Add terminator at the end of
+ pm7325x_vreg_data[] array
+
+From: Bhupesh Sharma <bhupesh.sharma@linaro.org>
+
+[ Upstream commit f26cdadad729743888eb4ac2c17eac3cf845b493 ]
+
+Add missing terminator(s) at the end of pm7325x_vreg_data[]
+array instances.
+
+Fixes: c4e5aa3dbee5 ("regulator: qcom-rpmh: Add PM7325/PMR735A regulator support")
+Cc: Mark Brown <broonie@kernel.org>
+Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Signed-off-by: Bhupesh Sharma <bhupesh.sharma@linaro.org>
+Link: https://lore.kernel.org/r/20210617051712.345372-5-bhupesh.sharma@linaro.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/qcom-rpmh-regulator.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c
+index 22fec370fa61..ac79dc34f9e8 100644
+--- a/drivers/regulator/qcom-rpmh-regulator.c
++++ b/drivers/regulator/qcom-rpmh-regulator.c
+@@ -1070,6 +1070,7 @@ static const struct rpmh_vreg_init_data pm7325_vreg_data[] = {
+ RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"),
+ RPMH_VREG("ldo18", "ldo%s18", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"),
+ RPMH_VREG("ldo19", "ldo%s19", &pmic5_pldo_lv, "vdd-l11-l17-l18-l19"),
++ {}
+ };
+
+ static const struct rpmh_vreg_init_data pmr735a_vreg_data[] = {
+@@ -1083,6 +1084,7 @@ static const struct rpmh_vreg_init_data pmr735a_vreg_data[] = {
+ RPMH_VREG("ldo5", "ldo%s5", &pmic5_nldo, "vdd-l5-l6"),
+ RPMH_VREG("ldo6", "ldo%s6", &pmic5_nldo, "vdd-l5-l6"),
+ RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, "vdd-l7-bob"),
++ {}
+ };
+
+ static int rpmh_regulator_probe(struct platform_device *pdev)
+--
+2.30.2
+
--- /dev/null
+From edaf755d19190f6e493a53344e5c3e253a662fbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 May 2021 11:53:18 +0800
+Subject: regulator: uniphier: Add missing MODULE_DEVICE_TABLE
+
+From: Zou Wei <zou_wei@huawei.com>
+
+[ Upstream commit d019f38a1af3c6015cde6a47951a3ec43beeed80 ]
+
+This patch adds missing MODULE_DEVICE_TABLE definition which generates
+correct modalias for automatic loading of this driver when it is built
+as an external module.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Zou Wei <zou_wei@huawei.com>
+Link: https://lore.kernel.org/r/1620705198-104566-1-git-send-email-zou_wei@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/uniphier-regulator.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/regulator/uniphier-regulator.c b/drivers/regulator/uniphier-regulator.c
+index 2e02e26b516c..e75b0973e325 100644
+--- a/drivers/regulator/uniphier-regulator.c
++++ b/drivers/regulator/uniphier-regulator.c
+@@ -201,6 +201,7 @@ static const struct of_device_id uniphier_regulator_match[] = {
+ },
+ { /* Sentinel */ },
+ };
++MODULE_DEVICE_TABLE(of, uniphier_regulator_match);
+
+ static struct platform_driver uniphier_regulator_driver = {
+ .probe = uniphier_regulator_probe,
+--
+2.30.2
+
--- /dev/null
+From 3dbe5f81565f4934fb81492a38ba9328338f1635 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Jun 2021 10:27:45 +0200
+Subject: Revert "be2net: disable bh with spin_lock in be_process_mcc"
+
+From: Petr Oros <poros@redhat.com>
+
+[ Upstream commit d6765985a42a660f078896d5c5b27f97c580a490 ]
+
+Patch was based on wrong presumption that be_poll can be called only
+from bh context. It reintroducing old regression (also reverted) and
+causing deadlock when we use netconsole with benet in bonding.
+
+Old revert: commit 072a9c486004 ("netpoll: revert 6bdb7fe3104 and fix
+be_poll() instead")
+
+[ 331.269715] bond0: (slave enp0s7f0): Releasing backup interface
+[ 331.270121] CPU: 4 PID: 1479 Comm: ifenslave Not tainted 5.13.0-rc7+ #2
+[ 331.270122] Call Trace:
+[ 331.270122] [c00000001789f200] [c0000000008c505c] dump_stack+0x100/0x174 (unreliable)
+[ 331.270124] [c00000001789f240] [c008000001238b9c] be_poll+0x64/0xe90 [be2net]
+[ 331.270125] [c00000001789f330] [c000000000d1e6e4] netpoll_poll_dev+0x174/0x3d0
+[ 331.270127] [c00000001789f400] [c008000001bc167c] bond_poll_controller+0xb4/0x130 [bonding]
+[ 331.270128] [c00000001789f450] [c000000000d1e624] netpoll_poll_dev+0xb4/0x3d0
+[ 331.270129] [c00000001789f520] [c000000000d1ed88] netpoll_send_skb+0x448/0x470
+[ 331.270130] [c00000001789f5d0] [c0080000011f14f8] write_msg+0x180/0x1b0 [netconsole]
+[ 331.270131] [c00000001789f640] [c000000000230c0c] console_unlock+0x54c/0x790
+[ 331.270132] [c00000001789f7b0] [c000000000233098] vprintk_emit+0x2d8/0x450
+[ 331.270133] [c00000001789f810] [c000000000234758] vprintk+0xc8/0x270
+[ 331.270134] [c00000001789f850] [c000000000233c28] printk+0x40/0x54
+[ 331.270135] [c00000001789f870] [c000000000ccf908] __netdev_printk+0x150/0x198
+[ 331.270136] [c00000001789f910] [c000000000ccfdb4] netdev_info+0x68/0x94
+[ 331.270137] [c00000001789f950] [c008000001bcbd70] __bond_release_one+0x188/0x6b0 [bonding]
+[ 331.270138] [c00000001789faa0] [c008000001bcc6f4] bond_do_ioctl+0x42c/0x490 [bonding]
+[ 331.270139] [c00000001789fb60] [c000000000d0d17c] dev_ifsioc+0x17c/0x400
+[ 331.270140] [c00000001789fbc0] [c000000000d0db70] dev_ioctl+0x390/0x890
+[ 331.270141] [c00000001789fc10] [c000000000c7c76c] sock_do_ioctl+0xac/0x1b0
+[ 331.270142] [c00000001789fc90] [c000000000c7ffac] sock_ioctl+0x31c/0x6e0
+[ 331.270143] [c00000001789fd60] [c0000000005b9728] sys_ioctl+0xf8/0x150
+[ 331.270145] [c00000001789fdb0] [c0000000000336c0] system_call_exception+0x160/0x2f0
+[ 331.270146] [c00000001789fe10] [c00000000000d35c] system_call_common+0xec/0x278
+[ 331.270147] --- interrupt: c00 at 0x7fffa6c6ec00
+[ 331.270147] NIP: 00007fffa6c6ec00 LR: 0000000105c4185c CTR: 0000000000000000
+[ 331.270148] REGS: c00000001789fe80 TRAP: 0c00 Not tainted (5.13.0-rc7+)
+[ 331.270148] MSR: 800000000280f033 <SF,VEC,VSX,EE,PR,FP,ME,IR,DR,RI,LE> CR: 28000428 XER: 00000000
+[ 331.270155] IRQMASK: 0
+[ 331.270156] GPR00: 0000000000000036 00007fffd494d5b0 00007fffa6d57100 0000000000000003
+[ 331.270158] GPR04: 0000000000008991 00007fffd494d6d0 0000000000000008 00007fffd494f28c
+[ 331.270161] GPR08: 0000000000000003 0000000000000000 0000000000000000 0000000000000000
+[ 331.270164] GPR12: 0000000000000000 00007fffa6dfa220 0000000000000000 0000000000000000
+[ 331.270167] GPR16: 0000000105c44880 0000000000000000 0000000105c60088 0000000105c60318
+[ 331.270170] GPR20: 0000000105c602c0 0000000105c44560 0000000000000000 0000000000000000
+[ 331.270172] GPR24: 00007fffd494dc50 00007fffd494d6a8 0000000105c60008 00007fffd494d6d0
+[ 331.270175] GPR28: 00007fffd494f27e 0000000105c6026c 00007fffd494f284 0000000000000000
+[ 331.270178] NIP [00007fffa6c6ec00] 0x7fffa6c6ec00
+[ 331.270178] LR [0000000105c4185c] 0x105c4185c
+[ 331.270179] --- interrupt: c00
+
+This reverts commit d0d006a43e9a7a796f6f178839c92fcc222c564d.
+
+Fixes: d0d006a43e9a7a ("be2net: disable bh with spin_lock in be_process_mcc")
+Signed-off-by: Petr Oros <poros@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 6 ++++--
+ drivers/net/ethernet/emulex/benet/be_main.c | 2 ++
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 701c12c9e033..649c5c429bd7 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -550,7 +550,7 @@ int be_process_mcc(struct be_adapter *adapter)
+ int num = 0, status = 0;
+ struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
+
+- spin_lock_bh(&adapter->mcc_cq_lock);
++ spin_lock(&adapter->mcc_cq_lock);
+
+ while ((compl = be_mcc_compl_get(adapter))) {
+ if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
+@@ -566,7 +566,7 @@ int be_process_mcc(struct be_adapter *adapter)
+ if (num)
+ be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num);
+
+- spin_unlock_bh(&adapter->mcc_cq_lock);
++ spin_unlock(&adapter->mcc_cq_lock);
+ return status;
+ }
+
+@@ -581,7 +581,9 @@ static int be_mcc_wait_compl(struct be_adapter *adapter)
+ if (be_check_error(adapter, BE_ERROR_ANY))
+ return -EIO;
+
++ local_bh_disable();
+ status = be_process_mcc(adapter);
++ local_bh_enable();
+
+ if (atomic_read(&mcc_obj->q.used) == 0)
+ break;
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 7968568bbe21..361c1c87c183 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -5501,7 +5501,9 @@ static void be_worker(struct work_struct *work)
+ * mcc completions
+ */
+ if (!netif_running(adapter->netdev)) {
++ local_bh_disable();
+ be_process_mcc(adapter);
++ local_bh_enable();
+ goto reschedule;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 9b79d9c6bde2d15c22de2cb5b873b349d3a6fbac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Jun 2021 13:27:05 +0300
+Subject: Revert "IB/cm: Mark stale CM id's whenever the mad agent was
+ unregistered"
+
+From: Mark Zhang <markzhang@nvidia.com>
+
+[ Upstream commit 3595c398f6dbab79a38550ff26104c6ec1035cd3 ]
+
+This reverts commit 9db0ff53cb9b43ed75bacd42a89c1a0ab048b2b0, which wasn't
+a full fix and still causes to the following panic:
+
+panic @ time 1605623870.843, thread 0xfffffeb63b552000: vm_fault_lookup: fault on nofault entry, addr: 0xfffffe811a94e000
+ time = 1605623870
+ cpuid = 9, TSC = 0xb7937acc1b6
+ Panic occurred in module kernel loaded at 0xffffffff80200000:Stack: --------------------------------------------------
+ kernel:vm_fault+0x19da
+ kernel:vm_fault_trap+0x6e
+ kernel:trap_pfault+0x1f1
+ kernel:trap+0x31e
+ kernel:cm_destroy_id+0x38c
+ kernel:rdma_destroy_id+0x127
+ kernel:sdp_shutdown_task+0x3ae
+ kernel:taskqueue_run_locked+0x10b
+ kernel:taskqueue_thread_loop+0x87
+ kernel:fork_exit+0x83
+
+Link: https://lore.kernel.org/r/4346449a7cdacc7a4eedc89cb1b42d8434ec9814.1622629024.git.leonro@nvidia.com
+Signed-off-by: Mark Zhang <markzhang@nvidia.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cm.c | 123 ++++-------------------------------
+ 1 file changed, 14 insertions(+), 109 deletions(-)
+
+diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
+index 94613275edcc..162261fd16d6 100644
+--- a/drivers/infiniband/core/cm.c
++++ b/drivers/infiniband/core/cm.c
+@@ -121,8 +121,6 @@ static struct ib_cm {
+ __be32 random_id_operand;
+ struct list_head timewait_list;
+ struct workqueue_struct *wq;
+- /* Sync on cm change port state */
+- spinlock_t state_lock;
+ } cm;
+
+ /* Counter indexes ordered by attribute ID */
+@@ -203,8 +201,6 @@ struct cm_port {
+ struct cm_device *cm_dev;
+ struct ib_mad_agent *mad_agent;
+ u32 port_num;
+- struct list_head cm_priv_prim_list;
+- struct list_head cm_priv_altr_list;
+ struct cm_counter_group counter_group[CM_COUNTER_GROUPS];
+ };
+
+@@ -285,12 +281,6 @@ struct cm_id_private {
+ u8 service_timeout;
+ u8 target_ack_delay;
+
+- struct list_head prim_list;
+- struct list_head altr_list;
+- /* Indicates that the send port mad is registered and av is set */
+- int prim_send_port_not_ready;
+- int altr_send_port_not_ready;
+-
+ struct list_head work_list;
+ atomic_t work_count;
+
+@@ -310,47 +300,20 @@ static struct ib_mad_send_buf *cm_alloc_msg(struct cm_id_private *cm_id_priv)
+ struct ib_mad_agent *mad_agent;
+ struct ib_mad_send_buf *m;
+ struct ib_ah *ah;
+- struct cm_av *av;
+- unsigned long flags, flags2;
+- int ret = 0;
+
+- /* don't let the port to be released till the agent is down */
+- spin_lock_irqsave(&cm.state_lock, flags2);
+- spin_lock_irqsave(&cm.lock, flags);
+- if (!cm_id_priv->prim_send_port_not_ready)
+- av = &cm_id_priv->av;
+- else if (!cm_id_priv->altr_send_port_not_ready &&
+- (cm_id_priv->alt_av.port))
+- av = &cm_id_priv->alt_av;
+- else {
+- pr_info("%s: not valid CM id\n", __func__);
+- ret = -ENODEV;
+- spin_unlock_irqrestore(&cm.lock, flags);
+- goto out;
+- }
+- spin_unlock_irqrestore(&cm.lock, flags);
+- /* Make sure the port haven't released the mad yet */
+ mad_agent = cm_id_priv->av.port->mad_agent;
+- if (!mad_agent) {
+- pr_info("%s: not a valid MAD agent\n", __func__);
+- ret = -ENODEV;
+- goto out;
+- }
+- ah = rdma_create_ah(mad_agent->qp->pd, &av->ah_attr, 0);
+- if (IS_ERR(ah)) {
+- ret = PTR_ERR(ah);
+- goto out;
+- }
++ ah = rdma_create_ah(mad_agent->qp->pd, &cm_id_priv->av.ah_attr, 0);
++ if (IS_ERR(ah))
++ return (void *)ah;
+
+ m = ib_create_send_mad(mad_agent, cm_id_priv->id.remote_cm_qpn,
+- av->pkey_index,
++ cm_id_priv->av.pkey_index,
+ 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
+ GFP_ATOMIC,
+ IB_MGMT_BASE_VERSION);
+ if (IS_ERR(m)) {
+ rdma_destroy_ah(ah, 0);
+- ret = PTR_ERR(m);
+- goto out;
++ return m;
+ }
+
+ /* Timeout set by caller if response is expected. */
+@@ -358,13 +321,8 @@ static struct ib_mad_send_buf *cm_alloc_msg(struct cm_id_private *cm_id_priv)
+ m->retries = cm_id_priv->max_cm_retries;
+
+ refcount_inc(&cm_id_priv->refcount);
+- spin_unlock_irqrestore(&cm.state_lock, flags2);
+ m->context[0] = cm_id_priv;
+ return m;
+-
+-out:
+- spin_unlock_irqrestore(&cm.state_lock, flags2);
+- return ERR_PTR(ret);
+ }
+
+ static struct ib_mad_send_buf *
+@@ -517,21 +475,6 @@ static int cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc,
+ grh, &av->ah_attr);
+ }
+
+-static void add_cm_id_to_port_list(struct cm_id_private *cm_id_priv,
+- struct cm_av *av, struct cm_port *port)
+-{
+- unsigned long flags;
+-
+- spin_lock_irqsave(&cm.lock, flags);
+- if (&cm_id_priv->av == av)
+- list_add_tail(&cm_id_priv->prim_list, &port->cm_priv_prim_list);
+- else if (&cm_id_priv->alt_av == av)
+- list_add_tail(&cm_id_priv->altr_list, &port->cm_priv_altr_list);
+- else
+- WARN_ON(true);
+- spin_unlock_irqrestore(&cm.lock, flags);
+-}
+-
+ static struct cm_port *
+ get_cm_port_from_path(struct sa_path_rec *path, const struct ib_gid_attr *attr)
+ {
+@@ -575,8 +518,7 @@ get_cm_port_from_path(struct sa_path_rec *path, const struct ib_gid_attr *attr)
+
+ static int cm_init_av_by_path(struct sa_path_rec *path,
+ const struct ib_gid_attr *sgid_attr,
+- struct cm_av *av,
+- struct cm_id_private *cm_id_priv)
++ struct cm_av *av)
+ {
+ struct rdma_ah_attr new_ah_attr;
+ struct cm_device *cm_dev;
+@@ -610,7 +552,6 @@ static int cm_init_av_by_path(struct sa_path_rec *path,
+ return ret;
+
+ av->timeout = path->packet_life_time + 1;
+- add_cm_id_to_port_list(cm_id_priv, av, port);
+ rdma_move_ah_attr(&av->ah_attr, &new_ah_attr);
+ return 0;
+ }
+@@ -890,8 +831,6 @@ static struct cm_id_private *cm_alloc_id_priv(struct ib_device *device,
+ spin_lock_init(&cm_id_priv->lock);
+ init_completion(&cm_id_priv->comp);
+ INIT_LIST_HEAD(&cm_id_priv->work_list);
+- INIT_LIST_HEAD(&cm_id_priv->prim_list);
+- INIT_LIST_HEAD(&cm_id_priv->altr_list);
+ atomic_set(&cm_id_priv->work_count, -1);
+ refcount_set(&cm_id_priv->refcount, 1);
+
+@@ -1192,12 +1131,7 @@ retest:
+ kfree(cm_id_priv->timewait_info);
+ cm_id_priv->timewait_info = NULL;
+ }
+- if (!list_empty(&cm_id_priv->altr_list) &&
+- (!cm_id_priv->altr_send_port_not_ready))
+- list_del(&cm_id_priv->altr_list);
+- if (!list_empty(&cm_id_priv->prim_list) &&
+- (!cm_id_priv->prim_send_port_not_ready))
+- list_del(&cm_id_priv->prim_list);
++
+ WARN_ON(cm_id_priv->listen_sharecount);
+ WARN_ON(!RB_EMPTY_NODE(&cm_id_priv->service_node));
+ if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node))
+@@ -1565,13 +1499,12 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
+ }
+
+ ret = cm_init_av_by_path(param->primary_path,
+- param->ppath_sgid_attr, &cm_id_priv->av,
+- cm_id_priv);
++ param->ppath_sgid_attr, &cm_id_priv->av);
+ if (ret)
+ goto out;
+ if (param->alternate_path) {
+ ret = cm_init_av_by_path(param->alternate_path, NULL,
+- &cm_id_priv->alt_av, cm_id_priv);
++ &cm_id_priv->alt_av);
+ if (ret)
+ goto out;
+ }
+@@ -2203,8 +2136,7 @@ static int cm_req_handler(struct cm_work *work)
+ sa_path_set_dmac(&work->path[0],
+ cm_id_priv->av.ah_attr.roce.dmac);
+ work->path[0].hop_limit = grh->hop_limit;
+- ret = cm_init_av_by_path(&work->path[0], gid_attr, &cm_id_priv->av,
+- cm_id_priv);
++ ret = cm_init_av_by_path(&work->path[0], gid_attr, &cm_id_priv->av);
+ if (ret) {
+ int err;
+
+@@ -2223,7 +2155,7 @@ static int cm_req_handler(struct cm_work *work)
+ }
+ if (cm_req_has_alt_path(req_msg)) {
+ ret = cm_init_av_by_path(&work->path[1], NULL,
+- &cm_id_priv->alt_av, cm_id_priv);
++ &cm_id_priv->alt_av);
+ if (ret) {
+ ib_send_cm_rej(&cm_id_priv->id,
+ IB_CM_REJ_INVALID_ALT_GID,
+@@ -3404,7 +3336,7 @@ static int cm_lap_handler(struct cm_work *work)
+ goto unlock;
+
+ ret = cm_init_av_by_path(param->alternate_path, NULL,
+- &cm_id_priv->alt_av, cm_id_priv);
++ &cm_id_priv->alt_av);
+ if (ret)
+ goto unlock;
+
+@@ -3524,8 +3456,7 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id,
+
+ cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+ ret = cm_init_av_by_path(param->path, param->sgid_attr,
+- &cm_id_priv->av,
+- cm_id_priv);
++ &cm_id_priv->av);
+ if (ret)
+ return ret;
+
+@@ -4010,9 +3941,7 @@ out:
+ static int cm_migrate(struct ib_cm_id *cm_id)
+ {
+ struct cm_id_private *cm_id_priv;
+- struct cm_av tmp_av;
+ unsigned long flags;
+- int tmp_send_port_not_ready;
+ int ret = 0;
+
+ cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+@@ -4021,14 +3950,7 @@ static int cm_migrate(struct ib_cm_id *cm_id)
+ (cm_id->lap_state == IB_CM_LAP_UNINIT ||
+ cm_id->lap_state == IB_CM_LAP_IDLE)) {
+ cm_id->lap_state = IB_CM_LAP_IDLE;
+- /* Swap address vector */
+- tmp_av = cm_id_priv->av;
+ cm_id_priv->av = cm_id_priv->alt_av;
+- cm_id_priv->alt_av = tmp_av;
+- /* Swap port send ready state */
+- tmp_send_port_not_ready = cm_id_priv->prim_send_port_not_ready;
+- cm_id_priv->prim_send_port_not_ready = cm_id_priv->altr_send_port_not_ready;
+- cm_id_priv->altr_send_port_not_ready = tmp_send_port_not_ready;
+ } else
+ ret = -EINVAL;
+ spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+@@ -4403,9 +4325,6 @@ static int cm_add_one(struct ib_device *ib_device)
+ port->cm_dev = cm_dev;
+ port->port_num = i;
+
+- INIT_LIST_HEAD(&port->cm_priv_prim_list);
+- INIT_LIST_HEAD(&port->cm_priv_altr_list);
+-
+ ret = cm_create_port_fs(port);
+ if (ret)
+ goto error1;
+@@ -4469,8 +4388,6 @@ static void cm_remove_one(struct ib_device *ib_device, void *client_data)
+ {
+ struct cm_device *cm_dev = client_data;
+ struct cm_port *port;
+- struct cm_id_private *cm_id_priv;
+- struct ib_mad_agent *cur_mad_agent;
+ struct ib_port_modify port_modify = {
+ .clr_port_cap_mask = IB_PORT_CM_SUP
+ };
+@@ -4491,24 +4408,13 @@ static void cm_remove_one(struct ib_device *ib_device, void *client_data)
+
+ port = cm_dev->port[i-1];
+ ib_modify_port(ib_device, port->port_num, 0, &port_modify);
+- /* Mark all the cm_id's as not valid */
+- spin_lock_irq(&cm.lock);
+- list_for_each_entry(cm_id_priv, &port->cm_priv_altr_list, altr_list)
+- cm_id_priv->altr_send_port_not_ready = 1;
+- list_for_each_entry(cm_id_priv, &port->cm_priv_prim_list, prim_list)
+- cm_id_priv->prim_send_port_not_ready = 1;
+- spin_unlock_irq(&cm.lock);
+ /*
+ * We flush the queue here after the going_down set, this
+ * verify that no new works will be queued in the recv handler,
+ * after that we can call the unregister_mad_agent
+ */
+ flush_workqueue(cm.wq);
+- spin_lock_irq(&cm.state_lock);
+- cur_mad_agent = port->mad_agent;
+- port->mad_agent = NULL;
+- spin_unlock_irq(&cm.state_lock);
+- ib_unregister_mad_agent(cur_mad_agent);
++ ib_unregister_mad_agent(port->mad_agent);
+ cm_remove_port_fs(port);
+ kfree(port);
+ }
+@@ -4523,7 +4429,6 @@ static int __init ib_cm_init(void)
+ INIT_LIST_HEAD(&cm.device_list);
+ rwlock_init(&cm.device_lock);
+ spin_lock_init(&cm.lock);
+- spin_lock_init(&cm.state_lock);
+ cm.listen_service_table = RB_ROOT;
+ cm.listen_service_id = be64_to_cpu(IB_CM_ASSIGN_SERVICE_ID);
+ cm.remote_id_table = RB_ROOT;
+--
+2.30.2
+
--- /dev/null
+From 7923b9635d8afa3c7c375065cce8de69b9ea15ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 21:13:11 -0700
+Subject: Revert "ibmvnic: remove duplicate napi_schedule call in open
+ function"
+
+From: Dany Madden <drt@linux.ibm.com>
+
+[ Upstream commit 2ca220f92878470c6ba03f9946e412323093cc94 ]
+
+This reverts commit 7c451f3ef676c805a4b77a743a01a5c21a250a73.
+
+When a vnic interface is taken down and then up, connectivity is not
+restored. We bisected it to this commit. Reverting this commit until
+we can fully investigate the issue/benefit of the change.
+
+Fixes: 7c451f3ef676 ("ibmvnic: remove duplicate napi_schedule call in open function")
+Reported-by: Cristobal Forno <cforno12@linux.ibm.com>
+Reported-by: Abdul Haleem <abdhalee@in.ibm.com>
+Signed-off-by: Dany Madden <drt@linux.ibm.com>
+Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 4b4eccc496a8..8b2f6eb8eb21 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -1210,6 +1210,11 @@ static int __ibmvnic_open(struct net_device *netdev)
+
+ netif_tx_start_all_queues(netdev);
+
++ if (prev_state == VNIC_CLOSED) {
++ for (i = 0; i < adapter->req_rx_queues; i++)
++ napi_schedule(&adapter->napi[i]);
++ }
++
+ adapter->state = VNIC_OPEN;
+ return rc;
+ }
+--
+2.30.2
+
--- /dev/null
+From ccd877a57e10bcd12fda425ee8b81182a44de677 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 21:13:10 -0700
+Subject: Revert "ibmvnic: simplify reset_long_term_buff function"
+
+From: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+
+[ Upstream commit 0ec13aff058a82426c8d44b688c804cc4a5a0a3d ]
+
+This reverts commit 1c7d45e7b2c29080bf6c8cd0e213cc3cbb62a054.
+
+We tried to optimize the number of hcalls we send and skipped sending
+the REQUEST_MAP calls for some maps. However during resets, we need to
+resend all the maps to the VIOS since the VIOS does not remember the
+old values. In fact we may have failed over to a new VIOS which will
+not have any of the mappings.
+
+When we send packets with map ids the VIOS does not know about, it
+triggers a FATAL reset. While the client does recover from the FATAL
+error reset, we are seeing a large number of such resets. Handling
+FATAL resets is lot more unnecessary work than issuing a few more
+hcalls so revert the commit and resend the maps to the VIOS.
+
+Fixes: 1c7d45e7b2c ("ibmvnic: simplify reset_long_term_buff function")
+Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 46 ++++++++++++++++++++++++------
+ 1 file changed, 38 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 5788bb956d73..4b4eccc496a8 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -257,12 +257,40 @@ static void free_long_term_buff(struct ibmvnic_adapter *adapter,
+ dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr);
+ }
+
+-static int reset_long_term_buff(struct ibmvnic_long_term_buff *ltb)
++static int reset_long_term_buff(struct ibmvnic_adapter *adapter,
++ struct ibmvnic_long_term_buff *ltb)
+ {
+- if (!ltb->buff)
+- return -EINVAL;
++ struct device *dev = &adapter->vdev->dev;
++ int rc;
+
+ memset(ltb->buff, 0, ltb->size);
++
++ mutex_lock(&adapter->fw_lock);
++ adapter->fw_done_rc = 0;
++
++ reinit_completion(&adapter->fw_done);
++ rc = send_request_map(adapter, ltb->addr, ltb->size, ltb->map_id);
++ if (rc) {
++ mutex_unlock(&adapter->fw_lock);
++ return rc;
++ }
++
++ rc = ibmvnic_wait_for_completion(adapter, &adapter->fw_done, 10000);
++ if (rc) {
++ dev_info(dev,
++ "Reset failed, long term map request timed out or aborted\n");
++ mutex_unlock(&adapter->fw_lock);
++ return rc;
++ }
++
++ if (adapter->fw_done_rc) {
++ dev_info(dev,
++ "Reset failed, attempting to free and reallocate buffer\n");
++ free_long_term_buff(adapter, ltb);
++ mutex_unlock(&adapter->fw_lock);
++ return alloc_long_term_buff(adapter, ltb, ltb->size);
++ }
++ mutex_unlock(&adapter->fw_lock);
+ return 0;
+ }
+
+@@ -484,7 +512,8 @@ static int reset_rx_pools(struct ibmvnic_adapter *adapter)
+ rx_pool->size *
+ rx_pool->buff_size);
+ } else {
+- rc = reset_long_term_buff(&rx_pool->long_term_buff);
++ rc = reset_long_term_buff(adapter,
++ &rx_pool->long_term_buff);
+ }
+
+ if (rc)
+@@ -607,11 +636,12 @@ static int init_rx_pools(struct net_device *netdev)
+ return 0;
+ }
+
+-static int reset_one_tx_pool(struct ibmvnic_tx_pool *tx_pool)
++static int reset_one_tx_pool(struct ibmvnic_adapter *adapter,
++ struct ibmvnic_tx_pool *tx_pool)
+ {
+ int rc, i;
+
+- rc = reset_long_term_buff(&tx_pool->long_term_buff);
++ rc = reset_long_term_buff(adapter, &tx_pool->long_term_buff);
+ if (rc)
+ return rc;
+
+@@ -638,10 +668,10 @@ static int reset_tx_pools(struct ibmvnic_adapter *adapter)
+
+ tx_scrqs = adapter->num_active_tx_pools;
+ for (i = 0; i < tx_scrqs; i++) {
+- rc = reset_one_tx_pool(&adapter->tso_pool[i]);
++ rc = reset_one_tx_pool(adapter, &adapter->tso_pool[i]);
+ if (rc)
+ return rc;
+- rc = reset_one_tx_pool(&adapter->tx_pool[i]);
++ rc = reset_one_tx_pool(adapter, &adapter->tx_pool[i]);
+ if (rc)
+ return rc;
+ }
+--
+2.30.2
+
--- /dev/null
+From 84ce2bdc6d1648429e50e3d79cbf92f419eee027 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 May 2021 11:00:33 -0700
+Subject: rtnetlink: avoid RCU read lock when holding RTNL
+
+From: Cong Wang <cong.wang@bytedance.com>
+
+[ Upstream commit a100243d95a60d74ae9bb9df1f5f2192e9aed6a7 ]
+
+When we call af_ops->set_link_af() we hold a RCU read lock
+as we retrieve af_ops from the RCU protected list, but this
+is unnecessary because we already hold RTNL lock, which is
+the writer lock for protecting rtnl_af_ops, so it is safer
+than RCU read lock. Similar for af_ops->validate_link_af().
+
+This was not a problem until we begin to take mutex lock
+down the path of ->set_link_af() in __ipv6_dev_mc_dec()
+recently. We can just drop the RCU read lock there and
+assert RTNL lock.
+
+Reported-and-tested-by: syzbot+7d941e89dd48bcf42573@syzkaller.appspotmail.com
+Fixes: 63ed8de4be81 ("mld: add mc_lock for protecting per-interface mld data")
+Tested-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: Cong Wang <cong.wang@bytedance.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/rtnetlink.c | 26 +++++++-------------------
+ net/ipv4/devinet.c | 4 ++--
+ 2 files changed, 9 insertions(+), 21 deletions(-)
+
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
+index ec931b080156..c6e75bd0035d 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -543,7 +543,9 @@ static const struct rtnl_af_ops *rtnl_af_lookup(const int family)
+ {
+ const struct rtnl_af_ops *ops;
+
+- list_for_each_entry_rcu(ops, &rtnl_af_ops, list) {
++ ASSERT_RTNL();
++
++ list_for_each_entry(ops, &rtnl_af_ops, list) {
+ if (ops->family == family)
+ return ops;
+ }
+@@ -2274,27 +2276,18 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
+ nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) {
+ const struct rtnl_af_ops *af_ops;
+
+- rcu_read_lock();
+ af_ops = rtnl_af_lookup(nla_type(af));
+- if (!af_ops) {
+- rcu_read_unlock();
++ if (!af_ops)
+ return -EAFNOSUPPORT;
+- }
+
+- if (!af_ops->set_link_af) {
+- rcu_read_unlock();
++ if (!af_ops->set_link_af)
+ return -EOPNOTSUPP;
+- }
+
+ if (af_ops->validate_link_af) {
+ err = af_ops->validate_link_af(dev, af);
+- if (err < 0) {
+- rcu_read_unlock();
++ if (err < 0)
+ return err;
+- }
+ }
+-
+- rcu_read_unlock();
+ }
+ }
+
+@@ -2868,17 +2861,12 @@ static int do_setlink(const struct sk_buff *skb,
+ nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) {
+ const struct rtnl_af_ops *af_ops;
+
+- rcu_read_lock();
+-
+ BUG_ON(!(af_ops = rtnl_af_lookup(nla_type(af))));
+
+ err = af_ops->set_link_af(dev, af, extack);
+- if (err < 0) {
+- rcu_read_unlock();
++ if (err < 0)
+ goto errout;
+- }
+
+- rcu_read_unlock();
+ status |= DO_SETLINK_NOTIFY;
+ }
+ }
+diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
+index 1c6429c353a9..73721a4448bd 100644
+--- a/net/ipv4/devinet.c
++++ b/net/ipv4/devinet.c
+@@ -1955,7 +1955,7 @@ static int inet_validate_link_af(const struct net_device *dev,
+ struct nlattr *a, *tb[IFLA_INET_MAX+1];
+ int err, rem;
+
+- if (dev && !__in_dev_get_rcu(dev))
++ if (dev && !__in_dev_get_rtnl(dev))
+ return -EAFNOSUPPORT;
+
+ err = nla_parse_nested_deprecated(tb, IFLA_INET_MAX, nla,
+@@ -1981,7 +1981,7 @@ static int inet_validate_link_af(const struct net_device *dev,
+ static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla,
+ struct netlink_ext_ack *extack)
+ {
+- struct in_device *in_dev = __in_dev_get_rcu(dev);
++ struct in_device *in_dev = __in_dev_get_rtnl(dev);
+ struct nlattr *a, *tb[IFLA_INET_MAX+1];
+ int rem;
+
+--
+2.30.2
+
--- /dev/null
+From b71630e70d54645216c2de4ab85298ab0f93b634 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Apr 2021 09:32:52 +0800
+Subject: rtw88: 8822c: fix lc calibration timing
+
+From: Po-Hao Huang <phhuang@realtek.com>
+
+[ Upstream commit 05684fd583e1acc34dddea283838fbfbed4904a0 ]
+
+Before this patch, we use value from 2 seconds ago to decide
+whether we should do lc calibration.
+Although this don't happen frequently, fix flow to the way it should be.
+
+Fixes: 7ae7784ec2a8 ("rtw88: 8822c: add LC calibration for RTL8822C")
+Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210426013252.5665-3-pkshih@realtek.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/rtw8822c.c | 22 ++++++++++---------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+index 6cb593cc33c2..6d06f26a4894 100644
+--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+@@ -4371,26 +4371,28 @@ static void rtw8822c_pwrtrack_set(struct rtw_dev *rtwdev, u8 rf_path)
+ }
+ }
+
+-static void rtw8822c_pwr_track_path(struct rtw_dev *rtwdev,
+- struct rtw_swing_table *swing_table,
+- u8 path)
++static void rtw8822c_pwr_track_stats(struct rtw_dev *rtwdev, u8 path)
+ {
+- struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+- u8 thermal_value, delta;
++ u8 thermal_value;
+
+ if (rtwdev->efuse.thermal_meter[path] == 0xff)
+ return;
+
+ thermal_value = rtw_read_rf(rtwdev, path, RF_T_METER, 0x7e);
+-
+ rtw_phy_pwrtrack_avg(rtwdev, thermal_value, path);
++}
+
+- delta = rtw_phy_pwrtrack_get_delta(rtwdev, path);
++static void rtw8822c_pwr_track_path(struct rtw_dev *rtwdev,
++ struct rtw_swing_table *swing_table,
++ u8 path)
++{
++ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
++ u8 delta;
+
++ delta = rtw_phy_pwrtrack_get_delta(rtwdev, path);
+ dm_info->delta_power_index[path] =
+ rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table, path, path,
+ delta);
+-
+ rtw8822c_pwrtrack_set(rtwdev, path);
+ }
+
+@@ -4401,12 +4403,12 @@ static void __rtw8822c_pwr_track(struct rtw_dev *rtwdev)
+
+ rtw_phy_config_swing_table(rtwdev, &swing_table);
+
++ for (i = 0; i < rtwdev->hal.rf_path_num; i++)
++ rtw8822c_pwr_track_stats(rtwdev, i);
+ if (rtw_phy_pwrtrack_need_lck(rtwdev))
+ rtw8822c_do_lck(rtwdev);
+-
+ for (i = 0; i < rtwdev->hal.rf_path_num; i++)
+ rtw8822c_pwr_track_path(rtwdev, &swing_table, i);
+-
+ }
+
+ static void rtw8822c_pwr_track(struct rtw_dev *rtwdev)
+--
+2.30.2
+
--- /dev/null
+From e4c710d9a4f8a09d2256ef43d66e3474e1f62902 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 May 2021 17:24:20 -0700
+Subject: s390: appldata depends on PROC_SYSCTL
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 5d3516b3647621d5a1180672ea9e0817fb718ada ]
+
+APPLDATA_BASE should depend on PROC_SYSCTL instead of PROC_FS.
+Building with PROC_FS but not PROC_SYSCTL causes a build error,
+since appldata_base.c uses data and APIs from fs/proc/proc_sysctl.c.
+
+arch/s390/appldata/appldata_base.o: in function `appldata_generic_handler':
+appldata_base.c:(.text+0x192): undefined reference to `sysctl_vals'
+
+Fixes: c185b783b099 ("[S390] Remove config options.")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Cc: Christian Borntraeger <borntraeger@de.ibm.com>
+Cc: linux-s390@vger.kernel.org
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Link: https://lore.kernel.org/r/20210528002420.17634-1-rdunlap@infradead.org
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index d6582f57e0a1..93488bbf491b 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -854,7 +854,7 @@ config CMM_IUCV
+ config APPLDATA_BASE
+ def_bool n
+ prompt "Linux - VM Monitor Stream, base infrastructure"
+- depends on PROC_FS
++ depends on PROC_SYSCTL
+ help
+ This provides a kernel interface for creating and updating z/VM APPLDATA
+ monitor records. The monitor records are updated at certain time
+--
+2.30.2
+
--- /dev/null
+From 3a666411ed34b4014ecf3b9c681b787a14c134b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Feb 2021 12:00:52 +0100
+Subject: s390: enable HAVE_IOREMAP_PROT
+
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+
+[ Upstream commit d460bb6c6417588dd8b0907d34f69b237918812a ]
+
+In commit b02002cc4c0f ("s390/pci: Implement ioremap_wc/prot() with
+MIO") we implemented both ioremap_wc() and ioremap_prot() however until
+now we had not set HAVE_IOREMAP_PROT in Kconfig, do so now.
+
+This also requires implementing pte_pgprot() as this is used in the
+generic_access_phys() code enabled by CONFIG_HAVE_IOREMAP_PROT. As with
+ioremap_wc() we need to take the MMIO Write Back bit index into account.
+
+Moreover since the pgprot value returned from pte_pgprot() is to be used
+for mappings into kernel address space we must make sure that it uses
+appropriate kernel page table protection bits. In particular a pgprot
+value originally coming from userspace could have the _PAGE_PROTECT
+bit set to enable fault based dirty bit accounting which would then make
+the mapping inaccessible when used in kernel address space.
+
+Fixes: b02002cc4c0f ("s390/pci: Implement ioremap_wc/prot() with MIO")
+Reviewed-by: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
+Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/Kconfig | 1 +
+ arch/s390/include/asm/pgtable.h | 19 +++++++++++++++++++
+ 2 files changed, 20 insertions(+)
+
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index b4c7c34069f8..d6582f57e0a1 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -164,6 +164,7 @@ config S390
+ select HAVE_FUTEX_CMPXCHG if FUTEX
+ select HAVE_GCC_PLUGINS
+ select HAVE_GENERIC_VDSO
++ select HAVE_IOREMAP_PROT if PCI
+ select HAVE_IRQ_EXIT_ON_IRQ_STACK
+ select HAVE_KERNEL_BZIP2
+ select HAVE_KERNEL_GZIP
+diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
+index b38f7b781564..adea53f69bfd 100644
+--- a/arch/s390/include/asm/pgtable.h
++++ b/arch/s390/include/asm/pgtable.h
+@@ -863,6 +863,25 @@ static inline int pte_unused(pte_t pte)
+ return pte_val(pte) & _PAGE_UNUSED;
+ }
+
++/*
++ * Extract the pgprot value from the given pte while at the same time making it
++ * usable for kernel address space mappings where fault driven dirty and
++ * young/old accounting is not supported, i.e _PAGE_PROTECT and _PAGE_INVALID
++ * must not be set.
++ */
++static inline pgprot_t pte_pgprot(pte_t pte)
++{
++ unsigned long pte_flags = pte_val(pte) & _PAGE_CHG_MASK;
++
++ if (pte_write(pte))
++ pte_flags |= pgprot_val(PAGE_KERNEL);
++ else
++ pte_flags |= pgprot_val(PAGE_KERNEL_RO);
++ pte_flags |= pte_val(pte) & mio_wb_bit_mask;
++
++ return __pgprot(pte_flags);
++}
++
+ /*
+ * pgd/pmd/pte modification functions
+ */
+--
+2.30.2
+
--- /dev/null
+From 2e6ae24a79f847d8f585578af986f7e5ace5182c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jun 2021 12:23:24 +0800
+Subject: samples/bpf: Fix Segmentation fault for xdp_redirect command
+
+From: Wang Hai <wanghai38@huawei.com>
+
+[ Upstream commit 85102ba58b4125ebad941d7555c3c248b23efd16 ]
+
+A Segmentation fault error is caused when the following command
+is executed.
+
+$ sudo ./samples/bpf/xdp_redirect lo
+Segmentation fault
+
+This command is missing a device <IFNAME|IFINDEX> as an argument, resulting
+in out-of-bounds access from argv.
+
+If the number of devices for the xdp_redirect parameter is not 2,
+we should report an error and exit.
+
+Fixes: 24251c264798 ("samples/bpf: add option for native and skb mode for redirect apps")
+Signed-off-by: Wang Hai <wanghai38@huawei.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20210616042324.314832-1-wanghai38@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ samples/bpf/xdp_redirect_user.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/samples/bpf/xdp_redirect_user.c b/samples/bpf/xdp_redirect_user.c
+index 41d705c3a1f7..eb876629109a 100644
+--- a/samples/bpf/xdp_redirect_user.c
++++ b/samples/bpf/xdp_redirect_user.c
+@@ -130,7 +130,7 @@ int main(int argc, char **argv)
+ if (!(xdp_flags & XDP_FLAGS_SKB_MODE))
+ xdp_flags |= XDP_FLAGS_DRV_MODE;
+
+- if (optind == argc) {
++ if (optind + 2 != argc) {
+ printf("usage: %s <IFNAME|IFINDEX>_IN <IFNAME|IFINDEX>_OUT\n", argv[0]);
+ return 1;
+ }
+--
+2.30.2
+
--- /dev/null
+From 5e0841e5c08b0ea6a2b14c67fd37529435fd8640 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jun 2021 12:25:34 +0800
+Subject: samples/bpf: Fix the error return code of xdp_redirect's main()
+
+From: Wang Hai <wanghai38@huawei.com>
+
+[ Upstream commit 7c6090ee2a7b3315410cfc83a94c3eb057407b25 ]
+
+Fix to return a negative error code from the error handling
+case instead of 0, as done elsewhere in this function.
+
+If bpf_map_update_elem() failed, main() should return a negative error.
+
+Fixes: 832622e6bd18 ("xdp: sample program for new bpf_redirect helper")
+Signed-off-by: Wang Hai <wanghai38@huawei.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20210616042534.315097-1-wanghai38@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ samples/bpf/xdp_redirect_user.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/samples/bpf/xdp_redirect_user.c b/samples/bpf/xdp_redirect_user.c
+index eb876629109a..93854e135134 100644
+--- a/samples/bpf/xdp_redirect_user.c
++++ b/samples/bpf/xdp_redirect_user.c
+@@ -213,5 +213,5 @@ int main(int argc, char **argv)
+ poll_stats(2, ifindex_out);
+
+ out:
+- return 0;
++ return ret;
+ }
+--
+2.30.2
+
--- /dev/null
+From 88200f570fa73dd31303c3c8f69ef90104b84b2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 14 Mar 2021 23:34:27 +0300
+Subject: sata_highbank: fix deferred probing
+
+From: Sergey Shtylyov <s.shtylyov@omprussia.ru>
+
+[ Upstream commit 4a24efa16e7db02306fb5db84518bb0a7ada5a46 ]
+
+The driver overrides the error codes returned by platform_get_irq() to
+-EINVAL, so if it returns -EPROBE_DEFER, the driver would fail the probe
+permanently instead of the deferred probing. Switch to propagating the
+error code upstream, still checking/overriding IRQ0 as libata regards it
+as "no IRQ" (thus polling) anyway...
+
+Fixes: 9ec36cafe43b ("of/irq: do irq resolution in platform_get_irq")
+Signed-off-by: Sergey Shtylyov <s.shtylyov@omprussia.ru>
+Link: https://lore.kernel.org/r/105b456d-1199-f6e9-ceb7-ffc5ba551d1a@omprussia.ru
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_highbank.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c
+index 64b2ef15ec19..8440203e835e 100644
+--- a/drivers/ata/sata_highbank.c
++++ b/drivers/ata/sata_highbank.c
+@@ -469,10 +469,12 @@ static int ahci_highbank_probe(struct platform_device *pdev)
+ }
+
+ irq = platform_get_irq(pdev, 0);
+- if (irq <= 0) {
++ if (irq < 0) {
+ dev_err(dev, "no irq\n");
+- return -EINVAL;
++ return irq;
+ }
++ if (!irq)
++ return -EINVAL;
+
+ hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
+ if (!hpriv) {
+--
+2.30.2
+
--- /dev/null
+From 9072eaf78a07d8e20aeebcd55a5b17bf30700648 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 May 2021 10:46:36 +0100
+Subject: sched/core: Initialize the idle task with preemption disabled
+
+From: Valentin Schneider <valentin.schneider@arm.com>
+
+[ Upstream commit f1a0a376ca0c4ef1fc3d24e3e502acbb5b795674 ]
+
+As pointed out by commit
+
+ de9b8f5dcbd9 ("sched: Fix crash trying to dequeue/enqueue the idle thread")
+
+init_idle() can and will be invoked more than once on the same idle
+task. At boot time, it is invoked for the boot CPU thread by
+sched_init(). Then smp_init() creates the threads for all the secondary
+CPUs and invokes init_idle() on them.
+
+As the hotplug machinery brings the secondaries to life, it will issue
+calls to idle_thread_get(), which itself invokes init_idle() yet again.
+In this case it's invoked twice more per secondary: at _cpu_up(), and at
+bringup_cpu().
+
+Given smp_init() already initializes the idle tasks for all *possible*
+CPUs, no further initialization should be required. Now, removing
+init_idle() from idle_thread_get() exposes some interesting expectations
+with regards to the idle task's preempt_count: the secondary startup always
+issues a preempt_disable(), requiring some reset of the preempt count to 0
+between hot-unplug and hotplug, which is currently served by
+idle_thread_get() -> idle_init().
+
+Given the idle task is supposed to have preemption disabled once and never
+see it re-enabled, it seems that what we actually want is to initialize its
+preempt_count to PREEMPT_DISABLED and leave it there. Do that, and remove
+init_idle() from idle_thread_get().
+
+Secondary startups were patched via coccinelle:
+
+ @begone@
+ @@
+
+ -preempt_disable();
+ ...
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
+
+Signed-off-by: Valentin Schneider <valentin.schneider@arm.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20210512094636.2958515-1-valentin.schneider@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/alpha/kernel/smp.c | 1 -
+ arch/arc/kernel/smp.c | 1 -
+ arch/arm/kernel/smp.c | 1 -
+ arch/arm64/include/asm/preempt.h | 2 +-
+ arch/arm64/kernel/smp.c | 1 -
+ arch/csky/kernel/smp.c | 1 -
+ arch/ia64/kernel/smpboot.c | 1 -
+ arch/mips/kernel/smp.c | 1 -
+ arch/openrisc/kernel/smp.c | 2 --
+ arch/parisc/kernel/smp.c | 1 -
+ arch/powerpc/kernel/smp.c | 1 -
+ arch/riscv/kernel/smpboot.c | 1 -
+ arch/s390/include/asm/preempt.h | 4 ++--
+ arch/s390/kernel/smp.c | 1 -
+ arch/sh/kernel/smp.c | 2 --
+ arch/sparc/kernel/smp_32.c | 1 -
+ arch/sparc/kernel/smp_64.c | 3 ---
+ arch/x86/include/asm/preempt.h | 2 +-
+ arch/x86/kernel/smpboot.c | 1 -
+ arch/xtensa/kernel/smp.c | 1 -
+ include/asm-generic/preempt.h | 2 +-
+ init/main.c | 6 +-----
+ kernel/fork.c | 2 +-
+ kernel/sched/core.c | 2 +-
+ kernel/smpboot.c | 1 -
+ 25 files changed, 8 insertions(+), 34 deletions(-)
+
+diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
+index f4dd9f3f3001..4b2575f936d4 100644
+--- a/arch/alpha/kernel/smp.c
++++ b/arch/alpha/kernel/smp.c
+@@ -166,7 +166,6 @@ smp_callin(void)
+ DBGS(("smp_callin: commencing CPU %d current %p active_mm %p\n",
+ cpuid, current, current->active_mm));
+
+- preempt_disable();
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
+ }
+
+diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
+index 52906d314537..db0e104d6835 100644
+--- a/arch/arc/kernel/smp.c
++++ b/arch/arc/kernel/smp.c
+@@ -189,7 +189,6 @@ void start_kernel_secondary(void)
+ pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
+
+ local_irq_enable();
+- preempt_disable();
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
+ }
+
+diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
+index 74679240a9d8..c7bb168b0d97 100644
+--- a/arch/arm/kernel/smp.c
++++ b/arch/arm/kernel/smp.c
+@@ -432,7 +432,6 @@ asmlinkage void secondary_start_kernel(void)
+ #endif
+ pr_debug("CPU%u: Booted secondary processor\n", cpu);
+
+- preempt_disable();
+ trace_hardirqs_off();
+
+ /*
+diff --git a/arch/arm64/include/asm/preempt.h b/arch/arm64/include/asm/preempt.h
+index 80e946b2abee..e83f0982b99c 100644
+--- a/arch/arm64/include/asm/preempt.h
++++ b/arch/arm64/include/asm/preempt.h
+@@ -23,7 +23,7 @@ static inline void preempt_count_set(u64 pc)
+ } while (0)
+
+ #define init_idle_preempt_count(p, cpu) do { \
+- task_thread_info(p)->preempt_count = PREEMPT_ENABLED; \
++ task_thread_info(p)->preempt_count = PREEMPT_DISABLED; \
+ } while (0)
+
+ static inline void set_preempt_need_resched(void)
+diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
+index dcd7041b2b07..6671000a8b7d 100644
+--- a/arch/arm64/kernel/smp.c
++++ b/arch/arm64/kernel/smp.c
+@@ -224,7 +224,6 @@ asmlinkage notrace void secondary_start_kernel(void)
+ init_gic_priority_masking();
+
+ rcu_cpu_starting(cpu);
+- preempt_disable();
+ trace_hardirqs_off();
+
+ /*
+diff --git a/arch/csky/kernel/smp.c b/arch/csky/kernel/smp.c
+index 0f9f5eef9338..e2993539af8e 100644
+--- a/arch/csky/kernel/smp.c
++++ b/arch/csky/kernel/smp.c
+@@ -281,7 +281,6 @@ void csky_start_secondary(void)
+ pr_info("CPU%u Online: %s...\n", cpu, __func__);
+
+ local_irq_enable();
+- preempt_disable();
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
+ }
+
+diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
+index 49b488580939..d10f780c13b9 100644
+--- a/arch/ia64/kernel/smpboot.c
++++ b/arch/ia64/kernel/smpboot.c
+@@ -441,7 +441,6 @@ start_secondary (void *unused)
+ #endif
+ efi_map_pal_code();
+ cpu_init();
+- preempt_disable();
+ smp_callin();
+
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
+diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
+index ef86fbad8546..d542fb7af3ba 100644
+--- a/arch/mips/kernel/smp.c
++++ b/arch/mips/kernel/smp.c
+@@ -348,7 +348,6 @@ asmlinkage void start_secondary(void)
+ */
+
+ calibrate_delay();
+- preempt_disable();
+ cpu = smp_processor_id();
+ cpu_data[cpu].udelay_val = loops_per_jiffy;
+
+diff --git a/arch/openrisc/kernel/smp.c b/arch/openrisc/kernel/smp.c
+index 48e1092a64de..415e209732a3 100644
+--- a/arch/openrisc/kernel/smp.c
++++ b/arch/openrisc/kernel/smp.c
+@@ -145,8 +145,6 @@ asmlinkage __init void secondary_start_kernel(void)
+ set_cpu_online(cpu, true);
+
+ local_irq_enable();
+-
+- preempt_disable();
+ /*
+ * OK, it's off to the idle thread for us
+ */
+diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
+index 10227f667c8a..1405b603b91b 100644
+--- a/arch/parisc/kernel/smp.c
++++ b/arch/parisc/kernel/smp.c
+@@ -302,7 +302,6 @@ void __init smp_callin(unsigned long pdce_proc)
+ #endif
+
+ smp_cpu_init(slave_id);
+- preempt_disable();
+
+ flush_cache_all_local(); /* start with known state */
+ flush_tlb_all_local(NULL);
+diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
+index 2e05c783440a..6c6e4d934d86 100644
+--- a/arch/powerpc/kernel/smp.c
++++ b/arch/powerpc/kernel/smp.c
+@@ -1547,7 +1547,6 @@ void start_secondary(void *unused)
+ smp_store_cpu_info(cpu);
+ set_dec(tb_ticks_per_jiffy);
+ rcu_cpu_starting(cpu);
+- preempt_disable();
+ cpu_callin_map[cpu] = 1;
+
+ if (smp_ops->setup_cpu)
+diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
+index 9a408e2942ac..bd82375db51a 100644
+--- a/arch/riscv/kernel/smpboot.c
++++ b/arch/riscv/kernel/smpboot.c
+@@ -180,7 +180,6 @@ asmlinkage __visible void smp_callin(void)
+ * Disable preemption before enabling interrupts, so we don't try to
+ * schedule a CPU that hasn't actually started yet.
+ */
+- preempt_disable();
+ local_irq_enable();
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
+ }
+diff --git a/arch/s390/include/asm/preempt.h b/arch/s390/include/asm/preempt.h
+index b49e0492842c..23ff51be7e29 100644
+--- a/arch/s390/include/asm/preempt.h
++++ b/arch/s390/include/asm/preempt.h
+@@ -32,7 +32,7 @@ static inline void preempt_count_set(int pc)
+ #define init_task_preempt_count(p) do { } while (0)
+
+ #define init_idle_preempt_count(p, cpu) do { \
+- S390_lowcore.preempt_count = PREEMPT_ENABLED; \
++ S390_lowcore.preempt_count = PREEMPT_DISABLED; \
+ } while (0)
+
+ static inline void set_preempt_need_resched(void)
+@@ -91,7 +91,7 @@ static inline void preempt_count_set(int pc)
+ #define init_task_preempt_count(p) do { } while (0)
+
+ #define init_idle_preempt_count(p, cpu) do { \
+- S390_lowcore.preempt_count = PREEMPT_ENABLED; \
++ S390_lowcore.preempt_count = PREEMPT_DISABLED; \
+ } while (0)
+
+ static inline void set_preempt_need_resched(void)
+diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
+index 2fec2b80d35d..111909aeb8d2 100644
+--- a/arch/s390/kernel/smp.c
++++ b/arch/s390/kernel/smp.c
+@@ -878,7 +878,6 @@ static void smp_init_secondary(void)
+ restore_access_regs(S390_lowcore.access_regs_save_area);
+ cpu_init();
+ rcu_cpu_starting(cpu);
+- preempt_disable();
+ init_cpu_timer();
+ vtime_init();
+ vdso_getcpu_init();
+diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
+index 372acdc9033e..65924d9ec245 100644
+--- a/arch/sh/kernel/smp.c
++++ b/arch/sh/kernel/smp.c
+@@ -186,8 +186,6 @@ asmlinkage void start_secondary(void)
+
+ per_cpu_trap_init();
+
+- preempt_disable();
+-
+ notify_cpu_starting(cpu);
+
+ local_irq_enable();
+diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c
+index 50c127ab46d5..22b148e5a5f8 100644
+--- a/arch/sparc/kernel/smp_32.c
++++ b/arch/sparc/kernel/smp_32.c
+@@ -348,7 +348,6 @@ static void sparc_start_secondary(void *arg)
+ */
+ arch_cpu_pre_starting(arg);
+
+- preempt_disable();
+ cpu = smp_processor_id();
+
+ notify_cpu_starting(cpu);
+diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
+index e38d8bf454e8..ae5faa1d989d 100644
+--- a/arch/sparc/kernel/smp_64.c
++++ b/arch/sparc/kernel/smp_64.c
+@@ -138,9 +138,6 @@ void smp_callin(void)
+
+ set_cpu_online(cpuid, true);
+
+- /* idle thread is expected to have preempt disabled */
+- preempt_disable();
+-
+ local_irq_enable();
+
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
+diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h
+index f8cb8af4de5c..fe5efbcba824 100644
+--- a/arch/x86/include/asm/preempt.h
++++ b/arch/x86/include/asm/preempt.h
+@@ -44,7 +44,7 @@ static __always_inline void preempt_count_set(int pc)
+ #define init_task_preempt_count(p) do { } while (0)
+
+ #define init_idle_preempt_count(p, cpu) do { \
+- per_cpu(__preempt_count, (cpu)) = PREEMPT_ENABLED; \
++ per_cpu(__preempt_count, (cpu)) = PREEMPT_DISABLED; \
+ } while (0)
+
+ /*
+diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
+index 7770245cc7fa..ec2d64aa2163 100644
+--- a/arch/x86/kernel/smpboot.c
++++ b/arch/x86/kernel/smpboot.c
+@@ -236,7 +236,6 @@ static void notrace start_secondary(void *unused)
+ cpu_init();
+ rcu_cpu_starting(raw_smp_processor_id());
+ x86_cpuinit.early_percpu_clock_init();
+- preempt_disable();
+ smp_callin();
+
+ enable_start_cpu0 = 0;
+diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c
+index cd85a7a2722b..1254da07ead1 100644
+--- a/arch/xtensa/kernel/smp.c
++++ b/arch/xtensa/kernel/smp.c
+@@ -145,7 +145,6 @@ void secondary_start_kernel(void)
+ cpumask_set_cpu(cpu, mm_cpumask(mm));
+ enter_lazy_tlb(mm, current);
+
+- preempt_disable();
+ trace_hardirqs_off();
+
+ calibrate_delay();
+diff --git a/include/asm-generic/preempt.h b/include/asm-generic/preempt.h
+index d683f5e6d791..b4d43a4af5f7 100644
+--- a/include/asm-generic/preempt.h
++++ b/include/asm-generic/preempt.h
+@@ -29,7 +29,7 @@ static __always_inline void preempt_count_set(int pc)
+ } while (0)
+
+ #define init_idle_preempt_count(p, cpu) do { \
+- task_thread_info(p)->preempt_count = PREEMPT_ENABLED; \
++ task_thread_info(p)->preempt_count = PREEMPT_DISABLED; \
+ } while (0)
+
+ static __always_inline void set_preempt_need_resched(void)
+diff --git a/init/main.c b/init/main.c
+index e9c42a183e33..e6836a9400d5 100644
+--- a/init/main.c
++++ b/init/main.c
+@@ -941,11 +941,7 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void)
+ * time - but meanwhile we still have a functioning scheduler.
+ */
+ sched_init();
+- /*
+- * Disable preemption - early bootup scheduling is extremely
+- * fragile until we cpu_idle() for the first time.
+- */
+- preempt_disable();
++
+ if (WARN(!irqs_disabled(),
+ "Interrupts were enabled *very* early, fixing it\n"))
+ local_irq_disable();
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 24a689df61c9..98b4bc7f0d7b 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -2407,7 +2407,7 @@ static inline void init_idle_pids(struct task_struct *idle)
+ }
+ }
+
+-struct task_struct *fork_idle(int cpu)
++struct task_struct * __init fork_idle(int cpu)
+ {
+ struct task_struct *task;
+ struct kernel_clone_args args = {
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 4ca80df205ce..0a90d4d7663b 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -7433,7 +7433,7 @@ void show_state_filter(unsigned long state_filter)
+ * NOTE: this function does not set the idle thread's NEED_RESCHED
+ * flag, to make booting more robust.
+ */
+-void init_idle(struct task_struct *idle, int cpu)
++void __init init_idle(struct task_struct *idle, int cpu)
+ {
+ struct rq *rq = cpu_rq(cpu);
+ unsigned long flags;
+diff --git a/kernel/smpboot.c b/kernel/smpboot.c
+index f25208e8df83..e4163042c4d6 100644
+--- a/kernel/smpboot.c
++++ b/kernel/smpboot.c
+@@ -33,7 +33,6 @@ struct task_struct *idle_thread_get(unsigned int cpu)
+
+ if (!tsk)
+ return ERR_PTR(-ENOMEM);
+- init_idle(tsk, cpu);
+ return tsk;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From f039fab0c5a7a1dc73deb673927895f599d3dbe5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 May 2021 21:57:50 +0100
+Subject: sched: Don't defer CPU pick to migration_cpu_stop()
+
+From: Valentin Schneider <valentin.schneider@arm.com>
+
+[ Upstream commit 475ea6c60279e9f2ddf7e4cf2648cd8ae0608361 ]
+
+Will reported that the 'XXX __migrate_task() can fail' in migration_cpu_stop()
+can happen, and it *is* sort of a big deal. Looking at it some more, one
+will note there is a glaring hole in the deferred CPU selection:
+
+ (w/ CONFIG_CPUSET=n, so that the affinity mask passed via taskset doesn't
+ get AND'd with cpu_online_mask)
+
+ $ taskset -pc 0-2 $PID
+ # offline CPUs 3-4
+ $ taskset -pc 3-5 $PID
+ `\
+ $PID may stay on 0-2 due to the cpumask_any_distribute() picking an
+ offline CPU and __migrate_task() refusing to do anything due to
+ cpu_is_allowed().
+
+set_cpus_allowed_ptr() goes to some length to pick a dest_cpu that matches
+the right constraints vs affinity and the online/active state of the
+CPUs. Reuse that instead of discarding it in the affine_move_task() case.
+
+Fixes: 6d337eab041d ("sched: Fix migrate_disable() vs set_cpus_allowed_ptr()")
+Reported-by: Will Deacon <will@kernel.org>
+Signed-off-by: Valentin Schneider <valentin.schneider@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20210526205751.842360-2-valentin.schneider@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 94002cb551c4..6e0ebc0781d1 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -1929,7 +1929,6 @@ static int migration_cpu_stop(void *data)
+ struct migration_arg *arg = data;
+ struct set_affinity_pending *pending = arg->pending;
+ struct task_struct *p = arg->task;
+- int dest_cpu = arg->dest_cpu;
+ struct rq *rq = this_rq();
+ bool complete = false;
+ struct rq_flags rf;
+@@ -1967,19 +1966,15 @@ static int migration_cpu_stop(void *data)
+ if (pending) {
+ p->migration_pending = NULL;
+ complete = true;
+- }
+
+- if (dest_cpu < 0) {
+ if (cpumask_test_cpu(task_cpu(p), &p->cpus_mask))
+ goto out;
+-
+- dest_cpu = cpumask_any_distribute(&p->cpus_mask);
+ }
+
+ if (task_on_rq_queued(p))
+- rq = __migrate_task(rq, &rf, p, dest_cpu);
++ rq = __migrate_task(rq, &rf, p, arg->dest_cpu);
+ else
+- p->wake_cpu = dest_cpu;
++ p->wake_cpu = arg->dest_cpu;
+
+ /*
+ * XXX __migrate_task() can fail, at which point we might end
+@@ -2262,7 +2257,7 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag
+ init_completion(&my_pending.done);
+ my_pending.arg = (struct migration_arg) {
+ .task = p,
+- .dest_cpu = -1, /* any */
++ .dest_cpu = dest_cpu,
+ .pending = &my_pending,
+ };
+
+@@ -2270,6 +2265,15 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag
+ } else {
+ pending = p->migration_pending;
+ refcount_inc(&pending->refs);
++ /*
++ * Affinity has changed, but we've already installed a
++ * pending. migration_cpu_stop() *must* see this, else
++ * we risk a completion of the pending despite having a
++ * task on a disallowed CPU.
++ *
++ * Serialized by p->pi_lock, so this is safe.
++ */
++ pending->arg.dest_cpu = dest_cpu;
+ }
+ }
+ pending = p->migration_pending;
+--
+2.30.2
+
--- /dev/null
+From 807721bc7bbfcb9baadd6eebb049a523ac64f14b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 May 2021 14:52:02 +0200
+Subject: sched/fair: Fix ascii art by relpacing tabs
+
+From: Odin Ugedal <odin@uged.al>
+
+[ Upstream commit 08f7c2f4d0e9f4283f5796b8168044c034a1bfcb ]
+
+When using something other than 8 spaces per tab, this ascii art
+makes not sense, and the reader might end up wondering what this
+advanced equation "is".
+
+Signed-off-by: Odin Ugedal <odin@uged.al>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Acked-by: Vincent Guittot <vincent.guittot@linaro.org>
+Link: https://lkml.kernel.org/r/20210518125202.78658-4-odin@uged.al
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index 23663318fb81..190ae8004a22 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -3139,7 +3139,7 @@ void reweight_task(struct task_struct *p, int prio)
+ *
+ * tg->weight * grq->load.weight
+ * ge->load.weight = ----------------------------- (1)
+- * \Sum grq->load.weight
++ * \Sum grq->load.weight
+ *
+ * Now, because computing that sum is prohibitively expensive to compute (been
+ * there, done that) we approximate it with this average stuff. The average
+@@ -3153,7 +3153,7 @@ void reweight_task(struct task_struct *p, int prio)
+ *
+ * tg->weight * grq->avg.load_avg
+ * ge->load.weight = ------------------------------ (3)
+- * tg->load_avg
++ * tg->load_avg
+ *
+ * Where: tg->load_avg ~= \Sum grq->avg.load_avg
+ *
+@@ -3169,7 +3169,7 @@ void reweight_task(struct task_struct *p, int prio)
+ *
+ * tg->weight * grq->load.weight
+ * ge->load.weight = ----------------------------- = tg->weight (4)
+- * grp->load.weight
++ * grp->load.weight
+ *
+ * That is, the sum collapses because all other CPUs are idle; the UP scenario.
+ *
+@@ -3188,7 +3188,7 @@ void reweight_task(struct task_struct *p, int prio)
+ *
+ * tg->weight * grq->load.weight
+ * ge->load.weight = ----------------------------- (6)
+- * tg_load_avg'
++ * tg_load_avg'
+ *
+ * Where:
+ *
+--
+2.30.2
+
--- /dev/null
+From 9444d957a467671c3200882a0eea8bd20f1b009f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 20:11:28 +0100
+Subject: sched/fair: Take thermal pressure into account while estimating
+ energy
+
+From: Lukasz Luba <lukasz.luba@arm.com>
+
+[ Upstream commit 489f16459e0008c7a5c4c5af34bd80898aa82c2d ]
+
+Energy Aware Scheduling (EAS) needs to be able to predict the frequency
+requests made by the SchedUtil governor to properly estimate energy used
+in the future. It has to take into account CPUs utilization and forecast
+Performance Domain (PD) frequency. There is a corner case when the max
+allowed frequency might be reduced due to thermal. SchedUtil is aware of
+that reduced frequency, so it should be taken into account also in EAS
+estimations.
+
+SchedUtil, as a CPUFreq governor, knows the maximum allowed frequency of
+a CPU, thanks to cpufreq_driver_resolve_freq() and internal clamping
+to 'policy::max'. SchedUtil is responsible to respect that upper limit
+while setting the frequency through CPUFreq drivers. This effective
+frequency is stored internally in 'sugov_policy::next_freq' and EAS has
+to predict that value.
+
+In the existing code the raw value of arch_scale_cpu_capacity() is used
+for clamping the returned CPU utilization from effective_cpu_util().
+This patch fixes issue with too big single CPU utilization, by introducing
+clamping to the allowed CPU capacity. The allowed CPU capacity is a CPU
+capacity reduced by thermal pressure raw value.
+
+Thanks to knowledge about allowed CPU capacity, we don't get too big value
+for a single CPU utilization, which is then added to the util sum. The
+util sum is used as a source of information for estimating whole PD energy.
+To avoid wrong energy estimation in EAS (due to capped frequency), make
+sure that the calculation of util sum is aware of allowed CPU capacity.
+
+This thermal pressure might be visible in scenarios where the CPUs are not
+heavily loaded, but some other component (like GPU) drastically reduced
+available power budget and increased the SoC temperature. Thus, we still
+use EAS for task placement and CPUs are not over-utilized.
+
+Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
+Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Link: https://lore.kernel.org/r/20210614191128.22735-1-lukasz.luba@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index 190ae8004a22..e807b743353d 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -6620,8 +6620,11 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
+ struct cpumask *pd_mask = perf_domain_span(pd);
+ unsigned long cpu_cap = arch_scale_cpu_capacity(cpumask_first(pd_mask));
+ unsigned long max_util = 0, sum_util = 0;
++ unsigned long _cpu_cap = cpu_cap;
+ int cpu;
+
++ _cpu_cap -= arch_scale_thermal_pressure(cpumask_first(pd_mask));
++
+ /*
+ * The capacity state of CPUs of the current rd can be driven by CPUs
+ * of another rd if they belong to the same pd. So, account for the
+@@ -6657,8 +6660,10 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
+ * is already enough to scale the EM reported power
+ * consumption at the (eventually clamped) cpu_capacity.
+ */
+- sum_util += effective_cpu_util(cpu, util_running, cpu_cap,
+- ENERGY_UTIL, NULL);
++ cpu_util = effective_cpu_util(cpu, util_running, cpu_cap,
++ ENERGY_UTIL, NULL);
++
++ sum_util += min(cpu_util, _cpu_cap);
+
+ /*
+ * Performance domain frequency: utilization clamping
+@@ -6669,7 +6674,7 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
+ */
+ cpu_util = effective_cpu_util(cpu, util_freq, cpu_cap,
+ FREQUENCY_UTIL, tsk);
+- max_util = max(max_util, cpu_util);
++ max_util = max(max_util, min(cpu_util, _cpu_cap));
+ }
+
+ return em_cpu_energy(pd->em_pd, max_util, sum_util);
+--
+2.30.2
+
--- /dev/null
+From 31a0094d20f0d808b6d334706b168afa1e6821a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 16:10:23 +0100
+Subject: sched: Make the idle task quack like a per-CPU kthread
+
+From: Valentin Schneider <valentin.schneider@arm.com>
+
+[ Upstream commit 00b89fe0197f0c55a045775c11553c0cdb7082fe ]
+
+For all intents and purposes, the idle task is a per-CPU kthread. It isn't
+created via the same route as other pcpu kthreads however, and as a result
+it is missing a few bells and whistles: it fails kthread_is_per_cpu() and
+it doesn't have PF_NO_SETAFFINITY set.
+
+Fix the former by giving the idle task a kthread struct along with the
+KTHREAD_IS_PER_CPU flag. This requires some extra iffery as init_idle()
+call be called more than once on the same idle task.
+
+Signed-off-by: Valentin Schneider <valentin.schneider@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20210510151024.2448573-2-valentin.schneider@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/kthread.h | 2 ++
+ kernel/kthread.c | 30 ++++++++++++++++++------------
+ kernel/sched/core.c | 21 +++++++++++++++------
+ 3 files changed, 35 insertions(+), 18 deletions(-)
+
+diff --git a/include/linux/kthread.h b/include/linux/kthread.h
+index 2484ed97e72f..d9133d6db308 100644
+--- a/include/linux/kthread.h
++++ b/include/linux/kthread.h
+@@ -33,6 +33,8 @@ struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data),
+ unsigned int cpu,
+ const char *namefmt);
+
++void set_kthread_struct(struct task_struct *p);
++
+ void kthread_set_per_cpu(struct task_struct *k, int cpu);
+ bool kthread_is_per_cpu(struct task_struct *k);
+
+diff --git a/kernel/kthread.c b/kernel/kthread.c
+index 0fccf7d0c6a1..6e02094849d3 100644
+--- a/kernel/kthread.c
++++ b/kernel/kthread.c
+@@ -68,16 +68,6 @@ enum KTHREAD_BITS {
+ KTHREAD_SHOULD_PARK,
+ };
+
+-static inline void set_kthread_struct(void *kthread)
+-{
+- /*
+- * We abuse ->set_child_tid to avoid the new member and because it
+- * can't be wrongly copied by copy_process(). We also rely on fact
+- * that the caller can't exec, so PF_KTHREAD can't be cleared.
+- */
+- current->set_child_tid = (__force void __user *)kthread;
+-}
+-
+ static inline struct kthread *to_kthread(struct task_struct *k)
+ {
+ WARN_ON(!(k->flags & PF_KTHREAD));
+@@ -103,6 +93,22 @@ static inline struct kthread *__to_kthread(struct task_struct *p)
+ return kthread;
+ }
+
++void set_kthread_struct(struct task_struct *p)
++{
++ struct kthread *kthread;
++
++ if (__to_kthread(p))
++ return;
++
++ kthread = kzalloc(sizeof(*kthread), GFP_KERNEL);
++ /*
++ * We abuse ->set_child_tid to avoid the new member and because it
++ * can't be wrongly copied by copy_process(). We also rely on fact
++ * that the caller can't exec, so PF_KTHREAD can't be cleared.
++ */
++ p->set_child_tid = (__force void __user *)kthread;
++}
++
+ void free_kthread_struct(struct task_struct *k)
+ {
+ struct kthread *kthread;
+@@ -272,8 +278,8 @@ static int kthread(void *_create)
+ struct kthread *self;
+ int ret;
+
+- self = kzalloc(sizeof(*self), GFP_KERNEL);
+- set_kthread_struct(self);
++ set_kthread_struct(current);
++ self = to_kthread(current);
+
+ /* If user was SIGKILLed, I release the structure. */
+ done = xchg(&create->done, NULL);
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 0a90d4d7663b..9724dd30ad44 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -7440,12 +7440,25 @@ void __init init_idle(struct task_struct *idle, int cpu)
+
+ __sched_fork(0, idle);
+
++ /*
++ * The idle task doesn't need the kthread struct to function, but it
++ * is dressed up as a per-CPU kthread and thus needs to play the part
++ * if we want to avoid special-casing it in code that deals with per-CPU
++ * kthreads.
++ */
++ set_kthread_struct(idle);
++
+ raw_spin_lock_irqsave(&idle->pi_lock, flags);
+ raw_spin_lock(&rq->lock);
+
+ idle->state = TASK_RUNNING;
+ idle->se.exec_start = sched_clock();
+- idle->flags |= PF_IDLE;
++ /*
++ * PF_KTHREAD should already be set at this point; regardless, make it
++ * look like a proper per-CPU kthread.
++ */
++ idle->flags |= PF_IDLE | PF_KTHREAD | PF_NO_SETAFFINITY;
++ kthread_set_per_cpu(idle, cpu);
+
+ scs_task_reset(idle);
+ kasan_unpoison_task_stack(idle);
+@@ -7662,12 +7675,8 @@ static void balance_push(struct rq *rq)
+ /*
+ * Both the cpu-hotplug and stop task are in this case and are
+ * required to complete the hotplug process.
+- *
+- * XXX: the idle task does not match kthread_is_per_cpu() due to
+- * histerical raisins.
+ */
+- if (rq->idle == push_task ||
+- kthread_is_per_cpu(push_task) ||
++ if (kthread_is_per_cpu(push_task) ||
+ is_migration_disabled(push_task)) {
+
+ /*
+--
+2.30.2
+
--- /dev/null
+From 344aa756188cc31cf1c0fda8f0f4738f6a18958f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Jun 2021 11:37:52 +0100
+Subject: sched/rt: Fix Deadline utilization tracking during policy change
+
+From: Vincent Donnefort <vincent.donnefort@arm.com>
+
+[ Upstream commit d7d607096ae6d378b4e92d49946d22739c047d4c ]
+
+DL keeps track of the utilization on a per-rq basis with the structure
+avg_dl. This utilization is updated during task_tick_dl(),
+put_prev_task_dl() and set_next_task_dl(). However, when the current
+running task changes its policy, set_next_task_dl() which would usually
+take care of updating the utilization when the rq starts running DL
+tasks, will not see a such change, leaving the avg_dl structure outdated.
+When that very same task will be dequeued later, put_prev_task_dl() will
+then update the utilization, based on a wrong last_update_time, leading to
+a huge spike in the DL utilization signal.
+
+The signal would eventually recover from this issue after few ms. Even
+if no DL tasks are run, avg_dl is also updated in
+__update_blocked_others(). But as the CPU capacity depends partly on the
+avg_dl, this issue has nonetheless a significant impact on the scheduler.
+
+Fix this issue by ensuring a load update when a running task changes
+its policy to DL.
+
+Fixes: 3727e0e ("sched/dl: Add dl_rq utilization tracking")
+Signed-off-by: Vincent Donnefort <vincent.donnefort@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
+Link: https://lore.kernel.org/r/1624271872-211872-3-git-send-email-vincent.donnefort@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/deadline.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
+index 9a2989749b8d..2f9964b467e0 100644
+--- a/kernel/sched/deadline.c
++++ b/kernel/sched/deadline.c
+@@ -2486,6 +2486,8 @@ static void switched_to_dl(struct rq *rq, struct task_struct *p)
+ check_preempt_curr_dl(rq, p, 0);
+ else
+ resched_curr(rq);
++ } else {
++ update_dl_rq_load_avg(rq_clock_pelt(rq), rq, 0);
+ }
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 4be8c004c8446c533d524f518d249f797d51de57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Jun 2021 11:37:51 +0100
+Subject: sched/rt: Fix RT utilization tracking during policy change
+
+From: Vincent Donnefort <vincent.donnefort@arm.com>
+
+[ Upstream commit fecfcbc288e9f4923f40fd23ca78a6acdc7fdf6c ]
+
+RT keeps track of the utilization on a per-rq basis with the structure
+avg_rt. This utilization is updated during task_tick_rt(),
+put_prev_task_rt() and set_next_task_rt(). However, when the current
+running task changes its policy, set_next_task_rt() which would usually
+take care of updating the utilization when the rq starts running RT tasks,
+will not see a such change, leaving the avg_rt structure outdated. When
+that very same task will be dequeued later, put_prev_task_rt() will then
+update the utilization, based on a wrong last_update_time, leading to a
+huge spike in the RT utilization signal.
+
+The signal would eventually recover from this issue after few ms. Even if
+no RT tasks are run, avg_rt is also updated in __update_blocked_others().
+But as the CPU capacity depends partly on the avg_rt, this issue has
+nonetheless a significant impact on the scheduler.
+
+Fix this issue by ensuring a load update when a running task changes
+its policy to RT.
+
+Fixes: 371bf427 ("sched/rt: Add rt_rq utilization tracking")
+Signed-off-by: Vincent Donnefort <vincent.donnefort@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
+Link: https://lore.kernel.org/r/1624271872-211872-2-git-send-email-vincent.donnefort@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/rt.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
+index c286e5ba3c94..3b1b8b025b74 100644
+--- a/kernel/sched/rt.c
++++ b/kernel/sched/rt.c
+@@ -2331,13 +2331,20 @@ void __init init_sched_rt_class(void)
+ static void switched_to_rt(struct rq *rq, struct task_struct *p)
+ {
+ /*
+- * If we are already running, then there's nothing
+- * that needs to be done. But if we are not running
+- * we may need to preempt the current running task.
+- * If that current running task is also an RT task
++ * If we are running, update the avg_rt tracking, as the running time
++ * will now on be accounted into the latter.
++ */
++ if (task_current(rq, p)) {
++ update_rt_rq_load_avg(rq_clock_pelt(rq), rq, 0);
++ return;
++ }
++
++ /*
++ * If we are not running we may need to preempt the current
++ * running task. If that current running task is also an RT task
+ * then see if we can move to another run queue.
+ */
+- if (task_on_rq_queued(p) && rq->curr != p) {
++ if (task_on_rq_queued(p)) {
+ #ifdef CONFIG_SMP
+ if (p->nr_cpus_allowed > 1 && rq->rt.overloaded)
+ rt_queue_push_tasks(rq);
+--
+2.30.2
+
--- /dev/null
+From 28cbc893898670d66417c1325d478b45416064ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 15:50:32 +0100
+Subject: sched/uclamp: Fix locking around cpu_util_update_eff()
+
+From: Qais Yousef <qais.yousef@arm.com>
+
+[ Upstream commit 93b73858701fd01de26a4a874eb95f9b7156fd4b ]
+
+cpu_cgroup_css_online() calls cpu_util_update_eff() without holding the
+uclamp_mutex or rcu_read_lock() like other call sites, which is
+a mistake.
+
+The uclamp_mutex is required to protect against concurrent reads and
+writes that could update the cgroup hierarchy.
+
+The rcu_read_lock() is required to traverse the cgroup data structures
+in cpu_util_update_eff().
+
+Surround the caller with the required locks and add some asserts to
+better document the dependency in cpu_util_update_eff().
+
+Fixes: 7226017ad37a ("sched/uclamp: Fix a bug in propagating uclamp value in new cgroups")
+Reported-by: Quentin Perret <qperret@google.com>
+Signed-off-by: Qais Yousef <qais.yousef@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20210510145032.1934078-3-qais.yousef@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 49b713da023d..94002cb551c4 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -8702,7 +8702,11 @@ static int cpu_cgroup_css_online(struct cgroup_subsys_state *css)
+
+ #ifdef CONFIG_UCLAMP_TASK_GROUP
+ /* Propagate the effective uclamp value for the new group */
++ mutex_lock(&uclamp_mutex);
++ rcu_read_lock();
+ cpu_util_update_eff(css);
++ rcu_read_unlock();
++ mutex_unlock(&uclamp_mutex);
+ #endif
+
+ return 0;
+@@ -8792,6 +8796,9 @@ static void cpu_util_update_eff(struct cgroup_subsys_state *css)
+ enum uclamp_id clamp_id;
+ unsigned int clamps;
+
++ lockdep_assert_held(&uclamp_mutex);
++ SCHED_WARN_ON(!rcu_read_lock_held());
++
+ css_for_each_descendant_pre(css, top_css) {
+ uc_parent = css_tg(css)->parent
+ ? css_tg(css)->parent->uclamp : NULL;
+--
+2.30.2
+
--- /dev/null
+From 16a2e798f9841419728a9017beb918ed31cc3f35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jun 2021 17:51:55 +0100
+Subject: sched/uclamp: Fix uclamp_tg_restrict()
+
+From: Qais Yousef <qais.yousef@arm.com>
+
+[ Upstream commit 0213b7083e81f4acd69db32cb72eb4e5f220329a ]
+
+Now cpu.uclamp.min acts as a protection, we need to make sure that the
+uclamp request of the task is within the allowed range of the cgroup,
+that is it is clamp()'ed correctly by tg->uclamp[UCLAMP_MIN] and
+tg->uclamp[UCLAMP_MAX].
+
+As reported by Xuewen [1] we can have some corner cases where there's
+inversion between uclamp requested by task (p) and the uclamp values of
+the taskgroup it's attached to (tg). Following table demonstrates
+2 corner cases:
+
+ | p | tg | effective
+ -----------+-----+------+-----------
+ CASE 1
+ -----------+-----+------+-----------
+ uclamp_min | 60% | 0% | 60%
+ -----------+-----+------+-----------
+ uclamp_max | 80% | 50% | 50%
+ -----------+-----+------+-----------
+ CASE 2
+ -----------+-----+------+-----------
+ uclamp_min | 0% | 30% | 30%
+ -----------+-----+------+-----------
+ uclamp_max | 20% | 50% | 20%
+ -----------+-----+------+-----------
+
+With this fix we get:
+
+ | p | tg | effective
+ -----------+-----+------+-----------
+ CASE 1
+ -----------+-----+------+-----------
+ uclamp_min | 60% | 0% | 50%
+ -----------+-----+------+-----------
+ uclamp_max | 80% | 50% | 50%
+ -----------+-----+------+-----------
+ CASE 2
+ -----------+-----+------+-----------
+ uclamp_min | 0% | 30% | 30%
+ -----------+-----+------+-----------
+ uclamp_max | 20% | 50% | 30%
+ -----------+-----+------+-----------
+
+Additionally uclamp_update_active_tasks() must now unconditionally
+update both UCLAMP_MIN/MAX because changing the tg's UCLAMP_MAX for
+instance could have an impact on the effective UCLAMP_MIN of the tasks.
+
+ | p | tg | effective
+ -----------+-----+------+-----------
+ old
+ -----------+-----+------+-----------
+ uclamp_min | 60% | 0% | 50%
+ -----------+-----+------+-----------
+ uclamp_max | 80% | 50% | 50%
+ -----------+-----+------+-----------
+ *new*
+ -----------+-----+------+-----------
+ uclamp_min | 60% | 0% | *60%*
+ -----------+-----+------+-----------
+ uclamp_max | 80% |*70%* | *70%*
+ -----------+-----+------+-----------
+
+[1] https://lore.kernel.org/lkml/CAB8ipk_a6VFNjiEnHRHkUMBKbA+qzPQvhtNjJ_YNzQhqV_o8Zw@mail.gmail.com/
+
+Fixes: 0c18f2ecfcc2 ("sched/uclamp: Fix wrong implementation of cpu.uclamp.min")
+Reported-by: Xuewen Yan <xuewen.yan94@gmail.com>
+Signed-off-by: Qais Yousef <qais.yousef@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20210617165155.3774110-1-qais.yousef@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c | 49 +++++++++++++++++----------------------------
+ 1 file changed, 18 insertions(+), 31 deletions(-)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 6e0ebc0781d1..e5858999b54d 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -1065,8 +1065,10 @@ static void uclamp_sync_util_min_rt_default(void)
+ static inline struct uclamp_se
+ uclamp_tg_restrict(struct task_struct *p, enum uclamp_id clamp_id)
+ {
++ /* Copy by value as we could modify it */
+ struct uclamp_se uc_req = p->uclamp_req[clamp_id];
+ #ifdef CONFIG_UCLAMP_TASK_GROUP
++ unsigned int tg_min, tg_max, value;
+
+ /*
+ * Tasks in autogroups or root task group will be
+@@ -1077,23 +1079,11 @@ uclamp_tg_restrict(struct task_struct *p, enum uclamp_id clamp_id)
+ if (task_group(p) == &root_task_group)
+ return uc_req;
+
+- switch (clamp_id) {
+- case UCLAMP_MIN: {
+- struct uclamp_se uc_min = task_group(p)->uclamp[clamp_id];
+- if (uc_req.value < uc_min.value)
+- return uc_min;
+- break;
+- }
+- case UCLAMP_MAX: {
+- struct uclamp_se uc_max = task_group(p)->uclamp[clamp_id];
+- if (uc_req.value > uc_max.value)
+- return uc_max;
+- break;
+- }
+- default:
+- WARN_ON_ONCE(1);
+- break;
+- }
++ tg_min = task_group(p)->uclamp[UCLAMP_MIN].value;
++ tg_max = task_group(p)->uclamp[UCLAMP_MAX].value;
++ value = uc_req.value;
++ value = clamp(value, tg_min, tg_max);
++ uclamp_se_set(&uc_req, value, false);
+ #endif
+
+ return uc_req;
+@@ -1292,8 +1282,9 @@ static inline void uclamp_rq_dec(struct rq *rq, struct task_struct *p)
+ }
+
+ static inline void
+-uclamp_update_active(struct task_struct *p, enum uclamp_id clamp_id)
++uclamp_update_active(struct task_struct *p)
+ {
++ enum uclamp_id clamp_id;
+ struct rq_flags rf;
+ struct rq *rq;
+
+@@ -1313,9 +1304,11 @@ uclamp_update_active(struct task_struct *p, enum uclamp_id clamp_id)
+ * affecting a valid clamp bucket, the next time it's enqueued,
+ * it will already see the updated clamp bucket value.
+ */
+- if (p->uclamp[clamp_id].active) {
+- uclamp_rq_dec_id(rq, p, clamp_id);
+- uclamp_rq_inc_id(rq, p, clamp_id);
++ for_each_clamp_id(clamp_id) {
++ if (p->uclamp[clamp_id].active) {
++ uclamp_rq_dec_id(rq, p, clamp_id);
++ uclamp_rq_inc_id(rq, p, clamp_id);
++ }
+ }
+
+ task_rq_unlock(rq, p, &rf);
+@@ -1323,20 +1316,14 @@ uclamp_update_active(struct task_struct *p, enum uclamp_id clamp_id)
+
+ #ifdef CONFIG_UCLAMP_TASK_GROUP
+ static inline void
+-uclamp_update_active_tasks(struct cgroup_subsys_state *css,
+- unsigned int clamps)
++uclamp_update_active_tasks(struct cgroup_subsys_state *css)
+ {
+- enum uclamp_id clamp_id;
+ struct css_task_iter it;
+ struct task_struct *p;
+
+ css_task_iter_start(css, 0, &it);
+- while ((p = css_task_iter_next(&it))) {
+- for_each_clamp_id(clamp_id) {
+- if ((0x1 << clamp_id) & clamps)
+- uclamp_update_active(p, clamp_id);
+- }
+- }
++ while ((p = css_task_iter_next(&it)))
++ uclamp_update_active(p);
+ css_task_iter_end(&it);
+ }
+
+@@ -8835,7 +8822,7 @@ static void cpu_util_update_eff(struct cgroup_subsys_state *css)
+ }
+
+ /* Immediately update descendants RUNNABLE tasks */
+- uclamp_update_active_tasks(css, clamps);
++ uclamp_update_active_tasks(css);
+ }
+ }
+
+--
+2.30.2
+
--- /dev/null
+From e14a5b24882036edae282482a098c2418a99a802 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 15:50:31 +0100
+Subject: sched/uclamp: Fix wrong implementation of cpu.uclamp.min
+
+From: Qais Yousef <qais.yousef@arm.com>
+
+[ Upstream commit 0c18f2ecfcc274a4bcc1d122f79ebd4001c3b445 ]
+
+cpu.uclamp.min is a protection as described in cgroup-v2 Resource
+Distribution Model
+
+ Documentation/admin-guide/cgroup-v2.rst
+
+which means we try our best to preserve the minimum performance point of
+tasks in this group. See full description of cpu.uclamp.min in the
+cgroup-v2.rst.
+
+But the current implementation makes it a limit, which is not what was
+intended.
+
+For example:
+
+ tg->cpu.uclamp.min = 20%
+
+ p0->uclamp[UCLAMP_MIN] = 0
+ p1->uclamp[UCLAMP_MIN] = 50%
+
+ Previous Behavior (limit):
+
+ p0->effective_uclamp = 0
+ p1->effective_uclamp = 20%
+
+ New Behavior (Protection):
+
+ p0->effective_uclamp = 20%
+ p1->effective_uclamp = 50%
+
+Which is inline with how protections should work.
+
+With this change the cgroup and per-task behaviors are the same, as
+expected.
+
+Additionally, we remove the confusing relationship between cgroup and
+!user_defined flag.
+
+We don't want for example RT tasks that are boosted by default to max to
+change their boost value when they attach to a cgroup. If a cgroup wants
+to limit the max performance point of tasks attached to it, then
+cpu.uclamp.max must be set accordingly.
+
+Or if they want to set different boost value based on cgroup, then
+sysctl_sched_util_clamp_min_rt_default must be used to NOT boost to max
+and set the right cpu.uclamp.min for each group to let the RT tasks
+obtain the desired boost value when attached to that group.
+
+As it stands the dependency on !user_defined flag adds an extra layer of
+complexity that is not required now cpu.uclamp.min behaves properly as
+a protection.
+
+The propagation model of effective cpu.uclamp.min in child cgroups as
+implemented by cpu_util_update_eff() is still correct. The parent
+protection sets an upper limit of what the child cgroups will
+effectively get.
+
+Fixes: 3eac870a3247 (sched/uclamp: Use TG's clamps to restrict TASK's clamps)
+Signed-off-by: Qais Yousef <qais.yousef@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20210510145032.1934078-2-qais.yousef@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c | 21 +++++++++++++++++----
+ 1 file changed, 17 insertions(+), 4 deletions(-)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 9724dd30ad44..49b713da023d 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -1067,7 +1067,6 @@ uclamp_tg_restrict(struct task_struct *p, enum uclamp_id clamp_id)
+ {
+ struct uclamp_se uc_req = p->uclamp_req[clamp_id];
+ #ifdef CONFIG_UCLAMP_TASK_GROUP
+- struct uclamp_se uc_max;
+
+ /*
+ * Tasks in autogroups or root task group will be
+@@ -1078,9 +1077,23 @@ uclamp_tg_restrict(struct task_struct *p, enum uclamp_id clamp_id)
+ if (task_group(p) == &root_task_group)
+ return uc_req;
+
+- uc_max = task_group(p)->uclamp[clamp_id];
+- if (uc_req.value > uc_max.value || !uc_req.user_defined)
+- return uc_max;
++ switch (clamp_id) {
++ case UCLAMP_MIN: {
++ struct uclamp_se uc_min = task_group(p)->uclamp[clamp_id];
++ if (uc_req.value < uc_min.value)
++ return uc_min;
++ break;
++ }
++ case UCLAMP_MAX: {
++ struct uclamp_se uc_max = task_group(p)->uclamp[clamp_id];
++ if (uc_req.value > uc_max.value)
++ return uc_max;
++ break;
++ }
++ default:
++ WARN_ON_ONCE(1);
++ break;
++ }
+ #endif
+
+ return uc_req;
+--
+2.30.2
+
--- /dev/null
+From 4920786e7c0dcdfbe344c1736d8f10bf31186cb9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 May 2021 16:48:57 -0700
+Subject: scsi: FlashPoint: Rename si_flags field
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 4d431153e751caa93f3b7e6f6313446974e92253 ]
+
+The BusLogic driver has build errors on ia64 due to a name collision (in
+the #included FlashPoint.c file). Rename the struct field in struct
+sccb_mgr_info from si_flags to si_mflags (manager flags) to mend the build.
+
+This is the first problem. There are 50+ others after this one:
+
+In file included from ../include/uapi/linux/signal.h:6,
+ from ../include/linux/signal_types.h:10,
+ from ../include/linux/sched.h:29,
+ from ../include/linux/hardirq.h:9,
+ from ../include/linux/interrupt.h:11,
+ from ../drivers/scsi/BusLogic.c:27:
+../arch/ia64/include/uapi/asm/siginfo.h:15:27: error: expected ':', ',', ';', '}' or '__attribute__' before '.' token
+ 15 | #define si_flags _sifields._sigfault._flags
+ | ^
+../drivers/scsi/FlashPoint.c:43:6: note: in expansion of macro 'si_flags'
+ 43 | u16 si_flags;
+ | ^~~~~~~~
+In file included from ../drivers/scsi/BusLogic.c:51:
+../drivers/scsi/FlashPoint.c: In function 'FlashPoint_ProbeHostAdapter':
+../drivers/scsi/FlashPoint.c:1076:11: error: 'struct sccb_mgr_info' has no member named '_sifields'
+ 1076 | pCardInfo->si_flags = 0x0000;
+ | ^~
+../drivers/scsi/FlashPoint.c:1079:12: error: 'struct sccb_mgr_info' has no member named '_sifields'
+
+Link: https://lore.kernel.org/r/20210529234857.6870-1-rdunlap@infradead.org
+Fixes: 391e2f25601e ("[SCSI] BusLogic: Port driver to 64-bit.")
+Cc: "James E.J. Bottomley" <jejb@linux.ibm.com>
+Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: Hannes Reinecke <hare@suse.de>
+Cc: Khalid Aziz <khalid.aziz@oracle.com>
+Cc: Khalid Aziz <khalid@gonehiking.org>
+Reported-by: kernel test robot <lkp@intel.com>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/FlashPoint.c | 32 ++++++++++++++++----------------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c
+index 0464e37c806a..2e25ef67825a 100644
+--- a/drivers/scsi/FlashPoint.c
++++ b/drivers/scsi/FlashPoint.c
+@@ -40,7 +40,7 @@ struct sccb_mgr_info {
+ u16 si_per_targ_ultra_nego;
+ u16 si_per_targ_no_disc;
+ u16 si_per_targ_wide_nego;
+- u16 si_flags;
++ u16 si_mflags;
+ unsigned char si_card_family;
+ unsigned char si_bustype;
+ unsigned char si_card_model[3];
+@@ -1073,22 +1073,22 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo)
+ ScamFlg =
+ (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
+
+- pCardInfo->si_flags = 0x0000;
++ pCardInfo->si_mflags = 0x0000;
+
+ if (i & 0x01)
+- pCardInfo->si_flags |= SCSI_PARITY_ENA;
++ pCardInfo->si_mflags |= SCSI_PARITY_ENA;
+
+ if (!(i & 0x02))
+- pCardInfo->si_flags |= SOFT_RESET;
++ pCardInfo->si_mflags |= SOFT_RESET;
+
+ if (i & 0x10)
+- pCardInfo->si_flags |= EXTENDED_TRANSLATION;
++ pCardInfo->si_mflags |= EXTENDED_TRANSLATION;
+
+ if (ScamFlg & SCAM_ENABLED)
+- pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
++ pCardInfo->si_mflags |= FLAG_SCAM_ENABLED;
+
+ if (ScamFlg & SCAM_LEVEL2)
+- pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
++ pCardInfo->si_mflags |= FLAG_SCAM_LEVEL2;
+
+ j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
+ if (i & 0x04) {
+@@ -1104,7 +1104,7 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo)
+
+ if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD))
+
+- pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
++ pCardInfo->si_mflags |= SUPPORT_16TAR_32LUN;
+
+ pCardInfo->si_card_family = HARPOON_FAMILY;
+ pCardInfo->si_bustype = BUSTYPE_PCI;
+@@ -1140,15 +1140,15 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo)
+
+ if (pCardInfo->si_card_model[1] == '3') {
+ if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
+- pCardInfo->si_flags |= LOW_BYTE_TERM;
++ pCardInfo->si_mflags |= LOW_BYTE_TERM;
+ } else if (pCardInfo->si_card_model[2] == '0') {
+ temp = RD_HARPOON(ioport + hp_xfer_pad);
+ WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4)));
+ if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
+- pCardInfo->si_flags |= LOW_BYTE_TERM;
++ pCardInfo->si_mflags |= LOW_BYTE_TERM;
+ WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4)));
+ if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
+- pCardInfo->si_flags |= HIGH_BYTE_TERM;
++ pCardInfo->si_mflags |= HIGH_BYTE_TERM;
+ WR_HARPOON(ioport + hp_xfer_pad, temp);
+ } else {
+ temp = RD_HARPOON(ioport + hp_ee_ctrl);
+@@ -1166,9 +1166,9 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo)
+ WR_HARPOON(ioport + hp_ee_ctrl, temp);
+ WR_HARPOON(ioport + hp_xfer_pad, temp2);
+ if (!(temp3 & BIT(7)))
+- pCardInfo->si_flags |= LOW_BYTE_TERM;
++ pCardInfo->si_mflags |= LOW_BYTE_TERM;
+ if (!(temp3 & BIT(6)))
+- pCardInfo->si_flags |= HIGH_BYTE_TERM;
++ pCardInfo->si_mflags |= HIGH_BYTE_TERM;
+ }
+
+ ARAM_ACCESS(ioport);
+@@ -1275,7 +1275,7 @@ static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info
+ WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id);
+ CurrCard->ourId = pCardInfo->si_id;
+
+- i = (unsigned char)pCardInfo->si_flags;
++ i = (unsigned char)pCardInfo->si_mflags;
+ if (i & SCSI_PARITY_ENA)
+ WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P));
+
+@@ -1289,14 +1289,14 @@ static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info
+ j |= SCSI_TERM_ENA_H;
+ WR_HARPOON(ioport + hp_ee_ctrl, j);
+
+- if (!(pCardInfo->si_flags & SOFT_RESET)) {
++ if (!(pCardInfo->si_mflags & SOFT_RESET)) {
+
+ FPT_sresb(ioport, thisCard);
+
+ FPT_scini(thisCard, pCardInfo->si_id, 0);
+ }
+
+- if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
++ if (pCardInfo->si_mflags & POST_ALL_UNDERRRUNS)
+ CurrCard->globalFlags |= F_NO_FILTER;
+
+ if (pCurrNvRam) {
+--
+2.30.2
+
--- /dev/null
+From d472105d0a124e921ce5c297c9bc8f2e98d6ab6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 13:18:00 -0500
+Subject: scsi: iscsi: Fix in-kernel conn failure handling
+
+From: Mike Christie <michael.christie@oracle.com>
+
+[ Upstream commit 23d6fefbb3f6b1cc29794427588b470ed06ff64e ]
+
+Commit 0ab710458da1 ("scsi: iscsi: Perform connection failure entirely in
+kernel space") has the following regressions/bugs that this patch fixes:
+
+1. It can return cmds to upper layers like dm-multipath where that can
+retry them. After they are successful the fs/app can send new I/O to the
+same sectors, but we've left the cmds running in FW or in the net layer.
+We need to be calling ep_disconnect if userspace is not up.
+
+This patch only fixes the issue for offload drivers. iscsi_tcp will be
+fixed in separate commit because it doesn't have a ep_disconnect call.
+
+2. The drivers that implement ep_disconnect expect that it's called before
+conn_stop. Besides crashes, if the cleanup_task callout is called before
+ep_disconnect it might free up driver/card resources for session1 then they
+could be allocated for session2. But because the driver's ep_disconnect is
+not called it has not cleaned up the firmware so the card is still using
+the resources for the original cmd.
+
+3. The stop_conn_work_fn can run after userspace has done its recovery and
+we are happily using the session. We will then end up with various bugs
+depending on what is going on at the time.
+
+We may also run stop_conn_work_fn late after userspace has called stop_conn
+and ep_disconnect and is now going to call start/bind conn. If
+stop_conn_work_fn runs after bind but before start, we would leave the conn
+in a unbound but sort of started state where IO might be allowed even
+though the drivers have been set in a state where they no longer expect
+I/O.
+
+4. Returning -EAGAIN in iscsi_if_destroy_conn if we haven't yet run the in
+kernel stop_conn function is breaking userspace. We should have been doing
+this for the caller.
+
+Link: https://lore.kernel.org/r/20210525181821.7617-8-michael.christie@oracle.com
+Fixes: 0ab710458da1 ("scsi: iscsi: Perform connection failure entirely in kernel space")
+Reviewed-by: Lee Duncan <lduncan@suse.com>
+Signed-off-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_transport_iscsi.c | 471 ++++++++++++++++------------
+ include/scsi/scsi_transport_iscsi.h | 10 +-
+ 2 files changed, 283 insertions(+), 198 deletions(-)
+
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index bab6654d8ee9..b8a93e607891 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -86,15 +86,11 @@ struct iscsi_internal {
+ struct transport_container session_cont;
+ };
+
+-/* Worker to perform connection failure on unresponsive connections
+- * completely in kernel space.
+- */
+-static void stop_conn_work_fn(struct work_struct *work);
+-static DECLARE_WORK(stop_conn_work, stop_conn_work_fn);
+-
+ static atomic_t iscsi_session_nr; /* sysfs session id for next new session */
+ static struct workqueue_struct *iscsi_eh_timer_workq;
+
++static struct workqueue_struct *iscsi_conn_cleanup_workq;
++
+ static DEFINE_IDA(iscsi_sess_ida);
+ /*
+ * list of registered transports and lock that must
+@@ -1623,12 +1619,6 @@ static DECLARE_TRANSPORT_CLASS(iscsi_connection_class,
+ static struct sock *nls;
+ static DEFINE_MUTEX(rx_queue_mutex);
+
+-/*
+- * conn_mutex protects the {start,bind,stop,destroy}_conn from racing
+- * against the kernel stop_connection recovery mechanism
+- */
+-static DEFINE_MUTEX(conn_mutex);
+-
+ static LIST_HEAD(sesslist);
+ static DEFINE_SPINLOCK(sesslock);
+ static LIST_HEAD(connlist);
+@@ -2245,6 +2235,123 @@ void iscsi_remove_session(struct iscsi_cls_session *session)
+ }
+ EXPORT_SYMBOL_GPL(iscsi_remove_session);
+
++static void iscsi_stop_conn(struct iscsi_cls_conn *conn, int flag)
++{
++ ISCSI_DBG_TRANS_CONN(conn, "Stopping conn.\n");
++
++ switch (flag) {
++ case STOP_CONN_RECOVER:
++ conn->state = ISCSI_CONN_FAILED;
++ break;
++ case STOP_CONN_TERM:
++ conn->state = ISCSI_CONN_DOWN;
++ break;
++ default:
++ iscsi_cls_conn_printk(KERN_ERR, conn, "invalid stop flag %d\n",
++ flag);
++ return;
++ }
++
++ conn->transport->stop_conn(conn, flag);
++ ISCSI_DBG_TRANS_CONN(conn, "Stopping conn done.\n");
++}
++
++static int iscsi_if_stop_conn(struct iscsi_transport *transport,
++ struct iscsi_uevent *ev)
++{
++ int flag = ev->u.stop_conn.flag;
++ struct iscsi_cls_conn *conn;
++
++ conn = iscsi_conn_lookup(ev->u.stop_conn.sid, ev->u.stop_conn.cid);
++ if (!conn)
++ return -EINVAL;
++
++ ISCSI_DBG_TRANS_CONN(conn, "iscsi if conn stop.\n");
++ /*
++ * If this is a termination we have to call stop_conn with that flag
++ * so the correct states get set. If we haven't run the work yet try to
++ * avoid the extra run.
++ */
++ if (flag == STOP_CONN_TERM) {
++ cancel_work_sync(&conn->cleanup_work);
++ iscsi_stop_conn(conn, flag);
++ } else {
++ /*
++ * Figure out if it was the kernel or userspace initiating this.
++ */
++ if (!test_and_set_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) {
++ iscsi_stop_conn(conn, flag);
++ } else {
++ ISCSI_DBG_TRANS_CONN(conn,
++ "flush kernel conn cleanup.\n");
++ flush_work(&conn->cleanup_work);
++ }
++ /*
++ * Only clear for recovery to avoid extra cleanup runs during
++ * termination.
++ */
++ clear_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags);
++ }
++ ISCSI_DBG_TRANS_CONN(conn, "iscsi if conn stop done.\n");
++ return 0;
++}
++
++static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active)
++{
++ struct iscsi_cls_session *session = iscsi_conn_to_session(conn);
++ struct iscsi_endpoint *ep;
++
++ ISCSI_DBG_TRANS_CONN(conn, "disconnect ep.\n");
++ conn->state = ISCSI_CONN_FAILED;
++
++ if (!conn->ep || !session->transport->ep_disconnect)
++ return;
++
++ ep = conn->ep;
++ conn->ep = NULL;
++
++ session->transport->unbind_conn(conn, is_active);
++ session->transport->ep_disconnect(ep);
++ ISCSI_DBG_TRANS_CONN(conn, "disconnect ep done.\n");
++}
++
++static void iscsi_cleanup_conn_work_fn(struct work_struct *work)
++{
++ struct iscsi_cls_conn *conn = container_of(work, struct iscsi_cls_conn,
++ cleanup_work);
++ struct iscsi_cls_session *session = iscsi_conn_to_session(conn);
++
++ mutex_lock(&conn->ep_mutex);
++ /*
++ * If we are not at least bound there is nothing for us to do. Userspace
++ * will do a ep_disconnect call if offload is used, but will not be
++ * doing a stop since there is nothing to clean up, so we have to clear
++ * the cleanup bit here.
++ */
++ if (conn->state != ISCSI_CONN_BOUND && conn->state != ISCSI_CONN_UP) {
++ ISCSI_DBG_TRANS_CONN(conn, "Got error while conn is already failed. Ignoring.\n");
++ clear_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags);
++ mutex_unlock(&conn->ep_mutex);
++ return;
++ }
++
++ iscsi_ep_disconnect(conn, false);
++
++ if (system_state != SYSTEM_RUNNING) {
++ /*
++ * If the user has set up for the session to never timeout
++ * then hang like they wanted. For all other cases fail right
++ * away since userspace is not going to relogin.
++ */
++ if (session->recovery_tmo > 0)
++ session->recovery_tmo = 0;
++ }
++
++ iscsi_stop_conn(conn, STOP_CONN_RECOVER);
++ mutex_unlock(&conn->ep_mutex);
++ ISCSI_DBG_TRANS_CONN(conn, "cleanup done.\n");
++}
++
+ void iscsi_free_session(struct iscsi_cls_session *session)
+ {
+ ISCSI_DBG_TRANS_SESSION(session, "Freeing session\n");
+@@ -2284,7 +2391,7 @@ iscsi_create_conn(struct iscsi_cls_session *session, int dd_size, uint32_t cid)
+
+ mutex_init(&conn->ep_mutex);
+ INIT_LIST_HEAD(&conn->conn_list);
+- INIT_LIST_HEAD(&conn->conn_list_err);
++ INIT_WORK(&conn->cleanup_work, iscsi_cleanup_conn_work_fn);
+ conn->transport = transport;
+ conn->cid = cid;
+ conn->state = ISCSI_CONN_DOWN;
+@@ -2341,7 +2448,6 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn)
+
+ spin_lock_irqsave(&connlock, flags);
+ list_del(&conn->conn_list);
+- list_del(&conn->conn_list_err);
+ spin_unlock_irqrestore(&connlock, flags);
+
+ transport_unregister_device(&conn->dev);
+@@ -2456,83 +2562,6 @@ int iscsi_offload_mesg(struct Scsi_Host *shost,
+ }
+ EXPORT_SYMBOL_GPL(iscsi_offload_mesg);
+
+-/*
+- * This can be called without the rx_queue_mutex, if invoked by the kernel
+- * stop work. But, in that case, it is guaranteed not to race with
+- * iscsi_destroy by conn_mutex.
+- */
+-static void iscsi_if_stop_conn(struct iscsi_cls_conn *conn, int flag)
+-{
+- /*
+- * It is important that this path doesn't rely on
+- * rx_queue_mutex, otherwise, a thread doing allocation on a
+- * start_session/start_connection could sleep waiting on a
+- * writeback to a failed iscsi device, that cannot be recovered
+- * because the lock is held. If we don't hold it here, the
+- * kernel stop_conn_work_fn has a chance to stop the broken
+- * session and resolve the allocation.
+- *
+- * Still, the user invoked .stop_conn() needs to be serialized
+- * with stop_conn_work_fn by a private mutex. Not pretty, but
+- * it works.
+- */
+- mutex_lock(&conn_mutex);
+- switch (flag) {
+- case STOP_CONN_RECOVER:
+- conn->state = ISCSI_CONN_FAILED;
+- break;
+- case STOP_CONN_TERM:
+- conn->state = ISCSI_CONN_DOWN;
+- break;
+- default:
+- iscsi_cls_conn_printk(KERN_ERR, conn,
+- "invalid stop flag %d\n", flag);
+- goto unlock;
+- }
+-
+- conn->transport->stop_conn(conn, flag);
+-unlock:
+- mutex_unlock(&conn_mutex);
+-}
+-
+-static void stop_conn_work_fn(struct work_struct *work)
+-{
+- struct iscsi_cls_conn *conn, *tmp;
+- unsigned long flags;
+- LIST_HEAD(recovery_list);
+-
+- spin_lock_irqsave(&connlock, flags);
+- if (list_empty(&connlist_err)) {
+- spin_unlock_irqrestore(&connlock, flags);
+- return;
+- }
+- list_splice_init(&connlist_err, &recovery_list);
+- spin_unlock_irqrestore(&connlock, flags);
+-
+- list_for_each_entry_safe(conn, tmp, &recovery_list, conn_list_err) {
+- uint32_t sid = iscsi_conn_get_sid(conn);
+- struct iscsi_cls_session *session;
+-
+- session = iscsi_session_lookup(sid);
+- if (session) {
+- if (system_state != SYSTEM_RUNNING) {
+- /*
+- * If the user has set up for the session to
+- * never timeout then hang like they wanted.
+- * For all other cases fail right away since
+- * userspace is not going to relogin.
+- */
+- if (session->recovery_tmo > 0)
+- session->recovery_tmo = 0;
+- }
+-
+- iscsi_if_stop_conn(conn, STOP_CONN_RECOVER);
+- }
+-
+- list_del_init(&conn->conn_list_err);
+- }
+-}
+-
+ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error)
+ {
+ struct nlmsghdr *nlh;
+@@ -2540,12 +2569,9 @@ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error)
+ struct iscsi_uevent *ev;
+ struct iscsi_internal *priv;
+ int len = nlmsg_total_size(sizeof(*ev));
+- unsigned long flags;
+
+- spin_lock_irqsave(&connlock, flags);
+- list_add(&conn->conn_list_err, &connlist_err);
+- spin_unlock_irqrestore(&connlock, flags);
+- queue_work(system_unbound_wq, &stop_conn_work);
++ if (!test_and_set_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags))
++ queue_work(iscsi_conn_cleanup_workq, &conn->cleanup_work);
+
+ priv = iscsi_if_transport_lookup(conn->transport);
+ if (!priv)
+@@ -2875,26 +2901,17 @@ static int
+ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
+ {
+ struct iscsi_cls_conn *conn;
+- unsigned long flags;
+
+ conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid);
+ if (!conn)
+ return -EINVAL;
+
+- spin_lock_irqsave(&connlock, flags);
+- if (!list_empty(&conn->conn_list_err)) {
+- spin_unlock_irqrestore(&connlock, flags);
+- return -EAGAIN;
+- }
+- spin_unlock_irqrestore(&connlock, flags);
+-
++ ISCSI_DBG_TRANS_CONN(conn, "Flushing cleanup during destruction\n");
++ flush_work(&conn->cleanup_work);
+ ISCSI_DBG_TRANS_CONN(conn, "Destroying transport conn\n");
+
+- mutex_lock(&conn_mutex);
+ if (transport->destroy_conn)
+ transport->destroy_conn(conn);
+- mutex_unlock(&conn_mutex);
+-
+ return 0;
+ }
+
+@@ -2973,7 +2990,7 @@ release_host:
+ }
+
+ static int iscsi_if_ep_disconnect(struct iscsi_transport *transport,
+- u64 ep_handle, bool is_active)
++ u64 ep_handle)
+ {
+ struct iscsi_cls_conn *conn;
+ struct iscsi_endpoint *ep;
+@@ -2984,17 +3001,30 @@ static int iscsi_if_ep_disconnect(struct iscsi_transport *transport,
+ ep = iscsi_lookup_endpoint(ep_handle);
+ if (!ep)
+ return -EINVAL;
++
+ conn = ep->conn;
+- if (conn) {
+- mutex_lock(&conn->ep_mutex);
+- conn->ep = NULL;
++ if (!conn) {
++ /*
++ * conn was not even bound yet, so we can't get iscsi conn
++ * failures yet.
++ */
++ transport->ep_disconnect(ep);
++ goto put_ep;
++ }
++
++ mutex_lock(&conn->ep_mutex);
++ /* Check if this was a conn error and the kernel took ownership */
++ if (test_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) {
++ ISCSI_DBG_TRANS_CONN(conn, "flush kernel conn cleanup.\n");
+ mutex_unlock(&conn->ep_mutex);
+- conn->state = ISCSI_CONN_FAILED;
+
+- transport->unbind_conn(conn, is_active);
++ flush_work(&conn->cleanup_work);
++ goto put_ep;
+ }
+
+- transport->ep_disconnect(ep);
++ iscsi_ep_disconnect(conn, false);
++ mutex_unlock(&conn->ep_mutex);
++put_ep:
+ iscsi_put_endpoint(ep);
+ return 0;
+ }
+@@ -3025,8 +3055,7 @@ iscsi_if_transport_ep(struct iscsi_transport *transport,
+ break;
+ case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
+ rc = iscsi_if_ep_disconnect(transport,
+- ev->u.ep_disconnect.ep_handle,
+- false);
++ ev->u.ep_disconnect.ep_handle);
+ break;
+ }
+ return rc;
+@@ -3653,18 +3682,129 @@ exit_host_stats:
+ return err;
+ }
+
++static int iscsi_if_transport_conn(struct iscsi_transport *transport,
++ struct nlmsghdr *nlh)
++{
++ struct iscsi_uevent *ev = nlmsg_data(nlh);
++ struct iscsi_cls_session *session;
++ struct iscsi_cls_conn *conn = NULL;
++ struct iscsi_endpoint *ep;
++ uint32_t pdu_len;
++ int err = 0;
++
++ switch (nlh->nlmsg_type) {
++ case ISCSI_UEVENT_CREATE_CONN:
++ return iscsi_if_create_conn(transport, ev);
++ case ISCSI_UEVENT_DESTROY_CONN:
++ return iscsi_if_destroy_conn(transport, ev);
++ case ISCSI_UEVENT_STOP_CONN:
++ return iscsi_if_stop_conn(transport, ev);
++ }
++
++ /*
++ * The following cmds need to be run under the ep_mutex so in kernel
++ * conn cleanup (ep_disconnect + unbind and conn) is not done while
++ * these are running. They also must not run if we have just run a conn
++ * cleanup because they would set the state in a way that might allow
++ * IO or send IO themselves.
++ */
++ switch (nlh->nlmsg_type) {
++ case ISCSI_UEVENT_START_CONN:
++ conn = iscsi_conn_lookup(ev->u.start_conn.sid,
++ ev->u.start_conn.cid);
++ break;
++ case ISCSI_UEVENT_BIND_CONN:
++ conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid);
++ break;
++ case ISCSI_UEVENT_SEND_PDU:
++ conn = iscsi_conn_lookup(ev->u.send_pdu.sid, ev->u.send_pdu.cid);
++ break;
++ }
++
++ if (!conn)
++ return -EINVAL;
++
++ mutex_lock(&conn->ep_mutex);
++ if (test_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) {
++ mutex_unlock(&conn->ep_mutex);
++ ev->r.retcode = -ENOTCONN;
++ return 0;
++ }
++
++ switch (nlh->nlmsg_type) {
++ case ISCSI_UEVENT_BIND_CONN:
++ if (conn->ep) {
++ /*
++ * For offload boot support where iscsid is restarted
++ * during the pivot root stage, the ep will be intact
++ * here when the new iscsid instance starts up and
++ * reconnects.
++ */
++ iscsi_ep_disconnect(conn, true);
++ }
++
++ session = iscsi_session_lookup(ev->u.b_conn.sid);
++ if (!session) {
++ err = -EINVAL;
++ break;
++ }
++
++ ev->r.retcode = transport->bind_conn(session, conn,
++ ev->u.b_conn.transport_eph,
++ ev->u.b_conn.is_leading);
++ if (!ev->r.retcode)
++ conn->state = ISCSI_CONN_BOUND;
++
++ if (ev->r.retcode || !transport->ep_connect)
++ break;
++
++ ep = iscsi_lookup_endpoint(ev->u.b_conn.transport_eph);
++ if (ep) {
++ ep->conn = conn;
++ conn->ep = ep;
++ iscsi_put_endpoint(ep);
++ } else {
++ err = -ENOTCONN;
++ iscsi_cls_conn_printk(KERN_ERR, conn,
++ "Could not set ep conn binding\n");
++ }
++ break;
++ case ISCSI_UEVENT_START_CONN:
++ ev->r.retcode = transport->start_conn(conn);
++ if (!ev->r.retcode)
++ conn->state = ISCSI_CONN_UP;
++ break;
++ case ISCSI_UEVENT_SEND_PDU:
++ pdu_len = nlh->nlmsg_len - sizeof(*nlh) - sizeof(*ev);
++
++ if ((ev->u.send_pdu.hdr_size > pdu_len) ||
++ (ev->u.send_pdu.data_size > (pdu_len - ev->u.send_pdu.hdr_size))) {
++ err = -EINVAL;
++ break;
++ }
++
++ ev->r.retcode = transport->send_pdu(conn,
++ (struct iscsi_hdr *)((char *)ev + sizeof(*ev)),
++ (char *)ev + sizeof(*ev) + ev->u.send_pdu.hdr_size,
++ ev->u.send_pdu.data_size);
++ break;
++ default:
++ err = -ENOSYS;
++ }
++
++ mutex_unlock(&conn->ep_mutex);
++ return err;
++}
+
+ static int
+ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
+ {
+ int err = 0;
+ u32 portid;
+- u32 pdu_len;
+ struct iscsi_uevent *ev = nlmsg_data(nlh);
+ struct iscsi_transport *transport = NULL;
+ struct iscsi_internal *priv;
+ struct iscsi_cls_session *session;
+- struct iscsi_cls_conn *conn;
+ struct iscsi_endpoint *ep = NULL;
+
+ if (!netlink_capable(skb, CAP_SYS_ADMIN))
+@@ -3741,90 +3881,16 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
+ else
+ err = -EINVAL;
+ break;
+- case ISCSI_UEVENT_CREATE_CONN:
+- err = iscsi_if_create_conn(transport, ev);
+- break;
+- case ISCSI_UEVENT_DESTROY_CONN:
+- err = iscsi_if_destroy_conn(transport, ev);
+- break;
+- case ISCSI_UEVENT_BIND_CONN:
+- session = iscsi_session_lookup(ev->u.b_conn.sid);
+- conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid);
+-
+- if (conn && conn->ep)
+- iscsi_if_ep_disconnect(transport, conn->ep->id, true);
+-
+- if (!session || !conn) {
+- err = -EINVAL;
+- break;
+- }
+-
+- mutex_lock(&conn_mutex);
+- ev->r.retcode = transport->bind_conn(session, conn,
+- ev->u.b_conn.transport_eph,
+- ev->u.b_conn.is_leading);
+- if (!ev->r.retcode)
+- conn->state = ISCSI_CONN_BOUND;
+- mutex_unlock(&conn_mutex);
+-
+- if (ev->r.retcode || !transport->ep_connect)
+- break;
+-
+- ep = iscsi_lookup_endpoint(ev->u.b_conn.transport_eph);
+- if (ep) {
+- ep->conn = conn;
+-
+- mutex_lock(&conn->ep_mutex);
+- conn->ep = ep;
+- mutex_unlock(&conn->ep_mutex);
+- iscsi_put_endpoint(ep);
+- } else
+- iscsi_cls_conn_printk(KERN_ERR, conn,
+- "Could not set ep conn "
+- "binding\n");
+- break;
+ case ISCSI_UEVENT_SET_PARAM:
+ err = iscsi_set_param(transport, ev);
+ break;
+- case ISCSI_UEVENT_START_CONN:
+- conn = iscsi_conn_lookup(ev->u.start_conn.sid, ev->u.start_conn.cid);
+- if (conn) {
+- mutex_lock(&conn_mutex);
+- ev->r.retcode = transport->start_conn(conn);
+- if (!ev->r.retcode)
+- conn->state = ISCSI_CONN_UP;
+- mutex_unlock(&conn_mutex);
+- }
+- else
+- err = -EINVAL;
+- break;
++ case ISCSI_UEVENT_CREATE_CONN:
++ case ISCSI_UEVENT_DESTROY_CONN:
+ case ISCSI_UEVENT_STOP_CONN:
+- conn = iscsi_conn_lookup(ev->u.stop_conn.sid, ev->u.stop_conn.cid);
+- if (conn)
+- iscsi_if_stop_conn(conn, ev->u.stop_conn.flag);
+- else
+- err = -EINVAL;
+- break;
++ case ISCSI_UEVENT_START_CONN:
++ case ISCSI_UEVENT_BIND_CONN:
+ case ISCSI_UEVENT_SEND_PDU:
+- pdu_len = nlh->nlmsg_len - sizeof(*nlh) - sizeof(*ev);
+-
+- if ((ev->u.send_pdu.hdr_size > pdu_len) ||
+- (ev->u.send_pdu.data_size > (pdu_len - ev->u.send_pdu.hdr_size))) {
+- err = -EINVAL;
+- break;
+- }
+-
+- conn = iscsi_conn_lookup(ev->u.send_pdu.sid, ev->u.send_pdu.cid);
+- if (conn) {
+- mutex_lock(&conn_mutex);
+- ev->r.retcode = transport->send_pdu(conn,
+- (struct iscsi_hdr*)((char*)ev + sizeof(*ev)),
+- (char*)ev + sizeof(*ev) + ev->u.send_pdu.hdr_size,
+- ev->u.send_pdu.data_size);
+- mutex_unlock(&conn_mutex);
+- }
+- else
+- err = -EINVAL;
++ err = iscsi_if_transport_conn(transport, nlh);
+ break;
+ case ISCSI_UEVENT_GET_STATS:
+ err = iscsi_if_get_stats(transport, nlh);
+@@ -4827,8 +4893,18 @@ static __init int iscsi_transport_init(void)
+ goto release_nls;
+ }
+
++ iscsi_conn_cleanup_workq = alloc_workqueue("%s",
++ WQ_SYSFS | WQ_MEM_RECLAIM | WQ_UNBOUND, 0,
++ "iscsi_conn_cleanup");
++ if (!iscsi_conn_cleanup_workq) {
++ err = -ENOMEM;
++ goto destroy_wq;
++ }
++
+ return 0;
+
++destroy_wq:
++ destroy_workqueue(iscsi_eh_timer_workq);
+ release_nls:
+ netlink_kernel_release(nls);
+ unregister_flashnode_bus:
+@@ -4850,6 +4926,7 @@ unregister_transport_class:
+
+ static void __exit iscsi_transport_exit(void)
+ {
++ destroy_workqueue(iscsi_conn_cleanup_workq);
+ destroy_workqueue(iscsi_eh_timer_workq);
+ netlink_kernel_release(nls);
+ bus_unregister(&iscsi_flashnode_bus);
+diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
+index d36a72cf049f..3974329d4d02 100644
+--- a/include/scsi/scsi_transport_iscsi.h
++++ b/include/scsi/scsi_transport_iscsi.h
+@@ -197,15 +197,23 @@ enum iscsi_connection_state {
+ ISCSI_CONN_BOUND,
+ };
+
++#define ISCSI_CLS_CONN_BIT_CLEANUP 1
++
+ struct iscsi_cls_conn {
+ struct list_head conn_list; /* item in connlist */
+- struct list_head conn_list_err; /* item in connlist_err */
+ void *dd_data; /* LLD private data */
+ struct iscsi_transport *transport;
+ uint32_t cid; /* connection id */
++ /*
++ * This protects the conn startup and binding/unbinding of the ep to
++ * the conn. Unbinding includes ep_disconnect and stop_conn.
++ */
+ struct mutex ep_mutex;
+ struct iscsi_endpoint *ep;
+
++ unsigned long flags;
++ struct work_struct cleanup_work;
++
+ struct device dev; /* sysfs transport/container device */
+ enum iscsi_connection_state state;
+ };
+--
+2.30.2
+
--- /dev/null
+From 5b3cf57da1a358b41ca11453c94d7313e4b31f9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 13:18:09 -0500
+Subject: scsi: iscsi: Flush block work before unblock
+
+From: Mike Christie <michael.christie@oracle.com>
+
+[ Upstream commit 7ce9fc5ecde0d8bd64c29baee6c5e3ce7074ec9a ]
+
+We set the max_active iSCSI EH works to 1, so all work is going to execute
+in order by default. However, userspace can now override this in sysfs. If
+max_active > 1, we can end up with the block_work on CPU1 and
+iscsi_unblock_session running the unblock_work on CPU2 and the session and
+target/device state will end up out of sync with each other.
+
+This adds a flush of the block_work in iscsi_unblock_session.
+
+Link: https://lore.kernel.org/r/20210525181821.7617-17-michael.christie@oracle.com
+Fixes: 1d726aa6ef57 ("scsi: iscsi: Optimize work queue flush use")
+Reviewed-by: Lee Duncan <lduncan@suse.com>
+Signed-off-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_transport_iscsi.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index b8a93e607891..6ce1cc992d1d 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -1969,6 +1969,8 @@ static void __iscsi_unblock_session(struct work_struct *work)
+ */
+ void iscsi_unblock_session(struct iscsi_cls_session *session)
+ {
++ flush_work(&session->block_work);
++
+ queue_work(iscsi_eh_timer_workq, &session->unblock_work);
+ /*
+ * Blocking the session can be done from any context so we only
+--
+2.30.2
+
--- /dev/null
+From 1cb12e22cc5ec6adf32f699d65a2a2acdd0a4b16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 13:17:57 -0500
+Subject: scsi: iscsi: Force immediate failure during shutdown
+
+From: Mike Christie <michael.christie@oracle.com>
+
+[ Upstream commit 06c203a5566beecebb1f8838d026de8a61c8df71 ]
+
+If the system is not up, we can just fail immediately since iscsid is not
+going to ever answer our netlink events. We are already setting the
+recovery_tmo to 0, but by passing stop_conn STOP_CONN_TERM we never will
+block the session and start the recovery timer, because for that flag
+userspace will do the unbind and destroy events which would remove the
+devices and wake up and kill the eh.
+
+Since the conn is dead and the system is going dowm this just has us use
+STOP_CONN_RECOVER with recovery_tmo=0 so we fail immediately. However, if
+the user has set the recovery_tmo=-1 we let the system hang like they
+requested since they might have used that setting for specific reasons
+(one known reason is for buggy cluster software).
+
+Link: https://lore.kernel.org/r/20210525181821.7617-5-michael.christie@oracle.com
+Signed-off-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_transport_iscsi.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index 82491343e94a..d134156d67f0 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -2513,11 +2513,17 @@ static void stop_conn_work_fn(struct work_struct *work)
+ session = iscsi_session_lookup(sid);
+ if (session) {
+ if (system_state != SYSTEM_RUNNING) {
+- session->recovery_tmo = 0;
+- iscsi_if_stop_conn(conn, STOP_CONN_TERM);
+- } else {
+- iscsi_if_stop_conn(conn, STOP_CONN_RECOVER);
++ /*
++ * If the user has set up for the session to
++ * never timeout then hang like they wanted.
++ * For all other cases fail right away since
++ * userspace is not going to relogin.
++ */
++ if (session->recovery_tmo > 0)
++ session->recovery_tmo = 0;
+ }
++
++ iscsi_if_stop_conn(conn, STOP_CONN_RECOVER);
+ }
+
+ list_del_init(&conn->conn_list_err);
+--
+2.30.2
+
--- /dev/null
+From be43bcc3116876d508ff031dbd836789babfffa9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 13:17:59 -0500
+Subject: scsi: iscsi: Rel ref after iscsi_lookup_endpoint()
+
+From: Mike Christie <michael.christie@oracle.com>
+
+[ Upstream commit 9e5fe1700896c85040943fdc0d3fee0dd3e0d36f ]
+
+Subsequent commits allow the kernel to do ep_disconnect. In that case we
+will have to get a proper refcount on the ep so one thread does not delete
+it from under another.
+
+Link: https://lore.kernel.org/r/20210525181821.7617-7-michael.christie@oracle.com
+Reviewed-by: Lee Duncan <lduncan@suse.com>
+Signed-off-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/iser/iscsi_iser.c | 1 +
+ drivers/scsi/be2iscsi/be_iscsi.c | 19 ++++++++++++------
+ drivers/scsi/bnx2i/bnx2i_iscsi.c | 23 +++++++++++++++-------
+ drivers/scsi/cxgbi/libcxgbi.c | 12 ++++++++----
+ drivers/scsi/qedi/qedi_iscsi.c | 25 +++++++++++++++++-------
+ drivers/scsi/qla4xxx/ql4_os.c | 1 +
+ drivers/scsi/scsi_transport_iscsi.c | 25 ++++++++++++++++--------
+ include/scsi/scsi_transport_iscsi.h | 1 +
+ 8 files changed, 75 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
+index 6baebcb6d14d..776e46ee95da 100644
+--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
++++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
+@@ -506,6 +506,7 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session,
+ iser_conn->iscsi_conn = conn;
+
+ out:
++ iscsi_put_endpoint(ep);
+ mutex_unlock(&iser_conn->state_mutex);
+ return error;
+ }
+diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
+index 0e935c49b57b..dd419e295184 100644
+--- a/drivers/scsi/be2iscsi/be_iscsi.c
++++ b/drivers/scsi/be2iscsi/be_iscsi.c
+@@ -182,6 +182,7 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
+ struct beiscsi_endpoint *beiscsi_ep;
+ struct iscsi_endpoint *ep;
+ uint16_t cri_index;
++ int rc = 0;
+
+ ep = iscsi_lookup_endpoint(transport_fd);
+ if (!ep)
+@@ -189,15 +190,17 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
+
+ beiscsi_ep = ep->dd_data;
+
+- if (iscsi_conn_bind(cls_session, cls_conn, is_leading))
+- return -EINVAL;
++ if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) {
++ rc = -EINVAL;
++ goto put_ep;
++ }
+
+ if (beiscsi_ep->phba != phba) {
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : beiscsi_ep->hba=%p not equal to phba=%p\n",
+ beiscsi_ep->phba, phba);
+-
+- return -EEXIST;
++ rc = -EEXIST;
++ goto put_ep;
+ }
+ cri_index = BE_GET_CRI_FROM_CID(beiscsi_ep->ep_cid);
+ if (phba->conn_table[cri_index]) {
+@@ -209,7 +212,8 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
+ beiscsi_ep->ep_cid,
+ beiscsi_conn,
+ phba->conn_table[cri_index]);
+- return -EINVAL;
++ rc = -EINVAL;
++ goto put_ep;
+ }
+ }
+
+@@ -226,7 +230,10 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
+ "BS_%d : cid %d phba->conn_table[%u]=%p\n",
+ beiscsi_ep->ep_cid, cri_index, beiscsi_conn);
+ phba->conn_table[cri_index] = beiscsi_conn;
+- return 0;
++
++put_ep:
++ iscsi_put_endpoint(ep);
++ return rc;
+ }
+
+ static int beiscsi_iface_create_ipv4(struct beiscsi_hba *phba)
+diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
+index b6c1da46d582..2ad85c6b99fd 100644
+--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
++++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
+@@ -1420,17 +1420,23 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session,
+ * Forcefully terminate all in progress connection recovery at the
+ * earliest, either in bind(), send_pdu(LOGIN), or conn_start()
+ */
+- if (bnx2i_adapter_ready(hba))
+- return -EIO;
++ if (bnx2i_adapter_ready(hba)) {
++ ret_code = -EIO;
++ goto put_ep;
++ }
+
+ bnx2i_ep = ep->dd_data;
+ if ((bnx2i_ep->state == EP_STATE_TCP_FIN_RCVD) ||
+- (bnx2i_ep->state == EP_STATE_TCP_RST_RCVD))
++ (bnx2i_ep->state == EP_STATE_TCP_RST_RCVD)) {
+ /* Peer disconnect via' FIN or RST */
+- return -EINVAL;
++ ret_code = -EINVAL;
++ goto put_ep;
++ }
+
+- if (iscsi_conn_bind(cls_session, cls_conn, is_leading))
+- return -EINVAL;
++ if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) {
++ ret_code = -EINVAL;
++ goto put_ep;
++ }
+
+ if (bnx2i_ep->hba != hba) {
+ /* Error - TCP connection does not belong to this device
+@@ -1441,7 +1447,8 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session,
+ iscsi_conn_printk(KERN_ALERT, cls_conn->dd_data,
+ "belong to hba (%s)\n",
+ hba->netdev->name);
+- return -EEXIST;
++ ret_code = -EEXIST;
++ goto put_ep;
+ }
+ bnx2i_ep->conn = bnx2i_conn;
+ bnx2i_conn->ep = bnx2i_ep;
+@@ -1458,6 +1465,8 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session,
+ bnx2i_put_rq_buf(bnx2i_conn, 0);
+
+ bnx2i_arm_cq_event_coalescing(bnx2i_conn->ep, CNIC_ARM_CQE);
++put_ep:
++ iscsi_put_endpoint(ep);
+ return ret_code;
+ }
+
+diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
+index f078b3c4e083..f6bcae829c29 100644
+--- a/drivers/scsi/cxgbi/libcxgbi.c
++++ b/drivers/scsi/cxgbi/libcxgbi.c
+@@ -2690,11 +2690,13 @@ int cxgbi_bind_conn(struct iscsi_cls_session *cls_session,
+ err = csk->cdev->csk_ddp_setup_pgidx(csk, csk->tid,
+ ppm->tformat.pgsz_idx_dflt);
+ if (err < 0)
+- return err;
++ goto put_ep;
+
+ err = iscsi_conn_bind(cls_session, cls_conn, is_leading);
+- if (err)
+- return -EINVAL;
++ if (err) {
++ err = -EINVAL;
++ goto put_ep;
++ }
+
+ /* calculate the tag idx bits needed for this conn based on cmds_max */
+ cconn->task_idx_bits = (__ilog2_u32(conn->session->cmds_max - 1)) + 1;
+@@ -2715,7 +2717,9 @@ int cxgbi_bind_conn(struct iscsi_cls_session *cls_session,
+ /* init recv engine */
+ iscsi_tcp_hdr_recv_prep(tcp_conn);
+
+- return 0;
++put_ep:
++ iscsi_put_endpoint(ep);
++ return err;
+ }
+ EXPORT_SYMBOL_GPL(cxgbi_bind_conn);
+
+diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c
+index ef16537c523c..087c7ff28cd5 100644
+--- a/drivers/scsi/qedi/qedi_iscsi.c
++++ b/drivers/scsi/qedi/qedi_iscsi.c
+@@ -377,6 +377,7 @@ static int qedi_conn_bind(struct iscsi_cls_session *cls_session,
+ struct qedi_ctx *qedi = iscsi_host_priv(shost);
+ struct qedi_endpoint *qedi_ep;
+ struct iscsi_endpoint *ep;
++ int rc = 0;
+
+ ep = iscsi_lookup_endpoint(transport_fd);
+ if (!ep)
+@@ -384,11 +385,16 @@ static int qedi_conn_bind(struct iscsi_cls_session *cls_session,
+
+ qedi_ep = ep->dd_data;
+ if ((qedi_ep->state == EP_STATE_TCP_FIN_RCVD) ||
+- (qedi_ep->state == EP_STATE_TCP_RST_RCVD))
+- return -EINVAL;
++ (qedi_ep->state == EP_STATE_TCP_RST_RCVD)) {
++ rc = -EINVAL;
++ goto put_ep;
++ }
++
++ if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) {
++ rc = -EINVAL;
++ goto put_ep;
++ }
+
+- if (iscsi_conn_bind(cls_session, cls_conn, is_leading))
+- return -EINVAL;
+
+ qedi_ep->conn = qedi_conn;
+ qedi_conn->ep = qedi_ep;
+@@ -398,13 +404,18 @@ static int qedi_conn_bind(struct iscsi_cls_session *cls_session,
+ qedi_conn->cmd_cleanup_req = 0;
+ qedi_conn->cmd_cleanup_cmpl = 0;
+
+- if (qedi_bind_conn_to_iscsi_cid(qedi, qedi_conn))
+- return -EINVAL;
++ if (qedi_bind_conn_to_iscsi_cid(qedi, qedi_conn)) {
++ rc = -EINVAL;
++ goto put_ep;
++ }
++
+
+ spin_lock_init(&qedi_conn->tmf_work_lock);
+ INIT_LIST_HEAD(&qedi_conn->tmf_work_list);
+ init_waitqueue_head(&qedi_conn->wait_queue);
+- return 0;
++put_ep:
++ iscsi_put_endpoint(ep);
++ return rc;
+ }
+
+ static int qedi_iscsi_update_conn(struct qedi_ctx *qedi,
+diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
+index 74d0d1bc208d..0e7a7e82e028 100644
+--- a/drivers/scsi/qla4xxx/ql4_os.c
++++ b/drivers/scsi/qla4xxx/ql4_os.c
+@@ -3235,6 +3235,7 @@ static int qla4xxx_conn_bind(struct iscsi_cls_session *cls_session,
+ conn = cls_conn->dd_data;
+ qla_conn = conn->dd_data;
+ qla_conn->qla_ep = ep->dd_data;
++ iscsi_put_endpoint(ep);
+ return 0;
+ }
+
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index 2eb77f69fe0c..bab6654d8ee9 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -266,9 +266,20 @@ void iscsi_destroy_endpoint(struct iscsi_endpoint *ep)
+ }
+ EXPORT_SYMBOL_GPL(iscsi_destroy_endpoint);
+
++void iscsi_put_endpoint(struct iscsi_endpoint *ep)
++{
++ put_device(&ep->dev);
++}
++EXPORT_SYMBOL_GPL(iscsi_put_endpoint);
++
++/**
++ * iscsi_lookup_endpoint - get ep from handle
++ * @handle: endpoint handle
++ *
++ * Caller must do a iscsi_put_endpoint.
++ */
+ struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle)
+ {
+- struct iscsi_endpoint *ep;
+ struct device *dev;
+
+ dev = class_find_device(&iscsi_endpoint_class, NULL, &handle,
+@@ -276,13 +287,7 @@ struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle)
+ if (!dev)
+ return NULL;
+
+- ep = iscsi_dev_to_endpoint(dev);
+- /*
+- * we can drop this now because the interface will prevent
+- * removals and lookups from racing.
+- */
+- put_device(dev);
+- return ep;
++ return iscsi_dev_to_endpoint(dev);
+ }
+ EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint);
+
+@@ -2990,6 +2995,7 @@ static int iscsi_if_ep_disconnect(struct iscsi_transport *transport,
+ }
+
+ transport->ep_disconnect(ep);
++ iscsi_put_endpoint(ep);
+ return 0;
+ }
+
+@@ -3015,6 +3021,7 @@ iscsi_if_transport_ep(struct iscsi_transport *transport,
+
+ ev->r.retcode = transport->ep_poll(ep,
+ ev->u.ep_poll.timeout_ms);
++ iscsi_put_endpoint(ep);
+ break;
+ case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
+ rc = iscsi_if_ep_disconnect(transport,
+@@ -3698,6 +3705,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
+ ev->u.c_bound_session.initial_cmdsn,
+ ev->u.c_bound_session.cmds_max,
+ ev->u.c_bound_session.queue_depth);
++ iscsi_put_endpoint(ep);
+ break;
+ case ISCSI_UEVENT_DESTROY_SESSION:
+ session = iscsi_session_lookup(ev->u.d_session.sid);
+@@ -3769,6 +3777,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
+ mutex_lock(&conn->ep_mutex);
+ conn->ep = ep;
+ mutex_unlock(&conn->ep_mutex);
++ iscsi_put_endpoint(ep);
+ } else
+ iscsi_cls_conn_printk(KERN_ERR, conn,
+ "Could not set ep conn "
+diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
+index 8874016b3c9a..d36a72cf049f 100644
+--- a/include/scsi/scsi_transport_iscsi.h
++++ b/include/scsi/scsi_transport_iscsi.h
+@@ -442,6 +442,7 @@ extern int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time);
+ extern struct iscsi_endpoint *iscsi_create_endpoint(int dd_size);
+ extern void iscsi_destroy_endpoint(struct iscsi_endpoint *ep);
+ extern struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle);
++extern void iscsi_put_endpoint(struct iscsi_endpoint *ep);
+ extern int iscsi_block_scsi_eh(struct scsi_cmnd *cmd);
+ extern struct iscsi_iface *iscsi_create_iface(struct Scsi_Host *shost,
+ struct iscsi_transport *t,
+--
+2.30.2
+
--- /dev/null
+From b93b4657e1b7b7939036c96db5178df6761cd754 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 13:17:55 -0500
+Subject: scsi: iscsi: Stop queueing during ep_disconnect
+
+From: Mike Christie <michael.christie@oracle.com>
+
+[ Upstream commit 891e2639deae721dc43764a44fa255890dc34313 ]
+
+During ep_disconnect we have been doing iscsi_suspend_tx/queue to block new
+I/O but every driver except cxgbi and iscsi_tcp can still get I/O from
+__iscsi_conn_send_pdu() if we haven't called iscsi_conn_failure() before
+ep_disconnect. This could happen if we were terminating the session, and
+the logout timed out before it was even sent to libiscsi.
+
+Fix the issue by adding a helper which reverses the bind_conn call that
+allows new I/O to be queued. Drivers implementing ep_disconnect can use this
+to make sure new I/O is not queued to them when handling the disconnect.
+
+Link: https://lore.kernel.org/r/20210525181821.7617-3-michael.christie@oracle.com
+Reviewed-by: Lee Duncan <lduncan@suse.com>
+Signed-off-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/iser/iscsi_iser.c | 1 +
+ drivers/scsi/be2iscsi/be_main.c | 1 +
+ drivers/scsi/bnx2i/bnx2i_iscsi.c | 1 +
+ drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | 1 +
+ drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 1 +
+ drivers/scsi/libiscsi.c | 70 +++++++++++++++++++++---
+ drivers/scsi/qedi/qedi_iscsi.c | 1 +
+ drivers/scsi/qla4xxx/ql4_os.c | 1 +
+ drivers/scsi/scsi_transport_iscsi.c | 10 +++-
+ include/scsi/libiscsi.h | 1 +
+ include/scsi/scsi_transport_iscsi.h | 1 +
+ 11 files changed, 78 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
+index 8fcaa1136f2c..6baebcb6d14d 100644
+--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
++++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
+@@ -1002,6 +1002,7 @@ static struct iscsi_transport iscsi_iser_transport = {
+ /* connection management */
+ .create_conn = iscsi_iser_conn_create,
+ .bind_conn = iscsi_iser_conn_bind,
++ .unbind_conn = iscsi_conn_unbind,
+ .destroy_conn = iscsi_conn_teardown,
+ .attr_is_visible = iser_attr_is_visible,
+ .set_param = iscsi_iser_set_param,
+diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
+index 22cf7f4b8d8c..27c4f1598f76 100644
+--- a/drivers/scsi/be2iscsi/be_main.c
++++ b/drivers/scsi/be2iscsi/be_main.c
+@@ -5809,6 +5809,7 @@ struct iscsi_transport beiscsi_iscsi_transport = {
+ .destroy_session = beiscsi_session_destroy,
+ .create_conn = beiscsi_conn_create,
+ .bind_conn = beiscsi_conn_bind,
++ .unbind_conn = iscsi_conn_unbind,
+ .destroy_conn = iscsi_conn_teardown,
+ .attr_is_visible = beiscsi_attr_is_visible,
+ .set_iface_param = beiscsi_iface_set_param,
+diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
+index 1e6d8f62ea3c..b6c1da46d582 100644
+--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
++++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
+@@ -2276,6 +2276,7 @@ struct iscsi_transport bnx2i_iscsi_transport = {
+ .destroy_session = bnx2i_session_destroy,
+ .create_conn = bnx2i_conn_create,
+ .bind_conn = bnx2i_conn_bind,
++ .unbind_conn = iscsi_conn_unbind,
+ .destroy_conn = bnx2i_conn_destroy,
+ .attr_is_visible = bnx2i_attr_is_visible,
+ .set_param = iscsi_set_param,
+diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
+index 203f938fca7e..f949a4e00783 100644
+--- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
++++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
+@@ -117,6 +117,7 @@ static struct iscsi_transport cxgb3i_iscsi_transport = {
+ /* connection management */
+ .create_conn = cxgbi_create_conn,
+ .bind_conn = cxgbi_bind_conn,
++ .unbind_conn = iscsi_conn_unbind,
+ .destroy_conn = iscsi_tcp_conn_teardown,
+ .start_conn = iscsi_conn_start,
+ .stop_conn = iscsi_conn_stop,
+diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+index 2c3491528d42..efb3e2b3398e 100644
+--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
++++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+@@ -134,6 +134,7 @@ static struct iscsi_transport cxgb4i_iscsi_transport = {
+ /* connection management */
+ .create_conn = cxgbi_create_conn,
+ .bind_conn = cxgbi_bind_conn,
++ .unbind_conn = iscsi_conn_unbind,
+ .destroy_conn = iscsi_tcp_conn_teardown,
+ .start_conn = iscsi_conn_start,
+ .stop_conn = iscsi_conn_stop,
+diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
+index 4834219497ee..2aaf83678654 100644
+--- a/drivers/scsi/libiscsi.c
++++ b/drivers/scsi/libiscsi.c
+@@ -1387,23 +1387,32 @@ void iscsi_session_failure(struct iscsi_session *session,
+ }
+ EXPORT_SYMBOL_GPL(iscsi_session_failure);
+
+-void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
++static bool iscsi_set_conn_failed(struct iscsi_conn *conn)
+ {
+ struct iscsi_session *session = conn->session;
+
+- spin_lock_bh(&session->frwd_lock);
+- if (session->state == ISCSI_STATE_FAILED) {
+- spin_unlock_bh(&session->frwd_lock);
+- return;
+- }
++ if (session->state == ISCSI_STATE_FAILED)
++ return false;
+
+ if (conn->stop_stage == 0)
+ session->state = ISCSI_STATE_FAILED;
+- spin_unlock_bh(&session->frwd_lock);
+
+ set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
+ set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
+- iscsi_conn_error_event(conn->cls_conn, err);
++ return true;
++}
++
++void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
++{
++ struct iscsi_session *session = conn->session;
++ bool needs_evt;
++
++ spin_lock_bh(&session->frwd_lock);
++ needs_evt = iscsi_set_conn_failed(conn);
++ spin_unlock_bh(&session->frwd_lock);
++
++ if (needs_evt)
++ iscsi_conn_error_event(conn->cls_conn, err);
+ }
+ EXPORT_SYMBOL_GPL(iscsi_conn_failure);
+
+@@ -2180,6 +2189,51 @@ done:
+ spin_unlock(&session->frwd_lock);
+ }
+
++/**
++ * iscsi_conn_unbind - prevent queueing to conn.
++ * @cls_conn: iscsi conn ep is bound to.
++ * @is_active: is the conn in use for boot or is this for EH/termination
++ *
++ * This must be called by drivers implementing the ep_disconnect callout.
++ * It disables queueing to the connection from libiscsi in preparation for
++ * an ep_disconnect call.
++ */
++void iscsi_conn_unbind(struct iscsi_cls_conn *cls_conn, bool is_active)
++{
++ struct iscsi_session *session;
++ struct iscsi_conn *conn;
++
++ if (!cls_conn)
++ return;
++
++ conn = cls_conn->dd_data;
++ session = conn->session;
++ /*
++ * Wait for iscsi_eh calls to exit. We don't wait for the tmf to
++ * complete or timeout. The caller just wants to know what's running
++ * is everything that needs to be cleaned up, and no cmds will be
++ * queued.
++ */
++ mutex_lock(&session->eh_mutex);
++
++ iscsi_suspend_queue(conn);
++ iscsi_suspend_tx(conn);
++
++ spin_lock_bh(&session->frwd_lock);
++ if (!is_active) {
++ /*
++ * if logout timed out before userspace could even send a PDU
++ * the state might still be in ISCSI_STATE_LOGGED_IN and
++ * allowing new cmds and TMFs.
++ */
++ if (session->state == ISCSI_STATE_LOGGED_IN)
++ iscsi_set_conn_failed(conn);
++ }
++ spin_unlock_bh(&session->frwd_lock);
++ mutex_unlock(&session->eh_mutex);
++}
++EXPORT_SYMBOL_GPL(iscsi_conn_unbind);
++
+ static void iscsi_prep_abort_task_pdu(struct iscsi_task *task,
+ struct iscsi_tm *hdr)
+ {
+diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c
+index 08c05403cd72..ef16537c523c 100644
+--- a/drivers/scsi/qedi/qedi_iscsi.c
++++ b/drivers/scsi/qedi/qedi_iscsi.c
+@@ -1401,6 +1401,7 @@ struct iscsi_transport qedi_iscsi_transport = {
+ .destroy_session = qedi_session_destroy,
+ .create_conn = qedi_conn_create,
+ .bind_conn = qedi_conn_bind,
++ .unbind_conn = iscsi_conn_unbind,
+ .start_conn = qedi_conn_start,
+ .stop_conn = iscsi_conn_stop,
+ .destroy_conn = qedi_conn_destroy,
+diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
+index ad3afe30f617..74d0d1bc208d 100644
+--- a/drivers/scsi/qla4xxx/ql4_os.c
++++ b/drivers/scsi/qla4xxx/ql4_os.c
+@@ -259,6 +259,7 @@ static struct iscsi_transport qla4xxx_iscsi_transport = {
+ .start_conn = qla4xxx_conn_start,
+ .create_conn = qla4xxx_conn_create,
+ .bind_conn = qla4xxx_conn_bind,
++ .unbind_conn = iscsi_conn_unbind,
+ .stop_conn = iscsi_conn_stop,
+ .destroy_conn = qla4xxx_conn_destroy,
+ .set_param = iscsi_set_param,
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index 441f0152193f..82491343e94a 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -2964,7 +2964,7 @@ release_host:
+ }
+
+ static int iscsi_if_ep_disconnect(struct iscsi_transport *transport,
+- u64 ep_handle)
++ u64 ep_handle, bool is_active)
+ {
+ struct iscsi_cls_conn *conn;
+ struct iscsi_endpoint *ep;
+@@ -2981,6 +2981,8 @@ static int iscsi_if_ep_disconnect(struct iscsi_transport *transport,
+ conn->ep = NULL;
+ mutex_unlock(&conn->ep_mutex);
+ conn->state = ISCSI_CONN_FAILED;
++
++ transport->unbind_conn(conn, is_active);
+ }
+
+ transport->ep_disconnect(ep);
+@@ -3012,7 +3014,8 @@ iscsi_if_transport_ep(struct iscsi_transport *transport,
+ break;
+ case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
+ rc = iscsi_if_ep_disconnect(transport,
+- ev->u.ep_disconnect.ep_handle);
++ ev->u.ep_disconnect.ep_handle,
++ false);
+ break;
+ }
+ return rc;
+@@ -3737,7 +3740,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
+ conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid);
+
+ if (conn && conn->ep)
+- iscsi_if_ep_disconnect(transport, conn->ep->id);
++ iscsi_if_ep_disconnect(transport, conn->ep->id, true);
+
+ if (!session || !conn) {
+ err = -EINVAL;
+@@ -4656,6 +4659,7 @@ iscsi_register_transport(struct iscsi_transport *tt)
+ int err;
+
+ BUG_ON(!tt);
++ WARN_ON(tt->ep_disconnect && !tt->unbind_conn);
+
+ priv = iscsi_if_transport_lookup(tt);
+ if (priv)
+diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
+index 02f966e9358f..091f284bd6e9 100644
+--- a/include/scsi/libiscsi.h
++++ b/include/scsi/libiscsi.h
+@@ -424,6 +424,7 @@ extern int iscsi_conn_start(struct iscsi_cls_conn *);
+ extern void iscsi_conn_stop(struct iscsi_cls_conn *, int);
+ extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *,
+ int);
++extern void iscsi_conn_unbind(struct iscsi_cls_conn *cls_conn, bool is_active);
+ extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err);
+ extern void iscsi_session_failure(struct iscsi_session *session,
+ enum iscsi_err err);
+diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
+index fc5a39839b4b..8874016b3c9a 100644
+--- a/include/scsi/scsi_transport_iscsi.h
++++ b/include/scsi/scsi_transport_iscsi.h
+@@ -82,6 +82,7 @@ struct iscsi_transport {
+ void (*destroy_session) (struct iscsi_cls_session *session);
+ struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess,
+ uint32_t cid);
++ void (*unbind_conn) (struct iscsi_cls_conn *conn, bool is_active);
+ int (*bind_conn) (struct iscsi_cls_session *session,
+ struct iscsi_cls_conn *cls_conn,
+ uint64_t transport_eph, int is_leading);
+--
+2.30.2
+
--- /dev/null
+From bfb0599f073d1649a089cd86fae4e3b0e1c28cd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 13:17:58 -0500
+Subject: scsi: iscsi: Use system_unbound_wq for destroy_work
+
+From: Mike Christie <michael.christie@oracle.com>
+
+[ Upstream commit b25b957d2db1585602c2c70fdf4261a5641fe6b7 ]
+
+Use the system_unbound_wq for async session destruction. We don't need a
+dedicated workqueue for async session destruction because:
+
+ 1. perf does not seem to be an issue since we only allow 1 active work.
+
+ 2. it does not have deps with other system works and we can run them in
+ parallel with each other.
+
+Link: https://lore.kernel.org/r/20210525181821.7617-6-michael.christie@oracle.com
+Reviewed-by: Lee Duncan <lduncan@suse.com>
+Signed-off-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_transport_iscsi.c | 15 +--------------
+ 1 file changed, 1 insertion(+), 14 deletions(-)
+
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index d134156d67f0..2eb77f69fe0c 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -95,8 +95,6 @@ static DECLARE_WORK(stop_conn_work, stop_conn_work_fn);
+ static atomic_t iscsi_session_nr; /* sysfs session id for next new session */
+ static struct workqueue_struct *iscsi_eh_timer_workq;
+
+-static struct workqueue_struct *iscsi_destroy_workq;
+-
+ static DEFINE_IDA(iscsi_sess_ida);
+ /*
+ * list of registered transports and lock that must
+@@ -3724,7 +3722,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
+ list_del_init(&session->sess_list);
+ spin_unlock_irqrestore(&sesslock, flags);
+
+- queue_work(iscsi_destroy_workq, &session->destroy_work);
++ queue_work(system_unbound_wq, &session->destroy_work);
+ }
+ break;
+ case ISCSI_UEVENT_UNBIND_SESSION:
+@@ -4820,18 +4818,8 @@ static __init int iscsi_transport_init(void)
+ goto release_nls;
+ }
+
+- iscsi_destroy_workq = alloc_workqueue("%s",
+- WQ_SYSFS | __WQ_LEGACY | WQ_MEM_RECLAIM | WQ_UNBOUND,
+- 1, "iscsi_destroy");
+- if (!iscsi_destroy_workq) {
+- err = -ENOMEM;
+- goto destroy_wq;
+- }
+-
+ return 0;
+
+-destroy_wq:
+- destroy_workqueue(iscsi_eh_timer_workq);
+ release_nls:
+ netlink_kernel_release(nls);
+ unregister_flashnode_bus:
+@@ -4853,7 +4841,6 @@ unregister_transport_class:
+
+ static void __exit iscsi_transport_exit(void)
+ {
+- destroy_workqueue(iscsi_destroy_workq);
+ destroy_workqueue(iscsi_eh_timer_workq);
+ netlink_kernel_release(nls);
+ bus_unregister(&iscsi_flashnode_bus);
+--
+2.30.2
+
--- /dev/null
+From ec50e2e5c74d02fdac1064fd9e0a87b33c1bc774 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 May 2021 16:13:00 +0800
+Subject: scsi: mpt3sas: Fix error return value in _scsih_expander_add()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit d6c2ce435ffe23ef7f395ae76ec747414589db46 ]
+
+When an expander does not contain any 'phys', an appropriate error code -1
+should be returned, as done elsewhere in this function. However, we
+currently do not explicitly assign this error code to 'rc'. As a result, 0
+was incorrectly returned.
+
+Link: https://lore.kernel.org/r/20210514081300.6650-1-thunder.leizhen@huawei.com
+Fixes: f92363d12359 ("[SCSI] mpt3sas: add new driver supporting 12GB SAS")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpt3sas/mpt3sas_scsih.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+index d00aca3c77ce..a5f70f0e0287 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+@@ -6884,8 +6884,10 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle)
+ handle, parent_handle,
+ (u64)sas_expander->sas_address, sas_expander->num_phys);
+
+- if (!sas_expander->num_phys)
++ if (!sas_expander->num_phys) {
++ rc = -1;
+ goto out_fail;
++ }
+ sas_expander->phy = kcalloc(sas_expander->num_phys,
+ sizeof(struct _sas_phy), GFP_KERNEL);
+ if (!sas_expander->phy) {
+--
+2.30.2
+
--- /dev/null
+From 6589c1f37799d1bc7afb7c9d03d715a1e62a7f87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 May 2021 12:39:07 -0700
+Subject: seccomp: Support atomic "addfd + send reply"
+
+From: Rodrigo Campos <rodrigo@kinvolk.io>
+
+[ Upstream commit 0ae71c7720e3ae3aabd2e8a072d27f7bd173d25c ]
+
+Alban Crequy reported a race condition userspace faces when we want to
+add some fds and make the syscall return them[1] using seccomp notify.
+
+The problem is that currently two different ioctl() calls are needed by
+the process handling the syscalls (agent) for another userspace process
+(target): SECCOMP_IOCTL_NOTIF_ADDFD to allocate the fd and
+SECCOMP_IOCTL_NOTIF_SEND to return that value. Therefore, it is possible
+for the agent to do the first ioctl to add a file descriptor but the
+target is interrupted (EINTR) before the agent does the second ioctl()
+call.
+
+This patch adds a flag to the ADDFD ioctl() so it adds the fd and
+returns that value atomically to the target program, as suggested by
+Kees Cook[2]. This is done by simply allowing
+seccomp_do_user_notification() to add the fd and return it in this case.
+Therefore, in this case the target wakes up from the wait in
+seccomp_do_user_notification() either to interrupt the syscall or to add
+the fd and return it.
+
+This "allocate an fd and return" functionality is useful for syscalls
+that return a file descriptor only, like connect(2). Other syscalls that
+return a file descriptor but not as return value (or return more than
+one fd), like socketpair(), pipe(), recvmsg with SCM_RIGHTs, will not
+work with this flag.
+
+This effectively combines SECCOMP_IOCTL_NOTIF_ADDFD and
+SECCOMP_IOCTL_NOTIF_SEND into an atomic opteration. The notification's
+return value, nor error can be set by the user. Upon successful invocation
+of the SECCOMP_IOCTL_NOTIF_ADDFD ioctl with the SECCOMP_ADDFD_FLAG_SEND
+flag, the notifying process's errno will be 0, and the return value will
+be the file descriptor number that was installed.
+
+[1]: https://lore.kernel.org/lkml/CADZs7q4sw71iNHmV8EOOXhUKJMORPzF7thraxZYddTZsxta-KQ@mail.gmail.com/
+[2]: https://lore.kernel.org/lkml/202012011322.26DCBC64F2@keescook/
+
+Signed-off-by: Rodrigo Campos <rodrigo@kinvolk.io>
+Signed-off-by: Sargun Dhillon <sargun@sargun.me>
+Acked-by: Tycho Andersen <tycho@tycho.pizza>
+Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20210517193908.3113-4-sargun@sargun.me
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../userspace-api/seccomp_filter.rst | 12 +++++
+ include/uapi/linux/seccomp.h | 1 +
+ kernel/seccomp.c | 51 ++++++++++++++++---
+ 3 files changed, 58 insertions(+), 6 deletions(-)
+
+diff --git a/Documentation/userspace-api/seccomp_filter.rst b/Documentation/userspace-api/seccomp_filter.rst
+index 6efb41cc8072..d61219889e49 100644
+--- a/Documentation/userspace-api/seccomp_filter.rst
++++ b/Documentation/userspace-api/seccomp_filter.rst
+@@ -259,6 +259,18 @@ and ``ioctl(SECCOMP_IOCTL_NOTIF_SEND)`` a response, indicating what should be
+ returned to userspace. The ``id`` member of ``struct seccomp_notif_resp`` should
+ be the same ``id`` as in ``struct seccomp_notif``.
+
++Userspace can also add file descriptors to the notifying process via
++``ioctl(SECCOMP_IOCTL_NOTIF_ADDFD)``. The ``id`` member of
++``struct seccomp_notif_addfd`` should be the same ``id`` as in
++``struct seccomp_notif``. The ``newfd_flags`` flag may be used to set flags
++like O_EXEC on the file descriptor in the notifying process. If the supervisor
++wants to inject the file descriptor with a specific number, the
++``SECCOMP_ADDFD_FLAG_SETFD`` flag can be used, and set the ``newfd`` member to
++the specific number to use. If that file descriptor is already open in the
++notifying process it will be replaced. The supervisor can also add an FD, and
++respond atomically by using the ``SECCOMP_ADDFD_FLAG_SEND`` flag and the return
++value will be the injected file descriptor number.
++
+ It is worth noting that ``struct seccomp_data`` contains the values of register
+ arguments to the syscall, but does not contain pointers to memory. The task's
+ memory is accessible to suitably privileged traces via ``ptrace()`` or
+diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h
+index 6ba18b82a02e..78074254ab98 100644
+--- a/include/uapi/linux/seccomp.h
++++ b/include/uapi/linux/seccomp.h
+@@ -115,6 +115,7 @@ struct seccomp_notif_resp {
+
+ /* valid flags for seccomp_notif_addfd */
+ #define SECCOMP_ADDFD_FLAG_SETFD (1UL << 0) /* Specify remote fd */
++#define SECCOMP_ADDFD_FLAG_SEND (1UL << 1) /* Addfd and return it, atomically */
+
+ /**
+ * struct seccomp_notif_addfd
+diff --git a/kernel/seccomp.c b/kernel/seccomp.c
+index 9f58049ac16d..057e17f3215d 100644
+--- a/kernel/seccomp.c
++++ b/kernel/seccomp.c
+@@ -107,6 +107,7 @@ struct seccomp_knotif {
+ * installing process should allocate the fd as normal.
+ * @flags: The flags for the new file descriptor. At the moment, only O_CLOEXEC
+ * is allowed.
++ * @ioctl_flags: The flags used for the seccomp_addfd ioctl.
+ * @ret: The return value of the installing process. It is set to the fd num
+ * upon success (>= 0).
+ * @completion: Indicates that the installing process has completed fd
+@@ -118,6 +119,7 @@ struct seccomp_kaddfd {
+ struct file *file;
+ int fd;
+ unsigned int flags;
++ __u32 ioctl_flags;
+
+ union {
+ bool setfd;
+@@ -1065,18 +1067,37 @@ static u64 seccomp_next_notify_id(struct seccomp_filter *filter)
+ return filter->notif->next_id++;
+ }
+
+-static void seccomp_handle_addfd(struct seccomp_kaddfd *addfd)
++static void seccomp_handle_addfd(struct seccomp_kaddfd *addfd, struct seccomp_knotif *n)
+ {
++ int fd;
++
+ /*
+ * Remove the notification, and reset the list pointers, indicating
+ * that it has been handled.
+ */
+ list_del_init(&addfd->list);
+ if (!addfd->setfd)
+- addfd->ret = receive_fd(addfd->file, addfd->flags);
++ fd = receive_fd(addfd->file, addfd->flags);
+ else
+- addfd->ret = receive_fd_replace(addfd->fd, addfd->file,
+- addfd->flags);
++ fd = receive_fd_replace(addfd->fd, addfd->file, addfd->flags);
++ addfd->ret = fd;
++
++ if (addfd->ioctl_flags & SECCOMP_ADDFD_FLAG_SEND) {
++ /* If we fail reset and return an error to the notifier */
++ if (fd < 0) {
++ n->state = SECCOMP_NOTIFY_SENT;
++ } else {
++ /* Return the FD we just added */
++ n->flags = 0;
++ n->error = 0;
++ n->val = fd;
++ }
++ }
++
++ /*
++ * Mark the notification as completed. From this point, addfd mem
++ * might be invalidated and we can't safely read it anymore.
++ */
+ complete(&addfd->completion);
+ }
+
+@@ -1120,7 +1141,7 @@ static int seccomp_do_user_notification(int this_syscall,
+ struct seccomp_kaddfd, list);
+ /* Check if we were woken up by a addfd message */
+ if (addfd)
+- seccomp_handle_addfd(addfd);
++ seccomp_handle_addfd(addfd, &n);
+
+ } while (n.state != SECCOMP_NOTIFY_REPLIED);
+
+@@ -1581,7 +1602,7 @@ static long seccomp_notify_addfd(struct seccomp_filter *filter,
+ if (addfd.newfd_flags & ~O_CLOEXEC)
+ return -EINVAL;
+
+- if (addfd.flags & ~SECCOMP_ADDFD_FLAG_SETFD)
++ if (addfd.flags & ~(SECCOMP_ADDFD_FLAG_SETFD | SECCOMP_ADDFD_FLAG_SEND))
+ return -EINVAL;
+
+ if (addfd.newfd && !(addfd.flags & SECCOMP_ADDFD_FLAG_SETFD))
+@@ -1591,6 +1612,7 @@ static long seccomp_notify_addfd(struct seccomp_filter *filter,
+ if (!kaddfd.file)
+ return -EBADF;
+
++ kaddfd.ioctl_flags = addfd.flags;
+ kaddfd.flags = addfd.newfd_flags;
+ kaddfd.setfd = addfd.flags & SECCOMP_ADDFD_FLAG_SETFD;
+ kaddfd.fd = addfd.newfd;
+@@ -1616,6 +1638,23 @@ static long seccomp_notify_addfd(struct seccomp_filter *filter,
+ goto out_unlock;
+ }
+
++ if (addfd.flags & SECCOMP_ADDFD_FLAG_SEND) {
++ /*
++ * Disallow queuing an atomic addfd + send reply while there are
++ * some addfd requests still to process.
++ *
++ * There is no clear reason to support it and allows us to keep
++ * the loop on the other side straight-forward.
++ */
++ if (!list_empty(&knotif->addfd)) {
++ ret = -EBUSY;
++ goto out_unlock;
++ }
++
++ /* Allow exactly only one reply */
++ knotif->state = SECCOMP_NOTIFY_REPLIED;
++ }
++
+ list_add(&kaddfd.list, &knotif->addfd);
+ complete(&knotif->ready);
+ mutex_unlock(&filter->notify_lock);
+--
+2.30.2
+
--- /dev/null
+From 79eeda3e22585114c77934f57b2a247ff6b9f257 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jun 2021 17:28:24 -0700
+Subject: selftests/bpf: Fix ringbuf test fetching map FD
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit 0c38740c08962ab109267cb23f4a40df2ccf2bbf ]
+
+Seems like 4d1b62986125 ("selftests/bpf: Convert few tests to light skeleton.")
+and 704e2beba23c ("selftests/bpf: Test ringbuf mmap read-only and read-write
+restrictions") were done independently on bpf and bpf-next trees and are in
+conflict with each other, despite a clean merge. Fix fetching of ringbuf's
+map_fd to use light skeleton properly.
+
+Fixes: 704e2beba23c ("selftests/bpf: Test ringbuf mmap read-only and read-write restrictions")
+Fixes: 4d1b62986125 ("selftests/bpf: Convert few tests to light skeleton.")
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20210618002824.2081922-1-andrii@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/ringbuf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/ringbuf.c b/tools/testing/selftests/bpf/prog_tests/ringbuf.c
+index f9a8ae331963..2a0549ae13f3 100644
+--- a/tools/testing/selftests/bpf/prog_tests/ringbuf.c
++++ b/tools/testing/selftests/bpf/prog_tests/ringbuf.c
+@@ -102,7 +102,7 @@ void test_ringbuf(void)
+ if (CHECK(err != 0, "skel_load", "skeleton load failed\n"))
+ goto cleanup;
+
+- rb_fd = bpf_map__fd(skel->maps.ringbuf);
++ rb_fd = skel->maps.ringbuf.map_fd;
+ /* good read/write cons_pos */
+ mmap_ptr = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, rb_fd, 0);
+ ASSERT_OK_PTR(mmap_ptr, "rw_cons_pos");
+--
+2.30.2
+
--- /dev/null
+From b30559e0607675a679139bc99fce1f8031cae27d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 19:13:36 -0700
+Subject: selftests/bpf: Retry for EAGAIN in udp_redir_to_connected()
+
+From: Cong Wang <cong.wang@bytedance.com>
+
+[ Upstream commit a7e65fe7d8201527129206754db1a2db6a6b2fde ]
+
+We use non-blocking sockets for testing sockmap redirections,
+and got some random EAGAIN errors from UDP tests.
+
+There is no guarantee the packet would be immediately available
+to receive as soon as it is sent out, even on the local host.
+For UDP, this is especially true because it does not lock the
+sock during BH (unlike the TCP path). This is probably why we
+only saw this error in UDP cases.
+
+No matter how hard we try to make the queue empty check accurate,
+it is always possible for recvmsg() to beat ->sk_data_ready().
+Therefore, we should just retry in case of EAGAIN.
+
+Fixes: d6378af615275 ("selftests/bpf: Add a test case for udp sockmap")
+Reported-by: Jiang Wang <jiang.wang@bytedance.com>
+Signed-off-by: Cong Wang <cong.wang@bytedance.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Acked-by: Jakub Sitnicki <jakub@cloudflare.com>
+Link: https://lore.kernel.org/bpf/20210615021342.7416-3-xiyou.wangcong@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/sockmap_listen.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_listen.c b/tools/testing/selftests/bpf/prog_tests/sockmap_listen.c
+index 648d9ae898d2..01ab11259809 100644
+--- a/tools/testing/selftests/bpf/prog_tests/sockmap_listen.c
++++ b/tools/testing/selftests/bpf/prog_tests/sockmap_listen.c
+@@ -1610,6 +1610,7 @@ static void udp_redir_to_connected(int family, int sotype, int sock_mapfd,
+ struct sockaddr_storage addr;
+ int c0, c1, p0, p1;
+ unsigned int pass;
++ int retries = 100;
+ socklen_t len;
+ int err, n;
+ u64 value;
+@@ -1686,9 +1687,13 @@ static void udp_redir_to_connected(int family, int sotype, int sock_mapfd,
+ if (pass != 1)
+ FAIL("%s: want pass count 1, have %d", log_prefix, pass);
+
++again:
+ n = read(mode == REDIR_INGRESS ? p0 : c0, &b, 1);
+- if (n < 0)
++ if (n < 0) {
++ if (errno == EAGAIN && retries--)
++ goto again;
+ FAIL_ERRNO("%s: read", log_prefix);
++ }
+ if (n == 0)
+ FAIL("%s: incomplete read", log_prefix);
+
+--
+2.30.2
+
--- /dev/null
+From 9a90a1a01ddf451399b163ea4f28e3a383d1443b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Jun 2021 14:52:11 -0700
+Subject: selftests/bpf: Whitelist test_progs.h from .gitignore
+
+From: Daniel Xu <dxu@dxuuu.xyz>
+
+[ Upstream commit 809ed84de8b3f2fd7b1d06efb94bf98fd318a7d7 ]
+
+Somehow test_progs.h was being included by the existing rule:
+
+ /test_progs*
+
+This is bad because:
+
+ 1) test_progs.h is a checked in file
+ 2) grep-like tools like ripgrep[0] respect gitignore and
+ test_progs.h was being hidden from searches
+
+[0]: https://github.com/BurntSushi/ripgrep
+
+Fixes: 74b5a5968fe8 ("selftests/bpf: Replace test_progs and test_maps w/ general rule")
+Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/a46f64944bf678bc652410ca6028d3450f4f7f4b.1623880296.git.dxu@dxuuu.xyz
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/.gitignore | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore
+index 4866f6a21901..d89efd9785d8 100644
+--- a/tools/testing/selftests/bpf/.gitignore
++++ b/tools/testing/selftests/bpf/.gitignore
+@@ -10,6 +10,7 @@ FEATURE-DUMP.libbpf
+ fixdep
+ test_dev_cgroup
+ /test_progs*
++!test_progs.h
+ test_verifier_log
+ feature
+ test_sock
+--
+2.30.2
+
--- /dev/null
+From 0f8587935c63e29e731c4107ee13183711516875 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jun 2021 15:43:15 +0200
+Subject: selftests/ftrace: fix event-no-pid on 1-core machine
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+[ Upstream commit 07b60713b57a8f952d029a2b6849d003d9c16108 ]
+
+When running event-no-pid test on small machines (e.g. cloud 1-core
+instance), other events might not happen:
+
+ + cat trace
+ + cnt=0
+ + [ 0 -eq 0 ]
+ + fail No other events were recorded
+ [15] event tracing - restricts events based on pid notrace filtering [FAIL]
+
+Schedule a simple sleep task to be sure that some other process events
+get recorded.
+
+Fixes: ebed9628f5c2 ("selftests/ftrace: Add test to test new set_event_notrace_pid file")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../testing/selftests/ftrace/test.d/event/event-no-pid.tc | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/tools/testing/selftests/ftrace/test.d/event/event-no-pid.tc b/tools/testing/selftests/ftrace/test.d/event/event-no-pid.tc
+index e6eb78f0b954..9933ed24f901 100644
+--- a/tools/testing/selftests/ftrace/test.d/event/event-no-pid.tc
++++ b/tools/testing/selftests/ftrace/test.d/event/event-no-pid.tc
+@@ -57,6 +57,10 @@ enable_events() {
+ echo 1 > tracing_on
+ }
+
++other_task() {
++ sleep .001 || usleep 1 || sleep 1
++}
++
+ echo 0 > options/event-fork
+
+ do_reset
+@@ -94,6 +98,9 @@ child=$!
+ echo "child = $child"
+ wait $child
+
++# Be sure some other events will happen for small systems (e.g. 1 core)
++other_task
++
+ echo 0 > tracing_on
+
+ cnt=`count_pid $mypid`
+--
+2.30.2
+
--- /dev/null
+From 32dcdb205ecadc4a87e84efe54fec60c1968353b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Jun 2021 12:05:56 -0700
+Subject: selftests/sgx: remove checks for file execute permissions
+
+From: Dave Hansen <dave.hansen@linux.intel.com>
+
+[ Upstream commit 4896df9d53ae5521f3ce83751e828ad70bc65c80 ]
+
+The SGX selftests can fail for a bunch of non-obvious reasons
+like 'noexec' permissions on /dev (which is the default *EVERYWHERE*
+it seems).
+
+A new test mistakenly also looked for +x permission on the
+/dev/sgx_enclave. File execute permissions really only apply to
+the ability of execve() to work on a file, *NOT* on the ability
+for an application to map the file with PROT_EXEC. SGX needs to
+mmap(PROT_EXEC), but doesn't need to execve() the device file.
+
+Remove the check.
+
+Fixes: 4284f7acb78b ("selftests/sgx: Improve error detection and messages")
+Reported-by: Tim Gardner <tim.gardner@canonical.com>
+Cc: Jarkko Sakkinen <jarkko@kernel.org>
+Cc: Reinette Chatre <reinette.chatre@intel.com>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: linux-sgx@vger.kernel.org
+Cc: linux-kselftest@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Tested-by: Reinette Chatre <reinette.chatre@intel.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/sgx/load.c | 16 +++-------------
+ 1 file changed, 3 insertions(+), 13 deletions(-)
+
+diff --git a/tools/testing/selftests/sgx/load.c b/tools/testing/selftests/sgx/load.c
+index f441ac34b4d4..bae78c3263d9 100644
+--- a/tools/testing/selftests/sgx/load.c
++++ b/tools/testing/selftests/sgx/load.c
+@@ -150,16 +150,6 @@ bool encl_load(const char *path, struct encl *encl)
+ goto err;
+ }
+
+- /*
+- * This just checks if the /dev file has these permission
+- * bits set. It does not check that the current user is
+- * the owner or in the owning group.
+- */
+- if (!(sb.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
+- fprintf(stderr, "no execute permissions on device file %s\n", device_path);
+- goto err;
+- }
+-
+ ptr = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED, fd, 0);
+ if (ptr == (void *)-1) {
+ perror("mmap for read");
+@@ -169,13 +159,13 @@ bool encl_load(const char *path, struct encl *encl)
+
+ #define ERR_MSG \
+ "mmap() succeeded for PROT_READ, but failed for PROT_EXEC.\n" \
+-" Check that current user has execute permissions on %s and \n" \
+-" that /dev does not have noexec set: mount | grep \"/dev .*noexec\"\n" \
++" Check that /dev does not have noexec set:\n" \
++" \tmount | grep \"/dev .*noexec\"\n" \
+ " If so, remount it executable: mount -o remount,exec /dev\n\n"
+
+ ptr = mmap(NULL, PAGE_SIZE, PROT_EXEC, MAP_SHARED, fd, 0);
+ if (ptr == (void *)-1) {
+- fprintf(stderr, ERR_MSG, device_path);
++ fprintf(stderr, ERR_MSG);
+ goto err;
+ }
+ munmap(ptr, PAGE_SIZE);
+--
+2.30.2
+
--- /dev/null
+From 07ebe5f2148061906fe08d7a6610bb0ec2949452 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 May 2021 20:25:37 -0700
+Subject: selftests: splice: Adjust for handler fallback removal
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 6daf076b717d189f4d02a303d45edd5732341ec1 ]
+
+Some pseudo-filesystems do not have an explicit splice fops since adding
+commit 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops"),
+and now will reject attempts to use splice() in those filesystem paths.
+
+Reported-by: kernel test robot <rong.a.chen@intel.com>
+Link: https://lore.kernel.org/lkml/202009181443.C2179FB@keescook/
+Fixes: 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops")
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: linux-kselftest@vger.kernel.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/splice/short_splice_read.sh | 119 ++++++++++++++----
+ 1 file changed, 98 insertions(+), 21 deletions(-)
+
+diff --git a/tools/testing/selftests/splice/short_splice_read.sh b/tools/testing/selftests/splice/short_splice_read.sh
+index 7810d3589d9a..22b6c8910b18 100755
+--- a/tools/testing/selftests/splice/short_splice_read.sh
++++ b/tools/testing/selftests/splice/short_splice_read.sh
+@@ -1,21 +1,87 @@
+ #!/bin/sh
+ # SPDX-License-Identifier: GPL-2.0
++#
++# Test for mishandling of splice() on pseudofilesystems, which should catch
++# bugs like 11990a5bd7e5 ("module: Correctly truncate sysfs sections output")
++#
++# Since splice fallback was removed as part of the set_fs() rework, many of these
++# tests expect to fail now. See https://lore.kernel.org/lkml/202009181443.C2179FB@keescook/
+ set -e
+
++DIR=$(dirname "$0")
++
+ ret=0
+
++expect_success()
++{
++ title="$1"
++ shift
++
++ echo "" >&2
++ echo "$title ..." >&2
++
++ set +e
++ "$@"
++ rc=$?
++ set -e
++
++ case "$rc" in
++ 0)
++ echo "ok: $title succeeded" >&2
++ ;;
++ 1)
++ echo "FAIL: $title should work" >&2
++ ret=$(( ret + 1 ))
++ ;;
++ *)
++ echo "FAIL: something else went wrong" >&2
++ ret=$(( ret + 1 ))
++ ;;
++ esac
++}
++
++expect_failure()
++{
++ title="$1"
++ shift
++
++ echo "" >&2
++ echo "$title ..." >&2
++
++ set +e
++ "$@"
++ rc=$?
++ set -e
++
++ case "$rc" in
++ 0)
++ echo "FAIL: $title unexpectedly worked" >&2
++ ret=$(( ret + 1 ))
++ ;;
++ 1)
++ echo "ok: $title correctly failed" >&2
++ ;;
++ *)
++ echo "FAIL: something else went wrong" >&2
++ ret=$(( ret + 1 ))
++ ;;
++ esac
++}
++
+ do_splice()
+ {
+ filename="$1"
+ bytes="$2"
+ expected="$3"
++ report="$4"
+
+- out=$(./splice_read "$filename" "$bytes" | cat)
++ out=$("$DIR"/splice_read "$filename" "$bytes" | cat)
+ if [ "$out" = "$expected" ] ; then
+- echo "ok: $filename $bytes"
++ echo " matched $report" >&2
++ return 0
+ else
+- echo "FAIL: $filename $bytes"
+- ret=1
++ echo " no match: '$out' vs $report" >&2
++ return 1
+ fi
+ }
+
+@@ -23,34 +89,45 @@ test_splice()
+ {
+ filename="$1"
+
++ echo " checking $filename ..." >&2
++
+ full=$(cat "$filename")
++ rc=$?
++ if [ $rc -ne 0 ] ; then
++ return 2
++ fi
++
+ two=$(echo "$full" | grep -m1 . | cut -c-2)
+
+ # Make sure full splice has the same contents as a standard read.
+- do_splice "$filename" 4096 "$full"
++ echo " splicing 4096 bytes ..." >&2
++ if ! do_splice "$filename" 4096 "$full" "full read" ; then
++ return 1
++ fi
+
+ # Make sure a partial splice see the first two characters.
+- do_splice "$filename" 2 "$two"
++ echo " splicing 2 bytes ..." >&2
++ if ! do_splice "$filename" 2 "$two" "'$two'" ; then
++ return 1
++ fi
++
++ return 0
+ }
+
+-# proc_single_open(), seq_read()
+-test_splice /proc/$$/limits
+-# special open, seq_read()
+-test_splice /proc/$$/comm
++### /proc/$pid/ has no splice interface; these should all fail.
++expect_failure "proc_single_open(), seq_read() splice" test_splice /proc/$$/limits
++expect_failure "special open(), seq_read() splice" test_splice /proc/$$/comm
+
+-# proc_handler, proc_dointvec_minmax
+-test_splice /proc/sys/fs/nr_open
+-# proc_handler, proc_dostring
+-test_splice /proc/sys/kernel/modprobe
+-# proc_handler, special read
+-test_splice /proc/sys/kernel/version
++### /proc/sys/ has a splice interface; these should all succeed.
++expect_success "proc_handler: proc_dointvec_minmax() splice" test_splice /proc/sys/fs/nr_open
++expect_success "proc_handler: proc_dostring() splice" test_splice /proc/sys/kernel/modprobe
++expect_success "proc_handler: special read splice" test_splice /proc/sys/kernel/version
+
++### /sys/ has no splice interface; these should all fail.
+ if ! [ -d /sys/module/test_module/sections ] ; then
+- modprobe test_module
++ expect_success "test_module kernel module load" modprobe test_module
+ fi
+-# kernfs, attr
+-test_splice /sys/module/test_module/coresize
+-# kernfs, binattr
+-test_splice /sys/module/test_module/sections/.init.text
++expect_failure "kernfs attr splice" test_splice /sys/module/test_module/coresize
++expect_failure "kernfs binattr splice" test_splice /sys/module/test_module/sections/.init.text
+
+ exit $ret
+--
+2.30.2
+
--- /dev/null
+From cc09a8258176956c3c73f28339edb5780c7fa902 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 13:25:03 -0700
+Subject: selftests: tls: clean up uninitialized warnings
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit baa00119d69e3318da8d99867fc1170ebddf09ce ]
+
+A bunch of tests uses uninitialized stack memory as random
+data to send. This is harmless but generates compiler warnings.
+Explicitly init the buffers with random data.
+
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Acked-by: Vadim Fedorenko <vfedorenko@novek.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/tls.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c
+index 426d07875a48..58fea6eb588d 100644
+--- a/tools/testing/selftests/net/tls.c
++++ b/tools/testing/selftests/net/tls.c
+@@ -25,6 +25,18 @@
+ #define TLS_PAYLOAD_MAX_LEN 16384
+ #define SOL_TLS 282
+
++static void memrnd(void *s, size_t n)
++{
++ int *dword = s;
++ char *byte;
++
++ for (; n >= 4; n -= 4)
++ *dword++ = rand();
++ byte = (void *)dword;
++ while (n--)
++ *byte++ = rand();
++}
++
+ FIXTURE(tls_basic)
+ {
+ int fd, cfd;
+@@ -308,6 +320,8 @@ TEST_F(tls, recv_max)
+ char recv_mem[TLS_PAYLOAD_MAX_LEN];
+ char buf[TLS_PAYLOAD_MAX_LEN];
+
++ memrnd(buf, sizeof(buf));
++
+ EXPECT_GE(send(self->fd, buf, send_len, 0), 0);
+ EXPECT_NE(recv(self->cfd, recv_mem, send_len, 0), -1);
+ EXPECT_EQ(memcmp(buf, recv_mem, send_len), 0);
+@@ -588,6 +602,8 @@ TEST_F(tls, recvmsg_single_max)
+ struct iovec vec;
+ struct msghdr hdr;
+
++ memrnd(send_mem, sizeof(send_mem));
++
+ EXPECT_EQ(send(self->fd, send_mem, send_len, 0), send_len);
+ vec.iov_base = (char *)recv_mem;
+ vec.iov_len = TLS_PAYLOAD_MAX_LEN;
+@@ -610,6 +626,8 @@ TEST_F(tls, recvmsg_multiple)
+ struct msghdr hdr;
+ int i;
+
++ memrnd(buf, sizeof(buf));
++
+ EXPECT_EQ(send(self->fd, buf, send_len, 0), send_len);
+ for (i = 0; i < msg_iovlen; i++) {
+ iov_base[i] = (char *)malloc(iov_len);
+@@ -634,6 +652,8 @@ TEST_F(tls, single_send_multiple_recv)
+ char send_mem[TLS_PAYLOAD_MAX_LEN * 2];
+ char recv_mem[TLS_PAYLOAD_MAX_LEN * 2];
+
++ memrnd(send_mem, sizeof(send_mem));
++
+ EXPECT_GE(send(self->fd, send_mem, total_len, 0), 0);
+ memset(recv_mem, 0, total_len);
+
+--
+2.30.2
+
--- /dev/null
+From 8c598f6990c081f99ec326e1b1aadecff6a81793 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 13:25:04 -0700
+Subject: selftests: tls: fix chacha+bidir tests
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 291c53e4dacd3a2cc3152d8af37f07f8496c594a ]
+
+ChaCha support did not adjust the bidirectional test.
+We need to set up KTLS in reverse direction correctly,
+otherwise these two cases will fail:
+
+ tls.12_chacha.bidir
+ tls.13_chacha.bidir
+
+Fixes: 4f336e88a870 ("selftests/tls: add CHACHA20-POLY1305 to tls selftests")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Acked-by: Vadim Fedorenko <vfedorenko@novek.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/tls.c | 67 ++++++++++++++++++-------------
+ 1 file changed, 39 insertions(+), 28 deletions(-)
+
+diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c
+index 58fea6eb588d..112d41d01b12 100644
+--- a/tools/testing/selftests/net/tls.c
++++ b/tools/testing/selftests/net/tls.c
+@@ -25,6 +25,35 @@
+ #define TLS_PAYLOAD_MAX_LEN 16384
+ #define SOL_TLS 282
+
++struct tls_crypto_info_keys {
++ union {
++ struct tls12_crypto_info_aes_gcm_128 aes128;
++ struct tls12_crypto_info_chacha20_poly1305 chacha20;
++ };
++ size_t len;
++};
++
++static void tls_crypto_info_init(uint16_t tls_version, uint16_t cipher_type,
++ struct tls_crypto_info_keys *tls12)
++{
++ memset(tls12, 0, sizeof(*tls12));
++
++ switch (cipher_type) {
++ case TLS_CIPHER_CHACHA20_POLY1305:
++ tls12->len = sizeof(struct tls12_crypto_info_chacha20_poly1305);
++ tls12->chacha20.info.version = tls_version;
++ tls12->chacha20.info.cipher_type = cipher_type;
++ break;
++ case TLS_CIPHER_AES_GCM_128:
++ tls12->len = sizeof(struct tls12_crypto_info_aes_gcm_128);
++ tls12->aes128.info.version = tls_version;
++ tls12->aes128.info.cipher_type = cipher_type;
++ break;
++ default:
++ break;
++ }
++}
++
+ static void memrnd(void *s, size_t n)
+ {
+ int *dword = s;
+@@ -145,33 +174,16 @@ FIXTURE_VARIANT_ADD(tls, 13_chacha)
+
+ FIXTURE_SETUP(tls)
+ {
+- union {
+- struct tls12_crypto_info_aes_gcm_128 aes128;
+- struct tls12_crypto_info_chacha20_poly1305 chacha20;
+- } tls12;
++ struct tls_crypto_info_keys tls12;
+ struct sockaddr_in addr;
+ socklen_t len;
+ int sfd, ret;
+- size_t tls12_sz;
+
+ self->notls = false;
+ len = sizeof(addr);
+
+- memset(&tls12, 0, sizeof(tls12));
+- switch (variant->cipher_type) {
+- case TLS_CIPHER_CHACHA20_POLY1305:
+- tls12_sz = sizeof(struct tls12_crypto_info_chacha20_poly1305);
+- tls12.chacha20.info.version = variant->tls_version;
+- tls12.chacha20.info.cipher_type = variant->cipher_type;
+- break;
+- case TLS_CIPHER_AES_GCM_128:
+- tls12_sz = sizeof(struct tls12_crypto_info_aes_gcm_128);
+- tls12.aes128.info.version = variant->tls_version;
+- tls12.aes128.info.cipher_type = variant->cipher_type;
+- break;
+- default:
+- tls12_sz = 0;
+- }
++ tls_crypto_info_init(variant->tls_version, variant->cipher_type,
++ &tls12);
+
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+@@ -199,7 +211,7 @@ FIXTURE_SETUP(tls)
+
+ if (!self->notls) {
+ ret = setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12,
+- tls12_sz);
++ tls12.len);
+ ASSERT_EQ(ret, 0);
+ }
+
+@@ -212,7 +224,7 @@ FIXTURE_SETUP(tls)
+ ASSERT_EQ(ret, 0);
+
+ ret = setsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12,
+- tls12_sz);
++ tls12.len);
+ ASSERT_EQ(ret, 0);
+ }
+
+@@ -854,18 +866,17 @@ TEST_F(tls, bidir)
+ int ret;
+
+ if (!self->notls) {
+- struct tls12_crypto_info_aes_gcm_128 tls12;
++ struct tls_crypto_info_keys tls12;
+
+- memset(&tls12, 0, sizeof(tls12));
+- tls12.info.version = variant->tls_version;
+- tls12.info.cipher_type = TLS_CIPHER_AES_GCM_128;
++ tls_crypto_info_init(variant->tls_version, variant->cipher_type,
++ &tls12);
+
+ ret = setsockopt(self->fd, SOL_TLS, TLS_RX, &tls12,
+- sizeof(tls12));
++ tls12.len);
+ ASSERT_EQ(ret, 0);
+
+ ret = setsockopt(self->cfd, SOL_TLS, TLS_TX, &tls12,
+- sizeof(tls12));
++ tls12.len);
+ ASSERT_EQ(ret, 0);
+ }
+
+--
+2.30.2
+
--- /dev/null
+From b60ac855fa2b5735c8e809e8424039949bdd2604 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 18:56:53 -0700
+Subject: selftests/vm/pkeys: fix alloc_random_pkey() to make it really, really
+ random
+
+From: Dave Hansen <dave.hansen@linux.intel.com>
+
+[ Upstream commit f36ef407628835a7d7fb3d235b1f1aac7022d9a3 ]
+
+Patch series "selftests/vm/pkeys: Bug fixes and a new test".
+
+There has been a lot of activity on the x86 front around the XSAVE
+architecture which is used to context-switch processor state (among other
+things). In addition, AMD has recently joined the protection keys club by
+adding processor support for PKU.
+
+The AMD implementation helped uncover a kernel bug around the PKRU "init
+state", which actually applied to Intel's implementation but was just
+harder to hit. This series adds a test which is expected to help find
+this class of bug both on AMD and Intel. All the work around pkeys on x86
+also uncovered a few bugs in the selftest.
+
+This patch (of 4):
+
+The "random" pkey allocation code currently does the good old:
+
+ srand((unsigned int)time(NULL));
+
+*But*, it unfortunately does this on every random pkey allocation.
+
+There may be thousands of these a second. time() has a one second
+resolution. So, each time alloc_random_pkey() is called, the PRNG is
+*RESET* to time(). This is nasty. Normally, if you do:
+
+ srand(<ANYTHING>);
+ foo = rand();
+ bar = rand();
+
+You'll be quite guaranteed that 'foo' and 'bar' are different. But, if
+you do:
+
+ srand(1);
+ foo = rand();
+ srand(1);
+ bar = rand();
+
+You are quite guaranteed that 'foo' and 'bar' are the *SAME*. The recent
+"fix" effectively forced the test case to use the same "random" pkey for
+the whole test, unless the test run crossed a second boundary.
+
+Only run srand() once at program startup.
+
+This explains some very odd and persistent test failures I've been seeing.
+
+Link: https://lkml.kernel.org/r/20210611164153.91B76FB8@viggo.jf.intel.com
+Link: https://lkml.kernel.org/r/20210611164155.192D00FF@viggo.jf.intel.com
+Fixes: 6e373263ce07 ("selftests/vm/pkeys: fix alloc_random_pkey() to make it really random")
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Cc: Ram Pai <linuxram@us.ibm.com>
+Cc: Sandipan Das <sandipan@linux.ibm.com>
+Cc: Florian Weimer <fweimer@redhat.com>
+Cc: "Desnes A. Nunes do Rosario" <desnesn@linux.vnet.ibm.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Thiago Jung Bauermann <bauerman@linux.ibm.com>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Michal Suchanek <msuchanek@suse.de>
+Cc: Shuah Khan <shuah@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/vm/protection_keys.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/vm/protection_keys.c b/tools/testing/selftests/vm/protection_keys.c
+index fdbb602ecf32..9ee0ae5d3e06 100644
+--- a/tools/testing/selftests/vm/protection_keys.c
++++ b/tools/testing/selftests/vm/protection_keys.c
+@@ -561,7 +561,6 @@ int alloc_random_pkey(void)
+ int nr_alloced = 0;
+ int random_index;
+ memset(alloced_pkeys, 0, sizeof(alloced_pkeys));
+- srand((unsigned int)time(NULL));
+
+ /* allocate every possible key and make a note of which ones we got */
+ max_nr_pkey_allocs = NR_PKEYS;
+@@ -1552,6 +1551,8 @@ int main(void)
+ int nr_iterations = 22;
+ int pkeys_supported = is_pkeys_supported();
+
++ srand((unsigned int)time(NULL));
++
+ setup_handlers();
+
+ printf("has pkeys: %d\n", pkeys_supported);
+--
+2.30.2
+
--- /dev/null
+From 422745c7db403ee40802bb70781d9a01df16fecc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 18:56:56 -0700
+Subject: selftests/vm/pkeys: handle negative sys_pkey_alloc() return code
+
+From: Dave Hansen <dave.hansen@linux.intel.com>
+
+[ Upstream commit bf68294a2ec39ed7fec6a5b45d52034e6983157a ]
+
+The alloc_pkey() sefltest function wraps the sys_pkey_alloc() system call.
+On success, it updates its "shadow" register value because
+sys_pkey_alloc() updates the real register.
+
+But, the success check is wrong. pkey_alloc() considers any non-zero
+return code to indicate success where the pkey register will be modified.
+This fails to take negative return codes into account.
+
+Consider only a positive return value as a successful call.
+
+Link: https://lkml.kernel.org/r/20210611164157.87AB4246@viggo.jf.intel.com
+Fixes: 5f23f6d082a9 ("x86/pkeys: Add self-tests")
+Reported-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Tested-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Cc: Ram Pai <linuxram@us.ibm.com>
+Cc: Sandipan Das <sandipan@linux.ibm.com>
+Cc: Florian Weimer <fweimer@redhat.com>
+Cc: "Desnes A. Nunes do Rosario" <desnesn@linux.vnet.ibm.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Thiago Jung Bauermann <bauerman@linux.ibm.com>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Michal Suchanek <msuchanek@suse.de>
+Cc: Shuah Khan <shuah@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/vm/protection_keys.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/vm/protection_keys.c b/tools/testing/selftests/vm/protection_keys.c
+index 9ee0ae5d3e06..356d62fca27f 100644
+--- a/tools/testing/selftests/vm/protection_keys.c
++++ b/tools/testing/selftests/vm/protection_keys.c
+@@ -510,7 +510,7 @@ int alloc_pkey(void)
+ " shadow: 0x%016llx\n",
+ __func__, __LINE__, ret, __read_pkey_reg(),
+ shadow_pkey_reg);
+- if (ret) {
++ if (ret > 0) {
+ /* clear both the bits: */
+ shadow_pkey_reg = set_pkey_bits(shadow_pkey_reg, ret,
+ ~PKEY_MASK);
+--
+2.30.2
+
--- /dev/null
+From 9b4cde27542760691573109a97682b0f18da9e7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jun 2021 18:56:59 -0700
+Subject: selftests/vm/pkeys: refill shadow register after implicit kernel
+ write
+
+From: Dave Hansen <dave.hansen@linux.intel.com>
+
+[ Upstream commit 6039ca254979694c5362dfebadd105e286c397bb ]
+
+The pkey test code keeps a "shadow" of the pkey register around. This
+ensures that any bugs which might write to the register can be caught more
+quickly.
+
+Generally, userspace has a good idea when the kernel is going to write to
+the register. For instance, alloc_pkey() is passed a permission mask.
+The caller of alloc_pkey() can update the shadow based on the return value
+and the mask.
+
+But, the kernel can also modify the pkey register in a more sneaky way.
+For mprotect(PROT_EXEC) mappings, the kernel will allocate a pkey and
+write the pkey register to create an execute-only mapping. The kernel
+never tells userspace what key it uses for this.
+
+This can cause the test to fail with messages like:
+
+ protection_keys_64.2: pkey-helpers.h:132: _read_pkey_reg: Assertion `pkey_reg == shadow_pkey_reg' failed.
+
+because the shadow was not updated with the new kernel-set value.
+
+Forcibly update the shadow value immediately after an mprotect().
+
+Link: https://lkml.kernel.org/r/20210611164200.EF76AB73@viggo.jf.intel.com
+Fixes: 6af17cf89e99 ("x86/pkeys/selftests: Add PROT_EXEC test")
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Cc: Ram Pai <linuxram@us.ibm.com>
+Cc: Sandipan Das <sandipan@linux.ibm.com>
+Cc: Florian Weimer <fweimer@redhat.com>
+Cc: "Desnes A. Nunes do Rosario" <desnesn@linux.vnet.ibm.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Thiago Jung Bauermann <bauerman@linux.ibm.com>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Michal Suchanek <msuchanek@suse.de>
+Cc: Shuah Khan <shuah@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/vm/protection_keys.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/tools/testing/selftests/vm/protection_keys.c b/tools/testing/selftests/vm/protection_keys.c
+index 356d62fca27f..87eecd5ba577 100644
+--- a/tools/testing/selftests/vm/protection_keys.c
++++ b/tools/testing/selftests/vm/protection_keys.c
+@@ -1448,6 +1448,13 @@ void test_implicit_mprotect_exec_only_memory(int *ptr, u16 pkey)
+ ret = mprotect(p1, PAGE_SIZE, PROT_EXEC);
+ pkey_assert(!ret);
+
++ /*
++ * Reset the shadow, assuming that the above mprotect()
++ * correctly changed PKRU, but to an unknown value since
++ * the actual alllocated pkey is unknown.
++ */
++ shadow_pkey_reg = __read_pkey_reg();
++
+ dprintf2("pkey_reg: %016llx\n", read_pkey_reg());
+
+ /* Make sure this is an *instruction* fault */
+--
+2.30.2
+
--- /dev/null
+From dfc0277bd5e79ea6eefdaaf9994d6f6e408718ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 20:27:04 +0530
+Subject: serial: 8250: 8250_omap: Fix possible interrupt storm on K3 SoCs
+
+From: Vignesh Raghavendra <vigneshr@ti.com>
+
+[ Upstream commit b67e830d38fa9335d927fe67e812e3ed81b4689c ]
+
+On K3 family of SoCs (which includes AM654 SoC), it is observed that RX
+TIMEOUT is signalled after RX FIFO has been drained, in which case a
+dummy read of RX FIFO is required to clear RX TIMEOUT condition.
+Otherwise, this would lead to an interrupt storm.
+
+Fix this by introducing UART_RX_TIMEOUT_QUIRK flag and doing a dummy
+read in IRQ handler when RX TIMEOUT is reported with no data in RX FIFO.
+
+Fixes: be70874498f3 ("serial: 8250_omap: Add support for AM654 UART controller")
+Reported-by: Jan Kiszka <jan.kiszka@siemens.com>
+Tested-by: Jan Kiszka <jan.kiszka@siemens.com>
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Link: https://lore.kernel.org/r/20210622145704.11168-1-vigneshr@ti.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250_omap.c | 20 +++++++++++++++++++-
+ 1 file changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
+index c06631ced414..79418d4beb48 100644
+--- a/drivers/tty/serial/8250/8250_omap.c
++++ b/drivers/tty/serial/8250/8250_omap.c
+@@ -43,6 +43,7 @@
+ #define UART_ERRATA_CLOCK_DISABLE (1 << 3)
+ #define UART_HAS_EFR2 BIT(4)
+ #define UART_HAS_RHR_IT_DIS BIT(5)
++#define UART_RX_TIMEOUT_QUIRK BIT(6)
+
+ #define OMAP_UART_FCR_RX_TRIG 6
+ #define OMAP_UART_FCR_TX_TRIG 4
+@@ -104,6 +105,9 @@
+ #define UART_OMAP_EFR2 0x23
+ #define UART_OMAP_EFR2_TIMEOUT_BEHAVE BIT(6)
+
++/* RX FIFO occupancy indicator */
++#define UART_OMAP_RX_LVL 0x64
++
+ struct omap8250_priv {
+ int line;
+ u8 habit;
+@@ -611,6 +615,7 @@ static int omap_8250_dma_handle_irq(struct uart_port *port);
+ static irqreturn_t omap8250_irq(int irq, void *dev_id)
+ {
+ struct uart_port *port = dev_id;
++ struct omap8250_priv *priv = port->private_data;
+ struct uart_8250_port *up = up_to_u8250p(port);
+ unsigned int iir;
+ int ret;
+@@ -625,6 +630,18 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id)
+ serial8250_rpm_get(up);
+ iir = serial_port_in(port, UART_IIR);
+ ret = serial8250_handle_irq(port, iir);
++
++ /*
++ * On K3 SoCs, it is observed that RX TIMEOUT is signalled after
++ * FIFO has been drained, in which case a dummy read of RX FIFO
++ * is required to clear RX TIMEOUT condition.
++ */
++ if (priv->habit & UART_RX_TIMEOUT_QUIRK &&
++ (iir & UART_IIR_RX_TIMEOUT) == UART_IIR_RX_TIMEOUT &&
++ serial_port_in(port, UART_OMAP_RX_LVL) == 0) {
++ serial_port_in(port, UART_RX);
++ }
++
+ serial8250_rpm_put(up);
+
+ return IRQ_RETVAL(ret);
+@@ -1218,7 +1235,8 @@ static struct omap8250_dma_params am33xx_dma = {
+
+ static struct omap8250_platdata am654_platdata = {
+ .dma_params = &am654_dma,
+- .habit = UART_HAS_EFR2 | UART_HAS_RHR_IT_DIS,
++ .habit = UART_HAS_EFR2 | UART_HAS_RHR_IT_DIS |
++ UART_RX_TIMEOUT_QUIRK,
+ };
+
+ static struct omap8250_platdata am33xx_platdata = {
+--
+2.30.2
+
--- /dev/null
+From 4fd479710993ffdaf609f70b7d11919e473b3703 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jun 2021 20:38:34 +0200
+Subject: serial: 8250: Actually allow UPF_MAGIC_MULTIPLIER baud rates
+
+From: Maciej W. Rozycki <macro@orcam.me.uk>
+
+[ Upstream commit 78bcae8616ac277d6cb7f38e211493948ed73e30 ]
+
+Support for magic baud rate divisors of 32770 and 32769 used with SMSC
+Super I/O chips for extra baud rates of 230400 and 460800 respectively
+where base rate is 115200[1] has been added around Linux 2.5.64, which
+predates our repo history, but the origin could be identified as commit
+2a717aad772f ("Merge with Linux 2.5.64.") with the old MIPS/Linux repo
+also at: <git://git.kernel.org/pub/scm/linux/kernel/git/ralf/linux.git>.
+
+Code that is now in `serial8250_do_get_divisor' was added back then to
+`serial8250_get_divisor', but that code would only ever trigger if one
+of the higher baud rates was actually requested, and that cannot ever
+happen, because the earlier call to `serial8250_get_baud_rate' never
+returns them. This is because it calls `uart_get_baud_rate' with the
+maximum requested being the base rate, that is clk/16 or 115200 for SMSC
+chips at their nominal clock rate.
+
+Fix it then and allow UPF_MAGIC_MULTIPLIER baud rates to be selected, by
+requesting the maximum baud rate of clk/4 rather than clk/16 if the flag
+has been set. Also correct the minimum baud rate, observing that these
+ports only support actual (non-magic) divisors of up to 32767 only.
+
+References:
+
+[1] "FDC37M81x, PC98/99 Compliant Enhanced Super I/O Controller with
+ Keyboard/Mouse Wake-Up", Standard Microsystems Corporation, Rev.
+ 03/27/2000, Table 31 - "Baud Rates", p. 77
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Link: https://lore.kernel.org/r/alpine.DEB.2.21.2105190412280.29169@angie.orcam.me.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250_port.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
+index fc5ab2032282..ff3f13693def 100644
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -2629,6 +2629,21 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port,
+ struct ktermios *old)
+ {
+ unsigned int tolerance = port->uartclk / 100;
++ unsigned int min;
++ unsigned int max;
++
++ /*
++ * Handle magic divisors for baud rates above baud_base on SMSC
++ * Super I/O chips. Enable custom rates of clk/4 and clk/8, but
++ * disable divisor values beyond 32767, which are unavailable.
++ */
++ if (port->flags & UPF_MAGIC_MULTIPLIER) {
++ min = port->uartclk / 16 / UART_DIV_MAX >> 1;
++ max = (port->uartclk + tolerance) / 4;
++ } else {
++ min = port->uartclk / 16 / UART_DIV_MAX;
++ max = (port->uartclk + tolerance) / 16;
++ }
+
+ /*
+ * Ask the core to calculate the divisor for us.
+@@ -2636,9 +2651,7 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port,
+ * slower than nominal still match standard baud rates without
+ * causing transmission errors.
+ */
+- return uart_get_baud_rate(port, termios, old,
+- port->uartclk / 16 / UART_DIV_MAX,
+- (port->uartclk + tolerance) / 16);
++ return uart_get_baud_rate(port, termios, old, min, max);
+ }
+
+ /*
+--
+2.30.2
+
--- /dev/null
+From cfeb27aa1676bf1979a03a8f6e77606e3441008b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Apr 2021 10:19:22 +0300
+Subject: serial: 8250_omap: fix a timeout loop condition
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit d7e325aaa8c3593b5a572b583ecad79e95f32e7f ]
+
+This loop ends on -1 so the error message will never be printed.
+
+Fixes: 4bcf59a5dea0 ("serial: 8250: 8250_omap: Account for data in flight during DMA teardown")
+Reviewed-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Link: https://lore.kernel.org/r/YIpd+kOpXKMpEXPf@mwanda
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250_omap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
+index 8ac11eaeca51..c06631ced414 100644
+--- a/drivers/tty/serial/8250/8250_omap.c
++++ b/drivers/tty/serial/8250/8250_omap.c
+@@ -813,7 +813,7 @@ static void __dma_rx_do_complete(struct uart_8250_port *p)
+ poll_count--)
+ cpu_relax();
+
+- if (!poll_count)
++ if (poll_count == -1)
+ dev_err(p->port.dev, "teardown incomplete\n");
+ }
+ }
+--
+2.30.2
+
--- /dev/null
+From 173bc3d045670a1b5cb58e8e190cb2e9eb59cd13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 May 2021 16:12:47 +0200
+Subject: serial: fsl_lpuart: don't modify arbitrary data on lpuart32
+
+From: Michael Walle <michael@walle.cc>
+
+[ Upstream commit ccf08fd1204bcb5311cc10aea037c71c6e74720a ]
+
+lpuart_rx_dma_startup() is used for both the 8 bit and the 32 bit
+version of the LPUART. Modify the UARTCR only for the 8 bit version.
+
+Fixes: f4eef224a09f ("serial: fsl_lpuart: add sysrq support when using dma")
+Signed-off-by: Michael Walle <michael@walle.cc>
+Link: https://lore.kernel.org/r/20210512141255.18277-2-michael@walle.cc
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/fsl_lpuart.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
+index 794035041744..fbf2e4d2d22b 100644
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -1625,7 +1625,7 @@ static void lpuart_rx_dma_startup(struct lpuart_port *sport)
+ sport->lpuart_dma_rx_use = true;
+ rx_dma_timer_init(sport);
+
+- if (sport->port.has_sysrq) {
++ if (sport->port.has_sysrq && !lpuart_is_32(sport)) {
+ cr3 = readb(sport->port.membase + UARTCR3);
+ cr3 |= UARTCR3_FEIE;
+ writeb(cr3, sport->port.membase + UARTCR3);
+--
+2.30.2
+
--- /dev/null
+From a3fb2bf2301eca1aa7df460e846eca3cfb65c949 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 May 2021 16:12:52 +0200
+Subject: serial: fsl_lpuart: remove RTSCTS handling from get_mctrl()
+
+From: Michael Walle <michael@walle.cc>
+
+[ Upstream commit e60c2991f18bf221fa9908ff10cb24eaedaa9bae ]
+
+The wrong code in set_mctrl() was already removed in commit 2b30efe2e88a
+("tty: serial: lpuart: Remove unnecessary code from set_mctrl"), but the
+code in get_mctrl() wasn't removed. It will not return the state of the
+RTS or CTS line but whether automatic flow control is enabled, which is
+wrong for the get_mctrl(). Thus remove it.
+
+Fixes: 2b30efe2e88a ("tty: serial: lpuart: Remove unnecessary code from set_mctrl")
+Signed-off-by: Michael Walle <michael@walle.cc>
+Link: https://lore.kernel.org/r/20210512141255.18277-7-michael@walle.cc
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/fsl_lpuart.c | 12 +-----------
+ 1 file changed, 1 insertion(+), 11 deletions(-)
+
+diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
+index fbf2e4d2d22b..9c78e43e669d 100644
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -1408,17 +1408,7 @@ static unsigned int lpuart_get_mctrl(struct uart_port *port)
+
+ static unsigned int lpuart32_get_mctrl(struct uart_port *port)
+ {
+- unsigned int temp = 0;
+- unsigned long reg;
+-
+- reg = lpuart32_read(port, UARTMODIR);
+- if (reg & UARTMODIR_TXCTSE)
+- temp |= TIOCM_CTS;
+-
+- if (reg & UARTMODIR_RXRTSE)
+- temp |= TIOCM_RTS;
+-
+- return temp;
++ return 0;
+ }
+
+ static void lpuart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+--
+2.30.2
+
--- /dev/null
+From c0bdd5197de3cee462c3bd0a21327a323693bcd8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Jun 2021 00:49:02 +0200
+Subject: serial: mvebu-uart: correctly calculate minimal possible baudrate
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit deeaf963569a0d9d1b08babb771f61bb501a5704 ]
+
+For default (x16) scheme which is currently used by mvebu-uart.c driver,
+maximal divisor of UART base clock is 1023*16. Therefore there is limit for
+minimal supported baudrate. This change calculate it correctly and prevents
+setting invalid divisor 0 into hardware registers.
+
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Fixes: 68a0db1d7da2 ("serial: mvebu-uart: add function to change baudrate")
+Link: https://lore.kernel.org/r/20210624224909.6350-4-pali@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/mvebu-uart.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c
+index 9638ae6aae79..1e26220c7852 100644
+--- a/drivers/tty/serial/mvebu-uart.c
++++ b/drivers/tty/serial/mvebu-uart.c
+@@ -481,7 +481,7 @@ static void mvebu_uart_set_termios(struct uart_port *port,
+ struct ktermios *old)
+ {
+ unsigned long flags;
+- unsigned int baud;
++ unsigned int baud, min_baud, max_baud;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+@@ -500,16 +500,21 @@ static void mvebu_uart_set_termios(struct uart_port *port,
+ port->ignore_status_mask |= STAT_RX_RDY(port) | STAT_BRK_ERR;
+
+ /*
++ * Maximal divisor is 1023 * 16 when using default (x16) scheme.
+ * Maximum achievable frequency with simple baudrate divisor is 230400.
+ * Since the error per bit frame would be of more than 15%, achieving
+ * higher frequencies would require to implement the fractional divisor
+ * feature.
+ */
+- baud = uart_get_baud_rate(port, termios, old, 0, 230400);
++ min_baud = DIV_ROUND_UP(port->uartclk, 1023 * 16);
++ max_baud = 230400;
++
++ baud = uart_get_baud_rate(port, termios, old, min_baud, max_baud);
+ if (mvebu_uart_baud_rate_set(port, baud)) {
+ /* No clock available, baudrate cannot be changed */
+ if (old)
+- baud = uart_get_baud_rate(port, old, NULL, 0, 230400);
++ baud = uart_get_baud_rate(port, old, NULL,
++ min_baud, max_baud);
+ } else {
+ tty_termios_encode_baud_rate(termios, baud, baud);
+ uart_update_timeout(port, termios->c_cflag, baud);
+--
+2.30.2
+
--- /dev/null
+From 8d8e814db04a01b3fde87d0b47df24b87bf005c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Jun 2021 00:49:01 +0200
+Subject: serial: mvebu-uart: do not allow changing baudrate when uartclk is
+ not available
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit ecd6b010d81f97b06b2f64d2d4f50ebf5acddaa9 ]
+
+Testing mvuart->clk for non-error is not enough as mvuart->clk may contain
+valid clk pointer but when clk_prepare_enable(mvuart->clk) failed then
+port->uartclk is zero.
+
+When mvuart->clk is not available then port->uartclk is zero too.
+
+Parent clock rate port->uartclk is needed to calculate UART clock divisor
+and without it is not possible to change baudrate.
+
+So fix test condition when it is possible to change baudrate.
+
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Fixes: 68a0db1d7da2 ("serial: mvebu-uart: add function to change baudrate")
+Link: https://lore.kernel.org/r/20210624224909.6350-3-pali@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/mvebu-uart.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c
+index 908a4ac6b5a7..9638ae6aae79 100644
+--- a/drivers/tty/serial/mvebu-uart.c
++++ b/drivers/tty/serial/mvebu-uart.c
+@@ -445,12 +445,11 @@ static void mvebu_uart_shutdown(struct uart_port *port)
+
+ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
+ {
+- struct mvebu_uart *mvuart = to_mvuart(port);
+ unsigned int d_divisor, m_divisor;
+ u32 brdv, osamp;
+
+- if (IS_ERR(mvuart->clk))
+- return -PTR_ERR(mvuart->clk);
++ if (!port->uartclk)
++ return -EOPNOTSUPP;
+
+ /*
+ * The baudrate is derived from the UART clock thanks to two divisors:
+--
+2.30.2
+
fuse-ignore-pg_workingset-after-stealing.patch
fuse-check-connected-before-queueing-on-fpq-io.patch
fuse-reject-internal-errno.patch
+thermal-cpufreq_cooling-update-offline-cpus-per-cpu-.patch
+spi-make-of_register_spi_device-also-set-the-fwnode.patch
+add-a-reference-to-ucounts-for-each-cred.patch
+staging-media-rkvdec-fix-pm_runtime_get_sync-usage-c.patch
+media-i2c-imx334-fix-the-pm-runtime-get-logic.patch
+media-marvel-ccic-fix-some-issues-when-getting-pm_ru.patch
+media-mdk-mdp-fix-pm_runtime_get_sync-usage-count.patch
+media-s5p-fix-pm_runtime_get_sync-usage-count.patch
+media-am437x-fix-pm_runtime_get_sync-usage-count.patch
+media-sh_vou-fix-pm_runtime_get_sync-usage-count.patch
+media-mtk-vcodec-fix-pm-runtime-get-logic.patch
+media-s5p-jpeg-fix-pm_runtime_get_sync-usage-count.patch
+media-sunxi-fix-pm_runtime_get_sync-usage-count.patch
+media-sti-bdisp-fix-pm_runtime_get_sync-usage-count.patch
+media-exynos4-is-fix-pm_runtime_get_sync-usage-count.patch
+media-exynos-gsc-fix-pm_runtime_get_sync-usage-count.patch
+spi-spi-loopback-test-fix-tx_buf-might-be-rx_buf.patch
+spi-spi-topcliff-pch-fix-potential-double-free-in-pc.patch
+spi-omap-100k-fix-the-length-judgment-problem.patch
+regulator-uniphier-add-missing-module_device_table.patch
+sched-core-initialize-the-idle-task-with-preemption-.patch
+hwrng-exynos-fix-runtime-pm-imbalance-on-error.patch
+crypto-nx-add-missing-module_device_table.patch
+media-sti-fix-obj-config-targets.patch
+sched-make-the-idle-task-quack-like-a-per-cpu-kthrea.patch
+media-cpia2-fix-memory-leak-in-cpia2_usb_probe.patch
+media-cobalt-fix-race-condition-in-setting-hpd.patch
+media-hevc-fix-dependent-slice-segment-flags.patch
+media-pvrusb2-fix-warning-in-pvr2_i2c_core_done.patch
+media-imx-imx7_mipi_csis-fix-logging-of-only-error-e.patch
+crypto-qat-check-return-code-of-qat_hal_rd_rel_reg.patch
+crypto-qat-remove-unused-macro-in-fw-loader.patch
+crypto-qce-skcipher-fix-incorrect-sg-count-for-dma-t.patch
+crypto-ecdh-fix-ecdh-nist-p192-s-entry-in-testmgr.patch
+crypto-ecdh-fix-ecdh_init.patch
+arm64-perf-convert-snprintf-to-sysfs_emit.patch
+sched-fair-fix-ascii-art-by-relpacing-tabs.patch
+ima-don-t-remove-security.ima-if-file-must-not-be-ap.patch
+media-i2c-ov2659-use-clk_-prepare_enable-disable_unp.patch
+media-bt878-do-not-schedule-tasklet-when-it-is-not-s.patch
+media-em28xx-fix-possible-memory-leak-of-em28xx-stru.patch
+media-hantro-fix-.buf_prepare.patch
+media-cedrus-fix-.buf_prepare.patch
+media-v4l2-core-avoid-the-dangling-pointer-in-v4l2_f.patch
+media-bt8xx-fix-a-missing-check-bug-in-bt878_probe.patch
+media-st-hva-fix-potential-null-pointer-dereferences.patch
+crypto-hisilicon-sec-fixup-3des-minimum-key-size-dec.patch
+arm64-entry-don-t-instrument-entry-code-with-kcov.patch
+makefile-fix-gdb-warning-with-config_relr.patch
+media-dvd_usb-memory-leak-in-cinergyt2_fe_attach.patch
+memstick-rtsx_usb_ms-fix-uaf.patch
+mmc-sdhci-sprd-use-sdhci_sprd_writew.patch
+mmc-via-sdmmc-add-a-check-against-null-pointer-deref.patch
+mmc-sdhci-of-aspeed-turn-down-a-phase-correction-war.patch
+spi-meson-spicc-fix-a-wrong-goto-jump-for-avoiding-m.patch
+spi-meson-spicc-fix-memory-leak-in-meson_spicc_probe.patch
+regulator-mt6315-fix-checking-return-value-of-devm_r.patch
+crypto-shash-avoid-comparing-pointers-to-exported-fu.patch
+media-dvb_net-avoid-speculation-from-net-slot.patch
+media-dvbdev-fix-error-logic-at-dvb_register_device.patch
+media-siano-fix-device-register-error-path.patch
+media-imx-csi-skip-first-few-frames-from-a-bt.656-so.patch
+hwmon-max31790-report-correct-current-pwm-duty-cycle.patch
+hwmon-max31790-fix-pwmx_enable-attributes.patch
+sched-fair-take-thermal-pressure-into-account-while-.patch
+perf-x86-reset-the-dirty-counter-to-prevent-the-leak.patch
+drivers-perf-fix-the-missed-ida_simple_remove-in-ddr.patch
+kvm-arm64-restore-pmu-configuration-on-first-run.patch
+kvm-ppc-book3s-hv-fix-tlb-management-on-smt8-power9-.patch
+btrfs-fix-error-handling-in-__btrfs_update_delayed_i.patch
+btrfs-abort-transaction-if-we-fail-to-update-the-del.patch
+btrfs-always-abort-the-transaction-if-we-abort-a-tra.patch
+btrfs-sysfs-fix-format-string-for-some-discard-stats.patch
+btrfs-scrub-fix-subpage-repair-error-caused-by-hard-.patch
+btrfs-fix-the-filemap_range_has_page-call-in-btrfs_p.patch
+btrfs-don-t-clear-page-extent-mapped-if-we-re-not-in.patch
+btrfs-disable-build-on-platforms-having-page-size-25.patch
+locking-lockdep-fix-the-dep-path-printing-for-backwa.patch
+lockding-lockdep-avoid-to-find-wrong-lock-dep-path-i.patch
+kvm-s390-get-rid-of-register-asm-usage.patch
+regulator-mt6358-fix-vdram2-.vsel_mask.patch
+regulator-da9052-ensure-enough-delay-time-for-.set_v.patch
+media-fix-media-controller-api-config-checks.patch
+seccomp-support-atomic-addfd-send-reply.patch
+hid-do-not-use-down_interruptible-when-unbinding-dev.patch
+edac-ti-add-missing-module_device_table.patch
+acpi-pm-s2idle-add-missing-lps0-functions-for-amd.patch
+acpi-scan-rearrange-dep_unmet-initialization.patch
+acpi-processor-idle-fix-up-c-state-latency-if-not-or.patch
+hv_utils-fix-passing-zero-to-ptr_err-warning.patch
+lib-vsprintf-fix-handling-of-number-field-widths-in-.patch
+input-goodix-platform-x86-touchscreen_dmi-move-upsid.patch
+platform-x86-touchscreen_dmi-add-an-extra-entry-for-.patch
+platform-x86-touchscreen_dmi-add-info-for-the-goodix.patch
+acpi-ec-make-more-asus-laptops-use-ecdt-_gpe.patch
+block_dump-remove-block_dump-feature-in-mark_inode_d.patch
+blk-mq-grab-rq-refcount-before-calling-fn-in-blk_mq_.patch
+blk-mq-clear-stale-request-in-tags-rq-before-freeing.patch
+fs-dlm-fix-srcu-read-lock-usage.patch
+fs-dlm-reconnect-if-socket-error-report-occurs.patch
+fs-dlm-cancel-work-sync-othercon.patch
+fs-dlm-fix-connection-tcp-eof-handling.patch
+random32-fix-implicit-truncation-warning-in-prandom_.patch
+open-don-t-silently-ignore-unknown-o-flags-in-openat.patch
+drivers-hv-fix-missing-error-code-in-vmbus_connect.patch
+fs-dlm-fix-lowcomms_start-error-case.patch
+fs-dlm-fix-memory-leak-when-fenced.patch
+acpica-fix-memory-leak-caused-by-_cid-repair-functio.patch
+acpi-bus-call-kobject_put-in-acpi_init-error-path.patch
+acpi-resources-add-checks-for-acpi-irq-override.patch
+hid-hid-input-add-surface-go-battery-quirk.patch
+hid-sony-fix-freeze-when-inserting-ghlive-ps3-wii-do.patch
+block-fix-race-between-adding-removing-rq-qos-and-no.patch
+platform-x86-asus-nb-wmi-revert-drop-duplicate-dmi-q.patch
+platform-x86-asus-nb-wmi-revert-add-support-for-asus.patch
+platform-x86-toshiba_acpi-fix-missing-error-code-in-.patch
+nvme-pci-fix-var.-type-for-increasing-cq_head.patch
+nvmet-fc-do-not-check-for-invalid-target-port-in-nvm.patch
+edac-intel-do-not-load-edac-driver-when-running-as-a.patch
+tools-power-x86-intel-speed-select-fix-uncore-memory.patch
+pci-hv-add-check-for-hyperv_initialized-in-init_hv_p.patch
+cifs-improve-fallocate-emulation.patch
+cifs-fix-check-of-dfs-interlinks.patch
+cifs-retry-lookup-and-readdir-when-eagain-is-returne.patch
+smb3-fix-uninitialized-value-for-port-in-witness-pro.patch
+cifs-fix-smb1-error-path-in-cifs_get_file_info_unix.patch
+acpi-ec-trust-dsdt-gpe-for-certain-hp-laptop.patch
+block-bfq-fix-delayed-stable-merge-check.patch
+clocksource-retry-clock-read-if-long-delays-detected.patch
+clocksource-check-per-cpu-clock-synchronization-when.patch
+tpm_tis_spi-add-missing-spi-device-id-entries.patch
+acpi-tables-add-custom-dsdt-file-as-makefile-prerequ.patch
+smb3-fix-possible-access-to-uninitialized-pointer-to.patch
+hid-wacom-correct-base-usage-for-capacitive-expressk.patch
+cifs-fix-missing-spinlock-around-update-to-ses-statu.patch
+bfq-remove-merged-request-already-in-bfq_requests_me.patch
+mailbox-qcom-use-platform_devid_auto-to-register-pla.patch
+block-fix-discard-request-merge.patch
+kthread_worker-fix-return-value-when-kthread_mod_del.patch
+ia64-mca_drv-fix-incorrect-array-size-calculation.patch
+writeback-cgroup-increment-isw_nr_in_flight-before-g.patch
+mm-define-default-max_ptrs_per_-in-include-pgtable.h.patch
+kbuild-skip-per-cpu-btf-generation-for-pahole-v1.18-.patch
+spi-allow-to-have-all-native-css-in-use-along-with-g.patch
+spi-avoid-undefined-behaviour-when-counting-unused-n.patch
+media-venus-rework-error-fail-recover-logic.patch
+media-s5p_cec-decrement-usage-count-if-disabled.patch
+media-i2c-ccs-core-return-the-right-error-code-at-su.patch
+media-hantro-do-a-pm-resume-earlier.patch
+crypto-ixp4xx-dma_unmap-the-correct-address.patch
+crypto-ixp4xx-update-iv-after-requests.patch
+crypto-ux500-fix-error-return-code-in-hash_hw_final.patch
+sata_highbank-fix-deferred-probing.patch
+pata_rb532_cf-fix-deferred-probing.patch
+media-i2c-change-rst-to-rset-to-fix-multiple-build-e.patch
+sched-uclamp-fix-wrong-implementation-of-cpu.uclamp..patch
+sched-uclamp-fix-locking-around-cpu_util_update_eff.patch
+kbuild-fix-objtool-dependency-for-object_files_non_s.patch
+pata_octeon_cf-avoid-warn_on-in-ata_host_activate.patch
+evm-fix-writing-securityfs-evm-overflow.patch
+crypto-testmgr-fix-initialization-of-secret_size.patch
+crypto-hisilicon-hpre-fix-unmapping-invalid-dma-addr.patch
+x86-elf-use-_bitul-macro-in-uapi-headers.patch
+crypto-sa2ul-fix-leaks-on-failure-paths-with-sa_dma_.patch
+crypto-sa2ul-fix-pm_runtime-enable-in-sa_ul_probe.patch
+crypto-sa2ul-use-of_device_get_match_data-helper.patch
+crypto-ccp-fix-a-resource-leak-in-an-error-handling-.patch
+media-rc-i2c-fix-an-error-message.patch
+regulator-bd71815-add-select-to-fix-build.patch
+pata_ep93xx-fix-deferred-probing.patch
+locking-lockdep-reduce-lockdep-dependency-list.patch
+sched-don-t-defer-cpu-pick-to-migration_cpu_stop.patch
+media-ipu3-cio2-fix-reference-counting-when-looping-.patch
+media-venus-hfi_cmds-fix-conceal-color-property.patch
+media-rkvdec-fix-.buf_prepare.patch
+media-exynos4-is-fix-a-use-after-free-in-isp_video_r.patch
+media-au0828-fix-a-null-vs-is_err-check.patch
+media-tc358743-fix-error-return-code-in-tc358743_pro.patch
+media-vicodec-use-_bitul-macro-in-uapi-headers.patch
+media-gspca-gl860-fix-zero-length-control-requests.patch
+regulator-fan53555-fix-missing-slew_reg-mask-shift-s.patch
+drivers-perf-hisi-fix-data-source-control.patch
+m68k-atari-fix-atari_kbd_core-kconfig-unmet-dependen.patch
+media-siano-fix-out-of-bounds-warnings-in-smscore_lo.patch
+regulator-fan53880-fix-vsel_mask-setting-for-fan5388.patch
+crypto-nitrox-fix-unchecked-variable-in-nitrox_regis.patch
+crypto-omap-sham-fix-pm-reference-leak-in-omap-sham-.patch
+crypto-x86-curve25519-fix-cpu-feature-checking-logic.patch
+crypto-sm2-fix-a-memory-leak-in-sm2.patch
+mmc-usdhi6rol0-fix-error-return-code-in-usdhi6_probe.patch
+arm64-mm-fix-ttbr0-values-stored-in-struct-thread_in.patch
+media-v4l2-core-ignore-native-time32-ioctls-on-64-bi.patch
+media-subdev-remove-vidioc_dqevent_time32-handling.patch
+media-s5p-g2d-fix-a-memory-leak-on-ctx-fh.m2m_ctx.patch
+media-i2c-rdacm21-fix-ov10640-powerup.patch
+media-i2c-rdacm21-power-up-ov10640-before-ov490.patch
+hwmon-pmbus-bpa-rs600-handle-vin-readings-256v.patch
+hwmon-lm70-revert-hwmon-lm70-add-support-for-acpi.patch
+hwmon-max31722-remove-non-standard-acpi-device-ids.patch
+hwmon-max31790-fix-fan-speed-reporting-for-fan7.12.patch
+kvm-nvmx-add-a-return-code-to-vmx_complete_nested_po.patch
+kvm-nvmx-sync-all-pgds-on-nested-transition-with-sha.patch
+kvm-nvmx-ensure-64-bit-shift-when-checking-vmfunc-bi.patch
+kvm-nvmx-don-t-clobber-nested-mmu-s-a-d-status-on-ep.patch
+kvm-x86-mmu-fix-return-value-in-tdp_mmu_map_handle_t.patch
+kvm-x86-mmu-fix-pf_fixed-count-in-tdp_mmu_map_handle.patch
+perf-arm-cmn-fix-invalid-pointer-when-access-dtc-obj.patch
+kvm-arm64-don-t-zero-the-cycle-count-register-when-p.patch
+regulator-hi655x-fix-pass-wrong-pointer-to-config.dr.patch
+regulator-qcom-rpmh-add-terminator-at-the-end-of-pm7.patch
+regulator-hi6421v600-fix-setting-idle-mode.patch
+regulator-bd9576-fix-the-driver-name-in-id-table.patch
+btrfs-clear-log-tree-recovering-status-if-starting-t.patch
+x86-sev-make-sure-irqs-are-disabled-while-ghcb-is-ac.patch
+x86-sev-split-up-runtime-vc-handler-for-correct-stat.patch
+sched-rt-fix-rt-utilization-tracking-during-policy-c.patch
+sched-rt-fix-deadline-utilization-tracking-during-po.patch
+sched-uclamp-fix-uclamp_tg_restrict.patch
+lockdep-fix-wait-type-for-empty-stack.patch
+lockdep-selftests-fix-selftests-vs-prove_raw_lock_ne.patch
+x86-sev-use-sev-prefix-for-messages-from-sev.c.patch
+spi-spi-sun6i-fix-chipselect-clock-bug.patch
+perf-fix-task-context-pmu-for-hetero.patch
+crypto-nx-fix-rcu-warning-in-nx842_of_upd_status.patch
+objtool-don-t-make-.altinstructions-writable.patch
+psi-fix-race-between-psi_trigger_create-destroy.patch
+kvm-selftests-fix-triple-fault-if-ept-0-in-dirty_log.patch
+kvm-selftests-remove-errant-asm-barrier.h-include-to.patch
+media-video-mux-skip-dangling-endpoints.patch
+media-mtk-vpu-on-suspend-read-write-regs-only-if-vpu.patch
+media-s5p-mfc-fix-display-delay-control-creation.patch
+edac-aspeed-use-proper-format-string-for-printing-re.patch
+pm-devfreq-add-missing-error-code-in-devfreq_add_dev.patch
+acpi-pm-fan-put-fan-device-ids-into-separate-header-.patch
+block-avoid-double-io-accounting-for-flush-request.patch
+x86-hyperv-fix-logical-processor-creation.patch
+nvme-pci-look-for-storaged3enable-on-companion-acpi-.patch
+acpi-tables-fpdt-add-missing-acpi_put_table-in-acpi_.patch
+acpi-sysfs-fix-a-buffer-overrun-problem-with-descrip.patch
+mark-pstore-blk-as-broken.patch
+md-revert-io-stats-accounting.patch
+hid-surface-hid-fix-get-report-request.patch
+clocksource-drivers-timer-ti-dm-save-and-restore-tim.patch
+nvme-tcp-fix-error-codes-in-nvme_tcp_setup_ctrl.patch
+extcon-extcon-max8997-fix-irq-freeing-at-error-path.patch
+acpi-apei-fix-synchronous-external-aborts-in-user-mo.patch
+edac-igen6-fix-core-dependency.patch
+blk-wbt-introduce-a-new-disable-state-to-prevent-fal.patch
+blk-wbt-make-sure-throttle-is-enabled-properly.patch
+block-bfq-avoid-delayed-merge-of-async-queues.patch
+block-bfq-reset-waker-pointer-with-shared-queues.patch
+acpi-bgrt-fix-cfi-violation.patch
+cpufreq-make-cpufreq_online-call-driver-offline-on-e.patch
+pm-devfreq-passive-fix-get_target_freq-when-not-usin.patch
+block-fix-trace-completion-for-chained-bio.patch
+blk-mq-update-hctx-dispatch_busy-in-case-of-real-sch.patch
+ocfs2-fix-snprintf-checking.patch
+dax-fix-enomem-handling-in-grab_mapping_entry.patch
+mm-debug_vm_pgtable-ensure-thp-availability-via-has_.patch
+mm-mmap_lock-use-local-locks-instead-of-disabling-pr.patch
+swap-fix-do_swap_page-race-with-swapoff.patch
+mm-shmem-fix-shmem_swapin-race-with-swapoff.patch
+mm-memcg-slab-properly-set-up-gfp-flags-for-objcg-po.patch
+mm-page_alloc-fix-counting-of-managed_pages.patch
+xfrm-xfrm_state_mtu-should-return-at-least-1280-for-.patch
+drm-bridge-sii8620-fix-dependency-on-extcon.patch
+drm-bridge-fix-the-stop-condition-of-drm_bridge_chai.patch
+drm-amd-dc-fix-a-missing-check-bug-in-dm_dp_mst_dete.patch
+drm-ast-fix-missing-conversions-to-managed-api.patch
+drm-bridge-anx7625-fix-power-on-delay.patch
+drm-bridge-fix-lontium_lt8912b-dependencies.patch
+video-fbdev-imxfb-fix-an-error-message.patch
+drm-imx-ipuv3-plane-do-not-advertise-yuv-formats-on-.patch
+drm-imx-ipuv3-plane-fix-prg-modifiers-after-drm-mana.patch
+rtnetlink-avoid-rcu-read-lock-when-holding-rtnl.patch
+net-mvpp2-put-fwnode-in-error-case-during-probe.patch
+net-pch_gbe-propagate-error-from-devm_gpio_request_o.patch
+pinctrl-renesas-r8a7796-add-missing-bias-for-preset-.patch
+pinctrl-renesas-r8a77990-jtag-pins-do-not-have-pull-.patch
+rdma-hns-remove-the-condition-of-light-load-for-post.patch
+drm-vmwgfx-mark-a-surface-gpu-dirty-after-the-svga3d.patch
+drm-vmwgfx-fix-cpu-updates-of-coherent-multisample-s.patch
+libbpf-fix-elf-symbol-visibility-update-logic.patch
+drm-i915-merge-fix-for-drm-switch-to-p4cc-format-mod.patch
+net-qrtr-ns-fix-error-return-code-in-qrtr_ns_init.patch
+clk-meson-g12a-fix-gp0-and-hifi-ranges.patch
+drm-amd-display-fix-potential-gpu-reset-deadlock.patch
+drm-amd-display-avoid-hpd-irq-in-gpu-reset-state.patch
+drm-amd-display-take-dc_lock-in-short-pulse-handler-.patch
+net-ftgmac100-add-missing-error-return-code-in-ftgma.patch
+clk-rockchip-fix-rk3568-cpll-clk-gate-bits.patch
+clk-sunxi-ng-v3s-fix-incorrect-postdivider-on-pll-au.patch
+drm-vc4-crtc-pass-the-drm_atomic_state-to-config_pv.patch
+drm-vc4-crtc-fix-vc4_get_crtc_encoder-logic.patch
+drm-vc4-crtc-lookup-the-encoder-from-the-register-at.patch
+drm-rockchip-set-alpha_en-to-0-if-it-is-not-used.patch
+drm-rockchip-cdn-dp-core-add-missing-clk_disable_unp.patch
+drm-rockchip-dsi-move-all-lane-config-except-lcdc-mu.patch
+drm-rockchip-lvds-fix-an-error-handling-path.patch
+drm-rockchip-cdn-dp-fix-sign-extension-on-an-int-mul.patch
+mptcp-fix-pr_debug-in-mptcp_token_new_connect.patch
+mptcp-generate-subflow-hmac-after-mptcp_finish_join.patch
+mptcp-make-sure-flag-signal-is-set-when-add-addr-wit.patch
+rdma-hns-fix-wrong-timer-context-buffer-page-size.patch
+rdma-srp-fix-a-recently-introduced-memory-leak.patch
+rdma-rtrs-clt-check-state-of-the-rtrs_clt_sess-befor.patch
+rdma-rtrs-do-not-reset-hb_missed_max-after-re-connec.patch
+rdma-rtrs-srv-fix-memory-leak-of-unfreed-rtrs_srv_st.patch
+rdma-rtrs-srv-fix-memory-leak-when-having-multiple-s.patch
+rdma-rtrs-clt-check-if-the-queue_depth-has-changed-d.patch
+rdma-rtrs-clt-fix-memory-leak-of-not-freed-sess-stat.patch
+ehea-fix-error-return-code-in-ehea_restart_qps.patch
+clk-tegra30-use-300mhz-for-video-decoder-by-default.patch
+xfrm-remove-the-fragment-check-for-ipv6-beet-mode.patch
+net-sched-act_vlan-fix-modify-to-allow-0.patch
+rdma-core-sanitize-wq-state-received-from-the-usersp.patch
+ib-cm-pair-cm_alloc_response_msg-with-a-cm_free_resp.patch
+ib-cm-split-cm_alloc_msg.patch
+revert-ib-cm-mark-stale-cm-id-s-whenever-the-mad-age.patch
+ib-cm-improve-the-calling-of-cm_init_av_for_lap-and-.patch
+drm-pl111-depend-on-config_vexpress_config.patch
+rdma-rxe-fix-failure-during-driver-load.patch
+drm-pl111-actually-fix-config_vexpress_config-depend.patch
+drm-vc4-hdmi-fix-error-path-of-hpd-gpios.patch
+clk-vc5-fix-output-disabling-when-enabling-a-fod.patch
+drm-qxl-ensure-surf.data-is-ininitialized.patch
+stmmac-prefetch-right-address.patch
+net-stmmac-fix-potential-integer-overflow.patch
+tools-bpftool-fix-error-return-code-in-do_batch.patch
+ath10k-go-to-path-err_unsupported-when-chip-id-is-no.patch
+ath10k-add-missing-error-return-code-in-ath10k_pci_p.patch
+wireless-carl9170-fix-leds-build-errors-warnings.patch
+ieee802154-hwsim-fix-possible-memory-leak-in-hwsim_s.patch
+clk-imx8mq-remove-sys-pll-1-2-clock-gates.patch
+wcn36xx-move-hal_buf-allocation-to-devm_kmalloc-in-p.patch
+net-wwan-fix-wwan-config-symbols.patch
+drm-i915-selftests-reorder-tasklet_disable-vs-local_.patch
+ssb-fix-error-return-code-in-ssb_bus_scan.patch
+brcmfmac-fix-setting-of-station-info-chains-bitmask.patch
+brcmfmac-correctly-report-average-rssi-in-station-in.patch
+brcmfmac-fix-a-double-free-in-brcmf_sdio_bus_reset.patch
+brcmfmac-delete-second-brcm-folder-hierarchy.patch
+brcmsmac-mac80211_if-fix-a-resource-leak-in-an-error.patch
+cw1200-revert-unnecessary-patches-that-fix-unreal-us.patch
+ath11k-fix-an-error-handling-path-in-ath11k_core_fet.patch
+ath10k-fix-an-error-code-in-ath10k_add_interface.patch
+ath11k-send-beacon-template-after-vdev_start-restart.patch
+wil6210-remove-erroneous-wiphy-locking.patch
+netlabel-fix-memory-leak-in-netlbl_mgmt_add_common.patch
+rdma-mlx5-don-t-add-slave-port-to-unaffiliated-list.patch
+netfilter-nft_exthdr-check-for-ipv6-packet-before-fu.patch
+netfilter-nft_osf-check-for-tcp-packet-before-furthe.patch
+netfilter-nft_tproxy-restrict-support-to-tcp-and-udp.patch
+rdma-rxe-fix-qp-reference-counting-for-atomic-ops.patch
+selftests-bpf-whitelist-test_progs.h-from-.gitignore.patch
+selftests-bpf-fix-ringbuf-test-fetching-map-fd.patch
+xsk-fix-missing-validation-for-skb-and-unaligned-mod.patch
+xsk-fix-broken-tx-ring-validation.patch
+bpf-fix-libelf-endian-handling-in-resolv_btfids.patch
+rdma-rtrs-srv-set-minimal-max_send_wr-and-max_recv_w.patch
+rdma-hns-clear-extended-doorbell-info-before-using.patch
+samples-bpf-fix-segmentation-fault-for-xdp_redirect-.patch
+samples-bpf-fix-the-error-return-code-of-xdp_redirec.patch
+net-pxa168_eth-fix-a-potential-data-race-in-pxa168_e.patch
+mt76-mt7915-fix-a-signedness-bug-in-mt7915_mcu_apply.patch
+mt76-fix-possible-null-pointer-dereference-in-mt76_t.patch
+mt76-mt7615-fix-null-pointer-dereference-in-tx_prepa.patch
+mt76-mt7921-fix-mt7921_wfsys_reset-sequence.patch
+mt76-mt7921-don-t-alter-rx-path-classifier.patch
+mt76-connac-fw_own-rely-on-all-packet-memory-all-bei.patch
+mt76-connac-fix-wow-with-disconnetion-and-bitmap-pat.patch
+mt76-mt7921-consider-the-invalid-value-for-to_rssi.patch
+mt76-mt7921-add-back-connection-monitor-support.patch
+mt76-mt7921-fix-invalid-register-access-in-wake_work.patch
+mt76-mt7921-fix-omac-idx-usage.patch
+mt76-mt7921-avoid-unnecessary-consecutive-wifi-reset.patch
+mt76-mt7921-do-not-schedule-hw-reset-if-the-device-i.patch
+mt76-testmode-fix-memory-leak-in-mt76_testmode_alloc.patch
+mt76-testmode-remove-undefined-behaviour-in-mt76_tes.patch
+mt76-mt7615-fix-potential-overflow-on-large-shift.patch
+mt76-mt7915-fix-mt_ee_cal_group_size.patch
+mt76-mt7921-wake-the-device-before-dumping-power-tab.patch
+mt76-mt7915-fix-rx-fcs-error-count-in-testmode.patch
+mt76-mt7921-fix-kernel-warning-when-reset-on-vif-is-.patch
+mt76-mt7921-fix-the-coredump-is-being-truncated.patch
+net-ethernet-aeroflex-fix-uaf-in-greth_of_remove.patch
+net-ethernet-ezchip-fix-uaf-in-nps_enet_remove.patch
+net-ethernet-ezchip-fix-error-handling.patch
+selftests-bpf-retry-for-eagain-in-udp_redir_to_conne.patch
+udp-fix-a-memory-leak-in-udp_read_sock.patch
+skmsg-clear-skb-redirect-pointer-before-dropping-it.patch
+skmsg-fix-a-memory-leak-in-sk_psock_verdict_apply.patch
+skmsg-teach-sk_psock_verdict_apply-to-return-errors.patch
+vrf-do-not-push-non-nd-strict-packets-with-a-source-.patch
+net-sched-add-barrier-to-ensure-correct-ordering-for.patch
+selftests-tls-clean-up-uninitialized-warnings.patch
+selftests-tls-fix-chacha-bidir-tests.patch
+tls-prevent-oversized-sendfile-hangs-by-ignoring-msg.patch
+netfilter-nf_tables-memleak-in-hw-offload-abort-path.patch
+netfilter-nf_tables_offload-check-flow_dissector_key.patch
+mptcp-fix-bad-handling-of-32-bit-ack-wrap-around.patch
+mptcp-fix-32-bit-dsn-expansion.patch
+net-mana-fix-a-memory-leak-in-an-error-handling-path.patch
+net-dsa-mv88e6xxx-fix-adding-vlan-0.patch
+pkt_sched-sch_qfq-fix-qfq_change_class-error-path.patch
+xfrm-fix-xfrm-offload-fallback-fail-case.patch
+netfilter-nf_tables-skip-netlink-portid-validation-i.patch
+netfilter-nf_tables-do-not-allow-to-delete-table-wit.patch
+iwlwifi-increase-pnvm-load-timeout.patch
+bpf-fix-regression-on-bpf_obj_get-with-non-o_rdwr-fl.patch
+rtw88-8822c-fix-lc-calibration-timing.patch
+vxlan-add-missing-rcu_read_lock-in-neigh_reduce.patch
+bpf-fix-integer-overflow-in-argument-calculation-for.patch
+mptcp-avoid-race-on-msk-state-changes.patch
+ip6_tunnel-fix-gre6-segmentation.patch
+net-ipv4-swap-flow-ports-when-validating-source.patch
+net-broadcom-bcm4908_enet-reset-dma-rings-sw-indexes.patch
+net-ti-am65-cpsw-nuss-fix-crash-when-changing-number.patch
+tc-testing-fix-list-handling.patch
+rdma-hns-force-rewrite-inline-flag-of-wqe.patch
+rdma-hns-fix-uninitialized-variable.patch
+ieee802154-hwsim-fix-memory-leak-in-hwsim_add_one.patch
+ieee802154-hwsim-avoid-possible-crash-in-hwsim_del_e.patch
+bpf-fix-null-ptr-deref-with-mixed-tail-calls-and-sub.patch
+drm-msm-dp-handle-irq_hpd-with-sink_count-0-correctl.patch
+drm-msm-disp-dpu1-avoid-perf-update-in-frame-done-ev.patch
+drm-msm-fix-error-return-code-in-msm_drm_init.patch
+drm-msm-dpu-fix-error-return-code-in-dpu_mdss_init.patch
+mac80211-remove-iwlwifi-specific-workaround-ndps-of-.patch
+net-bcmgenet-fix-attaching-to-pyh-failed-on-rpi-4b.patch
+ipv6-exthdrs-do-not-blindly-use-init_net.patch
+can-j1939-j1939_sk_setsockopt-prevent-allocation-of-.patch
+bpf-do-not-change-gso_size-during-bpf_skb_change_pro.patch
+i40e-fix-error-handling-in-i40e_vsi_open.patch
+i40e-fix-autoneg-disabling-for-non-10gbaset-links.patch
+i40e-fix-missing-rtnl-locking-when-setting-up-pf-swi.patch
+rdma-hns-add-a-check-to-ensure-integer-mtu-is-positi.patch
+rdma-hns-add-window-selection-field-of-congestion-co.patch
+revert-ibmvnic-simplify-reset_long_term_buff-functio.patch
+revert-ibmvnic-remove-duplicate-napi_schedule-call-i.patch
+ibmvnic-clean-pending-indirect-buffs-during-reset.patch
+ibmvnic-account-for-bufs-already-saved-in-indir_buf.patch
+ibmvnic-set-ltb-buff-to-null-after-freeing.patch
+ibmvnic-free-tx_pool-if-tso_pool-alloc-fails.patch
+rdma-cma-protect-rmw-with-qp_mutex.patch
+net-macsec-fix-the-length-used-to-copy-the-key-for-o.patch
+net-phy-mscc-fix-macsec-key-length.patch
+net-atlantic-fix-the-macsec-key-length.patch
+ipv6-fix-out-of-bound-access-in-ip6_parse_tlv.patch
+e1000e-check-the-pcim-state.patch
+net-dsa-sja1105-fix-null-pointer-dereference-in-sja1.patch
+bpfilter-specify-the-log-level-for-the-kmsg-message.patch
+rdma-cma-fix-incorrect-packet-lifetime-calculation.patch
+gve-fix-swapped-vars-when-fetching-max-queues.patch
+revert-be2net-disable-bh-with-spin_lock-in-be_proces.patch
+clk-zynqmp-fix-compile-testing-without-zynqmp_firmwa.patch
+bluetooth-virtio_bt-add-missing-null-pointer-check-o.patch
+bluetooth-mgmt-fix-slab-out-of-bounds-in-tlv_data_is.patch
+bluetooth-fix-set-extended-scan-response-data.patch
+bluetooth-fix-handling-of-hci_le_advertising_set_ter.patch
+clk-qcom-gcc-add-support-for-a-new-frequency-for-sc7.patch
+clk-actions-fix-uart-clock-dividers-on-owl-s500-soc.patch
+clk-actions-fix-sd-clocks-factor-table-on-owl-s500-s.patch
+clk-actions-fix-bisp_factor_table-based-clocks-on-ow.patch
+clk-actions-fix-ahpprediv-h-ahb-clock-chain-on-owl-s.patch
+clk-qcom-clk-alpha-pll-fix-cal_l-write-in-alpha_pll_.patch
+clk-si5341-wait-for-device_ready-on-startup.patch
+clk-si5341-avoid-divide-errors-due-to-bogus-register.patch
+clk-si5341-check-for-input-clock-presence-and-pll-lo.patch
+clk-si5341-update-initialization-magic.patch
+bpf-x86-fix-extable-offset-calculation.patch
+writeback-fix-obtain-a-reference-to-a-freeing-memcg-.patch
+net-lwtunnel-handle-mtu-calculation-in-forwading.patch
+net-sched-fix-warning-in-tcindex_alloc_perfect_hash.patch
+net-tipc-fix-fb_mtu-eat-two-pages.patch
+rdma-mlx5-don-t-access-null-cleared-mpi-pointer.patch
+rdma-core-always-release-restrack-object.patch
+mips-fix-pkmap-with-32-bit-mips-huge-page-support.patch
+staging-rtl8712-fix-some-tests-against-some-data-sub.patch
+staging-fbtft-rectify-gpio-handling.patch
+staging-fbtft-don-t-spam-logs-when-probe-is-deferred.patch
+asoc-rt5682-disable-irq-on-shutdown.patch
+rcu-invoke-rcu_spawn_core_kthreads-from-rcu_spawn_gp.patch
+serial-fsl_lpuart-don-t-modify-arbitrary-data-on-lpu.patch
+serial-fsl_lpuart-remove-rtscts-handling-from-get_mc.patch
+serial-8250_omap-fix-a-timeout-loop-condition.patch
+tty-nozomi-fix-a-resource-leak-in-an-error-handling-.patch
+phy-ralink-phy-mt7621-pci-properly-print-pointer-add.patch
+mwifiex-re-fix-for-unaligned-accesses.patch
+iio-adis_buffer-do-not-return-ints-in-irq-handlers.patch
+iio-adis16400-do-not-return-ints-in-irq-handlers.patch
+iio-adis16475-do-not-return-ints-in-irq-handlers.patch
+iio-accel-bma180-fix-buffer-alignment-in-iio_push_to.patch
+iio-accel-bma220-fix-buffer-alignment-in-iio_push_to.patch
+iio-accel-hid-fix-buffer-alignment-in-iio_push_to_bu.patch
+iio-accel-kxcjk-1013-fix-buffer-alignment-in-iio_pus.patch
+iio-accel-mxc4005-fix-overread-of-data-and-alignment.patch
+iio-accel-stk8312-fix-buffer-alignment-in-iio_push_t.patch
+iio-accel-stk8ba50-fix-buffer-alignment-in-iio_push_.patch
+iio-adc-ti-ads1015-fix-buffer-alignment-in-iio_push_.patch
+iio-adc-vf610-fix-buffer-alignment-in-iio_push_to_bu.patch
+iio-gyro-bmg160-fix-buffer-alignment-in-iio_push_to_.patch
+iio-humidity-am2315-fix-buffer-alignment-in-iio_push.patch
+iio-prox-srf08-fix-buffer-alignment-in-iio_push_to_b.patch
+iio-prox-pulsed-light-fix-buffer-alignment-in-iio_pu.patch
+iio-prox-as3935-fix-buffer-alignment-in-iio_push_to_.patch
+iio-magn-hmc5843-fix-buffer-alignment-in-iio_push_to.patch
+iio-magn-bmc150-fix-buffer-alignment-in-iio_push_to_.patch
+iio-light-isl29125-fix-buffer-alignment-in-iio_push_.patch
+iio-light-tcs3414-fix-buffer-alignment-in-iio_push_t.patch
+iio-light-tcs3472-fix-buffer-alignment-in-iio_push_t.patch
+iio-chemical-atlas-fix-buffer-alignment-in-iio_push_.patch
+iio-cros_ec_sensors-fix-alignment-of-buffer-in-iio_p.patch
+iio-potentiostat-lmp91000-fix-alignment-of-buffer-in.patch
+asoc-rk3328-fix-missing-clk_disable_unprepare-on-err.patch
+asoc-hisilicon-fix-missing-clk_disable_unprepare-on-.patch
+backlight-lm3630a_bl-put-fwnode-in-error-case-during.patch
+usb-typec-tcpm-fix-up-pr_swap-when-vsafe0v-is-signal.patch
+asoc-rsnd-tidyup-loop-on-rsnd_adg_clk_query.patch
+input-hil_kbd-fix-error-return-code-in-hil_dev_conne.patch
+perf-scripting-python-fix-tuple_set_u64.patch
+mtd-partitions-redboot-seek-fis-index-block-in-the-r.patch
+mtd-parsers-qcom-fix-leaking-of-partition-name.patch
+mtd-rawnand-arasan-ensure-proper-configuration-for-t.patch
+staging-mmal-vchiq-fix-incorrect-static-vchiq_instan.patch
+char-pcmcia-error-out-if-num_bytes_read-is-greater-t.patch
+misc-pvpanic-pci-fix-error-handling-in-pvpanic_pci_p.patch
+misc-pvpanic-mmio-fix-error-handling-in-pvpanic_mmio.patch
+firmware-stratix10-svc-fix-a-resource-leak-in-an-err.patch
+tty-nozomi-fix-the-error-handling-path-of-nozomi_car.patch
+leds-class-the-enotsupp-should-never-be-seen-by-user.patch
+leds-lgm-sso-fix-clock-handling.patch
+leds-lm3532-select-regmap-i2c-api.patch
+leds-lm36274-put-fwnode-in-error-case-during-probe.patch
+leds-lm3692x-put-fwnode-in-any-case-during-probe.patch
+leds-lm3697-don-t-spam-logs-when-probe-is-deferred.patch
+leds-lp50xx-put-fwnode-in-error-case-during-probe.patch
+scsi-flashpoint-rename-si_flags-field.patch
+scsi-iscsi-stop-queueing-during-ep_disconnect.patch
+scsi-iscsi-force-immediate-failure-during-shutdown.patch
+scsi-iscsi-use-system_unbound_wq-for-destroy_work.patch
+scsi-iscsi-rel-ref-after-iscsi_lookup_endpoint.patch
+scsi-iscsi-fix-in-kernel-conn-failure-handling.patch
+scsi-iscsi-flush-block-work-before-unblock.patch
+mfd-mp2629-select-mfd_core-to-fix-build-error.patch
+mfd-remove-software-node-conditionally-and-locate-at.patch
+mfd-rn5t618-fix-irq-trigger-by-changing-it-to-level-.patch
+fsi-core-fix-return-of-error-values-on-failures.patch
+fsi-scom-reset-the-fsi2pib-engine-for-any-error.patch
+fsi-occ-don-t-accept-response-from-un-initialized-oc.patch
+fsi-sbefifo-clean-up-correct-fifo-when-receiving-res.patch
+fsi-sbefifo-fix-reset-timeout.patch
+visorbus-fix-error-return-code-in-visorchipset_init.patch
+iommu-amd-fix-extended-features-logging.patch
+iommu-amd-tidy-up-dma-ops-init.patch
+s390-enable-have_ioremap_prot.patch
+s390-appldata-depends-on-proc_sysctl.patch
+selftests-splice-adjust-for-handler-fallback-removal.patch
+iommu-dma-fix-iova-reserve-dma-ranges.patch
+asoc-max98373-sdw-add-missing-memory-allocation-chec.patch
+asoc-max98373-sdw-use-first_hw_init-flag-on-resume.patch
+asoc-rt1308-sdw-use-first_hw_init-flag-on-resume.patch
+asoc-rt1316-sdw-use-first_hw_init-flag-on-resume.patch
+asoc-rt5682-sdw-use-first_hw_init-flag-on-resume.patch
+asoc-rt700-sdw-use-first_hw_init-flag-on-resume.patch
+asoc-rt711-sdca-sdw-use-first_hw_init-flag-on-resume.patch
+asoc-rt711-sdw-use-first_hw_init-flag-on-resume.patch
+asoc-rt715-sdca-sdw-use-first_hw_init-flag-on-resume.patch
+asoc-rt715-sdw-use-first_hw_init-flag-on-resume.patch
+asoc-rt715-sdca-fix-clock-stop-prepare-timeout-issue.patch
+asoc-rt5682-fix-a-problem-with-error-handling-in-the.patch
+asoc-rt5682-sdw-set-regcache_cache_only-false-before.patch
+asoc-rt711-sdca-sdw-add-readable-for-sdw_sdca_ctl-re.patch
+asoc-rt711-sdca-handle-mbq_regmap-in-rt711_sdca_io_i.patch
+asoc-mediatek-mtk-btcvsd-fix-an-error-handling-path-.patch
+usb-gadget-f_fs-fix-setting-of-device-and-driver-dat.patch
+usb-dwc2-don-t-reset-the-core-after-setting-turnarou.patch
+eeprom-idt_89hpesx-put-fwnode-in-matching-case-durin.patch
+eeprom-idt_89hpesx-restore-printing-the-unsupported-.patch
+mtd-spi-nor-otp-fix-access-to-security-registers-in-.patch
+mtd-spi-nor-otp-return-erofs-if-region-is-read-only.patch
+thunderbolt-bond-lanes-only-when-dual_link_port-null.patch
+mtd-spinand-fix-double-counting-of-ecc-stats.patch
+kunit-fix-result-propagation-for-parameterised-tests.patch
+iio-dummy-fix-build-error-when-config_iio_triggered_.patch
+iio-adc-at91-sama5d2-fix-buffer-alignment-in-iio_pus.patch
+iio-adc-hx711-fix-buffer-alignment-in-iio_push_to_bu.patch
+iio-adc-mxs-lradc-fix-buffer-alignment-in-iio_push_t.patch
+iio-adc-ti-ads8688-fix-alignment-of-buffer-in-iio_pu.patch
+iio-magn-rm3100-fix-alignment-of-buffer-in-iio_push_.patch
+iio-light-vcnl4000-fix-buffer-alignment-in-iio_push_.patch
+asoc-fsl_spdif-fix-error-handler-with-pm_runtime_ena.patch
+staging-gdm724x-check-for-buffer-overflow-in-gdm_lte.patch
+staging-gdm724x-check-for-overflow-in-gdm_lte_netif_.patch
+staging-rtl8712-fix-error-handling-in-r871xu_drv_ini.patch
+staging-rtl8712-fix-memory-leak-in-rtl871x_load_fw_c.patch
+coresight-core-fix-use-of-uninitialized-pointer.patch
+staging-mt7621-dts-fix-pci-address-for-pci-memory-ra.patch
+usb-phy-tegra-wait-for-vbus-wakeup-status-deassertio.patch
+usb-phy-tegra-correct-definition-of-b_sess_vld_wakeu.patch
+serial-8250-actually-allow-upf_magic_multiplier-baud.patch
+iio-light-vcnl4035-fix-buffer-alignment-in-iio_push_.patch
+iio-prox-isl29501-fix-buffer-alignment-in-iio_push_t.patch
+asoc-cs42l42-correct-definition-of-cs42l42_adc_pdn_m.patch
+of-fix-truncation-of-memory-sizes-on-32-bit-platform.patch
+mtd-rawnand-marvell-add-missing-clk_disable_unprepar.patch
+habanalabs-fix-an-error-handling-path-in-hl_pci_prob.patch
+scsi-mpt3sas-fix-error-return-value-in-_scsih_expand.patch
+soundwire-stream-fix-test-for-dp-prepare-complete.patch
+phy-uniphier-pcie-fix-updating-phy-parameters.patch
+phy-ti-dm816x-fix-the-error-handling-path-in-dm816x_.patch
+extcon-sm5502-drop-invalid-register-write-in-sm5502_.patch
+extcon-max8997-add-missing-modalias-string.patch
+powerpc-powernv-fix-machine-check-reporting-of-async.patch
+asoc-atmel-i2s-set-symmetric-sample-bits.patch
+asoc-atmel-i2s-fix-usage-of-capture-and-playback-at-.patch
+asoc-fsl_xcvr-disable-all-interrupts-when-suspend-ha.patch
+configfs-fix-memleak-in-configfs_release_bin_file.patch
+asoc-intel-sof_sdw-add-sof_rt715_dai_id_fix-for-alde.patch
+asoc-intel-sof_sdw-add-quirk-support-for-brya-and-bt.patch
+asoc-intel-sof_sdw-use-mach-data-for-adl-rvp-dmic-co.patch
+asoc-fsl_spdif-fix-unexpected-interrupt-after-suspen.patch
+leds-as3645a-fix-error-return-code-in-as3645a_parse_.patch
+leds-ktd2692-fix-an-error-handling-path.patch
+selftests-ftrace-fix-event-no-pid-on-1-core-machine.patch
+selftests-sgx-remove-checks-for-file-execute-permiss.patch
+staging-rtl8723bs-fix-an-error-handling-path.patch
+serial-8250-8250_omap-fix-possible-interrupt-storm-o.patch
+powerpc-offline-cpu-in-stop_this_cpu.patch
+powerpc-papr_scm-properly-handle-uuid-types-and-api.patch
+powerpc-64s-fix-copy-paste-data-exposure-into-newly-.patch
+powerpc-papr_scm-make-perf_stats-invisible-if-perf-s.patch
+powerpc-fix-is_kvm_guest-kvm_para_available.patch
+alsa-firewire-lib-fix-amdtp_domain_start-when-no-amd.patch
+serial-mvebu-uart-do-not-allow-changing-baudrate-whe.patch
+serial-mvebu-uart-correctly-calculate-minimal-possib.patch
+arm64-dts-marvell-armada-37xx-fix-reg-for-standard-v.patch
+powerpc-64s-fix-hash-page-fault-interrupt-handler.patch
+powerpc-64s-interrupt-preserve-regs-softe-for-nmi-in.patch
+vfio-pci-handle-concurrent-vma-faults.patch
+mm-huge_memory.c-remove-dedicated-macro-hpage_cache_.patch
+mm-huge_memory.c-add-missing-read-only-thp-checking-.patch
+mm-huge_memory.c-don-t-discard-hugepage-if-other-pro.patch
+hugetlb-remove-prep_compound_huge_page-cleanup.patch
+hugetlb-address-ref-count-racing-in-prep_compound_gi.patch
+mm-z3fold-fix-potential-memory-leak-in-z3fold_destro.patch
+mm-z3fold-use-release_z3fold_page_locked-to-release-.patch
+mm-migrate-fix-missing-update-page_private-to-hugetl.patch
+mm-zswap.c-fix-two-bugs-in-zswap_writeback_entry.patch
+kfence-unconditionally-use-unbound-work-queue.patch
+lib-math-rational.c-fix-divide-by-zero.patch
+selftests-vm-pkeys-fix-alloc_random_pkey-to-make-it-.patch
+selftests-vm-pkeys-handle-negative-sys_pkey_alloc-re.patch
+selftests-vm-pkeys-refill-shadow-register-after-impl.patch
+perf-llvm-return-enomem-when-asprintf-fails.patch
+i2c-mpc-restore-reread-of-i2c-status-register.patch
+csky-syscache-fixup-duplicate-cache-flush.patch
--- /dev/null
+From 12d418d4b9e9e10e4f94ce9b6f23ea77f391d3a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 19:13:38 -0700
+Subject: skmsg: Clear skb redirect pointer before dropping it
+
+From: Cong Wang <cong.wang@bytedance.com>
+
+[ Upstream commit 30b9c54a707db4155735cf71f4600241c1b7b6ff ]
+
+When we drop skb inside sk_psock_skb_redirect(), we have to clear
+its skb->_sk_redir pointer too, otherwise kfree_skb() would
+misinterpret it as a valid skb->_skb_refdst and dst_release()
+would eventually complain.
+
+Fixes: e3526bb92a20 ("skmsg: Move sk_redir from TCP_SKB_CB to skb")
+Reported-by: Jiang Wang <jiang.wang@bytedance.com>
+Signed-off-by: Cong Wang <cong.wang@bytedance.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Acked-by: Jakub Sitnicki <jakub@cloudflare.com>
+Link: https://lore.kernel.org/bpf/20210615021342.7416-5-xiyou.wangcong@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skmsg.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index 43ce17a6a585..df545748cd6a 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -866,12 +866,14 @@ static void sk_psock_skb_redirect(struct sk_buff *skb)
+ * a socket that is in this state so we drop the skb.
+ */
+ if (!psock_other || sock_flag(sk_other, SOCK_DEAD)) {
++ skb_bpf_redirect_clear(skb);
+ kfree_skb(skb);
+ return;
+ }
+ spin_lock_bh(&psock_other->ingress_lock);
+ if (!sk_psock_test_state(psock_other, SK_PSOCK_TX_ENABLED)) {
+ spin_unlock_bh(&psock_other->ingress_lock);
++ skb_bpf_redirect_clear(skb);
+ kfree_skb(skb);
+ return;
+ }
+--
+2.30.2
+
--- /dev/null
+From c2f84fa655c826d59afa3b3e388978dc036ab2d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 19:13:39 -0700
+Subject: skmsg: Fix a memory leak in sk_psock_verdict_apply()
+
+From: Cong Wang <cong.wang@bytedance.com>
+
+[ Upstream commit 0cf6672b23c8aa9d9274798dd63cbf6ede77ef90 ]
+
+If the dest psock does not set SK_PSOCK_TX_ENABLED,
+the skb can't be queued anywhere so must be dropped.
+
+This one is found during code review.
+
+Fixes: 799aa7f98d53 ("skmsg: Avoid lock_sock() in sk_psock_backlog()")
+Signed-off-by: Cong Wang <cong.wang@bytedance.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Acked-by: Jakub Sitnicki <jakub@cloudflare.com>
+Link: https://lore.kernel.org/bpf/20210615021342.7416-6-xiyou.wangcong@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skmsg.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index df545748cd6a..dd22ca838754 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -947,8 +947,13 @@ static void sk_psock_verdict_apply(struct sk_psock *psock,
+ if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) {
+ skb_queue_tail(&psock->ingress_skb, skb);
+ schedule_work(&psock->work);
++ err = 0;
+ }
+ spin_unlock_bh(&psock->ingress_lock);
++ if (err < 0) {
++ skb_bpf_redirect_clear(skb);
++ goto out_free;
++ }
+ }
+ break;
+ case __SK_REDIRECT:
+--
+2.30.2
+
--- /dev/null
+From 8569a683cc81410068d30d953d1d661f1e634bb0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 19:13:40 -0700
+Subject: skmsg: Teach sk_psock_verdict_apply() to return errors
+
+From: Cong Wang <cong.wang@bytedance.com>
+
+[ Upstream commit 1581a6c1c3291a8320b080f4411345f60229976d ]
+
+Currently sk_psock_verdict_apply() is void, but it handles some
+error conditions too. Its caller is impossible to learn whether
+it succeeds or fails, especially sk_psock_verdict_recv().
+
+Make it return int to indicate error cases and propagate errors
+to callers properly.
+
+Fixes: ef5659280eb1 ("bpf, sockmap: Allow skipping sk_skb parser program")
+Signed-off-by: Cong Wang <cong.wang@bytedance.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Acked-by: Jakub Sitnicki <jakub@cloudflare.com>
+Link: https://lore.kernel.org/bpf/20210615021342.7416-7-xiyou.wangcong@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skmsg.c | 23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index dd22ca838754..539c83a45665 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -847,7 +847,7 @@ out:
+ }
+ EXPORT_SYMBOL_GPL(sk_psock_msg_verdict);
+
+-static void sk_psock_skb_redirect(struct sk_buff *skb)
++static int sk_psock_skb_redirect(struct sk_buff *skb)
+ {
+ struct sk_psock *psock_other;
+ struct sock *sk_other;
+@@ -858,7 +858,7 @@ static void sk_psock_skb_redirect(struct sk_buff *skb)
+ */
+ if (unlikely(!sk_other)) {
+ kfree_skb(skb);
+- return;
++ return -EIO;
+ }
+ psock_other = sk_psock(sk_other);
+ /* This error indicates the socket is being torn down or had another
+@@ -868,19 +868,20 @@ static void sk_psock_skb_redirect(struct sk_buff *skb)
+ if (!psock_other || sock_flag(sk_other, SOCK_DEAD)) {
+ skb_bpf_redirect_clear(skb);
+ kfree_skb(skb);
+- return;
++ return -EIO;
+ }
+ spin_lock_bh(&psock_other->ingress_lock);
+ if (!sk_psock_test_state(psock_other, SK_PSOCK_TX_ENABLED)) {
+ spin_unlock_bh(&psock_other->ingress_lock);
+ skb_bpf_redirect_clear(skb);
+ kfree_skb(skb);
+- return;
++ return -EIO;
+ }
+
+ skb_queue_tail(&psock_other->ingress_skb, skb);
+ schedule_work(&psock_other->work);
+ spin_unlock_bh(&psock_other->ingress_lock);
++ return 0;
+ }
+
+ static void sk_psock_tls_verdict_apply(struct sk_buff *skb, struct sock *sk, int verdict)
+@@ -917,14 +918,15 @@ int sk_psock_tls_strp_read(struct sk_psock *psock, struct sk_buff *skb)
+ }
+ EXPORT_SYMBOL_GPL(sk_psock_tls_strp_read);
+
+-static void sk_psock_verdict_apply(struct sk_psock *psock,
+- struct sk_buff *skb, int verdict)
++static int sk_psock_verdict_apply(struct sk_psock *psock, struct sk_buff *skb,
++ int verdict)
+ {
+ struct sock *sk_other;
+- int err = -EIO;
++ int err = 0;
+
+ switch (verdict) {
+ case __SK_PASS:
++ err = -EIO;
+ sk_other = psock->sk;
+ if (sock_flag(sk_other, SOCK_DEAD) ||
+ !sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) {
+@@ -957,13 +959,15 @@ static void sk_psock_verdict_apply(struct sk_psock *psock,
+ }
+ break;
+ case __SK_REDIRECT:
+- sk_psock_skb_redirect(skb);
++ err = sk_psock_skb_redirect(skb);
+ break;
+ case __SK_DROP:
+ default:
+ out_free:
+ kfree_skb(skb);
+ }
++
++ return err;
+ }
+
+ static void sk_psock_write_space(struct sock *sk)
+@@ -1130,7 +1134,8 @@ static int sk_psock_verdict_recv(read_descriptor_t *desc, struct sk_buff *skb,
+ ret = sk_psock_map_verd(ret, skb_bpf_redirect_fetch(skb));
+ skb->sk = NULL;
+ }
+- sk_psock_verdict_apply(psock, skb, ret);
++ if (sk_psock_verdict_apply(psock, skb, ret) < 0)
++ len = 0;
+ out:
+ rcu_read_unlock();
+ return len;
+--
+2.30.2
+
--- /dev/null
+From 0c5492f9eb8b811ecd32b4d2662163aa3f2a91ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 17:54:50 -0500
+Subject: smb3: fix possible access to uninitialized pointer to DACL
+
+From: Steve French <stfrench@microsoft.com>
+
+[ Upstream commit a5628263a9f8d47d9a1548fe9d5d75ba4423a735 ]
+
+dacl_ptr can be null so we must check for it everywhere it is
+used in build_sec_desc.
+
+Addresses-Coverity: 1475598 ("Explicit null dereference")
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/cifsacl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
+index 784407f9280f..a18dee071fcd 100644
+--- a/fs/cifs/cifsacl.c
++++ b/fs/cifs/cifsacl.c
+@@ -1308,7 +1308,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
+ ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
+ ndacl_ptr->revision =
+ dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
+- ndacl_ptr->num_aces = dacl_ptr->num_aces;
++ ndacl_ptr->num_aces = dacl_ptr ? dacl_ptr->num_aces : 0;
+
+ if (uid_valid(uid)) { /* chown */
+ uid_t id;
+--
+2.30.2
+
--- /dev/null
+From a9497546ad6dfc923df38891d24cf8e11d8e4790 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Jun 2021 12:22:20 -0500
+Subject: smb3: fix uninitialized value for port in witness protocol move
+
+From: Steve French <stfrench@microsoft.com>
+
+[ Upstream commit ff93b71a3eff25fe9d4364ef13b6e01d935600c6 ]
+
+Although in practice this can not occur (since IPv4 and IPv6 are the
+only two cases currently supported), it is cleaner to avoid uninitialized
+variable warnings.
+
+Addresses smatch warning:
+ fs/cifs/cifs_swn.c:468 cifs_swn_store_swn_addr() error: uninitialized symbol 'port'.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+CC: Samuel Cabrero <scabrero@suse.de>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/cifs_swn.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/fs/cifs/cifs_swn.c b/fs/cifs/cifs_swn.c
+index d829b8bf833e..93b47818c6c2 100644
+--- a/fs/cifs/cifs_swn.c
++++ b/fs/cifs/cifs_swn.c
+@@ -447,15 +447,13 @@ static int cifs_swn_store_swn_addr(const struct sockaddr_storage *new,
+ const struct sockaddr_storage *old,
+ struct sockaddr_storage *dst)
+ {
+- __be16 port;
++ __be16 port = cpu_to_be16(CIFS_PORT);
+
+ if (old->ss_family == AF_INET) {
+ struct sockaddr_in *ipv4 = (struct sockaddr_in *)old;
+
+ port = ipv4->sin_port;
+- }
+-
+- if (old->ss_family == AF_INET6) {
++ } else if (old->ss_family == AF_INET6) {
+ struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)old;
+
+ port = ipv6->sin6_port;
+@@ -465,9 +463,7 @@ static int cifs_swn_store_swn_addr(const struct sockaddr_storage *new,
+ struct sockaddr_in *ipv4 = (struct sockaddr_in *)new;
+
+ ipv4->sin_port = port;
+- }
+-
+- if (new->ss_family == AF_INET6) {
++ } else if (new->ss_family == AF_INET6) {
+ struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)new;
+
+ ipv6->sin6_port = port;
+--
+2.30.2
+
--- /dev/null
+From 7d8487fbda31620be337a74c66a8f9f7d3306159 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 15:47:45 +0100
+Subject: soundwire: stream: Fix test for DP prepare complete
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit 3d3e88e336338834086278236d42039f3cde50e1 ]
+
+In sdw_prep_deprep_slave_ports(), after the wait_for_completion()
+the DP prepare status register is read. If this indicates that the
+port is now prepared, the code should continue with the port setup.
+It is irrelevant whether the wait_for_completion() timed out if the
+port is now ready.
+
+The previous implementation would always fail if the
+wait_for_completion() timed out, even if the port was reporting
+successful prepare.
+
+This patch also fixes a minor bug where the return from sdw_read()
+was not checked for error - any error code with LSBits clear could
+be misinterpreted as a successful port prepare.
+
+Fixes: 79df15b7d37c ("soundwire: Add helpers for ports operations")
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210618144745.30629-1-rf@opensource.cirrus.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/stream.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
+index 1eaedaaba094..1a18308f4ef4 100644
+--- a/drivers/soundwire/stream.c
++++ b/drivers/soundwire/stream.c
+@@ -422,7 +422,6 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
+ struct completion *port_ready;
+ struct sdw_dpn_prop *dpn_prop;
+ struct sdw_prepare_ch prep_ch;
+- unsigned int time_left;
+ bool intr = false;
+ int ret = 0, val;
+ u32 addr;
+@@ -479,15 +478,15 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
+
+ /* Wait for completion on port ready */
+ port_ready = &s_rt->slave->port_ready[prep_ch.num];
+- time_left = wait_for_completion_timeout(port_ready,
+- msecs_to_jiffies(dpn_prop->ch_prep_timeout));
++ wait_for_completion_timeout(port_ready,
++ msecs_to_jiffies(dpn_prop->ch_prep_timeout));
+
+ val = sdw_read(s_rt->slave, SDW_DPN_PREPARESTATUS(p_rt->num));
+- val &= p_rt->ch_mask;
+- if (!time_left || val) {
++ if ((val < 0) || (val & p_rt->ch_mask)) {
++ ret = (val < 0) ? val : -ETIMEDOUT;
+ dev_err(&s_rt->slave->dev,
+- "Chn prep failed for port:%d\n", prep_ch.num);
+- return -ETIMEDOUT;
++ "Chn prep failed for port %d: %d\n", prep_ch.num, ret);
++ return ret;
+ }
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 175c98e6fa2cdf5cbc91bc1754950b3a0910fe00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Apr 2021 19:44:24 +0300
+Subject: spi: Allow to have all native CSs in use along with GPIOs
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit dbaca8e56ea3f23fa215f48c2d46dd03ede06e02 ]
+
+The commit 7d93aecdb58d ("spi: Add generic support for unused native cs
+with cs-gpios") excludes the valid case for the controllers that doesn't
+need to switch native CS in order to perform the transfer, i.e. when
+
+ 0 native
+ ... ...
+ <n> - 1 native
+ <n> GPIO
+ <n> + 1 GPIO
+ ... ...
+
+where <n> defines maximum of native CSs supported by the controller.
+
+To allow this, bail out from spi_get_gpio_descs() conditionally for
+the controllers which explicitly marked with SPI_MASTER_GPIO_SS.
+
+Fixes: 7d93aecdb58d ("spi: Add generic support for unused native cs with cs-gpios")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20210420164425.40287-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index d83f91a6ab13..ae04ae79e56a 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -2623,8 +2623,9 @@ static int spi_get_gpio_descs(struct spi_controller *ctlr)
+ }
+
+ ctlr->unused_native_cs = ffz(native_cs_mask);
+- if (num_cs_gpios && ctlr->max_native_cs &&
+- ctlr->unused_native_cs >= ctlr->max_native_cs) {
++
++ if ((ctlr->flags & SPI_MASTER_GPIO_SS) && num_cs_gpios &&
++ ctlr->max_native_cs && ctlr->unused_native_cs >= ctlr->max_native_cs) {
+ dev_err(dev, "No unused native chip select available\n");
+ return -EINVAL;
+ }
+--
+2.30.2
+
--- /dev/null
+From 7c9d4d86d703069f19500f6de9f40c62de42db98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Apr 2021 19:44:25 +0300
+Subject: spi: Avoid undefined behaviour when counting unused native CSs
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit f60d7270c8a3d2beb1c23ae0da42497afa3584c2 ]
+
+ffz(), that has been used to count unused native CSs,
+might cause undefined behaviour when called against ~0U.
+To fix that, open code it with ffs(~value) - 1.
+
+Fixes: 7d93aecdb58d ("spi: Add generic support for unused native cs with cs-gpios")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20210420164425.40287-2-andriy.shevchenko@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index ae04ae79e56a..56c173869d97 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -2622,7 +2622,7 @@ static int spi_get_gpio_descs(struct spi_controller *ctlr)
+ native_cs_mask |= BIT(i);
+ }
+
+- ctlr->unused_native_cs = ffz(native_cs_mask);
++ ctlr->unused_native_cs = ffs(~native_cs_mask) - 1;
+
+ if ((ctlr->flags & SPI_MASTER_GPIO_SS) && num_cs_gpios &&
+ ctlr->max_native_cs && ctlr->unused_native_cs >= ctlr->max_native_cs) {
+--
+2.30.2
+
--- /dev/null
+From a0b5c3acb748de44a6eddf4127d7336656935aea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Apr 2021 11:14:02 +0100
+Subject: spi: Make of_register_spi_device also set the fwnode
+
+From: Charles Keepax <ckeepax@opensource.cirrus.com>
+
+[ Upstream commit 0e793ba77c18382f08e440260fe72bc6fce2a3cb ]
+
+Currently, the SPI core doesn't set the struct device fwnode pointer
+when it creates a new SPI device. This means when the device is
+registered the fwnode is NULL and the check in device_add which sets
+the fwnode->dev pointer is skipped. This wasn't previously an issue,
+however these two patches:
+
+commit 4731210c09f5 ("gpiolib: Bind gpio_device to a driver to enable
+fw_devlink=on by default")
+commit ced2af419528 ("gpiolib: Don't probe gpio_device if it's not the
+primary device")
+
+Added some code to the GPIO core which relies on using that
+fwnode->dev pointer to determine if a driver is bound to the fwnode
+and if not bind a stub GPIO driver. This means the GPIO providers
+behind SPI will get both the expected driver and this stub driver
+causing the stub driver to fail if it attempts to request any pin
+configuration. For example on my system:
+
+madera-pinctrl madera-pinctrl: pin gpio5 already requested by madera-pinctrl; cannot claim for gpiochip3
+madera-pinctrl madera-pinctrl: pin-4 (gpiochip3) status -22
+madera-pinctrl madera-pinctrl: could not request pin 4 (gpio5) from group aif1 on device madera-pinctrl
+gpio_stub_drv gpiochip3: Error applying setting, reverse things back
+gpio_stub_drv: probe of gpiochip3 failed with error -22
+
+The firmware node on the device created by the GPIO framework is set
+through the of_node pointer hence things generally actually work,
+however that fwnode->dev is never set, as the check was skipped at
+device_add time. This fix appears to match how the I2C subsystem
+handles the same situation.
+
+Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Link: https://lore.kernel.org/r/20210421101402.8468-1-ckeepax@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index e353b7a9e54e..d83f91a6ab13 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -2057,6 +2057,7 @@ of_register_spi_device(struct spi_controller *ctlr, struct device_node *nc)
+ /* Store a pointer to the node in the device structure */
+ of_node_get(nc);
+ spi->dev.of_node = nc;
++ spi->dev.fwnode = of_fwnode_handle(nc);
+
+ /* Register the new device */
+ rc = spi_add_device(spi);
+--
+2.30.2
+
--- /dev/null
+From 39f6e0162c39e6041a92dcb6ba0f926044ba406d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Jun 2021 13:29:32 +0800
+Subject: spi: meson-spicc: fix a wrong goto jump for avoiding memory leak.
+
+From: zpershuai <zpershuai@gmail.com>
+
+[ Upstream commit 95730d5eb73170a6d225a9998c478be273598634 ]
+
+In meson_spifc_probe function, when enable the device pclk clock is
+error, it should use clk_disable_unprepare to release the core clock.
+
+Signed-off-by: zpershuai <zpershuai@gmail.com>
+Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
+Link: https://lore.kernel.org/r/1623562172-22056-1-git-send-email-zpershuai@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-meson-spicc.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c
+index ecba6b4a5d85..51aef2c6e966 100644
+--- a/drivers/spi/spi-meson-spicc.c
++++ b/drivers/spi/spi-meson-spicc.c
+@@ -725,7 +725,7 @@ static int meson_spicc_probe(struct platform_device *pdev)
+ ret = clk_prepare_enable(spicc->pclk);
+ if (ret) {
+ dev_err(&pdev->dev, "pclk clock enable failed\n");
+- goto out_master;
++ goto out_core_clk;
+ }
+
+ device_reset_optional(&pdev->dev);
+@@ -764,9 +764,11 @@ static int meson_spicc_probe(struct platform_device *pdev)
+ return 0;
+
+ out_clk:
+- clk_disable_unprepare(spicc->core);
+ clk_disable_unprepare(spicc->pclk);
+
++out_core_clk:
++ clk_disable_unprepare(spicc->core);
++
+ out_master:
+ spi_master_put(master);
+
+--
+2.30.2
+
--- /dev/null
+From 37395ee9a7d9a2b6d2c2f908838ec7acf07fa06d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Jun 2021 13:29:16 +0800
+Subject: spi: meson-spicc: fix memory leak in meson_spicc_probe
+
+From: zpershuai <zpershuai@gmail.com>
+
+[ Upstream commit b2d501c13470409ee7613855b17e5e5ec4111e1c ]
+
+when meson_spicc_clk_init returns failed, it should goto the
+out_clk label.
+
+Signed-off-by: zpershuai <zpershuai@gmail.com>
+Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
+Link: https://lore.kernel.org/r/1623562156-21995-1-git-send-email-zpershuai@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-meson-spicc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c
+index 51aef2c6e966..b2c4621db34d 100644
+--- a/drivers/spi/spi-meson-spicc.c
++++ b/drivers/spi/spi-meson-spicc.c
+@@ -752,7 +752,7 @@ static int meson_spicc_probe(struct platform_device *pdev)
+ ret = meson_spicc_clk_init(spicc);
+ if (ret) {
+ dev_err(&pdev->dev, "clock registration failed\n");
+- goto out_master;
++ goto out_clk;
+ }
+
+ ret = devm_spi_register_master(&pdev->dev, master);
+--
+2.30.2
+
--- /dev/null
+From a42ca66e75c37a52c34b0890246bf6a5d61cb5af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Apr 2021 19:20:48 +0800
+Subject: spi: omap-100k: Fix the length judgment problem
+
+From: Tian Tao <tiantao6@hisilicon.com>
+
+[ Upstream commit e7a1a3abea373e41ba7dfe0fbc93cb79b6a3a529 ]
+
+word_len should be checked in the omap1_spi100k_setup_transfer
+function to see if it exceeds 32.
+
+Signed-off-by: Tian Tao <tiantao6@hisilicon.com>
+Link: https://lore.kernel.org/r/1619695248-39045-1-git-send-email-tiantao6@hisilicon.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-omap-100k.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c
+index 7062f2902253..f104470605b3 100644
+--- a/drivers/spi/spi-omap-100k.c
++++ b/drivers/spi/spi-omap-100k.c
+@@ -241,7 +241,7 @@ static int omap1_spi100k_setup_transfer(struct spi_device *spi,
+ else
+ word_len = spi->bits_per_word;
+
+- if (spi->bits_per_word > 32)
++ if (word_len > 32)
+ return -EINVAL;
+ cs->word_len = word_len;
+
+--
+2.30.2
+
--- /dev/null
+From 3f3cb1ef942768b37fd37bd6675e89a033d2e132 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 May 2021 14:58:23 +0800
+Subject: spi: spi-loopback-test: Fix 'tx_buf' might be 'rx_buf'
+
+From: Jay Fang <f.fangjian@huawei.com>
+
+[ Upstream commit 9e37a3ab0627011fb63875e9a93094b6fc8ddf48 ]
+
+In function 'spi_test_run_iter': Value 'tx_buf' might be 'rx_buf'.
+
+Signed-off-by: Jay Fang <f.fangjian@huawei.com>
+Link: https://lore.kernel.org/r/1620629903-15493-5-git-send-email-f.fangjian@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-loopback-test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c
+index f1cf2232f0b5..4d4f77a186a9 100644
+--- a/drivers/spi/spi-loopback-test.c
++++ b/drivers/spi/spi-loopback-test.c
+@@ -875,7 +875,7 @@ static int spi_test_run_iter(struct spi_device *spi,
+ test.transfers[i].len = len;
+ if (test.transfers[i].tx_buf)
+ test.transfers[i].tx_buf += tx_off;
+- if (test.transfers[i].tx_buf)
++ if (test.transfers[i].rx_buf)
+ test.transfers[i].rx_buf += rx_off;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From d6cf9b2bde9823df18620c1a0388a18ff50eb553 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 16:45:07 +0200
+Subject: spi: spi-sun6i: Fix chipselect/clock bug
+
+From: Mirko Vogt <mirko-dev|linux@nanl.de>
+
+[ Upstream commit 0d7993b234c9fad8cb6bec6adfaa74694ba85ecb ]
+
+The current sun6i SPI implementation initializes the transfer too early,
+resulting in SCK going high before the transfer. When using an additional
+(gpio) chipselect with sun6i, the chipselect is asserted at a time when
+clock is high, making the SPI transfer fail.
+
+This is due to SUN6I_GBL_CTL_BUS_ENABLE being written into
+SUN6I_GBL_CTL_REG at an early stage. Moving that to the transfer
+function, hence, right before the transfer starts, mitigates that
+problem.
+
+Fixes: 3558fe900e8af (spi: sunxi: Add Allwinner A31 SPI controller driver)
+Signed-off-by: Mirko Vogt <mirko-dev|linux@nanl.de>
+Signed-off-by: Ralf Schlatterbeck <rsc@runtux.com>
+Link: https://lore.kernel.org/r/20210614144507.y3udezjfbko7eavv@runtux.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-sun6i.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
+index cc8401980125..23ad052528db 100644
+--- a/drivers/spi/spi-sun6i.c
++++ b/drivers/spi/spi-sun6i.c
+@@ -379,6 +379,10 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
+ }
+
+ sun6i_spi_write(sspi, SUN6I_CLK_CTL_REG, reg);
++ /* Finally enable the bus - doing so before might raise SCK to HIGH */
++ reg = sun6i_spi_read(sspi, SUN6I_GBL_CTL_REG);
++ reg |= SUN6I_GBL_CTL_BUS_ENABLE;
++ sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, reg);
+
+ /* Setup the transfer now... */
+ if (sspi->tx_buf)
+@@ -504,7 +508,7 @@ static int sun6i_spi_runtime_resume(struct device *dev)
+ }
+
+ sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG,
+- SUN6I_GBL_CTL_BUS_ENABLE | SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP);
++ SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP);
+
+ return 0;
+
+--
+2.30.2
+
--- /dev/null
+From 1033031b2c270734309c14689234c420a447cb59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 May 2021 15:08:08 +0800
+Subject: spi: spi-topcliff-pch: Fix potential double free in
+ pch_spi_process_messages()
+
+From: Jay Fang <f.fangjian@huawei.com>
+
+[ Upstream commit 026a1dc1af52742c5897e64a3431445371a71871 ]
+
+pch_spi_set_tx() frees data->pkt_tx_buff on failure of kzalloc() for
+data->pkt_rx_buff, but its caller, pch_spi_process_messages(), will
+free data->pkt_tx_buff again. Set data->pkt_tx_buff to NULL after
+kfree() to avoid double free.
+
+Signed-off-by: Jay Fang <f.fangjian@huawei.com>
+Link: https://lore.kernel.org/r/1620284888-65215-1-git-send-email-f.fangjian@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-topcliff-pch.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c
+index b8870784fc6e..8c4615b76339 100644
+--- a/drivers/spi/spi-topcliff-pch.c
++++ b/drivers/spi/spi-topcliff-pch.c
+@@ -580,8 +580,10 @@ static void pch_spi_set_tx(struct pch_spi_data *data, int *bpw)
+ data->pkt_tx_buff = kzalloc(size, GFP_KERNEL);
+ if (data->pkt_tx_buff != NULL) {
+ data->pkt_rx_buff = kzalloc(size, GFP_KERNEL);
+- if (!data->pkt_rx_buff)
++ if (!data->pkt_rx_buff) {
+ kfree(data->pkt_tx_buff);
++ data->pkt_tx_buff = NULL;
++ }
+ }
+
+ if (!data->pkt_rx_buff) {
+--
+2.30.2
+
--- /dev/null
+From 5e4e244c11fb788d308e3db121576c8c9e8c7922 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 May 2021 15:29:49 +0800
+Subject: ssb: Fix error return code in ssb_bus_scan()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit 77a0989baa427dbd242c5784d05a53ca3d197d43 ]
+
+Fix to return -EINVAL from the error handling case instead of 0, as done
+elsewhere in this function.
+
+Fixes: 61e115a56d1a ("[SSB]: add Sonics Silicon Backplane bus support")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Acked-by: Michael Büsch <m@bues.ch>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210515072949.7151-1-thunder.leizhen@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ssb/scan.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c
+index f49ab1aa2149..4161e5d1f276 100644
+--- a/drivers/ssb/scan.c
++++ b/drivers/ssb/scan.c
+@@ -325,6 +325,7 @@ int ssb_bus_scan(struct ssb_bus *bus,
+ if (bus->nr_devices > ARRAY_SIZE(bus->devices)) {
+ pr_err("More than %d ssb cores found (%d)\n",
+ SSB_MAX_NR_CORES, bus->nr_devices);
++ err = -EINVAL;
+ goto err_unmap;
+ }
+ if (bus->bustype == SSB_BUSTYPE_SSB) {
+--
+2.30.2
+
--- /dev/null
+From 0595a02406a42ff922a29e150b2f7689a90ae3a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 May 2021 20:21:11 +0300
+Subject: staging: fbtft: Don't spam logs when probe is deferred
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 37667f6e57712cef5652fa67f1cbd1299e204d94 ]
+
+When requesting GPIO line the probe can be deferred.
+In such case don't spam logs with an error message.
+This can be achieved by switching to dev_err_probe().
+
+Fixes: c440eee1a7a1 ("Staging: fbtft: Switch to the gpio descriptor interface")
+Cc: Nishad Kamdar <nishadkamdar@gmail.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20210503172114.27891-3-andriy.shevchenko@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/fbtft/fbtft-core.c | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
+index 67c3b1975a4d..3723269890d5 100644
+--- a/drivers/staging/fbtft/fbtft-core.c
++++ b/drivers/staging/fbtft/fbtft-core.c
+@@ -75,20 +75,16 @@ static int fbtft_request_one_gpio(struct fbtft_par *par,
+ struct gpio_desc **gpiop)
+ {
+ struct device *dev = par->info->device;
+- int ret = 0;
+
+ *gpiop = devm_gpiod_get_index_optional(dev, name, index,
+ GPIOD_OUT_LOW);
+- if (IS_ERR(*gpiop)) {
+- ret = PTR_ERR(*gpiop);
+- dev_err(dev,
+- "Failed to request %s GPIO: %d\n", name, ret);
+- return ret;
+- }
++ if (IS_ERR(*gpiop))
++ return dev_err_probe(dev, PTR_ERR(*gpiop), "Failed to request %s GPIO\n", name);
++
+ fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' GPIO\n",
+ __func__, name);
+
+- return ret;
++ return 0;
+ }
+
+ static int fbtft_request_gpios(struct fbtft_par *par)
+--
+2.30.2
+
--- /dev/null
+From 1304f6492cd3b66f6b8dcd99906e52f876ec463e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 May 2021 20:21:10 +0300
+Subject: staging: fbtft: Rectify GPIO handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit ec03c2104365ead0a33627c05e685093eed3eaef ]
+
+The infamous commit c440eee1a7a1 ("Staging: staging: fbtft: Switch to
+the GPIO descriptor interface") broke GPIO handling completely.
+It has already four commits to rectify and it seems not enough.
+In order to fix the mess here we:
+
+ 1) Set default to "inactive" for all requested pins
+
+ 2) Fix CS#, RD#, and WR# pins polarity since it's active low
+ and GPIO descriptor interface takes it into consideration
+ from the Device Tree or ACPI
+
+ 3) Consolidate chip activation (CS# assertion) under default
+ ->reset() callback
+
+To summarize the expectations about polarity for GPIOs:
+
+ RD# Low
+ WR# Low
+ CS# Low
+ RESET# Low
+ DC or RS High
+ RW High
+ Data 0 .. 15 High
+
+See also Adafruit learning course [1] for the example of the schematics.
+
+While at it, drop unneeded NULL checks, since GPIO API is tolerant to that.
+
+[1]: https://learn.adafruit.com/adafruit-2-8-and-3-2-color-tft-touchscreen-breakout-v2/downloads
+
+Fixes: 92e3e884887c ("Staging: fbtft: Fix GPIO handling")
+Fixes: b918d1c27066 ("Staging: fbtft: Fix reset assertion when using gpio descriptor")
+Fixes: dbc4f989c878 ("Staging: fbtft: Fix probing of gpio descriptor")
+Fixes: c440eee1a7a1 ("Staging: fbtft: Switch to the gpio descriptor interface")
+Cc: Jan Sebastian Götte <linux@jaseg.net>
+Cc: Nishad Kamdar <nishadkamdar@gmail.com>
+Reviewed-by: Phil Reid <preid@electromag.com.au>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20210503172114.27891-2-andriy.shevchenko@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/fbtft/fb_agm1264k-fl.c | 20 ++++++++++----------
+ drivers/staging/fbtft/fb_bd663474.c | 4 ----
+ drivers/staging/fbtft/fb_ili9163.c | 4 ----
+ drivers/staging/fbtft/fb_ili9320.c | 1 -
+ drivers/staging/fbtft/fb_ili9325.c | 4 ----
+ drivers/staging/fbtft/fb_ili9340.c | 1 -
+ drivers/staging/fbtft/fb_s6d1121.c | 4 ----
+ drivers/staging/fbtft/fb_sh1106.c | 1 -
+ drivers/staging/fbtft/fb_ssd1289.c | 4 ----
+ drivers/staging/fbtft/fb_ssd1325.c | 2 --
+ drivers/staging/fbtft/fb_ssd1331.c | 6 ++----
+ drivers/staging/fbtft/fb_ssd1351.c | 1 -
+ drivers/staging/fbtft/fb_upd161704.c | 4 ----
+ drivers/staging/fbtft/fb_watterott.c | 1 -
+ drivers/staging/fbtft/fbtft-bus.c | 3 +--
+ drivers/staging/fbtft/fbtft-core.c | 13 ++++++-------
+ drivers/staging/fbtft/fbtft-io.c | 12 ++++++------
+ 17 files changed, 25 insertions(+), 60 deletions(-)
+
+diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c
+index eeeeec97ad27..b545c2ca80a4 100644
+--- a/drivers/staging/fbtft/fb_agm1264k-fl.c
++++ b/drivers/staging/fbtft/fb_agm1264k-fl.c
+@@ -84,9 +84,9 @@ static void reset(struct fbtft_par *par)
+
+ dev_dbg(par->info->device, "%s()\n", __func__);
+
+- gpiod_set_value(par->gpio.reset, 0);
+- udelay(20);
+ gpiod_set_value(par->gpio.reset, 1);
++ udelay(20);
++ gpiod_set_value(par->gpio.reset, 0);
+ mdelay(120);
+ }
+
+@@ -194,12 +194,12 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
+ /* select chip */
+ if (*buf) {
+ /* cs1 */
+- gpiod_set_value(par->CS0, 1);
+- gpiod_set_value(par->CS1, 0);
+- } else {
+- /* cs0 */
+ gpiod_set_value(par->CS0, 0);
+ gpiod_set_value(par->CS1, 1);
++ } else {
++ /* cs0 */
++ gpiod_set_value(par->CS0, 1);
++ gpiod_set_value(par->CS1, 0);
+ }
+
+ gpiod_set_value(par->RS, 0); /* RS->0 (command mode) */
+@@ -397,8 +397,8 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
+ }
+ kfree(convert_buf);
+
+- gpiod_set_value(par->CS0, 1);
+- gpiod_set_value(par->CS1, 1);
++ gpiod_set_value(par->CS0, 0);
++ gpiod_set_value(par->CS1, 0);
+
+ return ret;
+ }
+@@ -419,10 +419,10 @@ static int write(struct fbtft_par *par, void *buf, size_t len)
+ for (i = 0; i < 8; ++i)
+ gpiod_set_value(par->gpio.db[i], data & (1 << i));
+ /* set E */
+- gpiod_set_value(par->EPIN, 1);
++ gpiod_set_value(par->EPIN, 0);
+ udelay(5);
+ /* unset E - write */
+- gpiod_set_value(par->EPIN, 0);
++ gpiod_set_value(par->EPIN, 1);
+ udelay(1);
+ }
+
+diff --git a/drivers/staging/fbtft/fb_bd663474.c b/drivers/staging/fbtft/fb_bd663474.c
+index e2c7646588f8..1629c2c440a9 100644
+--- a/drivers/staging/fbtft/fb_bd663474.c
++++ b/drivers/staging/fbtft/fb_bd663474.c
+@@ -12,7 +12,6 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/gpio/consumer.h>
+ #include <linux/delay.h>
+
+ #include "fbtft.h"
+@@ -24,9 +23,6 @@
+
+ static int init_display(struct fbtft_par *par)
+ {
+- if (par->gpio.cs)
+- gpiod_set_value(par->gpio.cs, 0); /* Activate chip */
+-
+ par->fbtftops.reset(par);
+
+ /* Initialization sequence from Lib_UTFT */
+diff --git a/drivers/staging/fbtft/fb_ili9163.c b/drivers/staging/fbtft/fb_ili9163.c
+index 05648c3ffe47..6582a2c90aaf 100644
+--- a/drivers/staging/fbtft/fb_ili9163.c
++++ b/drivers/staging/fbtft/fb_ili9163.c
+@@ -11,7 +11,6 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/gpio/consumer.h>
+ #include <linux/delay.h>
+ #include <video/mipi_display.h>
+
+@@ -77,9 +76,6 @@ static int init_display(struct fbtft_par *par)
+ {
+ par->fbtftops.reset(par);
+
+- if (par->gpio.cs)
+- gpiod_set_value(par->gpio.cs, 0); /* Activate chip */
+-
+ write_reg(par, MIPI_DCS_SOFT_RESET); /* software reset */
+ mdelay(500);
+ write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE); /* exit sleep */
+diff --git a/drivers/staging/fbtft/fb_ili9320.c b/drivers/staging/fbtft/fb_ili9320.c
+index f2e72d14431d..a8f4c618b754 100644
+--- a/drivers/staging/fbtft/fb_ili9320.c
++++ b/drivers/staging/fbtft/fb_ili9320.c
+@@ -8,7 +8,6 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/gpio/consumer.h>
+ #include <linux/spi/spi.h>
+ #include <linux/delay.h>
+
+diff --git a/drivers/staging/fbtft/fb_ili9325.c b/drivers/staging/fbtft/fb_ili9325.c
+index c9aa4cb43123..16d3b17ca279 100644
+--- a/drivers/staging/fbtft/fb_ili9325.c
++++ b/drivers/staging/fbtft/fb_ili9325.c
+@@ -10,7 +10,6 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/gpio/consumer.h>
+ #include <linux/delay.h>
+
+ #include "fbtft.h"
+@@ -85,9 +84,6 @@ static int init_display(struct fbtft_par *par)
+ {
+ par->fbtftops.reset(par);
+
+- if (par->gpio.cs)
+- gpiod_set_value(par->gpio.cs, 0); /* Activate chip */
+-
+ bt &= 0x07;
+ vc &= 0x07;
+ vrh &= 0x0f;
+diff --git a/drivers/staging/fbtft/fb_ili9340.c b/drivers/staging/fbtft/fb_ili9340.c
+index 415183c7054a..704236bcaf3f 100644
+--- a/drivers/staging/fbtft/fb_ili9340.c
++++ b/drivers/staging/fbtft/fb_ili9340.c
+@@ -8,7 +8,6 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/gpio/consumer.h>
+ #include <linux/delay.h>
+ #include <video/mipi_display.h>
+
+diff --git a/drivers/staging/fbtft/fb_s6d1121.c b/drivers/staging/fbtft/fb_s6d1121.c
+index 8c7de3290343..62f27172f844 100644
+--- a/drivers/staging/fbtft/fb_s6d1121.c
++++ b/drivers/staging/fbtft/fb_s6d1121.c
+@@ -12,7 +12,6 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/gpio/consumer.h>
+ #include <linux/delay.h>
+
+ #include "fbtft.h"
+@@ -29,9 +28,6 @@ static int init_display(struct fbtft_par *par)
+ {
+ par->fbtftops.reset(par);
+
+- if (par->gpio.cs)
+- gpiod_set_value(par->gpio.cs, 0); /* Activate chip */
+-
+ /* Initialization sequence from Lib_UTFT */
+
+ write_reg(par, 0x0011, 0x2004);
+diff --git a/drivers/staging/fbtft/fb_sh1106.c b/drivers/staging/fbtft/fb_sh1106.c
+index 6f7249493ea3..7b9ab39e1c1a 100644
+--- a/drivers/staging/fbtft/fb_sh1106.c
++++ b/drivers/staging/fbtft/fb_sh1106.c
+@@ -9,7 +9,6 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/gpio/consumer.h>
+ #include <linux/delay.h>
+
+ #include "fbtft.h"
+diff --git a/drivers/staging/fbtft/fb_ssd1289.c b/drivers/staging/fbtft/fb_ssd1289.c
+index 7a3fe022cc69..f27bab38b3ec 100644
+--- a/drivers/staging/fbtft/fb_ssd1289.c
++++ b/drivers/staging/fbtft/fb_ssd1289.c
+@@ -10,7 +10,6 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/gpio/consumer.h>
+
+ #include "fbtft.h"
+
+@@ -28,9 +27,6 @@ static int init_display(struct fbtft_par *par)
+ {
+ par->fbtftops.reset(par);
+
+- if (par->gpio.cs)
+- gpiod_set_value(par->gpio.cs, 0); /* Activate chip */
+-
+ write_reg(par, 0x00, 0x0001);
+ write_reg(par, 0x03, 0xA8A4);
+ write_reg(par, 0x0C, 0x0000);
+diff --git a/drivers/staging/fbtft/fb_ssd1325.c b/drivers/staging/fbtft/fb_ssd1325.c
+index 8a3140d41d8b..796a2ac3e194 100644
+--- a/drivers/staging/fbtft/fb_ssd1325.c
++++ b/drivers/staging/fbtft/fb_ssd1325.c
+@@ -35,8 +35,6 @@ static int init_display(struct fbtft_par *par)
+ {
+ par->fbtftops.reset(par);
+
+- gpiod_set_value(par->gpio.cs, 0);
+-
+ write_reg(par, 0xb3);
+ write_reg(par, 0xf0);
+ write_reg(par, 0xae);
+diff --git a/drivers/staging/fbtft/fb_ssd1331.c b/drivers/staging/fbtft/fb_ssd1331.c
+index 37622c9462aa..ec5eced7f8cb 100644
+--- a/drivers/staging/fbtft/fb_ssd1331.c
++++ b/drivers/staging/fbtft/fb_ssd1331.c
+@@ -81,8 +81,7 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
+ va_start(args, len);
+
+ *buf = (u8)va_arg(args, unsigned int);
+- if (par->gpio.dc)
+- gpiod_set_value(par->gpio.dc, 0);
++ gpiod_set_value(par->gpio.dc, 0);
+ ret = par->fbtftops.write(par, par->buf, sizeof(u8));
+ if (ret < 0) {
+ va_end(args);
+@@ -104,8 +103,7 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
+ return;
+ }
+ }
+- if (par->gpio.dc)
+- gpiod_set_value(par->gpio.dc, 1);
++ gpiod_set_value(par->gpio.dc, 1);
+ va_end(args);
+ }
+
+diff --git a/drivers/staging/fbtft/fb_ssd1351.c b/drivers/staging/fbtft/fb_ssd1351.c
+index 900b28d826b2..cf263a58a148 100644
+--- a/drivers/staging/fbtft/fb_ssd1351.c
++++ b/drivers/staging/fbtft/fb_ssd1351.c
+@@ -2,7 +2,6 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/gpio/consumer.h>
+ #include <linux/spi/spi.h>
+ #include <linux/delay.h>
+
+diff --git a/drivers/staging/fbtft/fb_upd161704.c b/drivers/staging/fbtft/fb_upd161704.c
+index c77832ae5e5b..c680160d6380 100644
+--- a/drivers/staging/fbtft/fb_upd161704.c
++++ b/drivers/staging/fbtft/fb_upd161704.c
+@@ -12,7 +12,6 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/gpio/consumer.h>
+ #include <linux/delay.h>
+
+ #include "fbtft.h"
+@@ -26,9 +25,6 @@ static int init_display(struct fbtft_par *par)
+ {
+ par->fbtftops.reset(par);
+
+- if (par->gpio.cs)
+- gpiod_set_value(par->gpio.cs, 0); /* Activate chip */
+-
+ /* Initialization sequence from Lib_UTFT */
+
+ /* register reset */
+diff --git a/drivers/staging/fbtft/fb_watterott.c b/drivers/staging/fbtft/fb_watterott.c
+index 76b25df376b8..a57e1f4feef3 100644
+--- a/drivers/staging/fbtft/fb_watterott.c
++++ b/drivers/staging/fbtft/fb_watterott.c
+@@ -8,7 +8,6 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/gpio/consumer.h>
+ #include <linux/delay.h>
+
+ #include "fbtft.h"
+diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c
+index 63c65dd67b17..3d422bc11641 100644
+--- a/drivers/staging/fbtft/fbtft-bus.c
++++ b/drivers/staging/fbtft/fbtft-bus.c
+@@ -135,8 +135,7 @@ int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len)
+ remain = len / 2;
+ vmem16 = (u16 *)(par->info->screen_buffer + offset);
+
+- if (par->gpio.dc)
+- gpiod_set_value(par->gpio.dc, 1);
++ gpiod_set_value(par->gpio.dc, 1);
+
+ /* non buffered write */
+ if (!par->txbuf.buf)
+diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
+index 4f362dad4436..67c3b1975a4d 100644
+--- a/drivers/staging/fbtft/fbtft-core.c
++++ b/drivers/staging/fbtft/fbtft-core.c
+@@ -38,8 +38,7 @@ int fbtft_write_buf_dc(struct fbtft_par *par, void *buf, size_t len, int dc)
+ {
+ int ret;
+
+- if (par->gpio.dc)
+- gpiod_set_value(par->gpio.dc, dc);
++ gpiod_set_value(par->gpio.dc, dc);
+
+ ret = par->fbtftops.write(par, buf, len);
+ if (ret < 0)
+@@ -79,7 +78,7 @@ static int fbtft_request_one_gpio(struct fbtft_par *par,
+ int ret = 0;
+
+ *gpiop = devm_gpiod_get_index_optional(dev, name, index,
+- GPIOD_OUT_HIGH);
++ GPIOD_OUT_LOW);
+ if (IS_ERR(*gpiop)) {
+ ret = PTR_ERR(*gpiop);
+ dev_err(dev,
+@@ -226,11 +225,15 @@ static void fbtft_reset(struct fbtft_par *par)
+ {
+ if (!par->gpio.reset)
+ return;
++
+ fbtft_par_dbg(DEBUG_RESET, par, "%s()\n", __func__);
++
+ gpiod_set_value_cansleep(par->gpio.reset, 1);
+ usleep_range(20, 40);
+ gpiod_set_value_cansleep(par->gpio.reset, 0);
+ msleep(120);
++
++ gpiod_set_value_cansleep(par->gpio.cs, 1); /* Activate chip */
+ }
+
+ static void fbtft_update_display(struct fbtft_par *par, unsigned int start_line,
+@@ -922,8 +925,6 @@ static int fbtft_init_display_from_property(struct fbtft_par *par)
+ goto out_free;
+
+ par->fbtftops.reset(par);
+- if (par->gpio.cs)
+- gpiod_set_value(par->gpio.cs, 0); /* Activate chip */
+
+ index = -1;
+ val = values[++index];
+@@ -1018,8 +1019,6 @@ int fbtft_init_display(struct fbtft_par *par)
+ }
+
+ par->fbtftops.reset(par);
+- if (par->gpio.cs)
+- gpiod_set_value(par->gpio.cs, 0); /* Activate chip */
+
+ i = 0;
+ while (i < FBTFT_MAX_INIT_SEQUENCE) {
+diff --git a/drivers/staging/fbtft/fbtft-io.c b/drivers/staging/fbtft/fbtft-io.c
+index 0863d257d762..de1904a443c2 100644
+--- a/drivers/staging/fbtft/fbtft-io.c
++++ b/drivers/staging/fbtft/fbtft-io.c
+@@ -142,12 +142,12 @@ int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len)
+ data = *(u8 *)buf;
+
+ /* Start writing by pulling down /WR */
+- gpiod_set_value(par->gpio.wr, 0);
++ gpiod_set_value(par->gpio.wr, 1);
+
+ /* Set data */
+ #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
+ if (data == prev_data) {
+- gpiod_set_value(par->gpio.wr, 0); /* used as delay */
++ gpiod_set_value(par->gpio.wr, 1); /* used as delay */
+ } else {
+ for (i = 0; i < 8; i++) {
+ if ((data & 1) != (prev_data & 1))
+@@ -165,7 +165,7 @@ int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len)
+ #endif
+
+ /* Pullup /WR */
+- gpiod_set_value(par->gpio.wr, 1);
++ gpiod_set_value(par->gpio.wr, 0);
+
+ #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
+ prev_data = *(u8 *)buf;
+@@ -192,12 +192,12 @@ int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len)
+ data = *(u16 *)buf;
+
+ /* Start writing by pulling down /WR */
+- gpiod_set_value(par->gpio.wr, 0);
++ gpiod_set_value(par->gpio.wr, 1);
+
+ /* Set data */
+ #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
+ if (data == prev_data) {
+- gpiod_set_value(par->gpio.wr, 0); /* used as delay */
++ gpiod_set_value(par->gpio.wr, 1); /* used as delay */
+ } else {
+ for (i = 0; i < 16; i++) {
+ if ((data & 1) != (prev_data & 1))
+@@ -215,7 +215,7 @@ int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len)
+ #endif
+
+ /* Pullup /WR */
+- gpiod_set_value(par->gpio.wr, 1);
++ gpiod_set_value(par->gpio.wr, 0);
+
+ #ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
+ prev_data = *(u16 *)buf;
+--
+2.30.2
+
--- /dev/null
+From bf44a6b0c3b38e9bdf2f5fba7bf595e3c3f38255 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 12:55:35 +0300
+Subject: staging: gdm724x: check for buffer overflow in
+ gdm_lte_multi_sdu_pkt()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 4a36e160856db8a8ddd6a3d2e5db5a850ab87f82 ]
+
+There needs to be a check to verify that we don't read beyond the end
+of "buf". This function is called from do_rx(). The "buf" is the USB
+transfer_buffer and "len" is "urb->actual_length".
+
+Fixes: 61e121047645 ("staging: gdm7240: adding LTE USB driver")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Link: https://lore.kernel.org/r/YMcnl4zCwGWGDVMG@mwanda
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/gdm724x/gdm_lte.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c
+index 571f47d39484..a41af7aa74ec 100644
+--- a/drivers/staging/gdm724x/gdm_lte.c
++++ b/drivers/staging/gdm724x/gdm_lte.c
+@@ -677,6 +677,7 @@ static void gdm_lte_multi_sdu_pkt(struct phy_dev *phy_dev, char *buf, int len)
+ struct sdu *sdu = NULL;
+ u8 endian = phy_dev->get_endian(phy_dev->priv_dev);
+ u8 *data = (u8 *)multi_sdu->data;
++ int copied;
+ u16 i = 0;
+ u16 num_packet;
+ u16 hci_len;
+@@ -688,6 +689,12 @@ static void gdm_lte_multi_sdu_pkt(struct phy_dev *phy_dev, char *buf, int len)
+ num_packet = gdm_dev16_to_cpu(endian, multi_sdu->num_packet);
+
+ for (i = 0; i < num_packet; i++) {
++ copied = data - multi_sdu->data;
++ if (len < copied + sizeof(*sdu)) {
++ pr_err("rx prevent buffer overflow");
++ return;
++ }
++
+ sdu = (struct sdu *)data;
+
+ cmd_evt = gdm_dev16_to_cpu(endian, sdu->cmd_evt);
+@@ -698,7 +705,8 @@ static void gdm_lte_multi_sdu_pkt(struct phy_dev *phy_dev, char *buf, int len)
+ pr_err("rx sdu wrong hci %04x\n", cmd_evt);
+ return;
+ }
+- if (hci_len < 12) {
++ if (hci_len < 12 ||
++ len < copied + sizeof(*sdu) + (hci_len - 12)) {
+ pr_err("rx sdu invalid len %d\n", hci_len);
+ return;
+ }
+--
+2.30.2
+
--- /dev/null
+From 2e518e5aa579aff967acb2a9dba8e1e0f1fc7db1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 12:58:36 +0300
+Subject: staging: gdm724x: check for overflow in gdm_lte_netif_rx()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 7002b526f4ff1f6da34356e67085caafa6be383a ]
+
+This code assumes that "len" is at least 62 bytes, but we need a check
+to prevent a read overflow.
+
+Fixes: 61e121047645 ("staging: gdm7240: adding LTE USB driver")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Link: https://lore.kernel.org/r/YMcoTPsCYlhh2TQo@mwanda
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/gdm724x/gdm_lte.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c
+index a41af7aa74ec..bd5f87433404 100644
+--- a/drivers/staging/gdm724x/gdm_lte.c
++++ b/drivers/staging/gdm724x/gdm_lte.c
+@@ -611,10 +611,12 @@ static void gdm_lte_netif_rx(struct net_device *dev, char *buf,
+ * bytes (99,130,83,99 dec)
+ */
+ } __packed;
+- void *addr = buf + sizeof(struct iphdr) +
+- sizeof(struct udphdr) +
+- offsetof(struct dhcp_packet, chaddr);
+- ether_addr_copy(nic->dest_mac_addr, addr);
++ int offset = sizeof(struct iphdr) +
++ sizeof(struct udphdr) +
++ offsetof(struct dhcp_packet, chaddr);
++ if (offset + ETH_ALEN > len)
++ return;
++ ether_addr_copy(nic->dest_mac_addr, buf + offset);
+ }
+ }
+
+--
+2.30.2
+
--- /dev/null
+From c55f7411fe215f0d0d8ebd70440e2e4283d1c43c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Apr 2021 17:19:11 +0200
+Subject: staging: media: rkvdec: fix pm_runtime_get_sync() usage count
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit e90812c47b958407b54d05780dc483fdc1b57a93 ]
+
+The pm_runtime_get_sync() internally increments the
+dev->power.usage_count without decrementing it, even on errors.
+Replace it by the new pm_runtime_resume_and_get(), introduced by:
+commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter")
+in order to properly decrement the usage counter, avoiding
+a potential PM usage counter leak.
+
+Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/rkvdec/rkvdec.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
+index d821661d30f3..8c17615f3a7a 100644
+--- a/drivers/staging/media/rkvdec/rkvdec.c
++++ b/drivers/staging/media/rkvdec/rkvdec.c
+@@ -658,7 +658,7 @@ static void rkvdec_device_run(void *priv)
+ if (WARN_ON(!desc))
+ return;
+
+- ret = pm_runtime_get_sync(rkvdec->dev);
++ ret = pm_runtime_resume_and_get(rkvdec->dev);
+ if (ret < 0) {
+ rkvdec_job_finish_no_pm(ctx, VB2_BUF_STATE_ERROR);
+ return;
+--
+2.30.2
+
--- /dev/null
+From 8d0815493e7a5aa997de2167f77f10285996d336 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 23:57:37 +0200
+Subject: staging: mmal-vchiq: Fix incorrect static vchiq_instance.
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit afc023da53e46b88552822f2fe035c7129c505a2 ]
+
+For some reason lost in history function vchiq_mmal_init used
+a static variable for storing the vchiq_instance.
+This value is retrieved from vchiq per instance, so worked fine
+until you try to call vchiq_mmal_init multiple times concurrently
+when things then go wrong. This seemed to happen quite frequently
+if using the cutdown firmware (no MMAL or VCSM services running)
+as the vchiq_connect then failed, and one or other vchiq_shutdown
+was working on an invalid handle.
+
+Remove the static so that each caller gets a unique vchiq_instance.
+
+Fixes: 7b3ad5abf027 ("staging: Import the BCM2835 MMAL-based V4L2 camera driver.")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
+Link: https://lore.kernel.org/r/1621979857-26754-1-git-send-email-stefan.wahren@i2se.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
+index 06bca7be5203..76d3f0399964 100644
+--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
+@@ -1862,7 +1862,7 @@ int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance)
+ int status;
+ int err = -ENODEV;
+ struct vchiq_mmal_instance *instance;
+- static struct vchiq_instance *vchiq_instance;
++ struct vchiq_instance *vchiq_instance;
+ struct vchiq_service_params_kernel params = {
+ .version = VC_MMAL_VER,
+ .version_min = VC_MMAL_MIN_VER,
+--
+2.30.2
+
--- /dev/null
+From ae3a2181c02cb63b2cef45ea8e854112c367f141 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 12:06:17 +0200
+Subject: staging: mt7621-dts: fix pci address for PCI memory range
+
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+
+[ Upstream commit 5b4f167ef3555ec4c334a8dc89c1b44bb2c6bff5 ]
+
+Driver code call 'devm_of_pci_get_host_bridge_resources'
+to get resources and properly fill 'bridge->windows' and
+'bridge->dma_ranges'. After parsing the ranges and store
+as resources, at the end it makes a call to pci function
+'pci_add_resource_offset' to set the offset for the
+memory resource. To calculate offset, resource start address
+subtracts pci address of the range. MT7621 does not need
+any offset for the memory resource. Moreover, setting an
+offset got into 'WARN_ON' calls from pci devices driver code.
+Until now memory range pci_addr was being '0x00000000' and
+res->start is '0x60000000' but becase pci controller driver
+was manually setting resources and adding them using pci function
+'pci_add_resource' where a zero is passed as offset, things
+was properly working. Since PCI_IOBASE is defined now for
+ralink we don't set nothing manually anymore so we have to
+properly fix PCI address for this range to make things work
+and the new pci address must be set to '0x60000000'. Doing
+in this way the subtract result obtain zero as offset
+and pci device driver code properly works.
+
+Fixes: d59578da2bb8 ("staging: mt7621-dts: add dts files")
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20210614100617.28753-4-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/mt7621-dts/mt7621.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/staging/mt7621-dts/mt7621.dtsi b/drivers/staging/mt7621-dts/mt7621.dtsi
+index f0c9ae757bcd..d6628e5f4f66 100644
+--- a/drivers/staging/mt7621-dts/mt7621.dtsi
++++ b/drivers/staging/mt7621-dts/mt7621.dtsi
+@@ -498,7 +498,7 @@
+
+ bus-range = <0 255>;
+ ranges = <
+- 0x02000000 0 0x00000000 0x60000000 0 0x10000000 /* pci memory */
++ 0x02000000 0 0x60000000 0x60000000 0 0x10000000 /* pci memory */
+ 0x01000000 0 0x00000000 0x1e160000 0 0x00010000 /* io space */
+ >;
+
+--
+2.30.2
+
--- /dev/null
+From 44112fc39381a7c104390325c81eff6b58393c03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 01:00:13 +0300
+Subject: staging: rtl8712: fix error handling in r871xu_drv_init
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+[ Upstream commit d1d3e3cdfda8eb91f0e24be7ec8be1e6e01b3a1c ]
+
+Previous error handling path was unique for all
+possible errors and there was unnecessary branching.
+Also, one step for freeing drv_sw was missing. All
+these problems was fixed by restructuring error
+handling path.
+
+Also, moved out free_netdev() from r8712_free_drv_sw() for
+correct error handling.
+
+Fixes: 2865d42c78a9 ("staging: r8712u: Add the new driver to the mainline kernel")
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Link: https://lore.kernel.org/r/febb00f72354449bb4d305f373d6d2f47e539ab4.1623620630.git.paskripkin@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/rtl8712/os_intfs.c | 4 ----
+ drivers/staging/rtl8712/usb_intf.c | 24 ++++++++++++++----------
+ 2 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c
+index 0c3ae8495afb..2214aca09730 100644
+--- a/drivers/staging/rtl8712/os_intfs.c
++++ b/drivers/staging/rtl8712/os_intfs.c
+@@ -328,8 +328,6 @@ int r8712_init_drv_sw(struct _adapter *padapter)
+
+ void r8712_free_drv_sw(struct _adapter *padapter)
+ {
+- struct net_device *pnetdev = padapter->pnetdev;
+-
+ r8712_free_cmd_priv(&padapter->cmdpriv);
+ r8712_free_evt_priv(&padapter->evtpriv);
+ r8712_DeInitSwLeds(padapter);
+@@ -339,8 +337,6 @@ void r8712_free_drv_sw(struct _adapter *padapter)
+ _r8712_free_sta_priv(&padapter->stapriv);
+ _r8712_free_recv_priv(&padapter->recvpriv);
+ mp871xdeinit(padapter);
+- if (pnetdev)
+- free_netdev(pnetdev);
+ }
+
+ static void enable_video_mode(struct _adapter *padapter, int cbw40_value)
+diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c
+index dc21e7743349..b760bc355937 100644
+--- a/drivers/staging/rtl8712/usb_intf.c
++++ b/drivers/staging/rtl8712/usb_intf.c
+@@ -361,7 +361,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
+ /* step 1. */
+ pnetdev = r8712_init_netdev();
+ if (!pnetdev)
+- goto error;
++ goto put_dev;
+ padapter = netdev_priv(pnetdev);
+ disable_ht_for_spec_devid(pdid, padapter);
+ pdvobjpriv = &padapter->dvobjpriv;
+@@ -381,16 +381,16 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
+ * initialize the dvobj_priv
+ */
+ if (!padapter->dvobj_init) {
+- goto error;
++ goto put_dev;
+ } else {
+ status = padapter->dvobj_init(padapter);
+ if (status != _SUCCESS)
+- goto error;
++ goto free_netdev;
+ }
+ /* step 4. */
+ status = r8712_init_drv_sw(padapter);
+ if (status)
+- goto error;
++ goto dvobj_deinit;
+ /* step 5. read efuse/eeprom data and get mac_addr */
+ {
+ int i, offset;
+@@ -570,17 +570,20 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
+ }
+ /* step 6. Load the firmware asynchronously */
+ if (rtl871x_load_fw(padapter))
+- goto error;
++ goto deinit_drv_sw;
+ spin_lock_init(&padapter->lock_rx_ff0_filter);
+ mutex_init(&padapter->mutex_start);
+ return 0;
+-error:
++
++deinit_drv_sw:
++ r8712_free_drv_sw(padapter);
++dvobj_deinit:
++ padapter->dvobj_deinit(padapter);
++free_netdev:
++ free_netdev(pnetdev);
++put_dev:
+ usb_put_dev(udev);
+ usb_set_intfdata(pusb_intf, NULL);
+- if (padapter && padapter->dvobj_deinit)
+- padapter->dvobj_deinit(padapter);
+- if (pnetdev)
+- free_netdev(pnetdev);
+ return -ENODEV;
+ }
+
+@@ -612,6 +615,7 @@ static void r871xu_dev_remove(struct usb_interface *pusb_intf)
+ r8712_stop_drv_timers(padapter);
+ r871x_dev_unload(padapter);
+ r8712_free_drv_sw(padapter);
++ free_netdev(pnetdev);
+
+ /* decrease the reference count of the usb device structure
+ * when disconnect
+--
+2.30.2
+
--- /dev/null
+From e460d54cebc21069d6259556e46c209ec4feb059 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 01:00:19 +0300
+Subject: staging: rtl8712: fix memory leak in rtl871x_load_fw_cb
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+[ Upstream commit e02a3b945816a77702a2769a70ef5f9b06e49d54 ]
+
+There is a leak in rtl8712 driver.
+The problem was in non-freed adapter data if
+firmware load failed.
+
+This leak can be reproduced with this code:
+https://syzkaller.appspot.com/text?tag=ReproC&x=16612f02d00000,
+Autoload must fail (to not hit memory leak reported by syzkaller)
+
+There are 2 possible ways how rtl871x_load_fw_cb() and
+r871xu_dev_remove() can be called (in case of fw load error).
+
+1st case:
+ r871xu_dev_remove() then rtl871x_load_fw_cb()
+
+ In this case r871xu_dev_remove() will wait for
+ completion and then will jump to the end, because
+ rtl871x_load_fw_cb() set intfdata to NULL:
+
+ if (pnetdev) {
+ struct _adapter *padapter = netdev_priv(pnetdev);
+
+ /* never exit with a firmware callback pending */
+ wait_for_completion(&padapter->rtl8712_fw_ready);
+ pnetdev = usb_get_intfdata(pusb_intf);
+ usb_set_intfdata(pusb_intf, NULL);
+ if (!pnetdev)
+ goto firmware_load_fail;
+
+ ... clean up code here ...
+ }
+
+2nd case:
+ rtl871x_load_fw_cb() then r871xu_dev_remove()
+
+ In this case pnetdev (from code snippet above) will
+ be zero (because rtl871x_load_fw_cb() set it to NULL)
+ And clean up code won't be executed again.
+
+So, in all cases we need to free adapted data in rtl871x_load_fw_cb(),
+because disconnect function cannot take care of it. And there won't be
+any race conditions, because complete() call happens after setting
+intfdata to NULL.
+
+In previous patch I moved out free_netdev() from r8712_free_drv_sw()
+and that's why now it's possible to free adapter data and then call
+complete.
+
+Fixes: 8c213fa59199 ("staging: r8712u: Use asynchronous firmware loading")
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Link: https://lore.kernel.org/r/81e68fe0194499cc2e7692d35bc4dcf167827d8f.1623620630.git.paskripkin@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/rtl8712/hal_init.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c
+index 715f1fe8b472..22974277afa0 100644
+--- a/drivers/staging/rtl8712/hal_init.c
++++ b/drivers/staging/rtl8712/hal_init.c
+@@ -40,7 +40,10 @@ static void rtl871x_load_fw_cb(const struct firmware *firmware, void *context)
+ dev_err(&udev->dev, "r8712u: Firmware request failed\n");
+ usb_put_dev(udev);
+ usb_set_intfdata(usb_intf, NULL);
++ r8712_free_drv_sw(adapter);
++ adapter->dvobj_deinit(adapter);
+ complete(&adapter->rtl8712_fw_ready);
++ free_netdev(adapter->pnetdev);
+ return;
+ }
+ adapter->fw = firmware;
+--
+2.30.2
+
--- /dev/null
+From 0888e73d5c062158cdac4263e78bac73b8099e5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 May 2021 09:21:08 +0200
+Subject: staging: rtl8712: Fix some tests against some 'data' subtype frames
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 116138c3bd34f92e550431d495db515f5ea19f13 ]
+
+Commit 6e2baa44c6d1 ("staging: rtl8712: remove enum WIFI_FRAME_SUBTYPE")
+was wrong because:
+ WIFI_DATA_NULL != IEEE80211_STYPE_NULLFUNC
+ WIFI_DATA_CFACK != IEEE80211_STYPE_DATA_CFACK
+ WIFI_DATA_CFPOLL != IEEE80211_STYPE_DATA_CFPOLL
+ WIFI_DATA_CFACKPOLL != IEEE80211_STYPE_DATA_CFACKPOLL
+
+the WIFI_DATA_xxx definitions include WIFI_DATA_TYPE, which is 'BIT(3)'.
+Restore the previous behavior by adding the missing
+'IEEE80211_FTYPE_DATA |' (0x0008, that is to say BIT(3)) when these values
+are used.
+
+Hopefully, the wrong commit was small enough and hand review is possible.
+
+Fixes: 6e2baa44c6d1 ("staging: rtl8712: remove enum WIFI_FRAME_SUBTYPE")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/44aebfa3c5ce8f45ae05369c73e9ff77c6d271f9.1619939806.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/rtl8712/rtl871x_recv.c | 2 +-
+ drivers/staging/rtl8712/rtl871x_security.c | 12 ++++++------
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c
+index db2add576418..c23f6b376111 100644
+--- a/drivers/staging/rtl8712/rtl871x_recv.c
++++ b/drivers/staging/rtl8712/rtl871x_recv.c
+@@ -374,7 +374,7 @@ static sint ap2sta_data_frame(struct _adapter *adapter,
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
+ check_fwstate(pmlmepriv, _FW_LINKED)) {
+ /* if NULL-frame, drop packet */
+- if ((GetFrameSubType(ptr)) == IEEE80211_STYPE_NULLFUNC)
++ if ((GetFrameSubType(ptr)) == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC))
+ return _FAIL;
+ /* drop QoS-SubType Data, including QoS NULL,
+ * excluding QoS-Data
+diff --git a/drivers/staging/rtl8712/rtl871x_security.c b/drivers/staging/rtl8712/rtl871x_security.c
+index 63d63f7be481..e0a1c30a8fe6 100644
+--- a/drivers/staging/rtl8712/rtl871x_security.c
++++ b/drivers/staging/rtl8712/rtl871x_security.c
+@@ -1045,9 +1045,9 @@ static void aes_cipher(u8 *key, uint hdrlen,
+ else
+ a4_exists = 1;
+
+- if ((frtype == IEEE80211_STYPE_DATA_CFACK) ||
+- (frtype == IEEE80211_STYPE_DATA_CFPOLL) ||
+- (frtype == IEEE80211_STYPE_DATA_CFACKPOLL)) {
++ if ((frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFACK)) ||
++ (frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFPOLL)) ||
++ (frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFACKPOLL))) {
+ qc_exists = 1;
+ if (hdrlen != WLAN_HDR_A3_QOS_LEN)
+ hdrlen += 2;
+@@ -1225,9 +1225,9 @@ static void aes_decipher(u8 *key, uint hdrlen,
+ a4_exists = 0;
+ else
+ a4_exists = 1;
+- if ((frtype == IEEE80211_STYPE_DATA_CFACK) ||
+- (frtype == IEEE80211_STYPE_DATA_CFPOLL) ||
+- (frtype == IEEE80211_STYPE_DATA_CFACKPOLL)) {
++ if ((frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFACK)) ||
++ (frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFPOLL)) ||
++ (frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFACKPOLL))) {
+ qc_exists = 1;
+ if (hdrlen != WLAN_HDR_A3_QOS_LEN)
+ hdrlen += 2;
+--
+2.30.2
+
--- /dev/null
+From 14902a3450236b287c7dfedc029a76842b774b2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Jun 2021 10:21:31 +0200
+Subject: staging: rtl8723bs: Fix an error handling path
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit eb64c6f60ed5406da496cf772fee4b29674bcbb1 ]
+
+'ret' is known to be 0 at this point. It must be set to -ENOMEM if a
+memory allocation occurs.
+
+Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/a9533d1594900152e1e64e9f09e54240e3b7062a.1624177169.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+index 5088c3731b6d..6d0d0beed402 100644
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+@@ -420,8 +420,10 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
+ wep_key_len = wep_key_len <= 5 ? 5 : 13;
+ wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
+ pwep = kzalloc(wep_total_len, GFP_KERNEL);
+- if (!pwep)
++ if (!pwep) {
++ ret = -ENOMEM;
+ goto exit;
++ }
+
+ pwep->KeyLength = wep_key_len;
+ pwep->Length = wep_total_len;
+--
+2.30.2
+
--- /dev/null
+From 3046712a97a4489734da2ed72816a64fc1b167bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jun 2021 19:23:03 +0200
+Subject: stmmac: prefetch right address
+
+From: Matteo Croce <mcroce@microsoft.com>
+
+[ Upstream commit 4744bf072b4640c5e2ea65c2361ad6c832f28fa8 ]
+
+To support XDP, a headroom is prepended to the packet data.
+Consider this offset when doing a prefetch.
+
+Fixes: da5ec7f22a0f ("net: stmmac: refactor stmmac_init_rx_buffers for stmmac_reinit_rx_buffers")
+Signed-off-by: Matteo Croce <mcroce@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index c87202cbd3d6..91cd5073ddb2 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -5138,7 +5138,7 @@ read_again:
+
+ /* Buffer is good. Go on. */
+
+- prefetch(page_address(buf->page));
++ prefetch(page_address(buf->page) + buf->page_offset);
+ if (buf->sec_page)
+ prefetch(page_address(buf->sec_page));
+
+--
+2.30.2
+
--- /dev/null
+From 8b16a86f7abc37c069516cafea6dfa385edc6310 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jun 2021 19:36:50 -0700
+Subject: swap: fix do_swap_page() race with swapoff
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit 2799e77529c2a25492a4395db93996e3dacd762d ]
+
+When I was investigating the swap code, I found the below possible race
+window:
+
+CPU 1 CPU 2
+----- -----
+do_swap_page
+ if (data_race(si->flags & SWP_SYNCHRONOUS_IO)
+ swap_readpage
+ if (data_race(sis->flags & SWP_FS_OPS)) {
+ swapoff
+ ..
+ p->swap_file = NULL;
+ ..
+ struct file *swap_file = sis->swap_file;
+ struct address_space *mapping = swap_file->f_mapping;[oops!]
+
+Note that for the pages that are swapped in through swap cache, this isn't
+an issue. Because the page is locked, and the swap entry will be marked
+with SWAP_HAS_CACHE, so swapoff() can not proceed until the page has been
+unlocked.
+
+Fix this race by using get/put_swap_device() to guard against concurrent
+swapoff.
+
+Link: https://lkml.kernel.org/r/20210426123316.806267-3-linmiaohe@huawei.com
+Fixes: 0bcac06f27d7 ("mm,swap: skip swapcache for swapin of synchronous device")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Reviewed-by: "Huang, Ying" <ying.huang@intel.com>
+Cc: Alex Shi <alexs@kernel.org>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Dennis Zhou <dennis@kernel.org>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Wei Yang <richard.weiyang@gmail.com>
+Cc: Yang Shi <shy828301@gmail.com>
+Cc: Yu Zhao <yuzhao@google.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/swap.h | 9 +++++++++
+ mm/memory.c | 11 +++++++++--
+ 2 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/swap.h b/include/linux/swap.h
+index 144727041e78..a84f76db5070 100644
+--- a/include/linux/swap.h
++++ b/include/linux/swap.h
+@@ -526,6 +526,15 @@ static inline struct swap_info_struct *swp_swap_info(swp_entry_t entry)
+ return NULL;
+ }
+
++static inline struct swap_info_struct *get_swap_device(swp_entry_t entry)
++{
++ return NULL;
++}
++
++static inline void put_swap_device(struct swap_info_struct *si)
++{
++}
++
+ #define swap_address_space(entry) (NULL)
+ #define get_nr_swap_pages() 0L
+ #define total_swap_pages 0L
+diff --git a/mm/memory.c b/mm/memory.c
+index 486f4a2874e7..b15367c285bd 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -3353,6 +3353,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
+ {
+ struct vm_area_struct *vma = vmf->vma;
+ struct page *page = NULL, *swapcache;
++ struct swap_info_struct *si = NULL;
+ swp_entry_t entry;
+ pte_t pte;
+ int locked;
+@@ -3380,14 +3381,16 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
+ goto out;
+ }
+
++ /* Prevent swapoff from happening to us. */
++ si = get_swap_device(entry);
++ if (unlikely(!si))
++ goto out;
+
+ delayacct_set_flag(current, DELAYACCT_PF_SWAPIN);
+ page = lookup_swap_cache(entry, vma, vmf->address);
+ swapcache = page;
+
+ if (!page) {
+- struct swap_info_struct *si = swp_swap_info(entry);
+-
+ if (data_race(si->flags & SWP_SYNCHRONOUS_IO) &&
+ __swap_count(entry) == 1) {
+ /* skip swapcache */
+@@ -3556,6 +3559,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
+ unlock:
+ pte_unmap_unlock(vmf->pte, vmf->ptl);
+ out:
++ if (si)
++ put_swap_device(si);
+ return ret;
+ out_nomap:
+ pte_unmap_unlock(vmf->pte, vmf->ptl);
+@@ -3567,6 +3572,8 @@ out_release:
+ unlock_page(swapcache);
+ put_page(swapcache);
+ }
++ if (si)
++ put_swap_device(si);
+ return ret;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 6df2c5fa73afe6d57d3e1fff89f68fa03ed6186f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 12:05:00 -0300
+Subject: tc-testing: fix list handling
+
+From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+
+[ Upstream commit b4fd096cbb871340be837491fa1795864a48b2d9 ]
+
+python lists don't have an 'add' method, but 'append'.
+
+Fixes: 14e5175e9e04 ("tc-testing: introduce scapyPlugin for basic traffic")
+Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/tc-testing/plugin-lib/scapyPlugin.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/tc-testing/plugin-lib/scapyPlugin.py b/tools/testing/selftests/tc-testing/plugin-lib/scapyPlugin.py
+index 229ee185b27e..a7b21658af9b 100644
+--- a/tools/testing/selftests/tc-testing/plugin-lib/scapyPlugin.py
++++ b/tools/testing/selftests/tc-testing/plugin-lib/scapyPlugin.py
+@@ -36,7 +36,7 @@ class SubPlugin(TdcPlugin):
+ for k in scapy_keys:
+ if k not in scapyinfo:
+ keyfail = True
+- missing_keys.add(k)
++ missing_keys.append(k)
+ if keyfail:
+ print('{}: Scapy block present in the test, but is missing info:'
+ .format(self.sub_class))
+--
+2.30.2
+
--- /dev/null
+From eba42e3a40d2101e0c7bfdc967e5d39e521e4336 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 20:10:30 +0100
+Subject: thermal/cpufreq_cooling: Update offline CPUs per-cpu thermal_pressure
+
+From: Lukasz Luba <lukasz.luba@arm.com>
+
+[ Upstream commit 2ad8ccc17d1e4270cf65a3f2a07a7534aa23e3fb ]
+
+The thermal pressure signal gives information to the scheduler about
+reduced CPU capacity due to thermal. It is based on a value stored in
+a per-cpu 'thermal_pressure' variable. The online CPUs will get the
+new value there, while the offline won't. Unfortunately, when the CPU
+is back online, the value read from per-cpu variable might be wrong
+(stale data). This might affect the scheduler decisions, since it
+sees the CPU capacity differently than what is actually available.
+
+Fix it by making sure that all online+offline CPUs would get the
+proper value in their per-cpu variable when thermal framework sets
+capping.
+
+Fixes: f12e4f66ab6a3 ("thermal/cpu-cooling: Update thermal pressure in case of a maximum frequency capping")
+Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Link: https://lore.kernel.org/r/20210614191030.22241-1-lukasz.luba@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/cpufreq_cooling.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c
+index eeb4e4b76c0b..43b1ae8a7789 100644
+--- a/drivers/thermal/cpufreq_cooling.c
++++ b/drivers/thermal/cpufreq_cooling.c
+@@ -478,7 +478,7 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
+ ret = freq_qos_update_request(&cpufreq_cdev->qos_req, frequency);
+ if (ret >= 0) {
+ cpufreq_cdev->cpufreq_state = state;
+- cpus = cpufreq_cdev->policy->cpus;
++ cpus = cpufreq_cdev->policy->related_cpus;
+ max_capacity = arch_scale_cpu_capacity(cpumask_first(cpus));
+ capacity = frequency * max_capacity;
+ capacity /= cpufreq_cdev->policy->cpuinfo.max_freq;
+--
+2.30.2
+
--- /dev/null
+From 4202a2fe5825fba396b824839ef5fe45cdb815fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jun 2021 13:37:46 +0300
+Subject: thunderbolt: Bond lanes only when dual_link_port != NULL in
+ alloc_dev_default()
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit a0d36fa1065901f939b04587a09c65303a64ac88 ]
+
+We should not dereference ->dual_link_port if it is NULL and lane bonding
+is requested. For this reason move lane bonding configuration happen
+inside the block where ->dual_link_port != NULL.
+
+Fixes: 54509f5005ca ("thunderbolt: Add KUnit tests for path walking")
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Yehezkel Bernat <YehezkelShB@gmail.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thunderbolt/test.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
+index 5ff5a03bc9ce..6e0a5391fcd7 100644
+--- a/drivers/thunderbolt/test.c
++++ b/drivers/thunderbolt/test.c
+@@ -260,14 +260,14 @@ static struct tb_switch *alloc_dev_default(struct kunit *test,
+ if (port->dual_link_port && upstream_port->dual_link_port) {
+ port->dual_link_port->remote = upstream_port->dual_link_port;
+ upstream_port->dual_link_port->remote = port->dual_link_port;
+- }
+
+- if (bonded) {
+- /* Bonding is used */
+- port->bonded = true;
+- port->dual_link_port->bonded = true;
+- upstream_port->bonded = true;
+- upstream_port->dual_link_port->bonded = true;
++ if (bonded) {
++ /* Bonding is used */
++ port->bonded = true;
++ port->dual_link_port->bonded = true;
++ upstream_port->bonded = true;
++ upstream_port->dual_link_port->bonded = true;
++ }
+ }
+
+ return sw;
+--
+2.30.2
+
--- /dev/null
+From 7ef02b8d0953dc56be919a6a8ffdb2cef018d47e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 13:34:06 -0700
+Subject: tls: prevent oversized sendfile() hangs by ignoring MSG_MORE
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit d452d48b9f8b1a7f8152d33ef52cfd7fe1735b0a ]
+
+We got multiple reports that multi_chunk_sendfile test
+case from tls selftest fails. This was sort of expected,
+as the original fix was never applied (see it in the first
+Link:). The test in question uses sendfile() with count
+larger than the size of the underlying file. This will
+make splice set MSG_MORE on all sendpage calls, meaning
+TLS will never close and flush the last partial record.
+
+Eric seem to have addressed a similar problem in
+commit 35f9c09fe9c7 ("tcp: tcp_sendpages() should call tcp_push() once")
+by introducing MSG_SENDPAGE_NOTLAST. Unlike MSG_MORE
+MSG_SENDPAGE_NOTLAST is not set on the last call
+of a "pipefull" of data (PIPE_DEF_BUFFERS == 16,
+so every 16 pages or whenever we run out of data).
+
+Having a break every 16 pages should be fine, TLS
+can pack exactly 4 pages into a record, so for
+aligned reads there should be no difference,
+unaligned may see one extra record per sendpage().
+
+Sticking to TCP semantics seems preferable to modifying
+splice, but we can revisit it if real life scenarios
+show a regression.
+
+Reported-by: Vadim Fedorenko <vfedorenko@novek.ru>
+Reported-by: Seth Forshee <seth.forshee@canonical.com>
+Link: https://lore.kernel.org/netdev/1591392508-14592-1-git-send-email-pooja.trivedi@stackpath.com/
+Fixes: 3c4d7559159b ("tls: kernel TLS support")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Tested-by: Seth Forshee <seth.forshee@canonical.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tls/tls_sw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
+index 694de024d0ee..74e5701034aa 100644
+--- a/net/tls/tls_sw.c
++++ b/net/tls/tls_sw.c
+@@ -1153,7 +1153,7 @@ static int tls_sw_do_sendpage(struct sock *sk, struct page *page,
+ int ret = 0;
+ bool eor;
+
+- eor = !(flags & (MSG_MORE | MSG_SENDPAGE_NOTLAST));
++ eor = !(flags & MSG_SENDPAGE_NOTLAST);
+ sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
+
+ /* Call the sk_stream functions to manage the sndbuf mem. */
+--
+2.30.2
+
--- /dev/null
+From 3c36363197b82dc896f4f7dd354beedf027b3b19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jun 2021 19:59:16 +0800
+Subject: tools/bpftool: Fix error return code in do_batch()
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit ca16b429f39b4ce013bfa7e197f25681e65a2a42 ]
+
+Fix to return a negative error code from the error handling
+case instead of 0, as done elsewhere in this function.
+
+Fixes: 668da745af3c2 ("tools: bpftool: add support for quotations ...")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Reviewed-by: Quentin Monnet <quentin@isovalent.com>
+Link: https://lore.kernel.org/bpf/20210609115916.2186872-1-chengzhihao1@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c
+index d9afb730136a..0f36b9edd3f5 100644
+--- a/tools/bpf/bpftool/main.c
++++ b/tools/bpf/bpftool/main.c
+@@ -340,8 +340,10 @@ static int do_batch(int argc, char **argv)
+ n_argc = make_args(buf, n_argv, BATCH_ARG_NB_MAX, lines);
+ if (!n_argc)
+ continue;
+- if (n_argc < 0)
++ if (n_argc < 0) {
++ err = n_argc;
+ goto err_close;
++ }
+
+ if (json_output) {
+ jsonw_start_object(json_wtr);
+--
+2.30.2
+
--- /dev/null
+From ff89c70b36280c75b3208455c1f93bd7936bcc06 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 May 2021 03:17:32 -0700
+Subject: tools/power/x86/intel-speed-select: Fix uncore memory frequency
+ display
+
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+[ Upstream commit 159f130f60f402273b235801d1fde3fc115c6795 ]
+
+The uncore memory frequency value from the mailbox command
+CONFIG_TDP_GET_MEM_FREQ needs to be scaled based on the platform for
+display. There is no single constant multiplier.
+
+This change introduces CPU model specific memory frequency multiplier.
+
+Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/power/x86/intel-speed-select/isst-config.c | 16 ++++++++++++++++
+ tools/power/x86/intel-speed-select/isst-core.c | 15 +++++++++++++++
+ .../power/x86/intel-speed-select/isst-display.c | 2 +-
+ tools/power/x86/intel-speed-select/isst.h | 2 ++
+ 4 files changed, 34 insertions(+), 1 deletion(-)
+
+diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c
+index ab940c508ef0..d4f0a7872e49 100644
+--- a/tools/power/x86/intel-speed-select/isst-config.c
++++ b/tools/power/x86/intel-speed-select/isst-config.c
+@@ -106,6 +106,22 @@ int is_skx_based_platform(void)
+ return 0;
+ }
+
++int is_spr_platform(void)
++{
++ if (cpu_model == 0x8F)
++ return 1;
++
++ return 0;
++}
++
++int is_icx_platform(void)
++{
++ if (cpu_model == 0x6A || cpu_model == 0x6C)
++ return 1;
++
++ return 0;
++}
++
+ static int update_cpu_model(void)
+ {
+ unsigned int ebx, ecx, edx;
+diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c
+index 6a26d5769984..4431c8a0d40a 100644
+--- a/tools/power/x86/intel-speed-select/isst-core.c
++++ b/tools/power/x86/intel-speed-select/isst-core.c
+@@ -201,6 +201,7 @@ void isst_get_uncore_mem_freq(int cpu, int config_index,
+ {
+ unsigned int resp;
+ int ret;
++
+ ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_MEM_FREQ,
+ 0, config_index, &resp);
+ if (ret) {
+@@ -209,6 +210,20 @@ void isst_get_uncore_mem_freq(int cpu, int config_index,
+ }
+
+ ctdp_level->mem_freq = resp & GENMASK(7, 0);
++ if (is_spr_platform()) {
++ ctdp_level->mem_freq *= 200;
++ } else if (is_icx_platform()) {
++ if (ctdp_level->mem_freq < 7) {
++ ctdp_level->mem_freq = (12 - ctdp_level->mem_freq) * 133.33 * 2 * 10;
++ ctdp_level->mem_freq /= 10;
++ if (ctdp_level->mem_freq % 10 > 5)
++ ctdp_level->mem_freq++;
++ } else {
++ ctdp_level->mem_freq = 0;
++ }
++ } else {
++ ctdp_level->mem_freq = 0;
++ }
+ debug_printf(
+ "cpu:%d ctdp:%d CONFIG_TDP_GET_MEM_FREQ resp:%x uncore mem_freq:%d\n",
+ cpu, config_index, resp, ctdp_level->mem_freq);
+diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c
+index 3bf1820c0da1..f97d8859ada7 100644
+--- a/tools/power/x86/intel-speed-select/isst-display.c
++++ b/tools/power/x86/intel-speed-select/isst-display.c
+@@ -446,7 +446,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
+ if (ctdp_level->mem_freq) {
+ snprintf(header, sizeof(header), "mem-frequency(MHz)");
+ snprintf(value, sizeof(value), "%d",
+- ctdp_level->mem_freq * DISP_FREQ_MULTIPLIER);
++ ctdp_level->mem_freq);
+ format_and_print(outf, level + 2, header, value);
+ }
+
+diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h
+index 0cac6c54be87..1aa15d5ea57c 100644
+--- a/tools/power/x86/intel-speed-select/isst.h
++++ b/tools/power/x86/intel-speed-select/isst.h
+@@ -257,5 +257,7 @@ extern int get_cpufreq_base_freq(int cpu);
+ extern int isst_read_pm_config(int cpu, int *cp_state, int *cp_cap);
+ extern void isst_display_error_info_message(int error, char *msg, int arg_valid, int arg);
+ extern int is_skx_based_platform(void);
++extern int is_spr_platform(void);
++extern int is_icx_platform(void);
+ extern void isst_trl_display_information(int cpu, FILE *outf, unsigned long long trl);
+ #endif
+--
+2.30.2
+
--- /dev/null
+From 93b9af9228d0ba82b3c80bd9f549917541d4864f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 May 2021 17:23:52 +0200
+Subject: tpm_tis_spi: add missing SPI device ID entries
+
+From: Javier Martinez Canillas <javierm@redhat.com>
+
+[ Upstream commit c46ed2281bbe4b84e6f3d4bdfb0e4e9ab813fa9d ]
+
+The SPI core always reports a "MODALIAS=spi:<foo>", even if the device was
+registered via OF. This means that this module won't auto-load if a DT has
+for example has a node with a compatible "infineon,slb9670" string.
+
+In that case kmod will expect a "MODALIAS=of:N*T*Cinfineon,slb9670" uevent
+but instead will get a "MODALIAS=spi:slb9670", which is not present in the
+kernel module aliases:
+
+$ modinfo drivers/char/tpm/tpm_tis_spi.ko | grep alias
+alias: of:N*T*Cgoogle,cr50C*
+alias: of:N*T*Cgoogle,cr50
+alias: of:N*T*Ctcg,tpm_tis-spiC*
+alias: of:N*T*Ctcg,tpm_tis-spi
+alias: of:N*T*Cinfineon,slb9670C*
+alias: of:N*T*Cinfineon,slb9670
+alias: of:N*T*Cst,st33htpm-spiC*
+alias: of:N*T*Cst,st33htpm-spi
+alias: spi:cr50
+alias: spi:tpm_tis_spi
+alias: acpi*:SMO0768:*
+
+To workaround this issue, add in the SPI device ID table all the entries
+that are present in the OF device ID table.
+
+Reported-by: Alexander Wellbrock <a.wellbrock@mailbox.org>
+Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
+Tested-by: Peter Robinson <pbrobinson@gmail.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/tpm/tpm_tis_spi_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/char/tpm/tpm_tis_spi_main.c b/drivers/char/tpm/tpm_tis_spi_main.c
+index 3856f6ebcb34..de4209003a44 100644
+--- a/drivers/char/tpm/tpm_tis_spi_main.c
++++ b/drivers/char/tpm/tpm_tis_spi_main.c
+@@ -260,6 +260,8 @@ static int tpm_tis_spi_remove(struct spi_device *dev)
+ }
+
+ static const struct spi_device_id tpm_tis_spi_id[] = {
++ { "st33htpm-spi", (unsigned long)tpm_tis_spi_probe },
++ { "slb9670", (unsigned long)tpm_tis_spi_probe },
+ { "tpm_tis_spi", (unsigned long)tpm_tis_spi_probe },
+ { "cr50", (unsigned long)cr50_spi_probe },
+ {}
+--
+2.30.2
+
--- /dev/null
+From 6e29104c15d5172b4c49178553b3fe14ddee79ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 May 2021 19:22:33 +0200
+Subject: tty: nozomi: Fix a resource leak in an error handling function
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 31a9a318255960d32ae183e95d0999daf2418608 ]
+
+A 'request_irq()' call is not balanced by a corresponding 'free_irq()' in
+the error handling path, as already done in the remove function.
+
+Add it.
+
+Fixes: 9842c38e9176 ("kfifo: fix warn_unused_result")
+Reviewed-by: Jiri Slaby <jirislaby@kernel.org>
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/4f0d2b3038e82f081d370ccb0cade3ad88463fe7.1620580838.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/nozomi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c
+index 9a2d78ace49b..b270e137ef9b 100644
+--- a/drivers/tty/nozomi.c
++++ b/drivers/tty/nozomi.c
+@@ -1420,6 +1420,7 @@ err_free_tty:
+ tty_unregister_device(ntty_driver, dc->index_start + i);
+ tty_port_destroy(&dc->port[i].port);
+ }
++ free_irq(pdev->irq, dc);
+ err_free_kfifo:
+ for (i = 0; i < MAX_PORT; i++)
+ kfifo_free(&dc->port[i].fifo_ul);
+--
+2.30.2
+
--- /dev/null
+From 940fa706c1996f34d1282959a2cc430c7671fbac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 May 2021 20:51:57 +0200
+Subject: tty: nozomi: Fix the error handling path of 'nozomi_card_init()'
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 6ae7d0f5a92b9619f6e3c307ce56b2cefff3f0e9 ]
+
+The error handling path is broken and we may un-register things that have
+never been registered.
+
+Update the loops index accordingly.
+
+Fixes: 9842c38e9176 ("kfifo: fix warn_unused_result")
+Suggested-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/e28c2e92c7475da25b03d022ea2d6dcf1ba807a2.1621968629.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/nozomi.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c
+index b270e137ef9b..ce3a79e95fb5 100644
+--- a/drivers/tty/nozomi.c
++++ b/drivers/tty/nozomi.c
+@@ -1378,7 +1378,7 @@ static int nozomi_card_init(struct pci_dev *pdev,
+ NOZOMI_NAME, dc);
+ if (unlikely(ret)) {
+ dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq);
+- goto err_free_kfifo;
++ goto err_free_all_kfifo;
+ }
+
+ DBG1("base_addr: %p", dc->base_addr);
+@@ -1416,13 +1416,15 @@ static int nozomi_card_init(struct pci_dev *pdev,
+ return 0;
+
+ err_free_tty:
+- for (i = 0; i < MAX_PORT; ++i) {
++ for (i--; i >= 0; i--) {
+ tty_unregister_device(ntty_driver, dc->index_start + i);
+ tty_port_destroy(&dc->port[i].port);
+ }
+ free_irq(pdev->irq, dc);
++err_free_all_kfifo:
++ i = MAX_PORT;
+ err_free_kfifo:
+- for (i = 0; i < MAX_PORT; i++)
++ for (i--; i >= PORT_MDM; i--)
+ kfifo_free(&dc->port[i].fifo_ul);
+ err_free_sbuf:
+ kfree(dc->send_buf);
+--
+2.30.2
+
--- /dev/null
+From db36baf827e1945cb4560789d2f38a743c2f902b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jun 2021 19:13:37 -0700
+Subject: udp: Fix a memory leak in udp_read_sock()
+
+From: Cong Wang <cong.wang@bytedance.com>
+
+[ Upstream commit e00a5c331bf57f41fcfdc5da4f5caeafe5e54c1d ]
+
+sk_psock_verdict_recv() clones the skb and uses the clone
+afterward, so udp_read_sock() should free the skb after using
+it, regardless of error or not.
+
+This fixes a real kmemleak.
+
+Fixes: d7f571188ecf ("udp: Implement ->read_sock() for sockmap")
+Signed-off-by: Cong Wang <cong.wang@bytedance.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Acked-by: Jakub Sitnicki <jakub@cloudflare.com>
+Link: https://lore.kernel.org/bpf/20210615021342.7416-4-xiyou.wangcong@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/udp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 1307ad0d3b9e..8091276cb85b 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1798,11 +1798,13 @@ int udp_read_sock(struct sock *sk, read_descriptor_t *desc,
+ if (used <= 0) {
+ if (!copied)
+ copied = used;
++ kfree_skb(skb);
+ break;
+ } else if (used <= skb->len) {
+ copied += used;
+ }
+
++ kfree_skb(skb);
+ if (!desc->count)
+ break;
+ }
+--
+2.30.2
+
--- /dev/null
+From 95ad814a73a442ffa5de141af700ae6c3bf0f3e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Jun 2021 17:59:21 +0200
+Subject: usb: dwc2: Don't reset the core after setting turnaround time
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Clément Lassieur <clement@lassieur.org>
+
+[ Upstream commit aafe93516b8567ab5864e1f4cd3eeabc54fb0e5a ]
+
+Every time the hub signals a reset while we (device) are hsotg->connected,
+dwc2_hsotg_core_init_disconnected() is called, which in turn calls
+dwc2_hs_phy_init().
+
+GUSBCFG.USBTrdTim is cleared upon Core Soft Reset, so if
+hsotg->params.phy_utmi_width is 8-bit, the value of GUSBCFG.USBTrdTim (the
+default one: 0x5, corresponding to 16-bit) is always different from
+hsotg->params.phy_utmi_width, thus dwc2_core_reset() is called every
+time (usbcfg != usbcfg_old), which causes 2 issues:
+
+1) The call to dwc2_core_reset() does another reset 300us after the initial
+Chirp K of the first reset (which should last at least Tuch = 1ms), and
+messes up the High-speed Detection Handshake: both hub and device drive
+current into the D+ and D- lines at the same time.
+
+2) GUSBCFG.USBTrdTim is cleared by the second reset, so its value is always
+the default one (0x5).
+
+Setting GUSBCFG.USBTrdTim after the potential call to dwc2_core_reset()
+fixes both issues. It is now set even when select_phy is false because the
+cost of the Core Soft Reset is removed.
+
+Fixes: 1e868545f2bb ("usb: dwc2: gadget: Move gadget phy init into core phy init")
+Signed-off-by: Clément Lassieur <clement@lassieur.org>
+Link: https://lore.kernel.org/r/20210603155921.940651-1-clement@lassieur.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc2/core.c | 30 +++++++++++++++++++++---------
+ 1 file changed, 21 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
+index 6f70ab9577b4..272ae5722c86 100644
+--- a/drivers/usb/dwc2/core.c
++++ b/drivers/usb/dwc2/core.c
+@@ -1111,15 +1111,6 @@ static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
+ usbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16);
+ if (hsotg->params.phy_utmi_width == 16)
+ usbcfg |= GUSBCFG_PHYIF16;
+-
+- /* Set turnaround time */
+- if (dwc2_is_device_mode(hsotg)) {
+- usbcfg &= ~GUSBCFG_USBTRDTIM_MASK;
+- if (hsotg->params.phy_utmi_width == 16)
+- usbcfg |= 5 << GUSBCFG_USBTRDTIM_SHIFT;
+- else
+- usbcfg |= 9 << GUSBCFG_USBTRDTIM_SHIFT;
+- }
+ break;
+ default:
+ dev_err(hsotg->dev, "FS PHY selected at HS!\n");
+@@ -1141,6 +1132,24 @@ static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
+ return retval;
+ }
+
++static void dwc2_set_turnaround_time(struct dwc2_hsotg *hsotg)
++{
++ u32 usbcfg;
++
++ if (hsotg->params.phy_type != DWC2_PHY_TYPE_PARAM_UTMI)
++ return;
++
++ usbcfg = dwc2_readl(hsotg, GUSBCFG);
++
++ usbcfg &= ~GUSBCFG_USBTRDTIM_MASK;
++ if (hsotg->params.phy_utmi_width == 16)
++ usbcfg |= 5 << GUSBCFG_USBTRDTIM_SHIFT;
++ else
++ usbcfg |= 9 << GUSBCFG_USBTRDTIM_SHIFT;
++
++ dwc2_writel(hsotg, usbcfg, GUSBCFG);
++}
++
+ int dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
+ {
+ u32 usbcfg;
+@@ -1158,6 +1167,9 @@ int dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
+ retval = dwc2_hs_phy_init(hsotg, select_phy);
+ if (retval)
+ return retval;
++
++ if (dwc2_is_device_mode(hsotg))
++ dwc2_set_turnaround_time(hsotg);
+ }
+
+ if (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI &&
+--
+2.30.2
+
--- /dev/null
+From e3668df8c771c849802e2179024cafb638f0d399 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Jun 2021 12:15:07 -0500
+Subject: usb: gadget: f_fs: Fix setting of device and driver data
+ cross-references
+
+From: Andrew Gabbasov <andrew_gabbasov@mentor.com>
+
+[ Upstream commit ecfbd7b9054bddb12cea07fda41bb3a79a7b0149 ]
+
+FunctionFS device structure 'struct ffs_dev' and driver data structure
+'struct ffs_data' are bound to each other with cross-reference pointers
+'ffs_data->private_data' and 'ffs_dev->ffs_data'. While the first one
+is supposed to be valid through the whole life of 'struct ffs_data'
+(and while 'struct ffs_dev' exists non-freed), the second one is cleared
+in 'ffs_closed()' (called from 'ffs_data_reset()' or the last
+'ffs_data_put()'). This can be called several times, alternating in
+different order with 'ffs_free_inst()', that, if possible, clears
+the other cross-reference.
+
+As a result, different cases of these calls order may leave stale
+cross-reference pointers, used when the pointed structure is already
+freed. Even if it occasionally doesn't cause kernel crash, this error
+is reported by KASAN-enabled kernel configuration.
+
+For example, the case [last 'ffs_data_put()' - 'ffs_free_inst()'] was
+fixed by commit cdafb6d8b8da ("usb: gadget: f_fs: Fix use-after-free in
+ffs_free_inst").
+
+The other case ['ffs_data_reset()' - 'ffs_free_inst()' - 'ffs_data_put()']
+now causes KASAN reported error [1], when 'ffs_data_reset()' clears
+'ffs_dev->ffs_data', then 'ffs_free_inst()' frees the 'struct ffs_dev',
+but can't clear 'ffs_data->private_data', which is then accessed
+in 'ffs_closed()' called from 'ffs_data_put()'. This happens since
+'ffs_dev->ffs_data' reference is cleared too early.
+
+Moreover, one more use case, when 'ffs_free_inst()' is called immediately
+after mounting FunctionFS device (that is before the descriptors are
+written and 'ffs_ready()' is called), and then 'ffs_data_reset()'
+or 'ffs_data_put()' is called from accessing "ep0" file or unmounting
+the device. This causes KASAN error report like [2], since
+'ffs_dev->ffs_data' is not yet set when 'ffs_free_inst()' can't properly
+clear 'ffs_data->private_data', that is later accessed to freed structure.
+
+Fix these (and may be other) cases of stale pointers access by moving
+setting and clearing of the mentioned cross-references to the single
+places, setting both of them when 'struct ffs_data' is created and
+bound to 'struct ffs_dev', and clearing both of them when one of the
+structures is destroyed. It seems convenient to make this pointer
+initialization and structures binding in 'ffs_acquire_dev()' and
+make pointers clearing in 'ffs_release_dev()'. This required some
+changes in these functions parameters and return types.
+
+Also, 'ffs_release_dev()' calling requires some cleanup, fixing minor
+issues, like (1) 'ffs_release_dev()' is not called if 'ffs_free_inst()'
+is called without unmounting the device, and "release_dev" callback
+is not called at all, or (2) "release_dev" callback is called before
+"ffs_closed" callback on unmounting, which seems to be not correctly
+nested with "acquire_dev" and "ffs_ready" callbacks.
+Make this cleanup togther with other mentioned 'ffs_release_dev()' changes.
+
+[1]
+==================================================================
+root@rcar-gen3:~# mkdir /dev/cfs
+root@rcar-gen3:~# mkdir /dev/ffs
+root@rcar-gen3:~# modprobe libcomposite
+root@rcar-gen3:~# mount -t configfs none /dev/cfs
+root@rcar-gen3:~# mkdir /dev/cfs/usb_gadget/g1
+root@rcar-gen3:~# mkdir /dev/cfs/usb_gadget/g1/functions/ffs.ffs
+[ 64.340664] file system registered
+root@rcar-gen3:~# mount -t functionfs ffs /dev/ffs
+root@rcar-gen3:~# cd /dev/ffs
+root@rcar-gen3:/dev/ffs# /home/root/ffs-test
+ffs-test: info: ep0: writing descriptors (in v2 format)
+[ 83.181442] read descriptors
+[ 83.186085] read strings
+ffs-test: info: ep0: writing strings
+ffs-test: dbg: ep1: starting
+ffs-test: dbg: ep2: starting
+ffs-test: info: ep1: starts
+ffs-test: info: ep2: starts
+ffs-test: info: ep0: starts
+
+^C
+root@rcar-gen3:/dev/ffs# cd /home/root/
+root@rcar-gen3:~# rmdir /dev/cfs/usb_gadget/g1/functions/ffs.ffs
+[ 98.935061] unloading
+root@rcar-gen3:~# umount /dev/ffs
+[ 102.734301] ==================================================================
+[ 102.742059] BUG: KASAN: use-after-free in ffs_release_dev+0x64/0xa8 [usb_f_fs]
+[ 102.749683] Write of size 1 at addr ffff0004d46ff549 by task umount/2997
+[ 102.756709]
+[ 102.758311] CPU: 0 PID: 2997 Comm: umount Not tainted 5.13.0-rc4+ #8
+[ 102.764971] Hardware name: Renesas Salvator-X board based on r8a77951 (DT)
+[ 102.772179] Call trace:
+[ 102.774779] dump_backtrace+0x0/0x330
+[ 102.778653] show_stack+0x20/0x2c
+[ 102.782152] dump_stack+0x11c/0x1ac
+[ 102.785833] print_address_description.constprop.0+0x30/0x274
+[ 102.791862] kasan_report+0x14c/0x1c8
+[ 102.795719] __asan_report_store1_noabort+0x34/0x58
+[ 102.800840] ffs_release_dev+0x64/0xa8 [usb_f_fs]
+[ 102.805801] ffs_fs_kill_sb+0x50/0x84 [usb_f_fs]
+[ 102.810663] deactivate_locked_super+0xa0/0xf0
+[ 102.815339] deactivate_super+0x98/0xac
+[ 102.819378] cleanup_mnt+0xd0/0x1b0
+[ 102.823057] __cleanup_mnt+0x1c/0x28
+[ 102.826823] task_work_run+0x104/0x180
+[ 102.830774] do_notify_resume+0x458/0x14e0
+[ 102.835083] work_pending+0xc/0x5f8
+[ 102.838762]
+[ 102.840357] Allocated by task 2988:
+[ 102.844032] kasan_save_stack+0x28/0x58
+[ 102.848071] kasan_set_track+0x28/0x3c
+[ 102.852016] ____kasan_kmalloc+0x84/0x9c
+[ 102.856142] __kasan_kmalloc+0x10/0x1c
+[ 102.860088] __kmalloc+0x214/0x2f8
+[ 102.863678] kzalloc.constprop.0+0x14/0x20 [usb_f_fs]
+[ 102.868990] ffs_alloc_inst+0x8c/0x208 [usb_f_fs]
+[ 102.873942] try_get_usb_function_instance+0xf0/0x164 [libcomposite]
+[ 102.880629] usb_get_function_instance+0x64/0x68 [libcomposite]
+[ 102.886858] function_make+0x128/0x1ec [libcomposite]
+[ 102.892185] configfs_mkdir+0x330/0x590 [configfs]
+[ 102.897245] vfs_mkdir+0x12c/0x1bc
+[ 102.900835] do_mkdirat+0x180/0x1d0
+[ 102.904513] __arm64_sys_mkdirat+0x80/0x94
+[ 102.908822] invoke_syscall+0xf8/0x25c
+[ 102.912772] el0_svc_common.constprop.0+0x150/0x1a0
+[ 102.917891] do_el0_svc+0xa0/0xd4
+[ 102.921386] el0_svc+0x24/0x34
+[ 102.924613] el0_sync_handler+0xcc/0x154
+[ 102.928743] el0_sync+0x198/0x1c0
+[ 102.932238]
+[ 102.933832] Freed by task 2996:
+[ 102.937144] kasan_save_stack+0x28/0x58
+[ 102.941181] kasan_set_track+0x28/0x3c
+[ 102.945128] kasan_set_free_info+0x28/0x4c
+[ 102.949435] ____kasan_slab_free+0x104/0x118
+[ 102.953921] __kasan_slab_free+0x18/0x24
+[ 102.958047] slab_free_freelist_hook+0x148/0x1f0
+[ 102.962897] kfree+0x318/0x440
+[ 102.966123] ffs_free_inst+0x164/0x2d8 [usb_f_fs]
+[ 102.971075] usb_put_function_instance+0x84/0xa4 [libcomposite]
+[ 102.977302] ffs_attr_release+0x18/0x24 [usb_f_fs]
+[ 102.982344] config_item_put+0x140/0x1a4 [configfs]
+[ 102.987486] configfs_rmdir+0x3fc/0x518 [configfs]
+[ 102.992535] vfs_rmdir+0x114/0x234
+[ 102.996122] do_rmdir+0x274/0x2b0
+[ 102.999617] __arm64_sys_unlinkat+0x94/0xc8
+[ 103.004015] invoke_syscall+0xf8/0x25c
+[ 103.007961] el0_svc_common.constprop.0+0x150/0x1a0
+[ 103.013080] do_el0_svc+0xa0/0xd4
+[ 103.016575] el0_svc+0x24/0x34
+[ 103.019801] el0_sync_handler+0xcc/0x154
+[ 103.023930] el0_sync+0x198/0x1c0
+[ 103.027426]
+[ 103.029020] The buggy address belongs to the object at ffff0004d46ff500
+[ 103.029020] which belongs to the cache kmalloc-128 of size 128
+[ 103.042079] The buggy address is located 73 bytes inside of
+[ 103.042079] 128-byte region [ffff0004d46ff500, ffff0004d46ff580)
+[ 103.054236] The buggy address belongs to the page:
+[ 103.059262] page:0000000021aa849b refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff0004d46fee00 pfn:0x5146fe
+[ 103.070437] head:0000000021aa849b order:1 compound_mapcount:0
+[ 103.076456] flags: 0x8000000000010200(slab|head|zone=2)
+[ 103.081948] raw: 8000000000010200 fffffc0013521a80 0000000d0000000d ffff0004c0002300
+[ 103.090052] raw: ffff0004d46fee00 000000008020001e 00000001ffffffff 0000000000000000
+[ 103.098150] page dumped because: kasan: bad access detected
+[ 103.103985]
+[ 103.105578] Memory state around the buggy address:
+[ 103.110602] ffff0004d46ff400: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[ 103.118161] ffff0004d46ff480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+[ 103.125726] >ffff0004d46ff500: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[ 103.133284] ^
+[ 103.139120] ffff0004d46ff580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+[ 103.146679] ffff0004d46ff600: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[ 103.154238] ==================================================================
+[ 103.161792] Disabling lock debugging due to kernel taint
+[ 103.167319] Unable to handle kernel paging request at virtual address 0037801d6000018e
+[ 103.175406] Mem abort info:
+[ 103.178457] ESR = 0x96000004
+[ 103.181609] EC = 0x25: DABT (current EL), IL = 32 bits
+[ 103.187020] SET = 0, FnV = 0
+[ 103.190185] EA = 0, S1PTW = 0
+[ 103.193417] Data abort info:
+[ 103.196385] ISV = 0, ISS = 0x00000004
+[ 103.200315] CM = 0, WnR = 0
+[ 103.203366] [0037801d6000018e] address between user and kernel address ranges
+[ 103.210611] Internal error: Oops: 96000004 [#1] PREEMPT SMP
+[ 103.216231] Modules linked in: usb_f_fs libcomposite configfs ath9k_htc led_class mac80211 libarc4 ath9k_common ath9k_hw ath cfg80211 aes_ce_blk sata_rc4
+[ 103.259233] CPU: 0 PID: 2997 Comm: umount Tainted: G B 5.13.0-rc4+ #8
+[ 103.267031] Hardware name: Renesas Salvator-X board based on r8a77951 (DT)
+[ 103.273951] pstate: 00000005 (nzcv daif -PAN -UAO -TCO BTYPE=--)
+[ 103.280001] pc : ffs_data_clear+0x138/0x370 [usb_f_fs]
+[ 103.285197] lr : ffs_data_clear+0x124/0x370 [usb_f_fs]
+[ 103.290385] sp : ffff800014777a80
+[ 103.293725] x29: ffff800014777a80 x28: ffff0004d7649c80 x27: 0000000000000000
+[ 103.300931] x26: ffff800014777fb0 x25: ffff60009aec9394 x24: ffff0004d7649ca4
+[ 103.308136] x23: 1fffe0009a3d063a x22: dfff800000000000 x21: ffff0004d1e831d0
+[ 103.315340] x20: e1c000eb00000bb4 x19: ffff0004d1e83000 x18: 0000000000000000
+[ 103.322545] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
+[ 103.329748] x14: 0720072007200720 x13: 0720072007200720 x12: 1ffff000012ef658
+[ 103.336952] x11: ffff7000012ef658 x10: 0720072007200720 x9 : ffff800011322648
+[ 103.344157] x8 : ffff800014777818 x7 : ffff80000977b2c7 x6 : 0000000000000000
+[ 103.351359] x5 : 0000000000000001 x4 : ffff7000012ef659 x3 : 0000000000000001
+[ 103.358562] x2 : 0000000000000000 x1 : 1c38001d6000018e x0 : e1c000eb00000c70
+[ 103.365766] Call trace:
+[ 103.368235] ffs_data_clear+0x138/0x370 [usb_f_fs]
+[ 103.373076] ffs_data_reset+0x20/0x304 [usb_f_fs]
+[ 103.377829] ffs_data_closed+0x1ec/0x244 [usb_f_fs]
+[ 103.382755] ffs_fs_kill_sb+0x70/0x84 [usb_f_fs]
+[ 103.387420] deactivate_locked_super+0xa0/0xf0
+[ 103.391905] deactivate_super+0x98/0xac
+[ 103.395776] cleanup_mnt+0xd0/0x1b0
+[ 103.399299] __cleanup_mnt+0x1c/0x28
+[ 103.402906] task_work_run+0x104/0x180
+[ 103.406691] do_notify_resume+0x458/0x14e0
+[ 103.410823] work_pending+0xc/0x5f8
+[ 103.414351] Code: b4000a54 9102f280 12000802 d343fc01 (38f66821)
+[ 103.420490] ---[ end trace 57b43a50e8244f57 ]---
+Segmentation fault
+root@rcar-gen3:~#
+==================================================================
+
+[2]
+==================================================================
+root@rcar-gen3:~# mkdir /dev/ffs
+root@rcar-gen3:~# modprobe libcomposite
+root@rcar-gen3:~#
+root@rcar-gen3:~# mount -t configfs none /dev/cfs
+root@rcar-gen3:~# mkdir /dev/cfs/usb_gadget/g1
+root@rcar-gen3:~# mkdir /dev/cfs/usb_gadget/g1/functions/ffs.ffs
+[ 54.766480] file system registered
+root@rcar-gen3:~# mount -t functionfs ffs /dev/ffs
+root@rcar-gen3:~# rmdir /dev/cfs/usb_gadget/g1/functions/ffs.ffs
+[ 63.197597] unloading
+root@rcar-gen3:~# cat /dev/ffs/ep0
+cat: read error:[ 67.213506] ==================================================================
+[ 67.222095] BUG: KASAN: use-after-free in ffs_data_clear+0x70/0x370 [usb_f_fs]
+[ 67.229699] Write of size 1 at addr ffff0004c26e974a by task cat/2994
+[ 67.236446]
+[ 67.238045] CPU: 0 PID: 2994 Comm: cat Not tainted 5.13.0-rc4+ #8
+[ 67.244431] Hardware name: Renesas Salvator-X board based on r8a77951 (DT)
+[ 67.251624] Call trace:
+[ 67.254212] dump_backtrace+0x0/0x330
+[ 67.258081] show_stack+0x20/0x2c
+[ 67.261579] dump_stack+0x11c/0x1ac
+[ 67.265260] print_address_description.constprop.0+0x30/0x274
+[ 67.271286] kasan_report+0x14c/0x1c8
+[ 67.275143] __asan_report_store1_noabort+0x34/0x58
+[ 67.280265] ffs_data_clear+0x70/0x370 [usb_f_fs]
+[ 67.285220] ffs_data_reset+0x20/0x304 [usb_f_fs]
+[ 67.290172] ffs_data_closed+0x240/0x244 [usb_f_fs]
+[ 67.295305] ffs_ep0_release+0x40/0x54 [usb_f_fs]
+[ 67.300256] __fput+0x304/0x580
+[ 67.303576] ____fput+0x18/0x24
+[ 67.306893] task_work_run+0x104/0x180
+[ 67.310846] do_notify_resume+0x458/0x14e0
+[ 67.315154] work_pending+0xc/0x5f8
+[ 67.318834]
+[ 67.320429] Allocated by task 2988:
+[ 67.324105] kasan_save_stack+0x28/0x58
+[ 67.328144] kasan_set_track+0x28/0x3c
+[ 67.332090] ____kasan_kmalloc+0x84/0x9c
+[ 67.336217] __kasan_kmalloc+0x10/0x1c
+[ 67.340163] __kmalloc+0x214/0x2f8
+[ 67.343754] kzalloc.constprop.0+0x14/0x20 [usb_f_fs]
+[ 67.349066] ffs_alloc_inst+0x8c/0x208 [usb_f_fs]
+[ 67.354017] try_get_usb_function_instance+0xf0/0x164 [libcomposite]
+[ 67.360705] usb_get_function_instance+0x64/0x68 [libcomposite]
+[ 67.366934] function_make+0x128/0x1ec [libcomposite]
+[ 67.372260] configfs_mkdir+0x330/0x590 [configfs]
+[ 67.377320] vfs_mkdir+0x12c/0x1bc
+[ 67.380911] do_mkdirat+0x180/0x1d0
+[ 67.384589] __arm64_sys_mkdirat+0x80/0x94
+[ 67.388899] invoke_syscall+0xf8/0x25c
+[ 67.392850] el0_svc_common.constprop.0+0x150/0x1a0
+[ 67.397969] do_el0_svc+0xa0/0xd4
+[ 67.401464] el0_svc+0x24/0x34
+[ 67.404691] el0_sync_handler+0xcc/0x154
+[ 67.408819] el0_sync+0x198/0x1c0
+[ 67.412315]
+[ 67.413909] Freed by task 2993:
+[ 67.417220] kasan_save_stack+0x28/0x58
+[ 67.421257] kasan_set_track+0x28/0x3c
+[ 67.425204] kasan_set_free_info+0x28/0x4c
+[ 67.429513] ____kasan_slab_free+0x104/0x118
+[ 67.434001] __kasan_slab_free+0x18/0x24
+[ 67.438128] slab_free_freelist_hook+0x148/0x1f0
+[ 67.442978] kfree+0x318/0x440
+[ 67.446205] ffs_free_inst+0x164/0x2d8 [usb_f_fs]
+[ 67.451156] usb_put_function_instance+0x84/0xa4 [libcomposite]
+[ 67.457385] ffs_attr_release+0x18/0x24 [usb_f_fs]
+[ 67.462428] config_item_put+0x140/0x1a4 [configfs]
+[ 67.467570] configfs_rmdir+0x3fc/0x518 [configfs]
+[ 67.472626] vfs_rmdir+0x114/0x234
+[ 67.476215] do_rmdir+0x274/0x2b0
+[ 67.479710] __arm64_sys_unlinkat+0x94/0xc8
+[ 67.484108] invoke_syscall+0xf8/0x25c
+[ 67.488055] el0_svc_common.constprop.0+0x150/0x1a0
+[ 67.493175] do_el0_svc+0xa0/0xd4
+[ 67.496671] el0_svc+0x24/0x34
+[ 67.499896] el0_sync_handler+0xcc/0x154
+[ 67.504024] el0_sync+0x198/0x1c0
+[ 67.507520]
+[ 67.509114] The buggy address belongs to the object at ffff0004c26e9700
+[ 67.509114] which belongs to the cache kmalloc-128 of size 128
+[ 67.522171] The buggy address is located 74 bytes inside of
+[ 67.522171] 128-byte region [ffff0004c26e9700, ffff0004c26e9780)
+[ 67.534328] The buggy address belongs to the page:
+[ 67.539355] page:000000003177a217 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x5026e8
+[ 67.549175] head:000000003177a217 order:1 compound_mapcount:0
+[ 67.555195] flags: 0x8000000000010200(slab|head|zone=2)
+[ 67.560687] raw: 8000000000010200 fffffc0013037100 0000000c00000002 ffff0004c0002300
+[ 67.568791] raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000
+[ 67.576890] page dumped because: kasan: bad access detected
+[ 67.582725]
+[ 67.584318] Memory state around the buggy address:
+[ 67.589343] ffff0004c26e9600: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[ 67.596903] ffff0004c26e9680: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+[ 67.604463] >ffff0004c26e9700: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+[ 67.612022] ^
+[ 67.617860] ffff0004c26e9780: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+[ 67.625421] ffff0004c26e9800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 67.632981] ==================================================================
+[ 67.640535] Disabling lock debugging due to kernel taint
+ File descriptor[ 67.646100] Unable to handle kernel paging request at virtual address fabb801d4000018d
+ in bad state
+[ 67.655456] Mem abort info:
+[ 67.659619] ESR = 0x96000004
+[ 67.662801] EC = 0x25: DABT (current EL), IL = 32 bits
+[ 67.668225] SET = 0, FnV = 0
+[ 67.671375] EA = 0, S1PTW = 0
+[ 67.674613] Data abort info:
+[ 67.677587] ISV = 0, ISS = 0x00000004
+[ 67.681522] CM = 0, WnR = 0
+[ 67.684588] [fabb801d4000018d] address between user and kernel address ranges
+[ 67.691849] Internal error: Oops: 96000004 [#1] PREEMPT SMP
+[ 67.697470] Modules linked in: usb_f_fs libcomposite configfs ath9k_htc led_class mac80211 libarc4 ath9k_common ath9k_hw ath cfg80211 aes_ce_blk crypto_simd cryptd aes_ce_cipher ghash_ce gf128mul sha2_ce sha1_ce evdev sata_rcar libata xhci_plat_hcd scsi_mod xhci_hcd rene4
+[ 67.740467] CPU: 0 PID: 2994 Comm: cat Tainted: G B 5.13.0-rc4+ #8
+[ 67.748005] Hardware name: Renesas Salvator-X board based on r8a77951 (DT)
+[ 67.754924] pstate: 00000005 (nzcv daif -PAN -UAO -TCO BTYPE=--)
+[ 67.760974] pc : ffs_data_clear+0x138/0x370 [usb_f_fs]
+[ 67.766178] lr : ffs_data_clear+0x124/0x370 [usb_f_fs]
+[ 67.771365] sp : ffff800014767ad0
+[ 67.774706] x29: ffff800014767ad0 x28: ffff800009cf91c0 x27: ffff0004c54861a0
+[ 67.781913] x26: ffff0004dc90b288 x25: 1fffe00099ec10f5 x24: 00000000000a801d
+[ 67.789118] x23: 1fffe00099f6953a x22: dfff800000000000 x21: ffff0004cfb4a9d0
+[ 67.796322] x20: d5e000ea00000bb1 x19: ffff0004cfb4a800 x18: 0000000000000000
+[ 67.803526] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
+[ 67.810730] x14: 0720072007200720 x13: 0720072007200720 x12: 1ffff000028ecefa
+[ 67.817934] x11: ffff7000028ecefa x10: 0720072007200720 x9 : ffff80001132c014
+[ 67.825137] x8 : ffff8000147677d8 x7 : ffff8000147677d7 x6 : 0000000000000000
+[ 67.832341] x5 : 0000000000000001 x4 : ffff7000028ecefb x3 : 0000000000000001
+[ 67.839544] x2 : 0000000000000005 x1 : 1abc001d4000018d x0 : d5e000ea00000c6d
+[ 67.846748] Call trace:
+[ 67.849218] ffs_data_clear+0x138/0x370 [usb_f_fs]
+[ 67.854058] ffs_data_reset+0x20/0x304 [usb_f_fs]
+[ 67.858810] ffs_data_closed+0x240/0x244 [usb_f_fs]
+[ 67.863736] ffs_ep0_release+0x40/0x54 [usb_f_fs]
+[ 67.868488] __fput+0x304/0x580
+[ 67.871665] ____fput+0x18/0x24
+[ 67.874837] task_work_run+0x104/0x180
+[ 67.878622] do_notify_resume+0x458/0x14e0
+[ 67.882754] work_pending+0xc/0x5f8
+[ 67.886282] Code: b4000a54 9102f280 12000802 d343fc01 (38f66821)
+[ 67.892422] ---[ end trace 6d7cedf53d7abbea ]---
+Segmentation fault
+root@rcar-gen3:~#
+==================================================================
+
+Fixes: 4b187fceec3c ("usb: gadget: FunctionFS: add devices management code")
+Fixes: 3262ad824307 ("usb: gadget: f_fs: Stop ffs_closed NULL pointer dereference")
+Fixes: cdafb6d8b8da ("usb: gadget: f_fs: Fix use-after-free in ffs_free_inst")
+Reported-by: Bhuvanesh Surachari <bhuvanesh_surachari@mentor.com>
+Tested-by: Eugeniu Rosca <erosca@de.adit-jv.com>
+Reviewed-by: Eugeniu Rosca <erosca@de.adit-jv.com>
+Signed-off-by: Andrew Gabbasov <andrew_gabbasov@mentor.com>
+Link: https://lore.kernel.org/r/20210603171507.22514-1-andrew_gabbasov@mentor.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_fs.c | 65 +++++++++++++++---------------
+ 1 file changed, 32 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
+index d4844afeaffc..9c0c393abb39 100644
+--- a/drivers/usb/gadget/function/f_fs.c
++++ b/drivers/usb/gadget/function/f_fs.c
+@@ -250,8 +250,8 @@ EXPORT_SYMBOL_GPL(ffs_lock);
+ static struct ffs_dev *_ffs_find_dev(const char *name);
+ static struct ffs_dev *_ffs_alloc_dev(void);
+ static void _ffs_free_dev(struct ffs_dev *dev);
+-static void *ffs_acquire_dev(const char *dev_name);
+-static void ffs_release_dev(struct ffs_data *ffs_data);
++static int ffs_acquire_dev(const char *dev_name, struct ffs_data *ffs_data);
++static void ffs_release_dev(struct ffs_dev *ffs_dev);
+ static int ffs_ready(struct ffs_data *ffs);
+ static void ffs_closed(struct ffs_data *ffs);
+
+@@ -1554,8 +1554,8 @@ unmapped_value:
+ static int ffs_fs_get_tree(struct fs_context *fc)
+ {
+ struct ffs_sb_fill_data *ctx = fc->fs_private;
+- void *ffs_dev;
+ struct ffs_data *ffs;
++ int ret;
+
+ ENTER();
+
+@@ -1574,13 +1574,12 @@ static int ffs_fs_get_tree(struct fs_context *fc)
+ return -ENOMEM;
+ }
+
+- ffs_dev = ffs_acquire_dev(ffs->dev_name);
+- if (IS_ERR(ffs_dev)) {
++ ret = ffs_acquire_dev(ffs->dev_name, ffs);
++ if (ret) {
+ ffs_data_put(ffs);
+- return PTR_ERR(ffs_dev);
++ return ret;
+ }
+
+- ffs->private_data = ffs_dev;
+ ctx->ffs_data = ffs;
+ return get_tree_nodev(fc, ffs_sb_fill);
+ }
+@@ -1591,7 +1590,6 @@ static void ffs_fs_free_fc(struct fs_context *fc)
+
+ if (ctx) {
+ if (ctx->ffs_data) {
+- ffs_release_dev(ctx->ffs_data);
+ ffs_data_put(ctx->ffs_data);
+ }
+
+@@ -1630,10 +1628,8 @@ ffs_fs_kill_sb(struct super_block *sb)
+ ENTER();
+
+ kill_litter_super(sb);
+- if (sb->s_fs_info) {
+- ffs_release_dev(sb->s_fs_info);
++ if (sb->s_fs_info)
+ ffs_data_closed(sb->s_fs_info);
+- }
+ }
+
+ static struct file_system_type ffs_fs_type = {
+@@ -1703,6 +1699,7 @@ static void ffs_data_put(struct ffs_data *ffs)
+ if (refcount_dec_and_test(&ffs->ref)) {
+ pr_info("%s(): freeing\n", __func__);
+ ffs_data_clear(ffs);
++ ffs_release_dev(ffs->private_data);
+ BUG_ON(waitqueue_active(&ffs->ev.waitq) ||
+ swait_active(&ffs->ep0req_completion.wait) ||
+ waitqueue_active(&ffs->wait));
+@@ -3032,6 +3029,7 @@ static inline struct f_fs_opts *ffs_do_functionfs_bind(struct usb_function *f,
+ struct ffs_function *func = ffs_func_from_usb(f);
+ struct f_fs_opts *ffs_opts =
+ container_of(f->fi, struct f_fs_opts, func_inst);
++ struct ffs_data *ffs_data;
+ int ret;
+
+ ENTER();
+@@ -3046,12 +3044,13 @@ static inline struct f_fs_opts *ffs_do_functionfs_bind(struct usb_function *f,
+ if (!ffs_opts->no_configfs)
+ ffs_dev_lock();
+ ret = ffs_opts->dev->desc_ready ? 0 : -ENODEV;
+- func->ffs = ffs_opts->dev->ffs_data;
++ ffs_data = ffs_opts->dev->ffs_data;
+ if (!ffs_opts->no_configfs)
+ ffs_dev_unlock();
+ if (ret)
+ return ERR_PTR(ret);
+
++ func->ffs = ffs_data;
+ func->conf = c;
+ func->gadget = c->cdev->gadget;
+
+@@ -3506,6 +3505,7 @@ static void ffs_free_inst(struct usb_function_instance *f)
+ struct f_fs_opts *opts;
+
+ opts = to_f_fs_opts(f);
++ ffs_release_dev(opts->dev);
+ ffs_dev_lock();
+ _ffs_free_dev(opts->dev);
+ ffs_dev_unlock();
+@@ -3693,47 +3693,48 @@ static void _ffs_free_dev(struct ffs_dev *dev)
+ {
+ list_del(&dev->entry);
+
+- /* Clear the private_data pointer to stop incorrect dev access */
+- if (dev->ffs_data)
+- dev->ffs_data->private_data = NULL;
+-
+ kfree(dev);
+ if (list_empty(&ffs_devices))
+ functionfs_cleanup();
+ }
+
+-static void *ffs_acquire_dev(const char *dev_name)
++static int ffs_acquire_dev(const char *dev_name, struct ffs_data *ffs_data)
+ {
++ int ret = 0;
+ struct ffs_dev *ffs_dev;
+
+ ENTER();
+ ffs_dev_lock();
+
+ ffs_dev = _ffs_find_dev(dev_name);
+- if (!ffs_dev)
+- ffs_dev = ERR_PTR(-ENOENT);
+- else if (ffs_dev->mounted)
+- ffs_dev = ERR_PTR(-EBUSY);
+- else if (ffs_dev->ffs_acquire_dev_callback &&
+- ffs_dev->ffs_acquire_dev_callback(ffs_dev))
+- ffs_dev = ERR_PTR(-ENOENT);
+- else
++ if (!ffs_dev) {
++ ret = -ENOENT;
++ } else if (ffs_dev->mounted) {
++ ret = -EBUSY;
++ } else if (ffs_dev->ffs_acquire_dev_callback &&
++ ffs_dev->ffs_acquire_dev_callback(ffs_dev)) {
++ ret = -ENOENT;
++ } else {
+ ffs_dev->mounted = true;
++ ffs_dev->ffs_data = ffs_data;
++ ffs_data->private_data = ffs_dev;
++ }
+
+ ffs_dev_unlock();
+- return ffs_dev;
++ return ret;
+ }
+
+-static void ffs_release_dev(struct ffs_data *ffs_data)
++static void ffs_release_dev(struct ffs_dev *ffs_dev)
+ {
+- struct ffs_dev *ffs_dev;
+-
+ ENTER();
+ ffs_dev_lock();
+
+- ffs_dev = ffs_data->private_data;
+- if (ffs_dev) {
++ if (ffs_dev && ffs_dev->mounted) {
+ ffs_dev->mounted = false;
++ if (ffs_dev->ffs_data) {
++ ffs_dev->ffs_data->private_data = NULL;
++ ffs_dev->ffs_data = NULL;
++ }
+
+ if (ffs_dev->ffs_release_dev_callback)
+ ffs_dev->ffs_release_dev_callback(ffs_dev);
+@@ -3761,7 +3762,6 @@ static int ffs_ready(struct ffs_data *ffs)
+ }
+
+ ffs_obj->desc_ready = true;
+- ffs_obj->ffs_data = ffs;
+
+ if (ffs_obj->ffs_ready_callback) {
+ ret = ffs_obj->ffs_ready_callback(ffs);
+@@ -3789,7 +3789,6 @@ static void ffs_closed(struct ffs_data *ffs)
+ goto done;
+
+ ffs_obj->desc_ready = false;
+- ffs_obj->ffs_data = NULL;
+
+ if (test_and_clear_bit(FFS_FL_CALL_CLOSED_CALLBACK, &ffs->flags) &&
+ ffs_obj->ffs_closed_callback)
+--
+2.30.2
+
--- /dev/null
+From e14dff77ed386849542881b490f28803679d0a9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Jun 2021 17:59:36 +0300
+Subject: usb: phy: tegra: Correct definition of B_SESS_VLD_WAKEUP_EN bit
+
+From: Dmitry Osipenko <digetx@gmail.com>
+
+[ Upstream commit 7917e90667bc8dce02daa3c2e6df47f6fc9481f7 ]
+
+The B_SESS_VLD_WAKEUP_EN bit 6 was added by a mistake in a previous
+commit. This bit corresponds to B_SESS_END_WAKEUP_EN, which we don't use.
+The B_VBUS_VLD_WAKEUP_EN doesn't exist at all and B_SESS_VLD_WAKEUP_EN
+needs to be in place of it. We don't utilize B-sensors in the driver,
+so it never was a problem, nevertheless let's correct the definition of
+the bits.
+
+Fixes: 35192007d28d ("usb: phy: tegra: Support waking up from a low power mode")
+Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
+Link: https://lore.kernel.org/r/20210613145936.9902-2-digetx@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/phy/phy-tegra-usb.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c
+index 10fafcf9801b..c0f432d509aa 100644
+--- a/drivers/usb/phy/phy-tegra-usb.c
++++ b/drivers/usb/phy/phy-tegra-usb.c
+@@ -58,8 +58,7 @@
+ #define USB_WAKEUP_DEBOUNCE_COUNT(x) (((x) & 0x7) << 16)
+
+ #define USB_PHY_VBUS_SENSORS 0x404
+-#define B_SESS_VLD_WAKEUP_EN BIT(6)
+-#define B_VBUS_VLD_WAKEUP_EN BIT(14)
++#define B_SESS_VLD_WAKEUP_EN BIT(14)
+ #define A_SESS_VLD_WAKEUP_EN BIT(22)
+ #define A_VBUS_VLD_WAKEUP_EN BIT(30)
+
+@@ -545,7 +544,7 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
+
+ val = readl_relaxed(base + USB_PHY_VBUS_SENSORS);
+ val &= ~(A_VBUS_VLD_WAKEUP_EN | A_SESS_VLD_WAKEUP_EN);
+- val &= ~(B_VBUS_VLD_WAKEUP_EN | B_SESS_VLD_WAKEUP_EN);
++ val &= ~(B_SESS_VLD_WAKEUP_EN);
+ writel_relaxed(val, base + USB_PHY_VBUS_SENSORS);
+
+ val = readl_relaxed(base + UTMIP_BAT_CHRG_CFG0);
+--
+2.30.2
+
--- /dev/null
+From 53f1bebc123f810f2de082d4bc93acbca4757b2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Jun 2021 17:59:35 +0300
+Subject: usb: phy: tegra: Wait for VBUS wakeup status deassertion on suspend
+
+From: Dmitry Osipenko <digetx@gmail.com>
+
+[ Upstream commit 6f8d39a8ef55efde414b6e574384acbce70c3119 ]
+
+Some devices need an extra delay after losing VBUS, otherwise VBUS may
+be detected as active at suspend time, preventing the PHY's suspension
+by the VBUS detection sensor. This problem was found on Asus Transformer
+TF700T (Tegra30) tablet device, where the USB PHY wakes up immediately
+from suspend because VBUS sensor continues to detect VBUS as active after
+disconnection. We need to poll the PHY's VBUS wakeup status until it's
+deasserted before suspending PHY in order to fix this minor trouble.
+
+Fixes: 35192007d28d ("usb: phy: tegra: Support waking up from a low power mode")
+Reported-by: Maxim Schwalm <maxim.schwalm@gmail.com> # Asus TF700T
+Tested-by: Maxim Schwalm <maxim.schwalm@gmail.com> # Asus TF700T
+Reviewed-by: Peter Chen <peter.chen@kernel.org>
+Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
+Link: https://lore.kernel.org/r/20210613145936.9902-1-digetx@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/phy/phy-tegra-usb.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c
+index a48452a6172b..10fafcf9801b 100644
+--- a/drivers/usb/phy/phy-tegra-usb.c
++++ b/drivers/usb/phy/phy-tegra-usb.c
+@@ -64,6 +64,7 @@
+ #define A_VBUS_VLD_WAKEUP_EN BIT(30)
+
+ #define USB_PHY_VBUS_WAKEUP_ID 0x408
++#define VBUS_WAKEUP_STS BIT(10)
+ #define VBUS_WAKEUP_WAKEUP_EN BIT(30)
+
+ #define USB1_LEGACY_CTRL 0x410
+@@ -642,6 +643,15 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy)
+ void __iomem *base = phy->regs;
+ u32 val;
+
++ /*
++ * Give hardware time to settle down after VBUS disconnection,
++ * otherwise PHY will immediately wake up from suspend.
++ */
++ if (phy->wakeup_enabled && phy->mode != USB_DR_MODE_HOST)
++ readl_relaxed_poll_timeout(base + USB_PHY_VBUS_WAKEUP_ID,
++ val, !(val & VBUS_WAKEUP_STS),
++ 5000, 100000);
++
+ utmi_phy_clk_disable(phy);
+
+ /* PHY won't resume if reset is asserted */
+--
+2.30.2
+
--- /dev/null
+From c304bc51900af2bfd78a83111271091aa256e154 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 May 2021 12:21:09 -0700
+Subject: usb: typec: tcpm: Fix up PR_SWAP when vsafe0v is signalled
+
+From: Badhri Jagan Sridharan <badhri@google.com>
+
+[ Upstream commit d112efbe6dbf7d4c482e2a3f381fa315aabfe63b ]
+
+During PR_SWAP, When TCPM is in PR_SWAP_SNK_SRC_SINK_OFF, vbus is
+expected to reach VSAFE0V when source turns off vbus. Do not move
+to SNK_UNATTACHED state when this happens.
+
+Fixes: 28b43d3d746b ("usb: typec: tcpm: Introduce vsafe0v for vbus")
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
+Link: https://lore.kernel.org/r/20210517192112.40934-1-badhri@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/tcpm/tcpm.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
+index c67533191091..1b7f18d35df4 100644
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -5225,6 +5225,9 @@ static void _tcpm_pd_vbus_vsafe0v(struct tcpm_port *port)
+ tcpm_set_state(port, SNK_UNATTACHED, 0);
+ }
+ break;
++ case PR_SWAP_SNK_SRC_SINK_OFF:
++ /* Do nothing, vsafe0v is expected during transition */
++ break;
+ default:
+ if (port->pwr_role == TYPEC_SINK && port->auto_vbus_discharge_enabled)
+ tcpm_set_state(port, SNK_UNATTACHED, 0);
+--
+2.30.2
+
--- /dev/null
+From 2b28199781ea8d89b14dcf1aedde75c7d1e696d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jun 2021 14:08:12 -0600
+Subject: vfio/pci: Handle concurrent vma faults
+
+From: Alex Williamson <alex.williamson@redhat.com>
+
+[ Upstream commit 6a45ece4c9af473555f01f0f8b97eba56e3c7d0d ]
+
+io_remap_pfn_range() will trigger a BUG_ON if it encounters a
+populated pte within the mapping range. This can occur because we map
+the entire vma on fault and multiple faults can be blocked behind the
+vma_lock. This leads to traces like the one reported below.
+
+We can use our vma_list to test whether a given vma is mapped to avoid
+this issue.
+
+[ 1591.733256] kernel BUG at mm/memory.c:2177!
+[ 1591.739515] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
+[ 1591.747381] Modules linked in: vfio_iommu_type1 vfio_pci vfio_virqfd vfio pv680_mii(O)
+[ 1591.760536] CPU: 2 PID: 227 Comm: lcore-worker-2 Tainted: G O 5.11.0-rc3+ #1
+[ 1591.770735] Hardware name: , BIOS HixxxxFPGA 1P B600 V121-1
+[ 1591.778872] pstate: 40400009 (nZcv daif +PAN -UAO -TCO BTYPE=--)
+[ 1591.786134] pc : remap_pfn_range+0x214/0x340
+[ 1591.793564] lr : remap_pfn_range+0x1b8/0x340
+[ 1591.799117] sp : ffff80001068bbd0
+[ 1591.803476] x29: ffff80001068bbd0 x28: 0000042eff6f0000
+[ 1591.810404] x27: 0000001100910000 x26: 0000001300910000
+[ 1591.817457] x25: 0068000000000fd3 x24: ffffa92f1338e358
+[ 1591.825144] x23: 0000001140000000 x22: 0000000000000041
+[ 1591.832506] x21: 0000001300910000 x20: ffffa92f141a4000
+[ 1591.839520] x19: 0000001100a00000 x18: 0000000000000000
+[ 1591.846108] x17: 0000000000000000 x16: ffffa92f11844540
+[ 1591.853570] x15: 0000000000000000 x14: 0000000000000000
+[ 1591.860768] x13: fffffc0000000000 x12: 0000000000000880
+[ 1591.868053] x11: ffff0821bf3d01d0 x10: ffff5ef2abd89000
+[ 1591.875932] x9 : ffffa92f12ab0064 x8 : ffffa92f136471c0
+[ 1591.883208] x7 : 0000001140910000 x6 : 0000000200000000
+[ 1591.890177] x5 : 0000000000000001 x4 : 0000000000000001
+[ 1591.896656] x3 : 0000000000000000 x2 : 0168044000000fd3
+[ 1591.903215] x1 : ffff082126261880 x0 : fffffc2084989868
+[ 1591.910234] Call trace:
+[ 1591.914837] remap_pfn_range+0x214/0x340
+[ 1591.921765] vfio_pci_mmap_fault+0xac/0x130 [vfio_pci]
+[ 1591.931200] __do_fault+0x44/0x12c
+[ 1591.937031] handle_mm_fault+0xcc8/0x1230
+[ 1591.942475] do_page_fault+0x16c/0x484
+[ 1591.948635] do_translation_fault+0xbc/0xd8
+[ 1591.954171] do_mem_abort+0x4c/0xc0
+[ 1591.960316] el0_da+0x40/0x80
+[ 1591.965585] el0_sync_handler+0x168/0x1b0
+[ 1591.971608] el0_sync+0x174/0x180
+[ 1591.978312] Code: eb1b027f 540000c0 f9400022 b4fffe02 (d4210000)
+
+Fixes: 11c4cd07ba11 ("vfio-pci: Fault mmaps to enable vma tracking")
+Reported-by: Zeng Tao <prime.zeng@hisilicon.com>
+Suggested-by: Zeng Tao <prime.zeng@hisilicon.com>
+Link: https://lore.kernel.org/r/162497742783.3883260.3282953006487785034.stgit@omen
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/pci/vfio_pci.c | 29 +++++++++++++++++++++--------
+ 1 file changed, 21 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
+index bd7c482c948a..b94958552eb8 100644
+--- a/drivers/vfio/pci/vfio_pci.c
++++ b/drivers/vfio/pci/vfio_pci.c
+@@ -1594,6 +1594,7 @@ static vm_fault_t vfio_pci_mmap_fault(struct vm_fault *vmf)
+ {
+ struct vm_area_struct *vma = vmf->vma;
+ struct vfio_pci_device *vdev = vma->vm_private_data;
++ struct vfio_pci_mmap_vma *mmap_vma;
+ vm_fault_t ret = VM_FAULT_NOPAGE;
+
+ mutex_lock(&vdev->vma_lock);
+@@ -1601,24 +1602,36 @@ static vm_fault_t vfio_pci_mmap_fault(struct vm_fault *vmf)
+
+ if (!__vfio_pci_memory_enabled(vdev)) {
+ ret = VM_FAULT_SIGBUS;
+- mutex_unlock(&vdev->vma_lock);
+ goto up_out;
+ }
+
+- if (__vfio_pci_add_vma(vdev, vma)) {
+- ret = VM_FAULT_OOM;
+- mutex_unlock(&vdev->vma_lock);
+- goto up_out;
++ /*
++ * We populate the whole vma on fault, so we need to test whether
++ * the vma has already been mapped, such as for concurrent faults
++ * to the same vma. io_remap_pfn_range() will trigger a BUG_ON if
++ * we ask it to fill the same range again.
++ */
++ list_for_each_entry(mmap_vma, &vdev->vma_list, vma_next) {
++ if (mmap_vma->vma == vma)
++ goto up_out;
+ }
+
+- mutex_unlock(&vdev->vma_lock);
+-
+ if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+- vma->vm_end - vma->vm_start, vma->vm_page_prot))
++ vma->vm_end - vma->vm_start,
++ vma->vm_page_prot)) {
+ ret = VM_FAULT_SIGBUS;
++ zap_vma_ptes(vma, vma->vm_start, vma->vm_end - vma->vm_start);
++ goto up_out;
++ }
++
++ if (__vfio_pci_add_vma(vdev, vma)) {
++ ret = VM_FAULT_OOM;
++ zap_vma_ptes(vma, vma->vm_start, vma->vm_end - vma->vm_start);
++ }
+
+ up_out:
+ up_read(&vdev->memory_lock);
++ mutex_unlock(&vdev->vma_lock);
+ return ret;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From f103d2d17c458ff465816466da11a4f8332fbdb1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 May 2021 20:57:05 +0200
+Subject: video: fbdev: imxfb: Fix an error message
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 767d724a160eb1cd00c86fb8c2e21fa1ab3c37ac ]
+
+'ret' is known to be 0 here.
+No error code is available, so just remove it from the error message.
+
+Fixes: 72330b0eeefc ("i.MX Framebuffer: Use readl/writel instead of direct pointer deref")
+Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/d7b25026f82659da3c6f7159eea480faa9d738be.1620327302.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/imxfb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c
+index 7f8debd2da06..ad598257ab38 100644
+--- a/drivers/video/fbdev/imxfb.c
++++ b/drivers/video/fbdev/imxfb.c
+@@ -992,7 +992,7 @@ static int imxfb_probe(struct platform_device *pdev)
+ info->screen_buffer = dma_alloc_wc(&pdev->dev, fbi->map_size,
+ &fbi->map_dma, GFP_KERNEL);
+ if (!info->screen_buffer) {
+- dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);
++ dev_err(&pdev->dev, "Failed to allocate video RAM\n");
+ ret = -ENOMEM;
+ goto failed_map;
+ }
+--
+2.30.2
+
--- /dev/null
+From 07d4bf7be1576e7ca9a863c9e39e2e3cd4744a87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 May 2021 16:26:14 +0800
+Subject: visorbus: fix error return code in visorchipset_init()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit ce52ec5beecc1079c251f60e3973b3758f60eb59 ]
+
+Commit 1366a3db3dcf ("staging: unisys: visorbus: visorchipset_init clean
+up gotos") assigns the initial value -ENODEV to the local variable 'err',
+and the first several error branches will return this value after "goto
+error". But commit f1f537c2e7f5 ("staging: unisys: visorbus: Consolidate
+controlvm channel creation.") overwrites 'err' in the middle of the way.
+As a result, some error branches do not successfully return the initial
+value -ENODEV of 'err', but return 0.
+
+In addition, when kzalloc() fails, -ENOMEM should be returned instead of
+-ENODEV.
+
+Fixes: f1f537c2e7f5 ("staging: unisys: visorbus: Consolidate controlvm channel creation.")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Link: https://lore.kernel.org/r/20210528082614.9337-1-thunder.leizhen@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/visorbus/visorchipset.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/visorbus/visorchipset.c b/drivers/visorbus/visorchipset.c
+index cb1eb7e05f87..5668cad86e37 100644
+--- a/drivers/visorbus/visorchipset.c
++++ b/drivers/visorbus/visorchipset.c
+@@ -1561,7 +1561,7 @@ schedule_out:
+
+ static int visorchipset_init(struct acpi_device *acpi_device)
+ {
+- int err = -ENODEV;
++ int err = -ENOMEM;
+ struct visorchannel *controlvm_channel;
+
+ chipset_dev = kzalloc(sizeof(*chipset_dev), GFP_KERNEL);
+@@ -1584,8 +1584,10 @@ static int visorchipset_init(struct acpi_device *acpi_device)
+ "controlvm",
+ sizeof(struct visor_controlvm_channel),
+ VISOR_CONTROLVM_CHANNEL_VERSIONID,
+- VISOR_CHANNEL_SIGNATURE))
++ VISOR_CHANNEL_SIGNATURE)) {
++ err = -ENODEV;
+ goto error_delete_groups;
++ }
+ /* if booting in a crash kernel */
+ if (is_kdump_kernel())
+ INIT_DELAYED_WORK(&chipset_dev->periodic_controlvm_work,
+--
+2.30.2
+
--- /dev/null
+From d1f7c53b5b44aed70121dab2070f25f5bed677a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 17:15:53 +0200
+Subject: vrf: do not push non-ND strict packets with a source LLA through
+ packet taps again
+
+From: Antoine Tenart <atenart@kernel.org>
+
+[ Upstream commit 603113c514e95c3350598bc3cccbd03af7ea4ab2 ]
+
+Non-ND strict packets with a source LLA go through the packet taps
+again, while non-ND strict packets with other source addresses do not,
+and we can see a clone of those packets on the vrf interface (we should
+not). This is due to a series of changes:
+
+Commit 6f12fa775530[1] made non-ND strict packets not being pushed again
+in the packet taps. This changed with commit 205704c618af[2] for those
+packets having a source LLA, as they need a lookup with the orig_iif.
+
+The issue now is those packets do not skip the 'vrf_ip6_rcv' function to
+the end (as the ones without a source LLA) and go through the check to
+call packet taps again. This check was changed by commit 6f12fa775530[1]
+and do not exclude non-strict packets anymore. Packets matching
+'need_strict && !is_ndisc && is_ll_src' are now being sent through the
+packet taps again. This can be seen by dumping packets on the vrf
+interface.
+
+Fix this by having the same code path for all non-ND strict packets and
+selectively lookup with the orig_iif for those with a source LLA. This
+has the effect to revert to the pre-205704c618af[2] condition, which
+should also be easier to maintain.
+
+[1] 6f12fa775530 ("vrf: mark skb for multicast or link-local as enslaved to VRF")
+[2] 205704c618af ("vrf: packets with lladdr src needs dst at input with orig_iif when needs strict")
+
+Fixes: 205704c618af ("vrf: packets with lladdr src needs dst at input with orig_iif when needs strict")
+Cc: Stephen Suryaputra <ssuryaextr@gmail.com>
+Reported-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Antoine Tenart <atenart@kernel.org>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vrf.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
+index 28a6c4cfe9b8..414afcb0a23f 100644
+--- a/drivers/net/vrf.c
++++ b/drivers/net/vrf.c
+@@ -1366,22 +1366,22 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
+ int orig_iif = skb->skb_iif;
+ bool need_strict = rt6_need_strict(&ipv6_hdr(skb)->daddr);
+ bool is_ndisc = ipv6_ndisc_frame(skb);
+- bool is_ll_src;
+
+ /* loopback, multicast & non-ND link-local traffic; do not push through
+ * packet taps again. Reset pkt_type for upper layers to process skb.
+- * for packets with lladdr src, however, skip so that the dst can be
+- * determine at input using original ifindex in the case that daddr
+- * needs strict
++ * For strict packets with a source LLA, determine the dst using the
++ * original ifindex.
+ */
+- is_ll_src = ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL;
+- if (skb->pkt_type == PACKET_LOOPBACK ||
+- (need_strict && !is_ndisc && !is_ll_src)) {
++ if (skb->pkt_type == PACKET_LOOPBACK || (need_strict && !is_ndisc)) {
+ skb->dev = vrf_dev;
+ skb->skb_iif = vrf_dev->ifindex;
+ IP6CB(skb)->flags |= IP6SKB_L3SLAVE;
++
+ if (skb->pkt_type == PACKET_LOOPBACK)
+ skb->pkt_type = PACKET_HOST;
++ else if (ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)
++ vrf_ip6_input_dst(skb, vrf_dev, orig_iif);
++
+ goto out;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 9a710d81b2d7fdbe89c1ae9daf88af9379efb187 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Jun 2021 07:44:17 -0700
+Subject: vxlan: add missing rcu_read_lock() in neigh_reduce()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 85e8b032d6ebb0f698a34dd22c2f13443d905888 ]
+
+syzbot complained in neigh_reduce(), because rcu_read_lock_bh()
+is treated differently than rcu_read_lock()
+
+WARNING: suspicious RCU usage
+5.13.0-rc6-syzkaller #0 Not tainted
+-----------------------------
+include/net/addrconf.h:313 suspicious rcu_dereference_check() usage!
+
+other info that might help us debug this:
+
+rcu_scheduler_active = 2, debug_locks = 1
+3 locks held by kworker/0:0/5:
+ #0: ffff888011064d38 ((wq_completion)events){+.+.}-{0:0}, at: arch_atomic64_set arch/x86/include/asm/atomic64_64.h:34 [inline]
+ #0: ffff888011064d38 ((wq_completion)events){+.+.}-{0:0}, at: atomic64_set include/asm-generic/atomic-instrumented.h:856 [inline]
+ #0: ffff888011064d38 ((wq_completion)events){+.+.}-{0:0}, at: atomic_long_set include/asm-generic/atomic-long.h:41 [inline]
+ #0: ffff888011064d38 ((wq_completion)events){+.+.}-{0:0}, at: set_work_data kernel/workqueue.c:617 [inline]
+ #0: ffff888011064d38 ((wq_completion)events){+.+.}-{0:0}, at: set_work_pool_and_clear_pending kernel/workqueue.c:644 [inline]
+ #0: ffff888011064d38 ((wq_completion)events){+.+.}-{0:0}, at: process_one_work+0x871/0x1600 kernel/workqueue.c:2247
+ #1: ffffc90000ca7da8 ((work_completion)(&port->wq)){+.+.}-{0:0}, at: process_one_work+0x8a5/0x1600 kernel/workqueue.c:2251
+ #2: ffffffff8bf795c0 (rcu_read_lock_bh){....}-{1:2}, at: __dev_queue_xmit+0x1da/0x3130 net/core/dev.c:4180
+
+stack backtrace:
+CPU: 0 PID: 5 Comm: kworker/0:0 Not tainted 5.13.0-rc6-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Workqueue: events ipvlan_process_multicast
+Call Trace:
+ __dump_stack lib/dump_stack.c:79 [inline]
+ dump_stack+0x141/0x1d7 lib/dump_stack.c:120
+ __in6_dev_get include/net/addrconf.h:313 [inline]
+ __in6_dev_get include/net/addrconf.h:311 [inline]
+ neigh_reduce drivers/net/vxlan.c:2167 [inline]
+ vxlan_xmit+0x34d5/0x4c30 drivers/net/vxlan.c:2919
+ __netdev_start_xmit include/linux/netdevice.h:4944 [inline]
+ netdev_start_xmit include/linux/netdevice.h:4958 [inline]
+ xmit_one net/core/dev.c:3654 [inline]
+ dev_hard_start_xmit+0x1eb/0x920 net/core/dev.c:3670
+ __dev_queue_xmit+0x2133/0x3130 net/core/dev.c:4246
+ ipvlan_process_multicast+0xa99/0xd70 drivers/net/ipvlan/ipvlan_core.c:287
+ process_one_work+0x98d/0x1600 kernel/workqueue.c:2276
+ worker_thread+0x64c/0x1120 kernel/workqueue.c:2422
+ kthread+0x3b1/0x4a0 kernel/kthread.c:313
+ ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:294
+
+Fixes: f564f45c4518 ("vxlan: add ipv6 proxy support")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vxlan.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
+index 02a14f1b938a..5a8df5a195cb 100644
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -2164,6 +2164,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
+ struct neighbour *n;
+ struct nd_msg *msg;
+
++ rcu_read_lock();
+ in6_dev = __in6_dev_get(dev);
+ if (!in6_dev)
+ goto out;
+@@ -2215,6 +2216,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
+ }
+
+ out:
++ rcu_read_unlock();
+ consume_skb(skb);
+ return NETDEV_TX_OK;
+ }
+--
+2.30.2
+
--- /dev/null
+From 375bb4c17ff9abcd9137b103a0799d7c171ee9ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Jun 2021 18:33:47 +0100
+Subject: wcn36xx: Move hal_buf allocation to devm_kmalloc in probe
+
+From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+[ Upstream commit ef48667557c53d4b51a1ee3090eab7699324c9de ]
+
+Right now wcn->hal_buf is allocated in wcn36xx_start(). This is a problem
+since we should have setup all of the buffers we required by the time
+ieee80211_register_hw() is called.
+
+struct ieee80211_ops callbacks may run prior to mac_start() and therefore
+wcn->hal_buf must be initialized.
+
+This is easily remediated by moving the allocation to probe() taking the
+opportunity to tidy up freeing memory by using devm_kmalloc().
+
+Fixes: 8e84c2582169 ("wcn36xx: mac80211 driver for Qualcomm WCN3660/WCN3680 hardware")
+Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210605173347.2266003-1-bryan.odonoghue@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/wcn36xx/main.c | 21 ++++++++-------------
+ 1 file changed, 8 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
+index afb4877eaad8..dabed4e3ca45 100644
+--- a/drivers/net/wireless/ath/wcn36xx/main.c
++++ b/drivers/net/wireless/ath/wcn36xx/main.c
+@@ -293,23 +293,16 @@ static int wcn36xx_start(struct ieee80211_hw *hw)
+ goto out_free_dxe_pool;
+ }
+
+- wcn->hal_buf = kmalloc(WCN36XX_HAL_BUF_SIZE, GFP_KERNEL);
+- if (!wcn->hal_buf) {
+- wcn36xx_err("Failed to allocate smd buf\n");
+- ret = -ENOMEM;
+- goto out_free_dxe_ctl;
+- }
+-
+ ret = wcn36xx_smd_load_nv(wcn);
+ if (ret) {
+ wcn36xx_err("Failed to push NV to chip\n");
+- goto out_free_smd_buf;
++ goto out_free_dxe_ctl;
+ }
+
+ ret = wcn36xx_smd_start(wcn);
+ if (ret) {
+ wcn36xx_err("Failed to start chip\n");
+- goto out_free_smd_buf;
++ goto out_free_dxe_ctl;
+ }
+
+ if (!wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) {
+@@ -336,8 +329,6 @@ static int wcn36xx_start(struct ieee80211_hw *hw)
+
+ out_smd_stop:
+ wcn36xx_smd_stop(wcn);
+-out_free_smd_buf:
+- kfree(wcn->hal_buf);
+ out_free_dxe_ctl:
+ wcn36xx_dxe_free_ctl_blks(wcn);
+ out_free_dxe_pool:
+@@ -372,8 +363,6 @@ static void wcn36xx_stop(struct ieee80211_hw *hw)
+
+ wcn36xx_dxe_free_mem_pools(wcn);
+ wcn36xx_dxe_free_ctl_blks(wcn);
+-
+- kfree(wcn->hal_buf);
+ }
+
+ static void wcn36xx_change_ps(struct wcn36xx *wcn, bool enable)
+@@ -1401,6 +1390,12 @@ static int wcn36xx_probe(struct platform_device *pdev)
+ mutex_init(&wcn->hal_mutex);
+ mutex_init(&wcn->scan_lock);
+
++ wcn->hal_buf = devm_kmalloc(wcn->dev, WCN36XX_HAL_BUF_SIZE, GFP_KERNEL);
++ if (!wcn->hal_buf) {
++ ret = -ENOMEM;
++ goto out_wq;
++ }
++
+ ret = dma_set_mask_and_coherent(wcn->dev, DMA_BIT_MASK(32));
+ if (ret < 0) {
+ wcn36xx_err("failed to set DMA mask: %d\n", ret);
+--
+2.30.2
+
--- /dev/null
+From 3c85aceb16cf2dfcfad717f03e6d309bddc50b22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Apr 2021 21:29:30 +0200
+Subject: wil6210: remove erroneous wiphy locking
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 8f78caa2264ece71c2e207cba023f28ab6665138 ]
+
+We already hold the wiphy lock in all cases when we get
+here, so this would deadlock, remove the erroneous locking.
+
+Fixes: a05829a7222e ("cfg80211: avoid holding the RTNL when calling the driver")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210426212929.83f1de07c2cd.I630a2a00eff185ba0452324b3d3f645e01128a95@changeid
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/wil6210/cfg80211.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
+index 6746fd206d2a..1ff2679963f0 100644
+--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
++++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
+@@ -2842,9 +2842,7 @@ void wil_p2p_wdev_free(struct wil6210_priv *wil)
+ wil->radio_wdev = wil->main_ndev->ieee80211_ptr;
+ mutex_unlock(&wil->vif_mutex);
+ if (p2p_wdev) {
+- wiphy_lock(wil->wiphy);
+ cfg80211_unregister_wdev(p2p_wdev);
+- wiphy_unlock(wil->wiphy);
+ kfree(p2p_wdev);
+ }
+ }
+--
+2.30.2
+
--- /dev/null
+From 97c6d4a39115663ead2bc06c2c2f95ce1167703c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 May 2021 17:41:28 +0300
+Subject: wireless: carl9170: fix LEDS build errors & warnings
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 272fdc0c4542fad173b44965be02a16d6db95499 ]
+
+kernel test robot reports over 200 build errors and warnings
+that are due to this Kconfig problem when CARL9170=m,
+MAC80211=y, and LEDS_CLASS=m.
+
+WARNING: unmet direct dependencies detected for MAC80211_LEDS
+ Depends on [n]: NET [=y] && WIRELESS [=y] && MAC80211 [=y] && (LEDS_CLASS [=m]=y || LEDS_CLASS [=m]=MAC80211 [=y])
+ Selected by [m]:
+ - CARL9170_LEDS [=y] && NETDEVICES [=y] && WLAN [=y] && WLAN_VENDOR_ATH [=y] && CARL9170 [=m]
+
+CARL9170_LEDS selects MAC80211_LEDS even though its kconfig
+dependencies are not met. This happens because 'select' does not follow
+any Kconfig dependency chains.
+
+Fix this by making CARL9170_LEDS depend on MAC80211_LEDS, where
+the latter supplies any needed dependencies on LEDS_CLASS.
+
+Fixes: 1d7e1e6b1b8ed ("carl9170: Makefile, Kconfig files and MAINTAINERS")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Reported-by: kernel test robot <lkp@intel.com>
+Cc: Kalle Valo <kvalo@codeaurora.org>
+Cc: Christian Lamparter <chunkeey@googlemail.com>
+Cc: linux-wireless@vger.kernel.org
+Cc: Arnd Bergmann <arnd@arndb.de>
+Suggested-by: Christian Lamparter <chunkeey@googlemail.com>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20210530031134.23274-1-rdunlap@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/carl9170/Kconfig | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/carl9170/Kconfig b/drivers/net/wireless/ath/carl9170/Kconfig
+index b2d760873992..ba9bea79381c 100644
+--- a/drivers/net/wireless/ath/carl9170/Kconfig
++++ b/drivers/net/wireless/ath/carl9170/Kconfig
+@@ -16,13 +16,11 @@ config CARL9170
+
+ config CARL9170_LEDS
+ bool "SoftLED Support"
+- depends on CARL9170
+- select MAC80211_LEDS
+- select LEDS_CLASS
+- select NEW_LEDS
+ default y
++ depends on CARL9170
++ depends on MAC80211_LEDS
+ help
+- This option is necessary, if you want your device' LEDs to blink
++ This option is necessary, if you want your device's LEDs to blink.
+
+ Say Y, unless you need the LEDs for firmware debugging.
+
+--
+2.30.2
+
--- /dev/null
+From 8f819edfb89d8ee518737d7160a6993209c3a63f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jun 2021 19:35:47 -0700
+Subject: writeback, cgroup: increment isw_nr_in_flight before grabbing an
+ inode
+
+From: Roman Gushchin <guro@fb.com>
+
+[ Upstream commit 8826ee4fe75051f8cbfa5d4a9aa70565938e724c ]
+
+isw_nr_in_flight is used to determine whether the inode switch queue
+should be flushed from the umount path. Currently it's increased after
+grabbing an inode and even scheduling the switch work. It means the
+umount path can walk past cleanup_offline_cgwb() with active inode
+references, which can result in a "Busy inodes after unmount." message and
+use-after-free issues (with inode->i_sb which gets freed).
+
+Fix it by incrementing isw_nr_in_flight before doing anything with the
+inode and decrementing in the case when switching wasn't scheduled.
+
+The problem hasn't yet been seen in the real life and was discovered by
+Jan Kara by looking into the code.
+
+Link: https://lkml.kernel.org/r/20210608230225.2078447-4-guro@fb.com
+Signed-off-by: Roman Gushchin <guro@fb.com>
+Suggested-by: Jan Kara <jack@suse.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Cc: Alexander Viro <viro@zeniv.linux.org.uk>
+Cc: Dave Chinner <dchinner@redhat.com>
+Cc: Dennis Zhou <dennis@kernel.org>
+Cc: Tejun Heo <tj@kernel.org>
+Cc: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fs-writeback.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index 7c46d1588a19..d684f541af48 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -505,6 +505,8 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
+ if (!isw)
+ return;
+
++ atomic_inc(&isw_nr_in_flight);
++
+ /* find and pin the new wb */
+ rcu_read_lock();
+ memcg_css = css_from_id(new_wb_id, &memory_cgrp_subsys);
+@@ -535,11 +537,10 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
+ * Let's continue after I_WB_SWITCH is guaranteed to be visible.
+ */
+ call_rcu(&isw->rcu_head, inode_switch_wbs_rcu_fn);
+-
+- atomic_inc(&isw_nr_in_flight);
+ return;
+
+ out_free:
++ atomic_dec(&isw_nr_in_flight);
+ if (isw->new_wb)
+ wb_put(isw->new_wb);
+ kfree(isw);
+--
+2.30.2
+
--- /dev/null
+From c13601636aa5f3bdf970d85dac884726b98df3de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Apr 2021 17:11:45 +0800
+Subject: writeback: fix obtain a reference to a freeing memcg css
+
+From: Muchun Song <songmuchun@bytedance.com>
+
+[ Upstream commit 8b0ed8443ae6458786580d36b7d5f8125535c5d4 ]
+
+The caller of wb_get_create() should pin the memcg, because
+wb_get_create() relies on this guarantee. The rcu read lock
+only can guarantee that the memcg css returned by css_from_id()
+cannot be released, but the reference of the memcg can be zero.
+
+ rcu_read_lock()
+ memcg_css = css_from_id()
+ wb_get_create(memcg_css)
+ cgwb_create(memcg_css)
+ // css_get can change the ref counter from 0 back to 1
+ css_get(memcg_css)
+ rcu_read_unlock()
+
+Fix it by holding a reference to the css before calling
+wb_get_create(). This is not a problem I encountered in the
+real world. Just the result of a code review.
+
+Fixes: 682aa8e1a6a1 ("writeback: implement unlocked_inode_to_wb transaction and use it for stat updates")
+Link: https://lore.kernel.org/r/20210402091145.80635-1-songmuchun@bytedance.com
+Signed-off-by: Muchun Song <songmuchun@bytedance.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Acked-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fs-writeback.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index d684f541af48..8d4130b01423 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -510,9 +510,14 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
+ /* find and pin the new wb */
+ rcu_read_lock();
+ memcg_css = css_from_id(new_wb_id, &memory_cgrp_subsys);
+- if (memcg_css)
+- isw->new_wb = wb_get_create(bdi, memcg_css, GFP_ATOMIC);
++ if (memcg_css && !css_tryget(memcg_css))
++ memcg_css = NULL;
+ rcu_read_unlock();
++ if (!memcg_css)
++ goto out_free;
++
++ isw->new_wb = wb_get_create(bdi, memcg_css, GFP_ATOMIC);
++ css_put(memcg_css);
+ if (!isw->new_wb)
+ goto out_free;
+
+--
+2.30.2
+
--- /dev/null
+From 98402e51ecd7ab65e0cc583321cfbbf2da264a94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 May 2021 01:58:42 -0700
+Subject: x86/elf: Use _BITUL() macro in UAPI headers
+
+From: Joe Richey <joerichey@google.com>
+
+[ Upstream commit d06aca989c243dd9e5d3e20aa4e5c2ecfdd07050 ]
+
+Replace BIT() in x86's UAPI header with _BITUL(). BIT() is not defined
+in the UAPI headers and its usage may cause userspace build errors.
+
+Fixes: 742c45c3ecc9 ("x86/elf: Enumerate kernel FSGSBASE capability in AT_HWCAP2")
+Signed-off-by: Joe Richey <joerichey@google.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Link: https://lkml.kernel.org/r/20210521085849.37676-2-joerichey94@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/uapi/asm/hwcap2.h | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/include/uapi/asm/hwcap2.h b/arch/x86/include/uapi/asm/hwcap2.h
+index 5fdfcb47000f..054604aba9f0 100644
+--- a/arch/x86/include/uapi/asm/hwcap2.h
++++ b/arch/x86/include/uapi/asm/hwcap2.h
+@@ -2,10 +2,12 @@
+ #ifndef _ASM_X86_HWCAP2_H
+ #define _ASM_X86_HWCAP2_H
+
++#include <linux/const.h>
++
+ /* MONITOR/MWAIT enabled in Ring 3 */
+-#define HWCAP2_RING3MWAIT (1 << 0)
++#define HWCAP2_RING3MWAIT _BITUL(0)
+
+ /* Kernel allows FSGSBASE instructions available in Ring 3 */
+-#define HWCAP2_FSGSBASE BIT(1)
++#define HWCAP2_FSGSBASE _BITUL(1)
+
+ #endif
+--
+2.30.2
+
--- /dev/null
+From 5e8fc6714a1aa2dbd7fe27a098778c1f00b4a7a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 May 2021 13:10:46 +0530
+Subject: x86/hyperv: fix logical processor creation
+
+From: Praveen Kumar <kumarpraveen@linux.microsoft.com>
+
+[ Upstream commit 450605c28d571eddca39a65fdbc1338add44c6d9 ]
+
+Microsoft Hypervisor expects the logical processor index to be the same
+as CPU's index during logical processor creation. Using cpu_physical_id
+confuses hypervisor's scheduler. That causes the root partition not boot
+when core scheduler is used.
+
+This patch removes the call to cpu_physical_id and uses the CPU index
+directly for bringing up logical processor. This scheme works for both
+classic scheduler and core scheduler.
+
+Fixes: 333abaf5abb3 (x86/hyperv: implement and use hv_smp_prepare_cpus)
+Signed-off-by: Praveen Kumar <kumarpraveen@linux.microsoft.com>
+Link: https://lore.kernel.org/r/20210531074046.113452-1-kumarpraveen@linux.microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/mshyperv.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
+index 22f13343b5da..4fa0a4280895 100644
+--- a/arch/x86/kernel/cpu/mshyperv.c
++++ b/arch/x86/kernel/cpu/mshyperv.c
+@@ -236,7 +236,7 @@ static void __init hv_smp_prepare_cpus(unsigned int max_cpus)
+ for_each_present_cpu(i) {
+ if (i == 0)
+ continue;
+- ret = hv_call_add_logical_proc(numa_cpu_node(i), i, cpu_physical_id(i));
++ ret = hv_call_add_logical_proc(numa_cpu_node(i), i, i);
+ BUG_ON(ret);
+ }
+
+--
+2.30.2
+
--- /dev/null
+From a02f2b582f1153453347d8252f2d26f86645fa9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 13:54:08 +0200
+Subject: x86/sev: Make sure IRQs are disabled while GHCB is active
+
+From: Joerg Roedel <jroedel@suse.de>
+
+[ Upstream commit d187f217335dba2b49fc9002aab2004e04acddee ]
+
+The #VC handler only cares about IRQs being disabled while the GHCB is
+active, as it must not be interrupted by something which could cause
+another #VC while it holds the GHCB (NMI is the exception for which the
+backup GHCB exits).
+
+Make sure nothing interrupts the code path while the GHCB is active
+by making sure that callers of __sev_{get,put}_ghcb() have disabled
+interrupts upfront.
+
+ [ bp: Massage commit message. ]
+
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20210618115409.22735-2-joro@8bytes.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/sev.c | 34 ++++++++++++++++++++++------------
+ 1 file changed, 22 insertions(+), 12 deletions(-)
+
+diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
+index 651b81cd648e..396d578043d1 100644
+--- a/arch/x86/kernel/sev.c
++++ b/arch/x86/kernel/sev.c
+@@ -12,7 +12,6 @@
+ #include <linux/sched/debug.h> /* For show_regs() */
+ #include <linux/percpu-defs.h>
+ #include <linux/mem_encrypt.h>
+-#include <linux/lockdep.h>
+ #include <linux/printk.h>
+ #include <linux/mm_types.h>
+ #include <linux/set_memory.h>
+@@ -192,11 +191,19 @@ void noinstr __sev_es_ist_exit(void)
+ this_cpu_write(cpu_tss_rw.x86_tss.ist[IST_INDEX_VC], *(unsigned long *)ist);
+ }
+
+-static __always_inline struct ghcb *sev_es_get_ghcb(struct ghcb_state *state)
++/*
++ * Nothing shall interrupt this code path while holding the per-CPU
++ * GHCB. The backup GHCB is only for NMIs interrupting this path.
++ *
++ * Callers must disable local interrupts around it.
++ */
++static noinstr struct ghcb *__sev_get_ghcb(struct ghcb_state *state)
+ {
+ struct sev_es_runtime_data *data;
+ struct ghcb *ghcb;
+
++ WARN_ON(!irqs_disabled());
++
+ data = this_cpu_read(runtime_data);
+ ghcb = &data->ghcb_page;
+
+@@ -213,7 +220,9 @@ static __always_inline struct ghcb *sev_es_get_ghcb(struct ghcb_state *state)
+ data->ghcb_active = false;
+ data->backup_ghcb_active = false;
+
++ instrumentation_begin();
+ panic("Unable to handle #VC exception! GHCB and Backup GHCB are already in use");
++ instrumentation_end();
+ }
+
+ /* Mark backup_ghcb active before writing to it */
+@@ -479,11 +488,13 @@ static enum es_result vc_slow_virt_to_phys(struct ghcb *ghcb, struct es_em_ctxt
+ /* Include code shared with pre-decompression boot stage */
+ #include "sev-shared.c"
+
+-static __always_inline void sev_es_put_ghcb(struct ghcb_state *state)
++static noinstr void __sev_put_ghcb(struct ghcb_state *state)
+ {
+ struct sev_es_runtime_data *data;
+ struct ghcb *ghcb;
+
++ WARN_ON(!irqs_disabled());
++
+ data = this_cpu_read(runtime_data);
+ ghcb = &data->ghcb_page;
+
+@@ -507,7 +518,7 @@ void noinstr __sev_es_nmi_complete(void)
+ struct ghcb_state state;
+ struct ghcb *ghcb;
+
+- ghcb = sev_es_get_ghcb(&state);
++ ghcb = __sev_get_ghcb(&state);
+
+ vc_ghcb_invalidate(ghcb);
+ ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_NMI_COMPLETE);
+@@ -517,7 +528,7 @@ void noinstr __sev_es_nmi_complete(void)
+ sev_es_wr_ghcb_msr(__pa_nodebug(ghcb));
+ VMGEXIT();
+
+- sev_es_put_ghcb(&state);
++ __sev_put_ghcb(&state);
+ }
+
+ static u64 get_jump_table_addr(void)
+@@ -529,7 +540,7 @@ static u64 get_jump_table_addr(void)
+
+ local_irq_save(flags);
+
+- ghcb = sev_es_get_ghcb(&state);
++ ghcb = __sev_get_ghcb(&state);
+
+ vc_ghcb_invalidate(ghcb);
+ ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_AP_JUMP_TABLE);
+@@ -543,7 +554,7 @@ static u64 get_jump_table_addr(void)
+ ghcb_sw_exit_info_2_is_valid(ghcb))
+ ret = ghcb->save.sw_exit_info_2;
+
+- sev_es_put_ghcb(&state);
++ __sev_put_ghcb(&state);
+
+ local_irq_restore(flags);
+
+@@ -668,7 +679,7 @@ static void sev_es_ap_hlt_loop(void)
+ struct ghcb_state state;
+ struct ghcb *ghcb;
+
+- ghcb = sev_es_get_ghcb(&state);
++ ghcb = __sev_get_ghcb(&state);
+
+ while (true) {
+ vc_ghcb_invalidate(ghcb);
+@@ -685,7 +696,7 @@ static void sev_es_ap_hlt_loop(void)
+ break;
+ }
+
+- sev_es_put_ghcb(&state);
++ __sev_put_ghcb(&state);
+ }
+
+ /*
+@@ -1344,7 +1355,6 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication)
+ }
+
+ irq_state = irqentry_nmi_enter(regs);
+- lockdep_assert_irqs_disabled();
+ instrumentation_begin();
+
+ /*
+@@ -1353,7 +1363,7 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication)
+ * keep the IRQs disabled to protect us against concurrent TLB flushes.
+ */
+
+- ghcb = sev_es_get_ghcb(&state);
++ ghcb = __sev_get_ghcb(&state);
+
+ vc_ghcb_invalidate(ghcb);
+ result = vc_init_em_ctxt(&ctxt, regs, error_code);
+@@ -1361,7 +1371,7 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication)
+ if (result == ES_OK)
+ result = vc_handle_exitcode(&ctxt, ghcb, error_code);
+
+- sev_es_put_ghcb(&state);
++ __sev_put_ghcb(&state);
+
+ /* Done - now check the result */
+ switch (result) {
+--
+2.30.2
+
--- /dev/null
+From f26aff1831acfe611fc7d547ad189702cc2a37f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 13:54:09 +0200
+Subject: x86/sev: Split up runtime #VC handler for correct state tracking
+
+From: Joerg Roedel <jroedel@suse.de>
+
+[ Upstream commit be1a5408868af341f61f93c191b5e346ee88c82a ]
+
+Split up the #VC handler code into a from-user and a from-kernel part.
+This allows clean and correct state tracking, as the #VC handler needs
+to enter NMI-state when raised from kernel mode and plain IRQ state when
+raised from user-mode.
+
+Fixes: 62441a1fb532 ("x86/sev-es: Correctly track IRQ states in runtime #VC handler")
+Suggested-by: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20210618115409.22735-3-joro@8bytes.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/entry/entry_64.S | 4 +-
+ arch/x86/include/asm/idtentry.h | 29 +++----
+ arch/x86/kernel/sev.c | 148 +++++++++++++++++---------------
+ 3 files changed, 91 insertions(+), 90 deletions(-)
+
+diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
+index a16a5294d55f..1886aaf19914 100644
+--- a/arch/x86/entry/entry_64.S
++++ b/arch/x86/entry/entry_64.S
+@@ -506,7 +506,7 @@ SYM_CODE_START(\asmsym)
+
+ movq %rsp, %rdi /* pt_regs pointer */
+
+- call \cfunc
++ call kernel_\cfunc
+
+ /*
+ * No need to switch back to the IST stack. The current stack is either
+@@ -517,7 +517,7 @@ SYM_CODE_START(\asmsym)
+
+ /* Switch to the regular task stack */
+ .Lfrom_usermode_switch_stack_\@:
+- idtentry_body safe_stack_\cfunc, has_error_code=1
++ idtentry_body user_\cfunc, has_error_code=1
+
+ _ASM_NOKPROBE(\asmsym)
+ SYM_CODE_END(\asmsym)
+diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h
+index 73d45b0dfff2..cd9f3e304944 100644
+--- a/arch/x86/include/asm/idtentry.h
++++ b/arch/x86/include/asm/idtentry.h
+@@ -312,8 +312,8 @@ static __always_inline void __##func(struct pt_regs *regs)
+ */
+ #define DECLARE_IDTENTRY_VC(vector, func) \
+ DECLARE_IDTENTRY_RAW_ERRORCODE(vector, func); \
+- __visible noinstr void ist_##func(struct pt_regs *regs, unsigned long error_code); \
+- __visible noinstr void safe_stack_##func(struct pt_regs *regs, unsigned long error_code)
++ __visible noinstr void kernel_##func(struct pt_regs *regs, unsigned long error_code); \
++ __visible noinstr void user_##func(struct pt_regs *regs, unsigned long error_code)
+
+ /**
+ * DEFINE_IDTENTRY_IST - Emit code for IST entry points
+@@ -355,33 +355,24 @@ static __always_inline void __##func(struct pt_regs *regs)
+ DEFINE_IDTENTRY_RAW_ERRORCODE(func)
+
+ /**
+- * DEFINE_IDTENTRY_VC_SAFE_STACK - Emit code for VMM communication handler
+- which runs on a safe stack.
++ * DEFINE_IDTENTRY_VC_KERNEL - Emit code for VMM communication handler
++ when raised from kernel mode
+ * @func: Function name of the entry point
+ *
+ * Maps to DEFINE_IDTENTRY_RAW_ERRORCODE
+ */
+-#define DEFINE_IDTENTRY_VC_SAFE_STACK(func) \
+- DEFINE_IDTENTRY_RAW_ERRORCODE(safe_stack_##func)
++#define DEFINE_IDTENTRY_VC_KERNEL(func) \
++ DEFINE_IDTENTRY_RAW_ERRORCODE(kernel_##func)
+
+ /**
+- * DEFINE_IDTENTRY_VC_IST - Emit code for VMM communication handler
+- which runs on the VC fall-back stack
++ * DEFINE_IDTENTRY_VC_USER - Emit code for VMM communication handler
++ when raised from user mode
+ * @func: Function name of the entry point
+ *
+ * Maps to DEFINE_IDTENTRY_RAW_ERRORCODE
+ */
+-#define DEFINE_IDTENTRY_VC_IST(func) \
+- DEFINE_IDTENTRY_RAW_ERRORCODE(ist_##func)
+-
+-/**
+- * DEFINE_IDTENTRY_VC - Emit code for VMM communication handler
+- * @func: Function name of the entry point
+- *
+- * Maps to DEFINE_IDTENTRY_RAW_ERRORCODE
+- */
+-#define DEFINE_IDTENTRY_VC(func) \
+- DEFINE_IDTENTRY_RAW_ERRORCODE(func)
++#define DEFINE_IDTENTRY_VC_USER(func) \
++ DEFINE_IDTENTRY_RAW_ERRORCODE(user_##func)
+
+ #else /* CONFIG_X86_64 */
+
+diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
+index 396d578043d1..f4641d8ee6a7 100644
+--- a/arch/x86/kernel/sev.c
++++ b/arch/x86/kernel/sev.c
+@@ -786,7 +786,7 @@ void __init sev_es_init_vc_handling(void)
+ sev_es_setup_play_dead();
+
+ /* Secondary CPUs use the runtime #VC handler */
+- initial_vc_handler = (unsigned long)safe_stack_exc_vmm_communication;
++ initial_vc_handler = (unsigned long)kernel_exc_vmm_communication;
+ }
+
+ static void __init vc_early_forward_exception(struct es_em_ctxt *ctxt)
+@@ -1224,14 +1224,6 @@ static enum es_result vc_handle_trap_ac(struct ghcb *ghcb,
+ return ES_EXCEPTION;
+ }
+
+-static __always_inline void vc_handle_trap_db(struct pt_regs *regs)
+-{
+- if (user_mode(regs))
+- noist_exc_debug(regs);
+- else
+- exc_debug(regs);
+-}
+-
+ static enum es_result vc_handle_exitcode(struct es_em_ctxt *ctxt,
+ struct ghcb *ghcb,
+ unsigned long exit_code)
+@@ -1327,41 +1319,13 @@ static __always_inline bool on_vc_fallback_stack(struct pt_regs *regs)
+ return (sp >= __this_cpu_ist_bottom_va(VC2) && sp < __this_cpu_ist_top_va(VC2));
+ }
+
+-/*
+- * Main #VC exception handler. It is called when the entry code was able to
+- * switch off the IST to a safe kernel stack.
+- *
+- * With the current implementation it is always possible to switch to a safe
+- * stack because #VC exceptions only happen at known places, like intercepted
+- * instructions or accesses to MMIO areas/IO ports. They can also happen with
+- * code instrumentation when the hypervisor intercepts #DB, but the critical
+- * paths are forbidden to be instrumented, so #DB exceptions currently also
+- * only happen in safe places.
+- */
+-DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication)
++static bool vc_raw_handle_exception(struct pt_regs *regs, unsigned long error_code)
+ {
+- irqentry_state_t irq_state;
+ struct ghcb_state state;
+ struct es_em_ctxt ctxt;
+ enum es_result result;
+ struct ghcb *ghcb;
+-
+- /*
+- * Handle #DB before calling into !noinstr code to avoid recursive #DB.
+- */
+- if (error_code == SVM_EXIT_EXCP_BASE + X86_TRAP_DB) {
+- vc_handle_trap_db(regs);
+- return;
+- }
+-
+- irq_state = irqentry_nmi_enter(regs);
+- instrumentation_begin();
+-
+- /*
+- * This is invoked through an interrupt gate, so IRQs are disabled. The
+- * code below might walk page-tables for user or kernel addresses, so
+- * keep the IRQs disabled to protect us against concurrent TLB flushes.
+- */
++ bool ret = true;
+
+ ghcb = __sev_get_ghcb(&state);
+
+@@ -1381,15 +1345,18 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication)
+ case ES_UNSUPPORTED:
+ pr_err_ratelimited("Unsupported exit-code 0x%02lx in early #VC exception (IP: 0x%lx)\n",
+ error_code, regs->ip);
+- goto fail;
++ ret = false;
++ break;
+ case ES_VMM_ERROR:
+ pr_err_ratelimited("Failure in communication with VMM (exit-code 0x%02lx IP: 0x%lx)\n",
+ error_code, regs->ip);
+- goto fail;
++ ret = false;
++ break;
+ case ES_DECODE_FAILED:
+ pr_err_ratelimited("Failed to decode instruction (exit-code 0x%02lx IP: 0x%lx)\n",
+ error_code, regs->ip);
+- goto fail;
++ ret = false;
++ break;
+ case ES_EXCEPTION:
+ vc_forward_exception(&ctxt);
+ break;
+@@ -1405,24 +1372,52 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication)
+ BUG();
+ }
+
+-out:
+- instrumentation_end();
+- irqentry_nmi_exit(regs, irq_state);
++ return ret;
++}
+
+- return;
++static __always_inline bool vc_is_db(unsigned long error_code)
++{
++ return error_code == SVM_EXIT_EXCP_BASE + X86_TRAP_DB;
++}
+
+-fail:
+- if (user_mode(regs)) {
+- /*
+- * Do not kill the machine if user-space triggered the
+- * exception. Send SIGBUS instead and let user-space deal with
+- * it.
+- */
+- force_sig_fault(SIGBUS, BUS_OBJERR, (void __user *)0);
+- } else {
+- pr_emerg("PANIC: Unhandled #VC exception in kernel space (result=%d)\n",
+- result);
++/*
++ * Runtime #VC exception handler when raised from kernel mode. Runs in NMI mode
++ * and will panic when an error happens.
++ */
++DEFINE_IDTENTRY_VC_KERNEL(exc_vmm_communication)
++{
++ irqentry_state_t irq_state;
++
++ /*
++ * With the current implementation it is always possible to switch to a
++ * safe stack because #VC exceptions only happen at known places, like
++ * intercepted instructions or accesses to MMIO areas/IO ports. They can
++ * also happen with code instrumentation when the hypervisor intercepts
++ * #DB, but the critical paths are forbidden to be instrumented, so #DB
++ * exceptions currently also only happen in safe places.
++ *
++ * But keep this here in case the noinstr annotations are violated due
++ * to bug elsewhere.
++ */
++ if (unlikely(on_vc_fallback_stack(regs))) {
++ instrumentation_begin();
++ panic("Can't handle #VC exception from unsupported context\n");
++ instrumentation_end();
++ }
++
++ /*
++ * Handle #DB before calling into !noinstr code to avoid recursive #DB.
++ */
++ if (vc_is_db(error_code)) {
++ exc_debug(regs);
++ return;
++ }
++
++ irq_state = irqentry_nmi_enter(regs);
+
++ instrumentation_begin();
++
++ if (!vc_raw_handle_exception(regs, error_code)) {
+ /* Show some debug info */
+ show_regs(regs);
+
+@@ -1433,23 +1428,38 @@ fail:
+ panic("Returned from Terminate-Request to Hypervisor\n");
+ }
+
+- goto out;
++ instrumentation_end();
++ irqentry_nmi_exit(regs, irq_state);
+ }
+
+-/* This handler runs on the #VC fall-back stack. It can cause further #VC exceptions */
+-DEFINE_IDTENTRY_VC_IST(exc_vmm_communication)
++/*
++ * Runtime #VC exception handler when raised from user mode. Runs in IRQ mode
++ * and will kill the current task with SIGBUS when an error happens.
++ */
++DEFINE_IDTENTRY_VC_USER(exc_vmm_communication)
+ {
++ /*
++ * Handle #DB before calling into !noinstr code to avoid recursive #DB.
++ */
++ if (vc_is_db(error_code)) {
++ noist_exc_debug(regs);
++ return;
++ }
++
++ irqentry_enter_from_user_mode(regs);
+ instrumentation_begin();
+- panic("Can't handle #VC exception from unsupported context\n");
+- instrumentation_end();
+-}
+
+-DEFINE_IDTENTRY_VC(exc_vmm_communication)
+-{
+- if (likely(!on_vc_fallback_stack(regs)))
+- safe_stack_exc_vmm_communication(regs, error_code);
+- else
+- ist_exc_vmm_communication(regs, error_code);
++ if (!vc_raw_handle_exception(regs, error_code)) {
++ /*
++ * Do not kill the machine if user-space triggered the
++ * exception. Send SIGBUS instead and let user-space deal with
++ * it.
++ */
++ force_sig_fault(SIGBUS, BUS_OBJERR, (void __user *)0);
++ }
++
++ instrumentation_end();
++ irqentry_exit_to_user_mode(regs);
+ }
+
+ bool __init handle_vc_boot_ghcb(struct pt_regs *regs)
+--
+2.30.2
+
--- /dev/null
+From 718c7124633b6c059636171c5f3d9e60da09746e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 16:48:25 +0200
+Subject: x86/sev: Use "SEV: " prefix for messages from sev.c
+
+From: Joerg Roedel <jroedel@suse.de>
+
+[ Upstream commit 8d9d46bbf3b6b7ff8edcac33603ab45c29e0e07f ]
+
+The source file has been renamed froms sev-es.c to sev.c, but the
+messages are still prefixed with "SEV-ES: ". Change that to "SEV: " to
+make it consistent.
+
+Fixes: e759959fe3b8 ("x86/sev-es: Rename sev-es.{ch} to sev.{ch}")
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Link: https://lkml.kernel.org/r/20210622144825.27588-4-joro@8bytes.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/sev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
+index f4641d8ee6a7..d66a33d24f4f 100644
+--- a/arch/x86/kernel/sev.c
++++ b/arch/x86/kernel/sev.c
+@@ -7,7 +7,7 @@
+ * Author: Joerg Roedel <jroedel@suse.de>
+ */
+
+-#define pr_fmt(fmt) "SEV-ES: " fmt
++#define pr_fmt(fmt) "SEV: " fmt
+
+ #include <linux/sched/debug.h> /* For show_regs() */
+ #include <linux/percpu-defs.h>
+--
+2.30.2
+
--- /dev/null
+From d4cf5b8fb46f55fcf8f565c76d4593c96580d386 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 09:25:31 +0530
+Subject: xfrm: Fix xfrm offload fallback fail case
+
+From: Ayush Sawal <ayush.sawal@chelsio.com>
+
+[ Upstream commit dd72fadf2186fc8a6018f97fe72f4d5ca05df440 ]
+
+In case of xfrm offload, if xdo_dev_state_add() of driver returns
+-EOPNOTSUPP, xfrm offload fallback is failed.
+In xfrm state_add() both xso->dev and xso->real_dev are initialized to
+dev and when err(-EOPNOTSUPP) is returned only xso->dev is set to null.
+
+So in this scenario the condition in func validate_xmit_xfrm(),
+if ((x->xso.dev != dev) && (x->xso.real_dev == dev))
+ return skb;
+returns true, due to which skb is returned without calling esp_xmit()
+below which has fallback code. Hence the CRYPTO_FALLBACK is failing.
+
+So fixing this with by keeping x->xso.real_dev as NULL when err is
+returned in func xfrm_dev_state_add().
+
+Fixes: bdfd2d1fa79a ("bonding/xfrm: use real_dev instead of slave_dev")
+Signed-off-by: Ayush Sawal <ayush.sawal@chelsio.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_device.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
+index 6d6917b68856..e843b0d9e2a6 100644
+--- a/net/xfrm/xfrm_device.c
++++ b/net/xfrm/xfrm_device.c
+@@ -268,6 +268,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
+ xso->num_exthdrs = 0;
+ xso->flags = 0;
+ xso->dev = NULL;
++ xso->real_dev = NULL;
+ dev_put(dev);
+
+ if (err != -EOPNOTSUPP)
+--
+2.30.2
+
--- /dev/null
+From 5efccb2a87228edc76b0212af2f008acfc59033d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 May 2021 16:23:18 -0400
+Subject: xfrm: remove the fragment check for ipv6 beet mode
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit eebd49a4ffb420a991c606e54aa3c9f02857a334 ]
+
+In commit 68dc022d04eb ("xfrm: BEET mode doesn't support fragments
+for inner packets"), it tried to fix the issue that in TX side the
+packet is fragmented before the ESP encapping while in the RX side
+the fragments always get reassembled before decapping with ESP.
+
+This is not true for IPv6. IPv6 is different, and it's using exthdr
+to save fragment info, as well as the ESP info. Exthdrs are added
+in TX and processed in RX both in order. So in the above case, the
+ESP decapping will be done earlier than the fragment reassembling
+in TX side.
+
+Here just remove the fragment check for the IPv6 inner packets to
+recover the fragments support for BEET mode.
+
+Fixes: 68dc022d04eb ("xfrm: BEET mode doesn't support fragments for inner packets")
+Reported-by: Xiumei Mu <xmu@redhat.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_output.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
+index e4cb0ff4dcf4..ac907b9d32d1 100644
+--- a/net/xfrm/xfrm_output.c
++++ b/net/xfrm/xfrm_output.c
+@@ -711,15 +711,8 @@ out:
+ static int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb)
+ {
+ #if IS_ENABLED(CONFIG_IPV6)
+- unsigned int ptr = 0;
+ int err;
+
+- if (x->outer_mode.encap == XFRM_MODE_BEET &&
+- ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL, NULL) >= 0) {
+- net_warn_ratelimited("BEET mode doesn't support inner IPv6 fragments\n");
+- return -EAFNOSUPPORT;
+- }
+-
+ err = xfrm6_tunnel_check_size(skb);
+ if (err)
+ return err;
+--
+2.30.2
+
--- /dev/null
+From de454f51d79dcaa107a86115555e3837c763596d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Apr 2021 11:27:59 +0200
+Subject: xfrm: xfrm_state_mtu should return at least 1280 for ipv6
+
+From: Sabrina Dubroca <sd@queasysnail.net>
+
+[ Upstream commit b515d2637276a3810d6595e10ab02c13bfd0b63a ]
+
+Jianwen reported that IPv6 Interoperability tests are failing in an
+IPsec case where one of the links between the IPsec peers has an MTU
+of 1280. The peer generates a packet larger than this MTU, the router
+replies with a "Packet too big" message indicating an MTU of 1280.
+When the peer tries to send another large packet, xfrm_state_mtu
+returns 1280 - ipsec_overhead, which causes ip6_setup_cork to fail
+with EINVAL.
+
+We can fix this by forcing xfrm_state_mtu to return IPV6_MIN_MTU when
+IPv6 is used. After going through IPsec, the packet will then be
+fragmented to obey the actual network's PMTU, just before leaving the
+host.
+
+Currently, TFC padding is capped to PMTU - overhead to avoid
+fragementation: after padding and encapsulation, we still fit within
+the PMTU. That behavior is preserved in this patch.
+
+Fixes: 91657eafb64b ("xfrm: take net hdr len into account for esp payload size calculation")
+Reported-by: Jianwen Ji <jiji@redhat.com>
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/xfrm.h | 1 +
+ net/ipv4/esp4.c | 2 +-
+ net/ipv6/esp6.c | 2 +-
+ net/xfrm/xfrm_state.c | 14 ++++++++++++--
+ 4 files changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/xfrm.h b/include/net/xfrm.h
+index c58a6d4eb610..6232a5f048bd 100644
+--- a/include/net/xfrm.h
++++ b/include/net/xfrm.h
+@@ -1546,6 +1546,7 @@ void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
+ void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
+ u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
+ int xfrm_init_replay(struct xfrm_state *x);
++u32 __xfrm_state_mtu(struct xfrm_state *x, int mtu);
+ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
+ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload);
+ int xfrm_init_state(struct xfrm_state *x);
+diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
+index 35803ab7ac80..26171dec08c4 100644
+--- a/net/ipv4/esp4.c
++++ b/net/ipv4/esp4.c
+@@ -673,7 +673,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
+ struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
+ u32 padto;
+
+- padto = min(x->tfcpad, xfrm_state_mtu(x, dst->child_mtu_cached));
++ padto = min(x->tfcpad, __xfrm_state_mtu(x, dst->child_mtu_cached));
+ if (skb->len < padto)
+ esp.tfclen = padto - skb->len;
+ }
+diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
+index 393ae2b78e7d..1654e4ce094f 100644
+--- a/net/ipv6/esp6.c
++++ b/net/ipv6/esp6.c
+@@ -708,7 +708,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
+ struct xfrm_dst *dst = (struct xfrm_dst *)skb_dst(skb);
+ u32 padto;
+
+- padto = min(x->tfcpad, xfrm_state_mtu(x, dst->child_mtu_cached));
++ padto = min(x->tfcpad, __xfrm_state_mtu(x, dst->child_mtu_cached));
+ if (skb->len < padto)
+ esp.tfclen = padto - skb->len;
+ }
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index 4496f7efa220..c25586156c6a 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -2518,7 +2518,7 @@ void xfrm_state_delete_tunnel(struct xfrm_state *x)
+ }
+ EXPORT_SYMBOL(xfrm_state_delete_tunnel);
+
+-u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
++u32 __xfrm_state_mtu(struct xfrm_state *x, int mtu)
+ {
+ const struct xfrm_type *type = READ_ONCE(x->type);
+ struct crypto_aead *aead;
+@@ -2549,7 +2549,17 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
+ return ((mtu - x->props.header_len - crypto_aead_authsize(aead) -
+ net_adj) & ~(blksize - 1)) + net_adj - 2;
+ }
+-EXPORT_SYMBOL_GPL(xfrm_state_mtu);
++EXPORT_SYMBOL_GPL(__xfrm_state_mtu);
++
++u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
++{
++ mtu = __xfrm_state_mtu(x, mtu);
++
++ if (x->props.family == AF_INET6 && mtu < IPV6_MIN_MTU)
++ return IPV6_MIN_MTU;
++
++ return mtu;
++}
+
+ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload)
+ {
+--
+2.30.2
+
--- /dev/null
+From 62a8c24d307aa81c1508d3f3ba299c330b45725c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jun 2021 09:58:05 +0200
+Subject: xsk: Fix broken Tx ring validation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Magnus Karlsson <magnus.karlsson@intel.com>
+
+[ Upstream commit f654fae47e83e56b454fbbfd0af0a4f232e356d6 ]
+
+Fix broken Tx ring validation for AF_XDP. The commit under the Fixes
+tag, fixed an off-by-one error in the validation but introduced
+another error. Descriptors are now let through even if they straddle a
+chunk boundary which they are not allowed to do in aligned mode. Worse
+is that they are let through even if they straddle the end of the umem
+itself, tricking the kernel to read data outside the allowed umem
+region which might or might not be mapped at all.
+
+Fix this by reintroducing the old code, but subtract the length by one
+to fix the off-by-one error that the original patch was
+addressing. The test chunk != chunk_end makes sure packets do not
+straddle chunk boundraries. Note that packets of zero length are
+allowed in the interface, therefore the test if the length is
+non-zero.
+
+Fixes: ac31565c2193 ("xsk: Fix for xp_aligned_validate_desc() when len == chunk_size")
+Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
+Acked-by: Björn Töpel <bjorn@kernel.org>
+Link: https://lore.kernel.org/bpf/20210618075805.14412-1-magnus.karlsson@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xdp/xsk_queue.h | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/net/xdp/xsk_queue.h b/net/xdp/xsk_queue.h
+index 9d2a89d793c0..9ae13cccfb28 100644
+--- a/net/xdp/xsk_queue.h
++++ b/net/xdp/xsk_queue.h
+@@ -128,12 +128,15 @@ static inline bool xskq_cons_read_addr_unchecked(struct xsk_queue *q, u64 *addr)
+ static inline bool xp_aligned_validate_desc(struct xsk_buff_pool *pool,
+ struct xdp_desc *desc)
+ {
+- u64 chunk;
+-
+- if (desc->len > pool->chunk_size)
+- return false;
++ u64 chunk, chunk_end;
+
+ chunk = xp_aligned_extract_addr(pool, desc->addr);
++ if (likely(desc->len)) {
++ chunk_end = xp_aligned_extract_addr(pool, desc->addr + desc->len - 1);
++ if (chunk != chunk_end)
++ return false;
++ }
++
+ if (chunk >= pool->addrs_cnt)
+ return false;
+
+--
+2.30.2
+
--- /dev/null
+From 440d842182f191ab7155cec83f3540ccf2bddca9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jun 2021 11:22:55 +0200
+Subject: xsk: Fix missing validation for skb and unaligned mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Magnus Karlsson <magnus.karlsson@intel.com>
+
+[ Upstream commit 2f99619820c2269534eb2c0cde44870313c6d353 ]
+
+Fix a missing validation of a Tx descriptor when executing in skb mode
+and the umem is in unaligned mode. A descriptor could point to a
+buffer straddling the end of the umem, thus effectively tricking the
+kernel to read outside the allowed umem region. This could lead to a
+kernel crash if that part of memory is not mapped.
+
+In zero-copy mode, the descriptor validation code rejects such
+descriptors by checking a bit in the DMA address that tells us if the
+next page is physically contiguous or not. For the last page in the
+umem, this bit is not set, therefore any descriptor pointing to a
+packet straddling this last page boundary will be rejected. However,
+the skb path does not use this bit since it copies out data and can do
+so to two different pages. (It also does not have the array of DMA
+address, so it cannot even store this bit.) The code just returned
+that the packet is always physically contiguous. But this is
+unfortunately also returned for the last page in the umem, which means
+that packets that cross the end of the umem are being allowed, which
+they should not be.
+
+Fix this by introducing a check for this in the SKB path only, not
+penalizing the zero-copy path.
+
+Fixes: 2b43470add8c ("xsk: Introduce AF_XDP buffer allocation API")
+Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Björn Töpel <bjorn@kernel.org>
+Link: https://lore.kernel.org/bpf/20210617092255.3487-1-magnus.karlsson@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/xsk_buff_pool.h | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h
+index eaa8386dbc63..7a9a23e7a604 100644
+--- a/include/net/xsk_buff_pool.h
++++ b/include/net/xsk_buff_pool.h
+@@ -147,11 +147,16 @@ static inline bool xp_desc_crosses_non_contig_pg(struct xsk_buff_pool *pool,
+ {
+ bool cross_pg = (addr & (PAGE_SIZE - 1)) + len > PAGE_SIZE;
+
+- if (pool->dma_pages_cnt && cross_pg) {
++ if (likely(!cross_pg))
++ return false;
++
++ if (pool->dma_pages_cnt) {
+ return !(pool->dma_pages[addr >> PAGE_SHIFT] &
+ XSK_NEXT_PG_CONTIG_MASK);
+ }
+- return false;
++
++ /* skb path */
++ return addr + len > pool->addrs_cnt;
+ }
+
+ static inline u64 xp_aligned_extract_addr(struct xsk_buff_pool *pool, u64 addr)
+--
+2.30.2
+