]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Sat, 9 Dec 2023 02:36:59 +0000 (21:36 -0500)
committerSasha Levin <sashal@kernel.org>
Sat, 9 Dec 2023 02:36:59 +0000 (21:36 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
21 files changed:
queue-5.4/acpi-iort-make-iort_get_device_domain-irq-domain-agn.patch [new file with mode: 0644]
queue-5.4/acpi-iort-make-iort_msi_map_rid-pci-agnostic.patch [new file with mode: 0644]
queue-5.4/arcnet-restoring-support-for-multiple-sohard-arcnet-.patch [new file with mode: 0644]
queue-5.4/bpf-sockmap-updating-the-sg-structure-should-also-up.patch [new file with mode: 0644]
queue-5.4/hv_netvsc-rndis_filter-needs-to-select-nls.patch [new file with mode: 0644]
queue-5.4/ipv4-ip_gre-avoid-skb_pull-failure-in-ipgre_xmit.patch [new file with mode: 0644]
queue-5.4/ipv6-fix-potential-null-deref-in-fib6_add.patch [new file with mode: 0644]
queue-5.4/net-arcnet-com20020-fix-error-handling.patch [new file with mode: 0644]
queue-5.4/net-arcnet-fix-reset-flag-handling.patch [new file with mode: 0644]
queue-5.4/net-hns-fix-fake-link-up-on-xge-port.patch [new file with mode: 0644]
queue-5.4/netfilter-xt_owner-fix-for-unsafe-access-of-sk-sk_so.patch [new file with mode: 0644]
queue-5.4/of-add-missing-return-section-in-kerneldoc-comments.patch [new file with mode: 0644]
queue-5.4/of-base-add-of_get_cpu_state_node-to-get-idle-states.patch [new file with mode: 0644]
queue-5.4/of-base-fix-some-formatting-issues-and-provide-missi.patch [new file with mode: 0644]
queue-5.4/of-dynamic-fix-of_reconfig_get_state_change-return-v.patch [new file with mode: 0644]
queue-5.4/of-fix-kerneldoc-output-formatting.patch [new file with mode: 0644]
queue-5.4/of-iommu-make-of_map_rid-pci-agnostic.patch [new file with mode: 0644]
queue-5.4/of-irq-make-of_msi_map_get_device_domain-bus-agnosti.patch [new file with mode: 0644]
queue-5.4/of-irq-make-of_msi_map_rid-pci-bus-agnostic.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/tcp-do-not-accept-ack-of-bytes-we-never-sent.patch [new file with mode: 0644]

diff --git a/queue-5.4/acpi-iort-make-iort_get_device_domain-irq-domain-agn.patch b/queue-5.4/acpi-iort-make-iort_get_device_domain-irq-domain-agn.patch
new file mode 100644 (file)
index 0000000..6a178ec
--- /dev/null
@@ -0,0 +1,137 @@
+From 923ff2cab90e59991db251dfcf3029e878f6c8f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2020 09:20:03 +0100
+Subject: ACPI/IORT: Make iort_get_device_domain IRQ domain agnostic
+
+From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+
+[ Upstream commit d1718a1b7a86743b9c517bf9521695ba909c734f ]
+
+iort_get_device_domain() is PCI specific but it need not be,
+since it can be used to retrieve IRQ domain nexus of any kind
+by adding an irq_domain_bus_token input to it.
+
+Make it PCI agnostic by also renaming the requestor ID input
+to a more generic ID name.
+
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>   # pci/msi.c
+Cc: Will Deacon <will@kernel.org>
+Cc: Hanjun Guo <guohanjun@huawei.com>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Sudeep Holla <sudeep.holla@arm.com>
+Cc: Robin Murphy <robin.murphy@arm.com>
+Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
+Link: https://lore.kernel.org/r/20200619082013.13661-3-lorenzo.pieralisi@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/arm64/iort.c | 14 +++++++-------
+ drivers/pci/msi.c         |  3 ++-
+ include/linux/acpi_iort.h |  7 ++++---
+ 3 files changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
+index 09eb170f26d27..0428e74b6002b 100644
+--- a/drivers/acpi/arm64/iort.c
++++ b/drivers/acpi/arm64/iort.c
+@@ -503,7 +503,6 @@ static struct acpi_iort_node *iort_find_dev_node(struct device *dev)
+               node = iort_get_iort_node(dev->fwnode);
+               if (node)
+                       return node;
+-
+               /*
+                * if not, then it should be a platform device defined in
+                * DSDT/SSDT (with Named Component node in IORT)
+@@ -594,13 +593,13 @@ static int __maybe_unused iort_find_its_base(u32 its_id, phys_addr_t *base)
+ /**
+  * iort_dev_find_its_id() - Find the ITS identifier for a device
+  * @dev: The device.
+- * @req_id: Device's requester ID
++ * @id: Device's ID
+  * @idx: Index of the ITS identifier list.
+  * @its_id: ITS identifier.
+  *
+  * Returns: 0 on success, appropriate error value otherwise
+  */
+-static int iort_dev_find_its_id(struct device *dev, u32 req_id,
++static int iort_dev_find_its_id(struct device *dev, u32 id,
+                               unsigned int idx, int *its_id)
+ {
+       struct acpi_iort_its_group *its;
+@@ -610,7 +609,7 @@ static int iort_dev_find_its_id(struct device *dev, u32 req_id,
+       if (!node)
+               return -ENXIO;
+-      node = iort_node_map_id(node, req_id, NULL, IORT_MSI_TYPE);
++      node = iort_node_map_id(node, id, NULL, IORT_MSI_TYPE);
+       if (!node)
+               return -ENXIO;
+@@ -633,19 +632,20 @@ static int iort_dev_find_its_id(struct device *dev, u32 req_id,
+  *
+  * Returns: the MSI domain for this device, NULL otherwise
+  */
+-struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
++struct irq_domain *iort_get_device_domain(struct device *dev, u32 id,
++                                        enum irq_domain_bus_token bus_token)
+ {
+       struct fwnode_handle *handle;
+       int its_id;
+-      if (iort_dev_find_its_id(dev, req_id, 0, &its_id))
++      if (iort_dev_find_its_id(dev, id, 0, &its_id))
+               return NULL;
+       handle = iort_find_domain_token(its_id);
+       if (!handle)
+               return NULL;
+-      return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
++      return irq_find_matching_fwnode(handle, bus_token);
+ }
+ static void iort_set_device_domain(struct device *dev,
+diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
+index 715c85d4e688d..6336316c37932 100644
+--- a/drivers/pci/msi.c
++++ b/drivers/pci/msi.c
+@@ -1626,7 +1626,8 @@ struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)
+       pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
+       dom = of_msi_map_get_device_domain(&pdev->dev, rid);
+       if (!dom)
+-              dom = iort_get_device_domain(&pdev->dev, rid);
++              dom = iort_get_device_domain(&pdev->dev, rid,
++                                           DOMAIN_BUS_PCI_MSI);
+       return dom;
+ }
+ #endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */
+diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
+index 64f700254ca0f..6bf603a4e6d2c 100644
+--- a/include/linux/acpi_iort.h
++++ b/include/linux/acpi_iort.h
+@@ -30,7 +30,8 @@ struct fwnode_handle *iort_find_domain_token(int trans_id);
+ #ifdef CONFIG_ACPI_IORT
+ void acpi_iort_init(void);
+ u32 iort_msi_map_rid(struct device *dev, u32 req_id);
+-struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
++struct irq_domain *iort_get_device_domain(struct device *dev, u32 id,
++                                        enum irq_domain_bus_token bus_token);
+ void acpi_configure_pmsi_domain(struct device *dev);
+ int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);
+ /* IOMMU interface */
+@@ -41,8 +42,8 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head);
+ static inline void acpi_iort_init(void) { }
+ static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
+ { return req_id; }
+-static inline struct irq_domain *iort_get_device_domain(struct device *dev,
+-                                                      u32 req_id)
++static inline struct irq_domain *iort_get_device_domain(
++      struct device *dev, u32 id, enum irq_domain_bus_token bus_token)
+ { return NULL; }
+ static inline void acpi_configure_pmsi_domain(struct device *dev) { }
+ /* IOMMU interface */
+-- 
+2.42.0
+
diff --git a/queue-5.4/acpi-iort-make-iort_msi_map_rid-pci-agnostic.patch b/queue-5.4/acpi-iort-make-iort_msi_map_rid-pci-agnostic.patch
new file mode 100644 (file)
index 0000000..f1dc7e0
--- /dev/null
@@ -0,0 +1,105 @@
+From bba4d6d770955f88463130f210fbd3a408693f27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2020 09:20:04 +0100
+Subject: ACPI/IORT: Make iort_msi_map_rid() PCI agnostic
+
+From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+
+[ Upstream commit 39c3cf566ceafa7c1ae331a5f26fbb685d670001 ]
+
+There is nothing PCI specific in iort_msi_map_rid().
+
+Rename the function using a bus protocol agnostic name,
+iort_msi_map_id(), and convert current callers to it.
+
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Hanjun Guo <guohanjun@huawei.com>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Sudeep Holla <sudeep.holla@arm.com>
+Cc: Robin Murphy <robin.murphy@arm.com>
+Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
+Link: https://lore.kernel.org/r/20200619082013.13661-4-lorenzo.pieralisi@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/arm64/iort.c | 12 ++++++------
+ drivers/pci/msi.c         |  2 +-
+ include/linux/acpi_iort.h |  6 +++---
+ 3 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
+index 0428e74b6002b..13ae2ce9f50dd 100644
+--- a/drivers/acpi/arm64/iort.c
++++ b/drivers/acpi/arm64/iort.c
+@@ -521,22 +521,22 @@ static struct acpi_iort_node *iort_find_dev_node(struct device *dev)
+ }
+ /**
+- * iort_msi_map_rid() - Map a MSI requester ID for a device
++ * iort_msi_map_id() - Map a MSI input ID for a device
+  * @dev: The device for which the mapping is to be done.
+- * @req_id: The device requester ID.
++ * @input_id: The device input ID.
+  *
+- * Returns: mapped MSI RID on success, input requester ID otherwise
++ * Returns: mapped MSI ID on success, input ID otherwise
+  */
+-u32 iort_msi_map_rid(struct device *dev, u32 req_id)
++u32 iort_msi_map_id(struct device *dev, u32 input_id)
+ {
+       struct acpi_iort_node *node;
+       u32 dev_id;
+       node = iort_find_dev_node(dev);
+       if (!node)
+-              return req_id;
++              return input_id;
+-      iort_node_map_id(node, req_id, &dev_id, IORT_MSI_TYPE);
++      iort_node_map_id(node, input_id, &dev_id, IORT_MSI_TYPE);
+       return dev_id;
+ }
+diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
+index 6336316c37932..cc863cdd5cc74 100644
+--- a/drivers/pci/msi.c
++++ b/drivers/pci/msi.c
+@@ -1604,7 +1604,7 @@ u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev)
+       of_node = irq_domain_get_of_node(domain);
+       rid = of_node ? of_msi_map_rid(&pdev->dev, of_node, rid) :
+-                      iort_msi_map_rid(&pdev->dev, rid);
++                      iort_msi_map_id(&pdev->dev, rid);
+       return rid;
+ }
+diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
+index 6bf603a4e6d2c..cce2cbd4f3018 100644
+--- a/include/linux/acpi_iort.h
++++ b/include/linux/acpi_iort.h
+@@ -29,7 +29,7 @@ void iort_deregister_domain_token(int trans_id);
+ struct fwnode_handle *iort_find_domain_token(int trans_id);
+ #ifdef CONFIG_ACPI_IORT
+ void acpi_iort_init(void);
+-u32 iort_msi_map_rid(struct device *dev, u32 req_id);
++u32 iort_msi_map_id(struct device *dev, u32 id);
+ struct irq_domain *iort_get_device_domain(struct device *dev, u32 id,
+                                         enum irq_domain_bus_token bus_token);
+ void acpi_configure_pmsi_domain(struct device *dev);
+@@ -40,8 +40,8 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev);
+ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head);
+ #else
+ static inline void acpi_iort_init(void) { }
+-static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
+-{ return req_id; }
++static inline u32 iort_msi_map_id(struct device *dev, u32 id)
++{ return id; }
+ static inline struct irq_domain *iort_get_device_domain(
+       struct device *dev, u32 id, enum irq_domain_bus_token bus_token)
+ { return NULL; }
+-- 
+2.42.0
+
diff --git a/queue-5.4/arcnet-restoring-support-for-multiple-sohard-arcnet-.patch b/queue-5.4/arcnet-restoring-support-for-multiple-sohard-arcnet-.patch
new file mode 100644 (file)
index 0000000..3844bdf
--- /dev/null
@@ -0,0 +1,216 @@
+From 10654aa2b57ab75495499ab3d2c94a9b2a763f53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Nov 2023 12:35:03 +0100
+Subject: arcnet: restoring support for multiple Sohard Arcnet cards
+
+From: Thomas Reichinger <thomas.reichinger@sohard.de>
+
+[ Upstream commit 6b17a597fc2f13aaaa0a2780eb7edb9ae7ac9aea ]
+
+Probe of Sohard Arcnet cards fails,
+if 2 or more cards are installed in a system.
+See kernel log:
+[    2.759203] arcnet: arcnet loaded
+[    2.763648] arcnet:com20020: COM20020 chipset support (by David Woodhouse et al.)
+[    2.770585] arcnet:com20020_pci: COM20020 PCI support
+[    2.772295] com20020 0000:02:00.0: enabling device (0000 -> 0003)
+[    2.772354] (unnamed net_device) (uninitialized): PLX-PCI Controls
+...
+[    3.071301] com20020 0000:02:00.0 arc0-0 (uninitialized): PCI COM20020: station FFh found at F080h, IRQ 101.
+[    3.071305] com20020 0000:02:00.0 arc0-0 (uninitialized): Using CKP 64 - data rate 2.5 Mb/s
+[    3.071534] com20020 0000:07:00.0: enabling device (0000 -> 0003)
+[    3.071581] (unnamed net_device) (uninitialized): PLX-PCI Controls
+...
+[    3.369501] com20020 0000:07:00.0: Led pci:green:tx:0-0 renamed to pci:green:tx:0-0_1 due to name collision
+[    3.369535] com20020 0000:07:00.0: Led pci:red:recon:0-0 renamed to pci:red:recon:0-0_1 due to name collision
+[    3.370586] com20020 0000:07:00.0 arc0-0 (uninitialized): PCI COM20020: station E1h found at C000h, IRQ 35.
+[    3.370589] com20020 0000:07:00.0 arc0-0 (uninitialized): Using CKP 64 - data rate 2.5 Mb/s
+[    3.370608] com20020: probe of 0000:07:00.0 failed with error -5
+
+commit 5ef216c1f848 ("arcnet: com20020-pci: add rotary index support")
+changes the device name of all COM20020 based PCI cards,
+even if only some cards support this:
+       snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i);
+
+The error happens because all Sohard Arcnet cards would be called arc0-0,
+since the Sohard Arcnet cards don't have a PLX rotary coder.
+I.e. EAE Arcnet cards have a PLX rotary coder,
+which sets the first decimal, ensuring unique devices names.
+
+This patch adds two new card feature flags to indicate
+which cards support LEDs and the PLX rotary coder.
+For EAE based cards the names still depend on the PLX rotary coder
+(untested, since missing EAE hardware).
+For Sohard based cards, this patch will result in devices
+being called arc0, arc1, ... (tested).
+
+Signed-off-by: Thomas Reichinger <thomas.reichinger@sohard.de>
+Fixes: 5ef216c1f848 ("arcnet: com20020-pci: add rotary index support")
+Link: https://lore.kernel.org/r/20231130113503.6812-1-thomas.reichinger@sohard.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/arcnet/arcdevice.h    |  2 +
+ drivers/net/arcnet/com20020-pci.c | 89 ++++++++++++++++---------------
+ 2 files changed, 48 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/net/arcnet/arcdevice.h b/drivers/net/arcnet/arcdevice.h
+index 7178f5349fa8f..7b783ee918346 100644
+--- a/drivers/net/arcnet/arcdevice.h
++++ b/drivers/net/arcnet/arcdevice.h
+@@ -186,6 +186,8 @@ do {                                                                       \
+ #define ARC_IS_5MBIT    1   /* card default speed is 5MBit */
+ #define ARC_CAN_10MBIT  2   /* card uses COM20022, supporting 10MBit,
+                                but default is 2.5MBit. */
++#define ARC_HAS_LED     4   /* card has software controlled LEDs */
++#define ARC_HAS_ROTARY  8   /* card has rotary encoder */
+ /* information needed to define an encapsulation driver */
+ struct ArcProto {
+diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
+index 28dccbc0e8d8f..9d9e4200064f9 100644
+--- a/drivers/net/arcnet/com20020-pci.c
++++ b/drivers/net/arcnet/com20020-pci.c
+@@ -213,12 +213,13 @@ static int com20020pci_probe(struct pci_dev *pdev,
+               if (!strncmp(ci->name, "EAE PLX-PCI FB2", 15))
+                       lp->backplane = 1;
+-              /* Get the dev_id from the PLX rotary coder */
+-              if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15))
+-                      dev_id_mask = 0x3;
+-              dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask;
+-
+-              snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i);
++              if (ci->flags & ARC_HAS_ROTARY) {
++                      /* Get the dev_id from the PLX rotary coder */
++                      if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15))
++                              dev_id_mask = 0x3;
++                      dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask;
++                      snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i);
++              }
+               if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) {
+                       pr_err("IO address %Xh is empty!\n", ioaddr);
+@@ -230,6 +231,10 @@ static int com20020pci_probe(struct pci_dev *pdev,
+                       goto err_free_arcdev;
+               }
++              ret = com20020_found(dev, IRQF_SHARED);
++              if (ret)
++                      goto err_free_arcdev;
++
+               card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev),
+                                   GFP_KERNEL);
+               if (!card) {
+@@ -239,41 +244,39 @@ static int com20020pci_probe(struct pci_dev *pdev,
+               card->index = i;
+               card->pci_priv = priv;
+-              card->tx_led.brightness_set = led_tx_set;
+-              card->tx_led.default_trigger = devm_kasprintf(&pdev->dev,
+-                                              GFP_KERNEL, "arc%d-%d-tx",
+-                                              dev->dev_id, i);
+-              card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+-                                              "pci:green:tx:%d-%d",
+-                                              dev->dev_id, i);
+-
+-              card->tx_led.dev = &dev->dev;
+-              card->recon_led.brightness_set = led_recon_set;
+-              card->recon_led.default_trigger = devm_kasprintf(&pdev->dev,
+-                                              GFP_KERNEL, "arc%d-%d-recon",
+-                                              dev->dev_id, i);
+-              card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+-                                              "pci:red:recon:%d-%d",
+-                                              dev->dev_id, i);
+-              card->recon_led.dev = &dev->dev;
+-              card->dev = dev;
+-
+-              ret = devm_led_classdev_register(&pdev->dev, &card->tx_led);
+-              if (ret)
+-                      goto err_free_arcdev;
+-              ret = devm_led_classdev_register(&pdev->dev, &card->recon_led);
+-              if (ret)
+-                      goto err_free_arcdev;
+-
+-              dev_set_drvdata(&dev->dev, card);
+-
+-              ret = com20020_found(dev, IRQF_SHARED);
+-              if (ret)
+-                      goto err_free_arcdev;
+-
+-              devm_arcnet_led_init(dev, dev->dev_id, i);
++              if (ci->flags & ARC_HAS_LED) {
++                      card->tx_led.brightness_set = led_tx_set;
++                      card->tx_led.default_trigger = devm_kasprintf(&pdev->dev,
++                                                      GFP_KERNEL, "arc%d-%d-tx",
++                                                      dev->dev_id, i);
++                      card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
++                                                      "pci:green:tx:%d-%d",
++                                                      dev->dev_id, i);
++
++                      card->tx_led.dev = &dev->dev;
++                      card->recon_led.brightness_set = led_recon_set;
++                      card->recon_led.default_trigger = devm_kasprintf(&pdev->dev,
++                                                      GFP_KERNEL, "arc%d-%d-recon",
++                                                      dev->dev_id, i);
++                      card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
++                                                      "pci:red:recon:%d-%d",
++                                                      dev->dev_id, i);
++                      card->recon_led.dev = &dev->dev;
++
++                      ret = devm_led_classdev_register(&pdev->dev, &card->tx_led);
++                      if (ret)
++                              goto err_free_arcdev;
++
++                      ret = devm_led_classdev_register(&pdev->dev, &card->recon_led);
++                      if (ret)
++                              goto err_free_arcdev;
++
++                      dev_set_drvdata(&dev->dev, card);
++                      devm_arcnet_led_init(dev, dev->dev_id, i);
++              }
++              card->dev = dev;
+               list_add(&card->list, &priv->list_dev);
+               continue;
+@@ -329,7 +332,7 @@ static struct com20020_pci_card_info card_info_5mbit = {
+ };
+ static struct com20020_pci_card_info card_info_sohard = {
+-      .name = "PLX-PCI",
++      .name = "SOHARD SH ARC-PCI",
+       .devcount = 1,
+       /* SOHARD needs PCI base addr 4 */
+       .chan_map_tbl = {
+@@ -364,7 +367,7 @@ static struct com20020_pci_card_info card_info_eae_arc1 = {
+               },
+       },
+       .rotary = 0x0,
+-      .flags = ARC_CAN_10MBIT,
++      .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT,
+ };
+ static struct com20020_pci_card_info card_info_eae_ma1 = {
+@@ -396,7 +399,7 @@ static struct com20020_pci_card_info card_info_eae_ma1 = {
+               },
+       },
+       .rotary = 0x0,
+-      .flags = ARC_CAN_10MBIT,
++      .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT,
+ };
+ static struct com20020_pci_card_info card_info_eae_fb2 = {
+@@ -421,7 +424,7 @@ static struct com20020_pci_card_info card_info_eae_fb2 = {
+               },
+       },
+       .rotary = 0x0,
+-      .flags = ARC_CAN_10MBIT,
++      .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT,
+ };
+ static const struct pci_device_id com20020pci_id_table[] = {
+-- 
+2.42.0
+
diff --git a/queue-5.4/bpf-sockmap-updating-the-sg-structure-should-also-up.patch b/queue-5.4/bpf-sockmap-updating-the-sg-structure-should-also-up.patch
new file mode 100644 (file)
index 0000000..d4a2962
--- /dev/null
@@ -0,0 +1,74 @@
+From f25918361336972575caf2fbee637ec22cb475a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Dec 2023 15:27:06 -0800
+Subject: bpf: sockmap, updating the sg structure should also update curr
+
+From: John Fastabend <john.fastabend@gmail.com>
+
+[ Upstream commit bb9aefde5bbaf6c168c77ba635c155b4980c2287 ]
+
+Curr pointer should be updated when the sg structure is shifted.
+
+Fixes: 7246d8ed4dcce ("bpf: helper to pop data from messages")
+Signed-off-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/r/20231206232706.374377-3-john.fastabend@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/filter.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/net/core/filter.c b/net/core/filter.c
+index d866e1c5970cc..3c4dcdc7217e0 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -2219,6 +2219,22 @@ BPF_CALL_2(bpf_msg_cork_bytes, struct sk_msg *, msg, u32, bytes)
+       return 0;
+ }
++static void sk_msg_reset_curr(struct sk_msg *msg)
++{
++      u32 i = msg->sg.start;
++      u32 len = 0;
++
++      do {
++              len += sk_msg_elem(msg, i)->length;
++              sk_msg_iter_var_next(i);
++              if (len >= msg->sg.size)
++                      break;
++      } while (i != msg->sg.end);
++
++      msg->sg.curr = i;
++      msg->sg.copybreak = 0;
++}
++
+ static const struct bpf_func_proto bpf_msg_cork_bytes_proto = {
+       .func           = bpf_msg_cork_bytes,
+       .gpl_only       = false,
+@@ -2338,6 +2354,7 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_msg *, msg, u32, start,
+                     msg->sg.end - shift + NR_MSG_FRAG_IDS :
+                     msg->sg.end - shift;
+ out:
++      sk_msg_reset_curr(msg);
+       msg->data = sg_virt(&msg->sg.data[first_sge]) + start - offset;
+       msg->data_end = msg->data + bytes;
+       return 0;
+@@ -2471,6 +2488,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
+               msg->sg.data[new] = rsge;
+       }
++      sk_msg_reset_curr(msg);
+       sk_msg_compute_data_pointers(msg);
+       return 0;
+ }
+@@ -2642,6 +2660,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
+       sk_mem_uncharge(msg->sk, len - pop);
+       msg->sg.size -= (len - pop);
++      sk_msg_reset_curr(msg);
+       sk_msg_compute_data_pointers(msg);
+       return 0;
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.4/hv_netvsc-rndis_filter-needs-to-select-nls.patch b/queue-5.4/hv_netvsc-rndis_filter-needs-to-select-nls.patch
new file mode 100644 (file)
index 0000000..76f8da4
--- /dev/null
@@ -0,0 +1,44 @@
+From 25c4f058b04a5cfe78869fb292c86b1ee324be73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Nov 2023 21:58:53 -0800
+Subject: hv_netvsc: rndis_filter needs to select NLS
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 6c89f49964375c904cea33c0247467873f4daf2c ]
+
+rndis_filter uses utf8s_to_utf16s() which is provided by setting
+NLS, so select NLS to fix the build error:
+
+ERROR: modpost: "utf8s_to_utf16s" [drivers/net/hyperv/hv_netvsc.ko] undefined!
+
+Fixes: 1ce09e899d28 ("hyperv: Add support for setting MAC from within guests")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Wei Liu <wei.liu@kernel.org>
+Cc: Dexuan Cui <decui@microsoft.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Simon Horman <horms@kernel.org> # build-tested
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://lore.kernel.org/r/20231130055853.19069-1-rdunlap@infradead.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/hyperv/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/hyperv/Kconfig b/drivers/net/hyperv/Kconfig
+index ca7bf7f897d36..c8cbd85adcf99 100644
+--- a/drivers/net/hyperv/Kconfig
++++ b/drivers/net/hyperv/Kconfig
+@@ -3,5 +3,6 @@ config HYPERV_NET
+       tristate "Microsoft Hyper-V virtual network driver"
+       depends on HYPERV
+       select UCS2_STRING
++      select NLS
+       help
+         Select this option to enable the Hyper-V virtual network driver.
+-- 
+2.42.0
+
diff --git a/queue-5.4/ipv4-ip_gre-avoid-skb_pull-failure-in-ipgre_xmit.patch b/queue-5.4/ipv4-ip_gre-avoid-skb_pull-failure-in-ipgre_xmit.patch
new file mode 100644 (file)
index 0000000..2963242
--- /dev/null
@@ -0,0 +1,58 @@
+From 3eb8cb022ac5e64bf5a872ede5079c0b753f355f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Dec 2023 01:14:41 +0900
+Subject: ipv4: ip_gre: Avoid skb_pull() failure in ipgre_xmit()
+
+From: Shigeru Yoshida <syoshida@redhat.com>
+
+[ Upstream commit 80d875cfc9d3711a029f234ef7d680db79e8fa4b ]
+
+In ipgre_xmit(), skb_pull() may fail even if pskb_inet_may_pull() returns
+true. For example, applications can use PF_PACKET to create a malformed
+packet with no IP header. This type of packet causes a problem such as
+uninit-value access.
+
+This patch ensures that skb_pull() can pull the required size by checking
+the skb with pskb_network_may_pull() before skb_pull().
+
+Fixes: c54419321455 ("GRE: Refactor GRE tunneling code.")
+Signed-off-by: Shigeru Yoshida <syoshida@redhat.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Suman Ghosh <sumang@marvell.com>
+Link: https://lore.kernel.org/r/20231202161441.221135-1-syoshida@redhat.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_gre.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
+index f8f008344273e..db48dec61f305 100644
+--- a/net/ipv4/ip_gre.c
++++ b/net/ipv4/ip_gre.c
+@@ -607,15 +607,18 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
+       }
+       if (dev->header_ops) {
++              int pull_len = tunnel->hlen + sizeof(struct iphdr);
++
+               if (skb_cow_head(skb, 0))
+                       goto free_skb;
+               tnl_params = (const struct iphdr *)skb->data;
+-              /* Pull skb since ip_tunnel_xmit() needs skb->data pointing
+-               * to gre header.
+-               */
+-              skb_pull(skb, tunnel->hlen + sizeof(struct iphdr));
++              if (!pskb_network_may_pull(skb, pull_len))
++                      goto free_skb;
++
++              /* ip_tunnel_xmit() needs skb->data pointing to gre header. */
++              skb_pull(skb, pull_len);
+               skb_reset_mac_header(skb);
+               if (skb->ip_summed == CHECKSUM_PARTIAL &&
+-- 
+2.42.0
+
diff --git a/queue-5.4/ipv6-fix-potential-null-deref-in-fib6_add.patch b/queue-5.4/ipv6-fix-potential-null-deref-in-fib6_add.patch
new file mode 100644 (file)
index 0000000..db0c53b
--- /dev/null
@@ -0,0 +1,79 @@
+From 2712197797e463a75a003b549c3c252c3a47e073 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Nov 2023 16:06:30 +0000
+Subject: ipv6: fix potential NULL deref in fib6_add()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 75475bb51e78a3f54ad2f69380f2a1c985e85f2d ]
+
+If fib6_find_prefix() returns NULL, we should silently fallback
+using fib6_null_entry regardless of RT6_DEBUG value.
+
+syzbot reported:
+
+WARNING: CPU: 0 PID: 5477 at net/ipv6/ip6_fib.c:1516 fib6_add+0x310d/0x3fa0 net/ipv6/ip6_fib.c:1516
+Modules linked in:
+CPU: 0 PID: 5477 Comm: syz-executor.0 Not tainted 6.7.0-rc2-syzkaller-00029-g9b6de136b5f0 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/10/2023
+RIP: 0010:fib6_add+0x310d/0x3fa0 net/ipv6/ip6_fib.c:1516
+Code: 00 48 8b 54 24 68 e8 42 22 00 00 48 85 c0 74 14 49 89 c6 e8 d5 d3 c2 f7 eb 5d e8 ce d3 c2 f7 e9 ca 00 00 00 e8 c4 d3 c2 f7 90 <0f> 0b 90 48 b8 00 00 00 00 00 fc ff df 48 8b 4c 24 38 80 3c 01 00
+RSP: 0018:ffffc90005067740 EFLAGS: 00010293
+RAX: ffffffff89cba5bc RBX: ffffc90005067ab0 RCX: ffff88801a2e9dc0
+RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000
+RBP: ffffc90005067980 R08: ffffffff89cbca85 R09: 1ffff110040d4b85
+R10: dffffc0000000000 R11: ffffed10040d4b86 R12: 00000000ffffffff
+R13: 1ffff110051c3904 R14: ffff8880206a5c00 R15: ffff888028e1c820
+FS: 00007f763783c6c0(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f763783bff8 CR3: 000000007f74d000 CR4: 00000000003506f0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+<TASK>
+__ip6_ins_rt net/ipv6/route.c:1303 [inline]
+ip6_route_add+0x88/0x120 net/ipv6/route.c:3847
+ipv6_route_ioctl+0x525/0x7b0 net/ipv6/route.c:4467
+inet6_ioctl+0x21a/0x270 net/ipv6/af_inet6.c:575
+sock_do_ioctl+0x152/0x460 net/socket.c:1220
+sock_ioctl+0x615/0x8c0 net/socket.c:1339
+vfs_ioctl fs/ioctl.c:51 [inline]
+__do_sys_ioctl fs/ioctl.c:871 [inline]
+__se_sys_ioctl+0xf8/0x170 fs/ioctl.c:857
+do_syscall_x64 arch/x86/entry/common.c:51 [inline]
+do_syscall_64+0x45/0x110 arch/x86/entry/common.c:82
+
+Fixes: 7bbfe00e0252 ("ipv6: fix general protection fault in fib6_add()")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Wei Wang <weiwan@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://lore.kernel.org/r/20231129160630.3509216-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_fib.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
+index ef55489651f87..d74a825c50f0c 100644
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -1433,13 +1433,9 @@ int fib6_add(struct fib6_node *root, struct fib6_info *rt,
+                       if (!pn_leaf && !(pn->fn_flags & RTN_RTINFO)) {
+                               pn_leaf = fib6_find_prefix(info->nl_net, table,
+                                                          pn);
+-#if RT6_DEBUG >= 2
+-                              if (!pn_leaf) {
+-                                      WARN_ON(!pn_leaf);
++                              if (!pn_leaf)
+                                       pn_leaf =
+                                           info->nl_net->ipv6.fib6_null_entry;
+-                              }
+-#endif
+                               fib6_info_hold(pn_leaf);
+                               rcu_assign_pointer(pn->leaf, pn_leaf);
+                       }
+-- 
+2.42.0
+
diff --git a/queue-5.4/net-arcnet-com20020-fix-error-handling.patch b/queue-5.4/net-arcnet-com20020-fix-error-handling.patch
new file mode 100644 (file)
index 0000000..4246d0b
--- /dev/null
@@ -0,0 +1,137 @@
+From c33a40189dcbd1ac546ce01ec12faf78bc6e8e0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 14 Mar 2021 14:08:36 -0400
+Subject: net: arcnet: com20020 fix error handling
+
+From: Tong Zhang <ztong0001@gmail.com>
+
+[ Upstream commit 6577b9a551aedb86bca6d4438c28386361845108 ]
+
+There are two issues when handling error case in com20020pci_probe()
+
+1. priv might be not initialized yet when calling com20020pci_remove()
+from com20020pci_probe(), since the priv is set at the very last but it
+can jump to error handling in the middle and priv remains NULL.
+2. memory leak - the net device is allocated in alloc_arcdev but not
+properly released if error happens in the middle of the big for loop
+
+[    1.529110] BUG: kernel NULL pointer dereference, address: 0000000000000008
+[    1.531447] RIP: 0010:com20020pci_remove+0x15/0x60 [com20020_pci]
+[    1.536805] Call Trace:
+[    1.536939]  com20020pci_probe+0x3f2/0x48c [com20020_pci]
+[    1.537226]  local_pci_probe+0x48/0x80
+[    1.539918]  com20020pci_init+0x3f/0x1000 [com20020_pci]
+
+Signed-off-by: Tong Zhang <ztong0001@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 6b17a597fc2f ("arcnet: restoring support for multiple Sohard Arcnet cards")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/arcnet/com20020-pci.c | 34 +++++++++++++++++--------------
+ 1 file changed, 19 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
+index b4f8798d8c509..28dccbc0e8d8f 100644
+--- a/drivers/net/arcnet/com20020-pci.c
++++ b/drivers/net/arcnet/com20020-pci.c
+@@ -127,6 +127,8 @@ static int com20020pci_probe(struct pci_dev *pdev,
+       int i, ioaddr, ret;
+       struct resource *r;
++      ret = 0;
++
+       if (pci_enable_device(pdev))
+               return -EIO;
+@@ -142,6 +144,8 @@ static int com20020pci_probe(struct pci_dev *pdev,
+       priv->ci = ci;
+       mm = &ci->misc_map;
++      pci_set_drvdata(pdev, priv);
++
+       INIT_LIST_HEAD(&priv->list_dev);
+       if (mm->size) {
+@@ -164,7 +168,7 @@ static int com20020pci_probe(struct pci_dev *pdev,
+               dev = alloc_arcdev(device);
+               if (!dev) {
+                       ret = -ENOMEM;
+-                      goto out_port;
++                      break;
+               }
+               dev->dev_port = i;
+@@ -181,7 +185,7 @@ static int com20020pci_probe(struct pci_dev *pdev,
+                       pr_err("IO region %xh-%xh already allocated\n",
+                              ioaddr, ioaddr + cm->size - 1);
+                       ret = -EBUSY;
+-                      goto out_port;
++                      goto err_free_arcdev;
+               }
+               /* Dummy access after Reset
+@@ -219,18 +223,18 @@ static int com20020pci_probe(struct pci_dev *pdev,
+               if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) {
+                       pr_err("IO address %Xh is empty!\n", ioaddr);
+                       ret = -EIO;
+-                      goto out_port;
++                      goto err_free_arcdev;
+               }
+               if (com20020_check(dev)) {
+                       ret = -EIO;
+-                      goto out_port;
++                      goto err_free_arcdev;
+               }
+               card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev),
+                                   GFP_KERNEL);
+               if (!card) {
+                       ret = -ENOMEM;
+-                      goto out_port;
++                      goto err_free_arcdev;
+               }
+               card->index = i;
+@@ -256,29 +260,29 @@ static int com20020pci_probe(struct pci_dev *pdev,
+               ret = devm_led_classdev_register(&pdev->dev, &card->tx_led);
+               if (ret)
+-                      goto out_port;
++                      goto err_free_arcdev;
+               ret = devm_led_classdev_register(&pdev->dev, &card->recon_led);
+               if (ret)
+-                      goto out_port;
++                      goto err_free_arcdev;
+               dev_set_drvdata(&dev->dev, card);
+               ret = com20020_found(dev, IRQF_SHARED);
+               if (ret)
+-                      goto out_port;
++                      goto err_free_arcdev;
+               devm_arcnet_led_init(dev, dev->dev_id, i);
+               list_add(&card->list, &priv->list_dev);
+-      }
++              continue;
+-      pci_set_drvdata(pdev, priv);
+-
+-      return 0;
+-
+-out_port:
+-      com20020pci_remove(pdev);
++err_free_arcdev:
++              free_arcdev(dev);
++              break;
++      }
++      if (ret)
++              com20020pci_remove(pdev);
+       return ret;
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.4/net-arcnet-fix-reset-flag-handling.patch b/queue-5.4/net-arcnet-fix-reset-flag-handling.patch
new file mode 100644 (file)
index 0000000..db9af0c
--- /dev/null
@@ -0,0 +1,315 @@
+From fd32bea442d3d892bb83f873fc7e5a5bf1fffca2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Jan 2021 20:48:02 +0100
+Subject: net: arcnet: Fix RESET flag handling
+
+From: Ahmed S. Darwish <a.darwish@linutronix.de>
+
+[ Upstream commit 01365633bd1c836240f9bbf86bbeee749795480a ]
+
+The main arcnet interrupt handler calls arcnet_close() then
+arcnet_open(), if the RESET status flag is encountered.
+
+This is invalid:
+
+  1) In general, interrupt handlers should never call ->ndo_stop() and
+     ->ndo_open() functions. They are usually full of blocking calls and
+     other methods that are expected to be called only from drivers
+     init and exit code paths.
+
+  2) arcnet_close() contains a del_timer_sync(). If the irq handler
+     interrupts the to-be-deleted timer, del_timer_sync() will just loop
+     forever.
+
+  3) arcnet_close() also calls tasklet_kill(), which has a warning if
+     called from irq context.
+
+  4) For device reset, the sequence "arcnet_close(); arcnet_open();" is
+     not complete.  Some children arcnet drivers have special init/exit
+     code sequences, which then embed a call to arcnet_open() and
+     arcnet_close() accordingly. Check drivers/net/arcnet/com20020.c.
+
+Run the device RESET sequence from a scheduled workqueue instead.
+
+Signed-off-by: Ahmed S. Darwish <a.darwish@linutronix.de>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: https://lore.kernel.org/r/20210128194802.727770-1-a.darwish@linutronix.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 6b17a597fc2f ("arcnet: restoring support for multiple Sohard Arcnet cards")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/arcnet/arc-rimi.c     |  4 +-
+ drivers/net/arcnet/arcdevice.h    |  6 +++
+ drivers/net/arcnet/arcnet.c       | 66 +++++++++++++++++++++++++++++--
+ drivers/net/arcnet/com20020-isa.c |  4 +-
+ drivers/net/arcnet/com20020-pci.c |  2 +-
+ drivers/net/arcnet/com20020_cs.c  |  2 +-
+ drivers/net/arcnet/com90io.c      |  4 +-
+ drivers/net/arcnet/com90xx.c      |  4 +-
+ 8 files changed, 78 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c
+index 14a5fb3781453..313b636edf239 100644
+--- a/drivers/net/arcnet/arc-rimi.c
++++ b/drivers/net/arcnet/arc-rimi.c
+@@ -332,7 +332,7 @@ static int __init arc_rimi_init(void)
+               dev->irq = 9;
+       if (arcrimi_probe(dev)) {
+-              free_netdev(dev);
++              free_arcdev(dev);
+               return -EIO;
+       }
+@@ -349,7 +349,7 @@ static void __exit arc_rimi_exit(void)
+       iounmap(lp->mem_start);
+       release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+       free_irq(dev->irq, dev);
+-      free_netdev(dev);
++      free_arcdev(dev);
+ }
+ #ifndef MODULE
+diff --git a/drivers/net/arcnet/arcdevice.h b/drivers/net/arcnet/arcdevice.h
+index b0f5bc07aef5b..7178f5349fa8f 100644
+--- a/drivers/net/arcnet/arcdevice.h
++++ b/drivers/net/arcnet/arcdevice.h
+@@ -298,6 +298,10 @@ struct arcnet_local {
+       int excnak_pending;    /* We just got an excesive nak interrupt */
++      /* RESET flag handling */
++      int reset_in_progress;
++      struct work_struct reset_work;
++
+       struct {
+               uint16_t sequence;      /* sequence number (incs with each packet) */
+               __be16 aborted_seq;
+@@ -350,7 +354,9 @@ void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc)
+ void arcnet_unregister_proto(struct ArcProto *proto);
+ irqreturn_t arcnet_interrupt(int irq, void *dev_id);
++
+ struct net_device *alloc_arcdev(const char *name);
++void free_arcdev(struct net_device *dev);
+ int arcnet_open(struct net_device *dev);
+ int arcnet_close(struct net_device *dev);
+diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
+index 2b112d3d85409..cf652c76af85e 100644
+--- a/drivers/net/arcnet/arcnet.c
++++ b/drivers/net/arcnet/arcnet.c
+@@ -387,10 +387,44 @@ static void arcnet_timer(struct timer_list *t)
+       struct arcnet_local *lp = from_timer(lp, t, timer);
+       struct net_device *dev = lp->dev;
+-      if (!netif_carrier_ok(dev)) {
++      spin_lock_irq(&lp->lock);
++
++      if (!lp->reset_in_progress && !netif_carrier_ok(dev)) {
+               netif_carrier_on(dev);
+               netdev_info(dev, "link up\n");
+       }
++
++      spin_unlock_irq(&lp->lock);
++}
++
++static void reset_device_work(struct work_struct *work)
++{
++      struct arcnet_local *lp;
++      struct net_device *dev;
++
++      lp = container_of(work, struct arcnet_local, reset_work);
++      dev = lp->dev;
++
++      /* Do not bring the network interface back up if an ifdown
++       * was already done.
++       */
++      if (!netif_running(dev) || !lp->reset_in_progress)
++              return;
++
++      rtnl_lock();
++
++      /* Do another check, in case of an ifdown that was triggered in
++       * the small race window between the exit condition above and
++       * acquiring RTNL.
++       */
++      if (!netif_running(dev) || !lp->reset_in_progress)
++              goto out;
++
++      dev_close(dev);
++      dev_open(dev, NULL);
++
++out:
++      rtnl_unlock();
+ }
+ static void arcnet_reply_tasklet(unsigned long data)
+@@ -452,12 +486,25 @@ struct net_device *alloc_arcdev(const char *name)
+               lp->dev = dev;
+               spin_lock_init(&lp->lock);
+               timer_setup(&lp->timer, arcnet_timer, 0);
++              INIT_WORK(&lp->reset_work, reset_device_work);
+       }
+       return dev;
+ }
+ EXPORT_SYMBOL(alloc_arcdev);
++void free_arcdev(struct net_device *dev)
++{
++      struct arcnet_local *lp = netdev_priv(dev);
++
++      /* Do not cancel this at ->ndo_close(), as the workqueue itself
++       * indirectly calls the ifdown path through dev_close().
++       */
++      cancel_work_sync(&lp->reset_work);
++      free_netdev(dev);
++}
++EXPORT_SYMBOL(free_arcdev);
++
+ /* Open/initialize the board.  This is called sometime after booting when
+  * the 'ifconfig' program is run.
+  *
+@@ -587,6 +634,10 @@ int arcnet_close(struct net_device *dev)
+       /* shut down the card */
+       lp->hw.close(dev);
++
++      /* reset counters */
++      lp->reset_in_progress = 0;
++
+       module_put(lp->hw.owner);
+       return 0;
+ }
+@@ -820,6 +871,9 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
+       spin_lock_irqsave(&lp->lock, flags);
++      if (lp->reset_in_progress)
++              goto out;
++
+       /* RESET flag was enabled - if device is not running, we must
+        * clear it right away (but nothing else).
+        */
+@@ -852,11 +906,14 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
+               if (status & RESETflag) {
+                       arc_printk(D_NORMAL, dev, "spurious reset (status=%Xh)\n",
+                                  status);
+-                      arcnet_close(dev);
+-                      arcnet_open(dev);
++
++                      lp->reset_in_progress = 1;
++                      netif_stop_queue(dev);
++                      netif_carrier_off(dev);
++                      schedule_work(&lp->reset_work);
+                       /* get out of the interrupt handler! */
+-                      break;
++                      goto out;
+               }
+               /* RX is inhibited - we must have received something.
+                * Prepare to receive into the next buffer.
+@@ -1052,6 +1109,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
+       udelay(1);
+       lp->hw.intmask(dev, lp->intmask);
++out:
+       spin_unlock_irqrestore(&lp->lock, flags);
+       return retval;
+ }
+diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c
+index cd27fdc1059b9..141b05451252e 100644
+--- a/drivers/net/arcnet/com20020-isa.c
++++ b/drivers/net/arcnet/com20020-isa.c
+@@ -169,7 +169,7 @@ static int __init com20020_init(void)
+               dev->irq = 9;
+       if (com20020isa_probe(dev)) {
+-              free_netdev(dev);
++              free_arcdev(dev);
+               return -EIO;
+       }
+@@ -182,7 +182,7 @@ static void __exit com20020_exit(void)
+       unregister_netdev(my_dev);
+       free_irq(my_dev->irq, my_dev);
+       release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE);
+-      free_netdev(my_dev);
++      free_arcdev(my_dev);
+ }
+ #ifndef MODULE
+diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
+index 9f44e2e458df1..b4f8798d8c509 100644
+--- a/drivers/net/arcnet/com20020-pci.c
++++ b/drivers/net/arcnet/com20020-pci.c
+@@ -294,7 +294,7 @@ static void com20020pci_remove(struct pci_dev *pdev)
+               unregister_netdev(dev);
+               free_irq(dev->irq, dev);
+-              free_netdev(dev);
++              free_arcdev(dev);
+       }
+ }
+diff --git a/drivers/net/arcnet/com20020_cs.c b/drivers/net/arcnet/com20020_cs.c
+index cf607ffcf358e..9cc5eb6a8e905 100644
+--- a/drivers/net/arcnet/com20020_cs.c
++++ b/drivers/net/arcnet/com20020_cs.c
+@@ -177,7 +177,7 @@ static void com20020_detach(struct pcmcia_device *link)
+               dev = info->dev;
+               if (dev) {
+                       dev_dbg(&link->dev, "kfree...\n");
+-                      free_netdev(dev);
++                      free_arcdev(dev);
+               }
+               dev_dbg(&link->dev, "kfree2...\n");
+               kfree(info);
+diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c
+index 186bbf87bc849..5843b8976fd19 100644
+--- a/drivers/net/arcnet/com90io.c
++++ b/drivers/net/arcnet/com90io.c
+@@ -396,7 +396,7 @@ static int __init com90io_init(void)
+       err = com90io_probe(dev);
+       if (err) {
+-              free_netdev(dev);
++              free_arcdev(dev);
+               return err;
+       }
+@@ -419,7 +419,7 @@ static void __exit com90io_exit(void)
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+-      free_netdev(dev);
++      free_arcdev(dev);
+ }
+ module_init(com90io_init)
+diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c
+index bd75d06ad7dfc..5e40ecf189b15 100644
+--- a/drivers/net/arcnet/com90xx.c
++++ b/drivers/net/arcnet/com90xx.c
+@@ -554,7 +554,7 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem,
+ err_release_mem:
+       release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+ err_free_dev:
+-      free_netdev(dev);
++      free_arcdev(dev);
+       return -EIO;
+ }
+@@ -672,7 +672,7 @@ static void __exit com90xx_exit(void)
+               release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+               release_mem_region(dev->mem_start,
+                                  dev->mem_end - dev->mem_start + 1);
+-              free_netdev(dev);
++              free_arcdev(dev);
+       }
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.4/net-hns-fix-fake-link-up-on-xge-port.patch b/queue-5.4/net-hns-fix-fake-link-up-on-xge-port.patch
new file mode 100644 (file)
index 0000000..e7be318
--- /dev/null
@@ -0,0 +1,74 @@
+From 825a0ae8dd0c9904ee7e26b1cbec0714451951f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Dec 2023 22:32:32 +0800
+Subject: net: hns: fix fake link up on xge port
+
+From: Yonglong Liu <liuyonglong@huawei.com>
+
+[ Upstream commit f708aba40f9c1eeb9c7e93ed4863b5f85b09b288 ]
+
+If a xge port just connect with an optical module and no fiber,
+it may have a fake link up because there may be interference on
+the hardware. This patch adds an anti-shake to avoid the problem.
+And the time of anti-shake is base on tests.
+
+Fixes: b917078c1c10 ("net: hns: Add ACPI support to check SFP present")
+Signed-off-by: Yonglong Liu <liuyonglong@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 29 +++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+index 8aace2de0cc91..e34245649057e 100644
+--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
++++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+@@ -66,6 +66,27 @@ static enum mac_mode hns_get_enet_interface(const struct hns_mac_cb *mac_cb)
+       }
+ }
++static u32 hns_mac_link_anti_shake(struct mac_driver *mac_ctrl_drv)
++{
++#define HNS_MAC_LINK_WAIT_TIME 5
++#define HNS_MAC_LINK_WAIT_CNT 40
++
++      u32 link_status = 0;
++      int i;
++
++      if (!mac_ctrl_drv->get_link_status)
++              return link_status;
++
++      for (i = 0; i < HNS_MAC_LINK_WAIT_CNT; i++) {
++              msleep(HNS_MAC_LINK_WAIT_TIME);
++              mac_ctrl_drv->get_link_status(mac_ctrl_drv, &link_status);
++              if (!link_status)
++                      break;
++      }
++
++      return link_status;
++}
++
+ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status)
+ {
+       struct mac_driver *mac_ctrl_drv;
+@@ -83,6 +104,14 @@ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status)
+                                                              &sfp_prsnt);
+               if (!ret)
+                       *link_status = *link_status && sfp_prsnt;
++
++              /* for FIBER port, it may have a fake link up.
++               * when the link status changes from down to up, we need to do
++               * anti-shake. the anti-shake time is base on tests.
++               * only FIBER port need to do this.
++               */
++              if (*link_status && !mac_cb->link)
++                      *link_status = hns_mac_link_anti_shake(mac_ctrl_drv);
+       }
+       mac_cb->link = *link_status;
+-- 
+2.42.0
+
diff --git a/queue-5.4/netfilter-xt_owner-fix-for-unsafe-access-of-sk-sk_so.patch b/queue-5.4/netfilter-xt_owner-fix-for-unsafe-access-of-sk-sk_so.patch
new file mode 100644 (file)
index 0000000..9961d95
--- /dev/null
@@ -0,0 +1,71 @@
+From 7861d807c7bd847121a26b55cb66c30b62b3b718 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 21:58:12 +0100
+Subject: netfilter: xt_owner: Fix for unsafe access of sk->sk_socket
+
+From: Phil Sutter <phil@nwl.cc>
+
+[ Upstream commit 7ae836a3d630e146b732fe8ef7d86b243748751f ]
+
+A concurrently running sock_orphan() may NULL the sk_socket pointer in
+between check and deref. Follow other users (like nft_meta.c for
+instance) and acquire sk_callback_lock before dereferencing sk_socket.
+
+Fixes: 0265ab44bacc ("[NETFILTER]: merge ipt_owner/ip6t_owner in xt_owner")
+Reported-by: Jann Horn <jannh@google.com>
+Signed-off-by: Phil Sutter <phil@nwl.cc>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/xt_owner.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
+index e85ce69924aee..50332888c8d23 100644
+--- a/net/netfilter/xt_owner.c
++++ b/net/netfilter/xt_owner.c
+@@ -76,18 +76,23 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
+                */
+               return false;
+-      filp = sk->sk_socket->file;
+-      if (filp == NULL)
++      read_lock_bh(&sk->sk_callback_lock);
++      filp = sk->sk_socket ? sk->sk_socket->file : NULL;
++      if (filp == NULL) {
++              read_unlock_bh(&sk->sk_callback_lock);
+               return ((info->match ^ info->invert) &
+                      (XT_OWNER_UID | XT_OWNER_GID)) == 0;
++      }
+       if (info->match & XT_OWNER_UID) {
+               kuid_t uid_min = make_kuid(net->user_ns, info->uid_min);
+               kuid_t uid_max = make_kuid(net->user_ns, info->uid_max);
+               if ((uid_gte(filp->f_cred->fsuid, uid_min) &&
+                    uid_lte(filp->f_cred->fsuid, uid_max)) ^
+-                  !(info->invert & XT_OWNER_UID))
++                  !(info->invert & XT_OWNER_UID)) {
++                      read_unlock_bh(&sk->sk_callback_lock);
+                       return false;
++              }
+       }
+       if (info->match & XT_OWNER_GID) {
+@@ -112,10 +117,13 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
+                       }
+               }
+-              if (match ^ !(info->invert & XT_OWNER_GID))
++              if (match ^ !(info->invert & XT_OWNER_GID)) {
++                      read_unlock_bh(&sk->sk_callback_lock);
+                       return false;
++              }
+       }
++      read_unlock_bh(&sk->sk_callback_lock);
+       return true;
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.4/of-add-missing-return-section-in-kerneldoc-comments.patch b/queue-5.4/of-add-missing-return-section-in-kerneldoc-comments.patch
new file mode 100644 (file)
index 0000000..9108c51
--- /dev/null
@@ -0,0 +1,812 @@
+From 0d4adf4c5580c4abf8fd489ba7f9585ea7ce9271 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 10:47:12 -0600
+Subject: of: Add missing 'Return' section in kerneldoc comments
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit 8c8239c2c1fb82f171cb22a707f3bb88a2f22109 ]
+
+Many of the DT kerneldoc comments are lacking a 'Return' section. Let's
+add the section in cases we have a description of return values. There's
+still some cases where the return values are not documented.
+
+Cc: Frank Rowand <frowand.list@gmail.com>
+Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Link: https://lore.kernel.org/r/20210325164713.1296407-8-robh@kernel.org
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/base.c     | 39 +++++++++++++------------
+ drivers/of/dynamic.c  | 19 ++++++++-----
+ drivers/of/fdt.c      |  8 +++---
+ drivers/of/irq.c      | 14 ++++-----
+ drivers/of/overlay.c  | 16 +++++------
+ drivers/of/platform.c | 10 +++----
+ drivers/of/property.c | 66 +++++++++++++++++++++++++++----------------
+ include/linux/of.h    | 63 ++++++++++++++++++++++++++---------------
+ 8 files changed, 140 insertions(+), 95 deletions(-)
+
+diff --git a/drivers/of/base.c b/drivers/of/base.c
+index c4c64ef5fb7a8..c8af9a65f98b0 100644
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -306,7 +306,7 @@ struct device_node *__of_find_all_nodes(struct device_node *prev)
+  * @prev:     Previous node or NULL to start iteration
+  *            of_node_put() will be called on it
+  *
+- * Returns a node pointer with refcount incremented, use
++ * Return: A node pointer with refcount incremented, use
+  * of_node_put() on it when done.
+  */
+ struct device_node *of_find_all_nodes(struct device_node *prev)
+@@ -436,7 +436,7 @@ bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun,
+  * before booting secondary cores. This function uses arch_match_cpu_phys_id
+  * which can be overridden by architecture specific implementation.
+  *
+- * Returns a node pointer for the logical cpu with refcount incremented, use
++ * Return: A node pointer for the logical cpu with refcount incremented, use
+  * of_node_put() on it when done. Returns NULL if not found.
+  */
+ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
+@@ -456,8 +456,8 @@ EXPORT_SYMBOL(of_get_cpu_node);
+  *
+  * @cpu_node: Pointer to the device_node for CPU.
+  *
+- * Returns the logical CPU number of the given CPU device_node.
+- * Returns -ENODEV if the CPU is not found.
++ * Return: The logical CPU number of the given CPU device_node or -ENODEV if the
++ * CPU is not found.
+  */
+ int of_cpu_node_to_id(struct device_node *cpu_node)
+ {
+@@ -489,7 +489,7 @@ EXPORT_SYMBOL(of_cpu_node_to_id);
+  * bindings. This function check for both and returns the idle state node for
+  * the requested index.
+  *
+- * In case an idle state node is found at @index, the refcount is incremented
++ * Return: An idle state node if found at @index. The refcount is incremented
+  * for it, so call of_node_put() on it when done. Returns NULL if not found.
+  */
+ struct device_node *of_get_cpu_state_node(struct device_node *cpu_node,
+@@ -623,7 +623,7 @@ int of_device_compatible_match(struct device_node *device,
+  * of_machine_is_compatible - Test root of device tree for a given compatible value
+  * @compat: compatible string to look for in root node's compatible property.
+  *
+- * Returns a positive integer if the root node has the given value in its
++ * Return: A positive integer if the root node has the given value in its
+  * compatible property.
+  */
+ int of_machine_is_compatible(const char *compat)
+@@ -645,7 +645,7 @@ EXPORT_SYMBOL(of_machine_is_compatible);
+  *
+  *  @device: Node to check for availability, with locks already held
+  *
+- *  Returns true if the status property is absent or set to "okay" or "ok",
++ *  Return: True if the status property is absent or set to "okay" or "ok",
+  *  false otherwise
+  */
+ static bool __of_device_is_available(const struct device_node *device)
+@@ -673,7 +673,7 @@ static bool __of_device_is_available(const struct device_node *device)
+  *
+  *  @device: Node to check for availability
+  *
+- *  Returns true if the status property is absent or set to "okay" or "ok",
++ *  Return: True if the status property is absent or set to "okay" or "ok",
+  *  false otherwise
+  */
+ bool of_device_is_available(const struct device_node *device)
+@@ -694,7 +694,7 @@ EXPORT_SYMBOL(of_device_is_available);
+  *
+  *  @device: Node to check for endianness
+  *
+- *  Returns true if the device has a "big-endian" property, or if the kernel
++ *  Return: True if the device has a "big-endian" property, or if the kernel
+  *  was compiled for BE *and* the device has a "native-endian" property.
+  *  Returns false otherwise.
+  *
+@@ -878,7 +878,7 @@ EXPORT_SYMBOL(of_get_next_cpu_node);
+  * Lookup child node whose compatible property contains the given compatible
+  * string.
+  *
+- * Returns a node pointer with refcount incremented, use of_node_put() on it
++ * Return: a node pointer with refcount incremented, use of_node_put() on it
+  * when done; or NULL if not found.
+  */
+ struct device_node *of_get_compatible_child(const struct device_node *parent,
+@@ -1232,7 +1232,7 @@ EXPORT_SYMBOL(of_find_matching_node_and_match);
+  * It does this by stripping the manufacturer prefix (as delimited by a ',')
+  * from the first entry in the compatible list property.
+  *
+- * This routine returns 0 on success, <0 on failure.
++ * Return: This routine returns 0 on success, <0 on failure.
+  */
+ int of_modalias_node(struct device_node *node, char *modalias, int len)
+ {
+@@ -1252,7 +1252,7 @@ EXPORT_SYMBOL_GPL(of_modalias_node);
+  * of_find_node_by_phandle - Find a node given a phandle
+  * @handle:   phandle of the node to find
+  *
+- * Returns a node pointer with refcount incremented, use
++ * Return: A node pointer with refcount incremented, use
+  * of_node_put() on it when done.
+  */
+ struct device_node *of_find_node_by_phandle(phandle handle)
+@@ -1505,7 +1505,7 @@ static int __of_parse_phandle_with_args(const struct device_node *np,
+  * @index: For properties holding a table of phandles, this is the index into
+  *         the table
+  *
+- * Returns the device_node pointer with refcount incremented.  Use
++ * Return: The device_node pointer with refcount incremented.  Use
+  * of_node_put() on it when done.
+  */
+ struct device_node *of_parse_phandle(const struct device_node *np,
+@@ -1805,7 +1805,7 @@ EXPORT_SYMBOL(of_parse_phandle_with_fixed_args);
+  * @list_name:        property name that contains a list
+  * @cells_name:       property name that specifies phandles' arguments count
+  *
+- * Returns the number of phandle + argument tuples within a property. It
++ * Return: The number of phandle + argument tuples within a property. It
+  * is a typical pattern to encode a list of phandle and variable
+  * arguments into a single property. The number of arguments is encoded
+  * by a property in the phandle-target node. For example, a gpios
+@@ -2104,7 +2104,9 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
+  * @stem:     Alias stem of the given device_node
+  *
+  * The function travels the lookup table to get the alias id for the given
+- * device_node and alias stem.  It returns the alias id if found.
++ * device_node and alias stem.
++ *
++ * Return: The alias id if found.
+  */
+ int of_alias_get_id(struct device_node *np, const char *stem)
+ {
+@@ -2213,8 +2215,9 @@ EXPORT_SYMBOL_GPL(of_alias_get_highest_id);
+  * @index: Index to use for preferred console.
+  *
+  * Check if the given device node matches the stdout-path property in the
+- * /chosen node. If it does then register it as the preferred console and return
+- * TRUE. Otherwise return FALSE.
++ * /chosen node. If it does then register it as the preferred console.
++ *
++ * Return: TRUE if console successfully setup. Otherwise return FALSE.
+  */
+ bool of_console_check(struct device_node *dn, char *name, int index)
+ {
+@@ -2265,7 +2268,7 @@ struct device_node *of_find_next_cache_node(const struct device_node *np)
+  *
+  * @cpu: cpu number(logical index) for which the last cache level is needed
+  *
+- * Returns the the level at which the last cache is present. It is exactly
++ * Return: The the level at which the last cache is present. It is exactly
+  * same as  the total number of cache levels for the given logical cpu.
+  */
+ int of_find_last_cache_level(unsigned int cpu)
+diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
+index 49b16f76d78e8..92ee15be78d43 100644
+--- a/drivers/of/dynamic.c
++++ b/drivers/of/dynamic.c
+@@ -27,7 +27,7 @@ static struct device_node *kobj_to_device_node(struct kobject *kobj)
+  * @node:     Node to inc refcount, NULL is supported to simplify writing of
+  *            callers
+  *
+- * Returns node.
++ * Return: The node with refcount incremented.
+  */
+ struct device_node *of_node_get(struct device_node *node)
+ {
+@@ -104,7 +104,8 @@ int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p)
+  * @arg               - argument of the of notifier
+  *
+  * Returns the new state of a device based on the notifier used.
+- * Returns 0 on device going from enabled to disabled, 1 on device
++ *
++ * Return: 0 on device going from enabled to disabled, 1 on device
+  * going from disabled to enabled and -1 on no change.
+  */
+ int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr)
+@@ -372,7 +373,8 @@ void of_node_release(struct kobject *kobj)
+  * property structure and the property name & contents. The property's
+  * flags have the OF_DYNAMIC bit set so that we can differentiate between
+  * dynamically allocated properties and not.
+- * Returns the newly allocated property or NULL on out of memory error.
++ *
++ * Return: The newly allocated property or NULL on out of memory error.
+  */
+ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
+ {
+@@ -415,7 +417,7 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
+  * another node.  The node data are dynamically allocated and all the node
+  * flags have the OF_DYNAMIC & OF_DETACHED bits set.
+  *
+- * Returns the newly allocated node or NULL on out of memory error.
++ * Return: The newly allocated node or NULL on out of memory error.
+  */
+ struct device_node *__of_node_dup(const struct device_node *np,
+                                 const char *full_name)
+@@ -781,7 +783,8 @@ static int __of_changeset_apply(struct of_changeset *ocs)
+  * Any side-effects of live tree state changes are applied here on
+  * success, like creation/destruction of devices and side-effects
+  * like creation of sysfs properties and directories.
+- * Returns 0 on success, a negative error value in case of an error.
++ *
++ * Return: 0 on success, a negative error value in case of an error.
+  * On error the partially applied effects are reverted.
+  */
+ int of_changeset_apply(struct of_changeset *ocs)
+@@ -875,7 +878,8 @@ static int __of_changeset_revert(struct of_changeset *ocs)
+  * was before the application.
+  * Any side-effects like creation/destruction of devices and
+  * removal of sysfs properties and directories are applied.
+- * Returns 0 on success, a negative error value in case of an error.
++ *
++ * Return: 0 on success, a negative error value in case of an error.
+  */
+ int of_changeset_revert(struct of_changeset *ocs)
+ {
+@@ -903,7 +907,8 @@ EXPORT_SYMBOL_GPL(of_changeset_revert);
+  * + OF_RECONFIG_ADD_PROPERTY
+  * + OF_RECONFIG_REMOVE_PROPERTY,
+  * + OF_RECONFIG_UPDATE_PROPERTY
+- * Returns 0 on success, a negative error value in case of an error.
++ *
++ * Return: 0 on success, a negative error value in case of an error.
+  */
+ int of_changeset_action(struct of_changeset *ocs, unsigned long action,
+               struct device_node *np, struct property *prop)
+diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
+index 09a98668e7db0..1db951f433538 100644
+--- a/drivers/of/fdt.c
++++ b/drivers/of/fdt.c
+@@ -282,7 +282,7 @@ static void reverse_nodes(struct device_node *parent)
+  * @dad: Parent struct device_node
+  * @nodepp: The device_node tree created by the call
+  *
+- * It returns the size of unflattened device tree or error code
++ * Return: The size of unflattened device tree or error code
+  */
+ static int unflatten_dt_nodes(const void *blob,
+                             void *mem,
+@@ -360,7 +360,7 @@ static int unflatten_dt_nodes(const void *blob,
+  * fills the "name" and "type" pointers of the nodes so the normal device-tree
+  * walking functions can be used.
+  *
+- * Returns NULL on failure or the memory chunk containing the unflattened
++ * Return: NULL on failure or the memory chunk containing the unflattened
+  * device tree on success.
+  */
+ void *__unflatten_device_tree(const void *blob,
+@@ -441,7 +441,7 @@ static DEFINE_MUTEX(of_fdt_unflatten_mutex);
+  * pointers of the nodes so the normal device-tree walking functions
+  * can be used.
+  *
+- * Returns NULL on failure or the memory chunk containing the unflattened
++ * Return: NULL on failure or the memory chunk containing the unflattened
+  * device tree on success.
+  */
+ void *of_fdt_unflatten_tree(const unsigned long *blob,
+@@ -719,7 +719,7 @@ const void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
+  * @node: node to test
+  * @compat: compatible string to compare with compatible list.
+  *
+- * On match, returns a non-zero value with smaller values returned for more
++ * Return: a non-zero value on match with smaller values returned for more
+  * specific compatible values.
+  */
+ static int of_fdt_is_compatible(const void *blob,
+diff --git a/drivers/of/irq.c b/drivers/of/irq.c
+index 25d17b8a1a1aa..352e14b007e78 100644
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -48,7 +48,7 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
+  * of_irq_find_parent - Given a device node, find its interrupt parent node
+  * @child: pointer to device node
+  *
+- * Returns a pointer to the interrupt parent node, or NULL if the interrupt
++ * Return: A pointer to the interrupt parent node, or NULL if the interrupt
+  * parent could not be determined.
+  */
+ struct device_node *of_irq_find_parent(struct device_node *child)
+@@ -81,14 +81,14 @@ EXPORT_SYMBOL_GPL(of_irq_find_parent);
+  * @addr:     address specifier (start of "reg" property of the device) in be32 format
+  * @out_irq:  structure of_phandle_args updated by this function
+  *
+- * Returns 0 on success and a negative number on error
+- *
+  * This function is a low-level interrupt tree walking function. It
+  * can be used to do a partial walk with synthetized reg and interrupts
+  * properties, for example when resolving PCI interrupts when no device
+  * node exist for the parent. It takes an interrupt specifier structure as
+  * input, walks the tree looking for any interrupt-map properties, translates
+  * the specifier for each map, and then returns the translated map.
++ *
++ * Return: 0 on success and a negative number on error
+  */
+ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
+ {
+@@ -380,7 +380,7 @@ EXPORT_SYMBOL_GPL(of_irq_to_resource);
+  * @dev: pointer to device tree node
+  * @index: zero-based index of the IRQ
+  *
+- * Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or
++ * Return: Linux IRQ number on success, or 0 on the IRQ mapping failure, or
+  * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
+  * of any other failure.
+  */
+@@ -407,7 +407,7 @@ EXPORT_SYMBOL_GPL(of_irq_get);
+  * @dev: pointer to device tree node
+  * @name: IRQ name
+  *
+- * Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or
++ * Return: Linux IRQ number on success, or 0 on the IRQ mapping failure, or
+  * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
+  * of any other failure.
+  */
+@@ -447,7 +447,7 @@ int of_irq_count(struct device_node *dev)
+  * @res: array of resources to fill in
+  * @nr_irqs: the number of IRQs (and upper bound for num of @res elements)
+  *
+- * Returns the size of the filled in table (up to @nr_irqs).
++ * Return: The size of the filled in table (up to @nr_irqs).
+  */
+ int of_irq_to_resource_table(struct device_node *dev, struct resource *res,
+               int nr_irqs)
+@@ -602,7 +602,7 @@ static u32 __of_msi_map_id(struct device *dev, struct device_node **np,
+  * Walk up the device hierarchy looking for devices with a "msi-map"
+  * property.  If found, apply the mapping to @id_in.
+  *
+- * Returns the mapped MSI ID.
++ * Return: The mapped MSI ID.
+  */
+ u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in)
+ {
+diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
+index dc298775f7620..b551fe44f2f95 100644
+--- a/drivers/of/overlay.c
++++ b/drivers/of/overlay.c
+@@ -296,7 +296,7 @@ static struct property *dup_and_fixup_symbol_prop(
+  *
+  * Update of property in symbols node is not allowed.
+  *
+- * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
++ * Return: 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
+  * invalid @overlay.
+  */
+ static int add_changeset_property(struct overlay_changeset *ovcs,
+@@ -401,7 +401,7 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
+  *
+  * NOTE_2: Multiple mods of created nodes not supported.
+  *
+- * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
++ * Return: 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
+  * invalid @overlay.
+  */
+ static int add_changeset_node(struct overlay_changeset *ovcs,
+@@ -473,7 +473,7 @@ static int add_changeset_node(struct overlay_changeset *ovcs,
+  *
+  * Do not allow symbols node to have any children.
+  *
+- * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
++ * Return: 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
+  * invalid @overlay_node.
+  */
+ static int build_changeset_next_level(struct overlay_changeset *ovcs,
+@@ -604,7 +604,7 @@ static int find_dup_cset_prop(struct overlay_changeset *ovcs,
+  * the same node or duplicate {add, delete, or update} properties entries
+  * for the same property.
+  *
+- * Returns 0 on success, or -EINVAL if duplicate changeset entry found.
++ * Return: 0 on success, or -EINVAL if duplicate changeset entry found.
+  */
+ static int changeset_dup_entry_check(struct overlay_changeset *ovcs)
+ {
+@@ -628,7 +628,7 @@ static int changeset_dup_entry_check(struct overlay_changeset *ovcs)
+  * any portions of the changeset that were successfully created will remain
+  * in @ovcs->cset.
+  *
+- * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
++ * Return: 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
+  * invalid overlay in @ovcs->fragments[].
+  */
+ static int build_changeset(struct overlay_changeset *ovcs)
+@@ -724,7 +724,7 @@ static struct device_node *find_target(struct device_node *info_node)
+  * the top level of @tree.  The relevant top level nodes are the fragment
+  * nodes and the __symbols__ node.  Any other top level node will be ignored.
+  *
+- * Returns 0 on success, -ENOMEM if memory allocation failure, -EINVAL if error
++ * Return: 0 on success, -ENOMEM if memory allocation failure, -EINVAL if error
+  * detected in @tree, or -ENOSPC if idr_alloc() error.
+  */
+ static int init_overlay_changeset(struct overlay_changeset *ovcs,
+@@ -1180,7 +1180,7 @@ static int overlay_removal_is_ok(struct overlay_changeset *remove_ovcs)
+  * If an error is returned by an overlay changeset post-remove notifier
+  * then no further overlay changeset post-remove notifier will be called.
+  *
+- * Returns 0 on success, or a negative error number.  *ovcs_id is set to
++ * Return: 0 on success, or a negative error number.  *ovcs_id is set to
+  * zero after reverting the changeset, even if a subsequent error occurs.
+  */
+ int of_overlay_remove(int *ovcs_id)
+@@ -1267,7 +1267,7 @@ EXPORT_SYMBOL_GPL(of_overlay_remove);
+  *
+  * Removes all overlays from the system in the correct order.
+  *
+- * Returns 0 on success, or a negative error number
++ * Return: 0 on success, or a negative error number
+  */
+ int of_overlay_remove_all(void)
+ {
+diff --git a/drivers/of/platform.c b/drivers/of/platform.c
+index b47a2292fe8e8..cf5dbc9536f20 100644
+--- a/drivers/of/platform.c
++++ b/drivers/of/platform.c
+@@ -44,7 +44,7 @@ static const struct of_device_id of_skipped_node_table[] = {
+  * Takes a reference to the embedded struct device which needs to be dropped
+  * after use.
+  *
+- * Returns platform_device pointer, or NULL if not found
++ * Return: platform_device pointer, or NULL if not found
+  */
+ struct platform_device *of_find_device_by_node(struct device_node *np)
+ {
+@@ -160,7 +160,7 @@ EXPORT_SYMBOL(of_device_alloc);
+  * @platform_data: pointer to populate platform_data pointer with
+  * @parent: Linux device model parent device.
+  *
+- * Returns pointer to created platform device, or NULL if a device was not
++ * Return: Pointer to created platform device, or NULL if a device was not
+  * registered.  Unavailable devices will not get registered.
+  */
+ static struct platform_device *of_platform_device_create_pdata(
+@@ -204,7 +204,7 @@ static struct platform_device *of_platform_device_create_pdata(
+  * @bus_id: name to assign device
+  * @parent: Linux device model parent device.
+  *
+- * Returns pointer to created platform device, or NULL if a device was not
++ * Return: Pointer to created platform device, or NULL if a device was not
+  * registered.  Unavailable devices will not get registered.
+  */
+ struct platform_device *of_platform_device_create(struct device_node *np,
+@@ -463,7 +463,7 @@ EXPORT_SYMBOL(of_platform_bus_probe);
+  * New board support should be using this function instead of
+  * of_platform_bus_probe().
+  *
+- * Returns 0 on success, < 0 on failure.
++ * Return: 0 on success, < 0 on failure.
+  */
+ int of_platform_populate(struct device_node *root,
+                       const struct of_device_id *matches,
+@@ -594,7 +594,7 @@ static void devm_of_platform_populate_release(struct device *dev, void *res)
+  * Similar to of_platform_populate(), but will automatically call
+  * of_platform_depopulate() when the device is unbound from the bus.
+  *
+- * Returns 0 on success, < 0 on failure.
++ * Return: 0 on success, < 0 on failure.
+  */
+ int devm_of_platform_populate(struct device *dev)
+ {
+diff --git a/drivers/of/property.c b/drivers/of/property.c
+index f6010ec0f67b1..28ea326d102f9 100644
+--- a/drivers/of/property.c
++++ b/drivers/of/property.c
+@@ -36,9 +36,11 @@
+  * @elem_size:        size of the individual element
+  *
+  * Search for a property in a device node and count the number of elements of
+- * size elem_size in it. Returns number of elements on sucess, -EINVAL if the
+- * property does not exist or its length does not match a multiple of elem_size
+- * and -ENODATA if the property does not have a value.
++ * size elem_size in it.
++ *
++ * Return: The number of elements on sucess, -EINVAL if the property does not
++ * exist or its length does not match a multiple of elem_size and -ENODATA if
++ * the property does not have a value.
+  */
+ int of_property_count_elems_of_size(const struct device_node *np,
+                               const char *propname, int elem_size)
+@@ -70,8 +72,9 @@ EXPORT_SYMBOL_GPL(of_property_count_elems_of_size);
+  * @len:      if !=NULL, actual length is written to here
+  *
+  * Search for a property in a device node and valid the requested size.
+- * Returns the property value on success, -EINVAL if the property does not
+- *  exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
++ *
++ * Return: The property value on success, -EINVAL if the property does not
++ * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
+  * property data is too small or too large.
+  *
+  */
+@@ -104,7 +107,9 @@ static void *of_find_property_value_of_size(const struct device_node *np,
+  * @out_value:        pointer to return value, modified only if no error.
+  *
+  * Search for a property in a device node and read nth 32-bit value from
+- * it. Returns 0 on success, -EINVAL if the property does not exist,
++ * it.
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist,
+  * -ENODATA if property does not have a value, and -EOVERFLOW if the
+  * property data isn't large enough.
+  *
+@@ -136,7 +141,9 @@ EXPORT_SYMBOL_GPL(of_property_read_u32_index);
+  * @out_value:        pointer to return value, modified only if no error.
+  *
+  * Search for a property in a device node and read nth 64-bit value from
+- * it. Returns 0 on success, -EINVAL if the property does not exist,
++ * it.
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist,
+  * -ENODATA if property does not have a value, and -EOVERFLOW if the
+  * property data isn't large enough.
+  *
+@@ -171,12 +178,14 @@ EXPORT_SYMBOL_GPL(of_property_read_u64_index);
+  *            sz_min will be read.
+  *
+  * Search for a property in a device node and read 8-bit value(s) from
+- * it. Returns number of elements read on success, -EINVAL if the property
+- * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
+- * if the property data is smaller than sz_min or longer than sz_max.
++ * it.
+  *
+  * dts entry of array should be like:
+- *    property = /bits/ 8 <0x50 0x60 0x70>;
++ *  ``property = /bits/ 8 <0x50 0x60 0x70>;``
++ *
++ * Return: The number of elements read on success, -EINVAL if the property
++ * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
++ * if the property data is smaller than sz_min or longer than sz_max.
+  *
+  * The out_values is modified only if a valid u8 value can be decoded.
+  */
+@@ -219,12 +228,14 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u8_array);
+  *            sz_min will be read.
+  *
+  * Search for a property in a device node and read 16-bit value(s) from
+- * it. Returns number of elements read on success, -EINVAL if the property
+- * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
+- * if the property data is smaller than sz_min or longer than sz_max.
++ * it.
+  *
+  * dts entry of array should be like:
+- *    property = /bits/ 16 <0x5000 0x6000 0x7000>;
++ *  ``property = /bits/ 16 <0x5000 0x6000 0x7000>;``
++ *
++ * Return: The number of elements read on success, -EINVAL if the property
++ * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
++ * if the property data is smaller than sz_min or longer than sz_max.
+  *
+  * The out_values is modified only if a valid u16 value can be decoded.
+  */
+@@ -267,7 +278,9 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u16_array);
+  *            sz_min will be read.
+  *
+  * Search for a property in a device node and read 32-bit value(s) from
+- * it. Returns number of elements read on success, -EINVAL if the property
++ * it.
++ *
++ * Return: The number of elements read on success, -EINVAL if the property
+  * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
+  * if the property data is smaller than sz_min or longer than sz_max.
+  *
+@@ -306,7 +319,9 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u32_array);
+  * @out_value:        pointer to return value, modified only if return value is 0.
+  *
+  * Search for a property in a device node and read a 64-bit value from
+- * it. Returns 0 on success, -EINVAL if the property does not exist,
++ * it.
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist,
+  * -ENODATA if property does not have a value, and -EOVERFLOW if the
+  * property data isn't large enough.
+  *
+@@ -341,7 +356,9 @@ EXPORT_SYMBOL_GPL(of_property_read_u64);
+  *            sz_min will be read.
+  *
+  * Search for a property in a device node and read 64-bit value(s) from
+- * it. Returns number of elements read on success, -EINVAL if the property
++ * it.
++ *
++ * Return: The number of elements read on success, -EINVAL if the property
+  * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
+  * if the property data is smaller than sz_min or longer than sz_max.
+  *
+@@ -383,10 +400,11 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u64_array);
+  *            return value is 0.
+  *
+  * Search for a property in a device tree node and retrieve a null
+- * terminated string value (pointer to data, not a copy). Returns 0 on
+- * success, -EINVAL if the property does not exist, -ENODATA if property
+- * does not have a value, and -EILSEQ if the string is not null-terminated
+- * within the length of the property data.
++ * terminated string value (pointer to data, not a copy).
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist, -ENODATA if
++ * property does not have a value, and -EILSEQ if the string is not
++ * null-terminated within the length of the property data.
+  *
+  * The out_string pointer is modified only if a valid string can be decoded.
+  */
+@@ -750,7 +768,7 @@ EXPORT_SYMBOL(of_graph_get_remote_port_parent);
+  * @node: pointer to a local endpoint device_node
+  *
+  * Return: Remote port node associated with remote endpoint node linked
+- *       to @node. Use of_node_put() on it when done.
++ * to @node. Use of_node_put() on it when done.
+  */
+ struct device_node *of_graph_get_remote_port(const struct device_node *node)
+ {
+@@ -783,7 +801,7 @@ EXPORT_SYMBOL(of_graph_get_endpoint_count);
+  * @endpoint: identifier (value of reg property) of the endpoint node
+  *
+  * Return: Remote device node associated with remote endpoint node linked
+- *       to @node. Use of_node_put() on it when done.
++ * to @node. Use of_node_put() on it when done.
+  */
+ struct device_node *of_graph_get_remote_node(const struct device_node *node,
+                                            u32 port, u32 endpoint)
+diff --git a/include/linux/of.h b/include/linux/of.h
+index e070c5ed62a09..8681277af9c6f 100644
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -424,12 +424,14 @@ extern int of_detach_node(struct device_node *);
+  * @sz:               number of array elements to read
+  *
+  * Search for a property in a device node and read 8-bit value(s) from
+- * it. Returns 0 on success, -EINVAL if the property does not exist,
+- * -ENODATA if property does not have a value, and -EOVERFLOW if the
+- * property data isn't large enough.
++ * it.
+  *
+  * dts entry of array should be like:
+- *    property = /bits/ 8 <0x50 0x60 0x70>;
++ *  ``property = /bits/ 8 <0x50 0x60 0x70>;``
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist,
++ * -ENODATA if property does not have a value, and -EOVERFLOW if the
++ * property data isn't large enough.
+  *
+  * The out_values is modified only if a valid u8 value can be decoded.
+  */
+@@ -454,12 +456,14 @@ static inline int of_property_read_u8_array(const struct device_node *np,
+  * @sz:               number of array elements to read
+  *
+  * Search for a property in a device node and read 16-bit value(s) from
+- * it. Returns 0 on success, -EINVAL if the property does not exist,
+- * -ENODATA if property does not have a value, and -EOVERFLOW if the
+- * property data isn't large enough.
++ * it.
+  *
+  * dts entry of array should be like:
+- *    property = /bits/ 16 <0x5000 0x6000 0x7000>;
++ *  ``property = /bits/ 16 <0x5000 0x6000 0x7000>;``
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist,
++ * -ENODATA if property does not have a value, and -EOVERFLOW if the
++ * property data isn't large enough.
+  *
+  * The out_values is modified only if a valid u16 value can be decoded.
+  */
+@@ -485,7 +489,9 @@ static inline int of_property_read_u16_array(const struct device_node *np,
+  * @sz:               number of array elements to read
+  *
+  * Search for a property in a device node and read 32-bit value(s) from
+- * it. Returns 0 on success, -EINVAL if the property does not exist,
++ * it.
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist,
+  * -ENODATA if property does not have a value, and -EOVERFLOW if the
+  * property data isn't large enough.
+  *
+@@ -513,7 +519,9 @@ static inline int of_property_read_u32_array(const struct device_node *np,
+  * @sz:               number of array elements to read
+  *
+  * Search for a property in a device node and read 64-bit value(s) from
+- * it. Returns 0 on success, -EINVAL if the property does not exist,
++ * it.
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist,
+  * -ENODATA if property does not have a value, and -EOVERFLOW if the
+  * property data isn't large enough.
+  *
+@@ -1046,7 +1054,9 @@ static inline bool of_node_is_type(const struct device_node *np, const char *typ
+  * @propname: name of the property to be searched.
+  *
+  * Search for a property in a device node and count the number of u8 elements
+- * in it. Returns number of elements on sucess, -EINVAL if the property does
++ * in it.
++ *
++ * Return: The number of elements on sucess, -EINVAL if the property does
+  * not exist or its length does not match a multiple of u8 and -ENODATA if the
+  * property does not have a value.
+  */
+@@ -1063,7 +1073,9 @@ static inline int of_property_count_u8_elems(const struct device_node *np,
+  * @propname: name of the property to be searched.
+  *
+  * Search for a property in a device node and count the number of u16 elements
+- * in it. Returns number of elements on sucess, -EINVAL if the property does
++ * in it.
++ *
++ * Return: The number of elements on sucess, -EINVAL if the property does
+  * not exist or its length does not match a multiple of u16 and -ENODATA if the
+  * property does not have a value.
+  */
+@@ -1080,7 +1092,9 @@ static inline int of_property_count_u16_elems(const struct device_node *np,
+  * @propname: name of the property to be searched.
+  *
+  * Search for a property in a device node and count the number of u32 elements
+- * in it. Returns number of elements on sucess, -EINVAL if the property does
++ * in it.
++ *
++ * Return: The number of elements on sucess, -EINVAL if the property does
+  * not exist or its length does not match a multiple of u32 and -ENODATA if the
+  * property does not have a value.
+  */
+@@ -1097,7 +1111,9 @@ static inline int of_property_count_u32_elems(const struct device_node *np,
+  * @propname: name of the property to be searched.
+  *
+  * Search for a property in a device node and count the number of u64 elements
+- * in it. Returns number of elements on sucess, -EINVAL if the property does
++ * in it.
++ *
++ * Return: The number of elements on sucess, -EINVAL if the property does
+  * not exist or its length does not match a multiple of u64 and -ENODATA if the
+  * property does not have a value.
+  */
+@@ -1118,7 +1134,7 @@ static inline int of_property_count_u64_elems(const struct device_node *np,
+  * Search for a property in a device tree node and retrieve a list of
+  * terminated string values (pointer to data, not a copy) in that property.
+  *
+- * If @out_strs is NULL, the number of strings in the property is returned.
++ * Return: If @out_strs is NULL, the number of strings in the property is returned.
+  */
+ static inline int of_property_read_string_array(const struct device_node *np,
+                                               const char *propname, const char **out_strs,
+@@ -1134,10 +1150,11 @@ static inline int of_property_read_string_array(const struct device_node *np,
+  * @propname: name of the property to be searched.
+  *
+  * Search for a property in a device tree node and retrieve the number of null
+- * terminated string contain in it. Returns the number of strings on
+- * success, -EINVAL if the property does not exist, -ENODATA if property
+- * does not have a value, and -EILSEQ if the string is not null-terminated
+- * within the length of the property data.
++ * terminated string contain in it.
++ *
++ * Return: The number of strings on success, -EINVAL if the property does not
++ * exist, -ENODATA if property does not have a value, and -EILSEQ if the string
++ * is not null-terminated within the length of the property data.
+  */
+ static inline int of_property_count_strings(const struct device_node *np,
+                                           const char *propname)
+@@ -1157,7 +1174,8 @@ static inline int of_property_count_strings(const struct device_node *np,
+  * Search for a property in a device tree node and retrieve a null
+  * terminated string value (pointer to data, not a copy) in the list of strings
+  * contained in that property.
+- * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
++ *
++ * Return: 0 on success, -EINVAL if the property does not exist, -ENODATA if
+  * property does not have a value, and -EILSEQ if the string is not
+  * null-terminated within the length of the property data.
+  *
+@@ -1177,7 +1195,8 @@ static inline int of_property_read_string_index(const struct device_node *np,
+  * @propname: name of the property to be searched.
+  *
+  * Search for a property in a device node.
+- * Returns true if the property exists false otherwise.
++ *
++ * Return: true if the property exists false otherwise.
+  */
+ static inline bool of_property_read_bool(const struct device_node *np,
+                                        const char *propname)
+@@ -1423,7 +1442,7 @@ static inline int of_reconfig_get_state_change(unsigned long action,
+  * of_device_is_system_power_controller - Tells if system-power-controller is found for device_node
+  * @np: Pointer to the given device_node
+  *
+- * return true if present false otherwise
++ * Return: true if present false otherwise
+  */
+ static inline bool of_device_is_system_power_controller(const struct device_node *np)
+ {
+-- 
+2.42.0
+
diff --git a/queue-5.4/of-base-add-of_get_cpu_state_node-to-get-idle-states.patch b/queue-5.4/of-base-add-of_get_cpu_state_node-to-get-idle-states.patch
new file mode 100644 (file)
index 0000000..5819f72
--- /dev/null
@@ -0,0 +1,116 @@
+From e8f906090506040660495eb0f530a35318533ba6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Oct 2019 12:01:48 +0200
+Subject: of: base: Add of_get_cpu_state_node() to get idle states for a CPU
+ node
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+[ Upstream commit b9f8c26afc405a4a616e765e949bdd551151e41d ]
+
+The CPU's idle state nodes are currently parsed at the common cpuidle DT
+library, but also when initializing data for specific CPU idle operations,
+as in the PSCI cpuidle driver case and qcom-spm cpuidle case.
+
+To avoid open-coding, let's introduce of_get_cpu_state_node(), which takes
+the device node for the CPU and the index to the requested idle state node,
+as in-parameters. In case a corresponding idle state node is found, it
+returns the node with the refcount incremented for it, else it returns
+NULL.
+
+Moreover, for PSCI there are two options to describe the CPU's idle states
+[1], either via a flattened description or a hierarchical layout. Hence,
+let's take both options into account.
+
+[1] Documentation/devicetree/bindings/arm/psci.yaml
+
+Suggested-by: Sudeep Holla <sudeep.holla@arm.com>
+Co-developed-by: Lina Iyer <lina.iyer@linaro.org>
+Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/base.c  | 36 ++++++++++++++++++++++++++++++++++++
+ include/linux/of.h |  8 ++++++++
+ 2 files changed, 44 insertions(+)
+
+diff --git a/drivers/of/base.c b/drivers/of/base.c
+index b5c84607a74bf..3f13b982e8b53 100644
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -477,6 +477,42 @@ int of_cpu_node_to_id(struct device_node *cpu_node)
+ }
+ EXPORT_SYMBOL(of_cpu_node_to_id);
++/**
++ * of_get_cpu_state_node - Get CPU's idle state node at the given index
++ *
++ * @cpu_node: The device node for the CPU
++ * @index: The index in the list of the idle states
++ *
++ * Two generic methods can be used to describe a CPU's idle states, either via
++ * a flattened description through the "cpu-idle-states" binding or via the
++ * hierarchical layout, using the "power-domains" and the "domain-idle-states"
++ * bindings. This function check for both and returns the idle state node for
++ * the requested index.
++ *
++ * In case an idle state node is found at @index, the refcount is incremented
++ * for it, so call of_node_put() on it when done. Returns NULL if not found.
++ */
++struct device_node *of_get_cpu_state_node(struct device_node *cpu_node,
++                                        int index)
++{
++      struct of_phandle_args args;
++      int err;
++
++      err = of_parse_phandle_with_args(cpu_node, "power-domains",
++                                      "#power-domain-cells", 0, &args);
++      if (!err) {
++              struct device_node *state_node =
++                      of_parse_phandle(args.np, "domain-idle-states", index);
++
++              of_node_put(args.np);
++              if (state_node)
++                      return state_node;
++      }
++
++      return of_parse_phandle(cpu_node, "cpu-idle-states", index);
++}
++EXPORT_SYMBOL(of_get_cpu_state_node);
++
+ /**
+  * __of_device_is_compatible() - Check if the node matches given constraints
+  * @device: pointer to node
+diff --git a/include/linux/of.h b/include/linux/of.h
+index a7621e2b440ad..e29b341598e99 100644
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -351,6 +351,8 @@ extern const void *of_get_property(const struct device_node *node,
+                               int *lenp);
+ extern struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
+ extern struct device_node *of_get_next_cpu_node(struct device_node *prev);
++extern struct device_node *of_get_cpu_state_node(struct device_node *cpu_node,
++                                               int index);
+ #define for_each_property_of_node(dn, pp) \
+       for (pp = dn->properties; pp != NULL; pp = pp->next)
+@@ -765,6 +767,12 @@ static inline struct device_node *of_get_next_cpu_node(struct device_node *prev)
+       return NULL;
+ }
++static inline struct device_node *of_get_cpu_state_node(struct device_node *cpu_node,
++                                      int index)
++{
++      return NULL;
++}
++
+ static inline int of_n_addr_cells(struct device_node *np)
+ {
+       return 0;
+-- 
+2.42.0
+
diff --git a/queue-5.4/of-base-fix-some-formatting-issues-and-provide-missi.patch b/queue-5.4/of-base-fix-some-formatting-issues-and-provide-missi.patch
new file mode 100644 (file)
index 0000000..2b95831
--- /dev/null
@@ -0,0 +1,105 @@
+From 538e78aea655244d2819a4745898f149e1b99a98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Mar 2021 10:40:30 +0000
+Subject: of: base: Fix some formatting issues and provide missing descriptions
+
+From: Lee Jones <lee.jones@linaro.org>
+
+[ Upstream commit 3637d49e11219512920aca8b8ccd0994be33fa8b ]
+
+Fixes the following W=1 kernel build warning(s):
+
+ drivers/of/base.c:315: warning: Function parameter or member 'cpun' not described in '__of_find_n_match_cpu_property'
+ drivers/of/base.c:315: warning: Function parameter or member 'prop_name' not described in '__of_find_n_match_cpu_property'
+ drivers/of/base.c:315: warning: Function parameter or member 'cpu' not described in '__of_find_n_match_cpu_property'
+ drivers/of/base.c:315: warning: Function parameter or member 'thread' not described in '__of_find_n_match_cpu_property'
+ drivers/of/base.c:315: warning: expecting prototype for property holds the physical id of the(). Prototype was for __of_find_n_match_cpu_property() instead
+ drivers/of/base.c:1139: warning: Function parameter or member 'match' not described in 'of_find_matching_node_and_match'
+ drivers/of/base.c:1779: warning: Function parameter or member 'np' not described in '__of_add_property'
+ drivers/of/base.c:1779: warning: Function parameter or member 'prop' not described in '__of_add_property'
+ drivers/of/base.c:1800: warning: Function parameter or member 'np' not described in 'of_add_property'
+ drivers/of/base.c:1800: warning: Function parameter or member 'prop' not described in 'of_add_property'
+ drivers/of/base.c:1849: warning: Function parameter or member 'np' not described in 'of_remove_property'
+ drivers/of/base.c:1849: warning: Function parameter or member 'prop' not described in 'of_remove_property'
+ drivers/of/base.c:2137: warning: Function parameter or member 'dn' not described in 'of_console_check'
+ drivers/of/base.c:2137: warning: Function parameter or member 'name' not described in 'of_console_check'
+ drivers/of/base.c:2137: warning: Function parameter or member 'index' not described in 'of_console_check'
+
+Cc: Rob Herring <robh+dt@kernel.org>
+Cc: Frank Rowand <frowand.list@gmail.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: devicetree@vger.kernel.org
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20210318104036.3175910-5-lee.jones@linaro.org
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/base.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/of/base.c b/drivers/of/base.c
+index 5c97366628b13..4032814133fe6 100644
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -367,7 +367,7 @@ bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
+       return (u32)phys_id == cpu;
+ }
+-/**
++/*
+  * Checks if the given "prop_name" property holds the physical id of the
+  * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not
+  * NULL, local thread number within the core is returned in it.
+@@ -1190,7 +1190,7 @@ EXPORT_SYMBOL(of_match_node);
+  *                    will; typically, you pass what the previous call
+  *                    returned. of_node_put() will be called on it
+  *    @matches:       array of of device match structures to search in
+- *    @match          Updated to point at the matches entry which matched
++ *    @match:         Updated to point at the matches entry which matched
+  *
+  *    Returns a node pointer with refcount incremented, use
+  *    of_node_put() on it when done.
+@@ -1853,6 +1853,8 @@ EXPORT_SYMBOL(of_count_phandle_with_args);
+ /**
+  * __of_add_property - Add a property to a node without lock operations
++ * @np:               Caller's Device Node
++ * @prob:     Property to add
+  */
+ int __of_add_property(struct device_node *np, struct property *prop)
+ {
+@@ -1874,6 +1876,8 @@ int __of_add_property(struct device_node *np, struct property *prop)
+ /**
+  * of_add_property - Add a property to a node
++ * @np:               Caller's Device Node
++ * @prob:     Property to add
+  */
+ int of_add_property(struct device_node *np, struct property *prop)
+ {
+@@ -1918,6 +1922,8 @@ int __of_remove_property(struct device_node *np, struct property *prop)
+ /**
+  * of_remove_property - Remove a property from a node.
++ * @np:               Caller's Device Node
++ * @prob:     Property to remove
+  *
+  * Note that we don't actually remove it, since we have given out
+  * who-knows-how-many pointers to the data using get-property.
+@@ -2203,9 +2209,9 @@ EXPORT_SYMBOL_GPL(of_alias_get_highest_id);
+ /**
+  * of_console_check() - Test and setup console for DT setup
+- * @dn - Pointer to device node
+- * @name - Name to use for preferred console without index. ex. "ttyS"
+- * @index - Index to use for preferred console.
++ * @dn: Pointer to device node
++ * @name: Name to use for preferred console without index. ex. "ttyS"
++ * @index: Index to use for preferred console.
+  *
+  * Check if the given device node matches the stdout-path property in the
+  * /chosen node. If it does then register it as the preferred console and return
+-- 
+2.42.0
+
diff --git a/queue-5.4/of-dynamic-fix-of_reconfig_get_state_change-return-v.patch b/queue-5.4/of-dynamic-fix-of_reconfig_get_state_change-return-v.patch
new file mode 100644 (file)
index 0000000..d261538
--- /dev/null
@@ -0,0 +1,41 @@
+From 8cf8ba72543852f7312e8388fc5f22a995d5eba3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Nov 2023 15:47:18 +0100
+Subject: of: dynamic: Fix of_reconfig_get_state_change() return value
+ documentation
+
+From: Luca Ceresoli <luca.ceresoli@bootlin.com>
+
+[ Upstream commit d79972789d17499b6091ded2fc0c6763c501a5ba ]
+
+The documented numeric return values do not match the actual returned
+values. Fix them by using the enum names instead of raw numbers.
+
+Fixes: b53a2340d0d3 ("of/reconfig: Add of_reconfig_get_state_change() of notifier helper.")
+Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
+Link: https://lore.kernel.org/r/20231123-fix-of_reconfig_get_state_change-docs-v1-1-f51892050ff9@bootlin.com
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/dynamic.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
+index 92ee15be78d43..ae969630958cd 100644
+--- a/drivers/of/dynamic.c
++++ b/drivers/of/dynamic.c
+@@ -105,8 +105,9 @@ int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p)
+  *
+  * Returns the new state of a device based on the notifier used.
+  *
+- * Return: 0 on device going from enabled to disabled, 1 on device
+- * going from disabled to enabled and -1 on no change.
++ * Return: OF_RECONFIG_CHANGE_REMOVE on device going from enabled to
++ * disabled, OF_RECONFIG_CHANGE_ADD on device going from disabled to
++ * enabled and OF_RECONFIG_NO_CHANGE on no change.
+  */
+ int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr)
+ {
+-- 
+2.42.0
+
diff --git a/queue-5.4/of-fix-kerneldoc-output-formatting.patch b/queue-5.4/of-fix-kerneldoc-output-formatting.patch
new file mode 100644 (file)
index 0000000..5603082
--- /dev/null
@@ -0,0 +1,500 @@
+From 19c581a873796822ddf355a4544dfa6550739ede Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Mar 2021 13:26:06 -0600
+Subject: of: Fix kerneldoc output formatting
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit 62f026f082e4d762a47b43ea693b38f025122332 ]
+
+The indentation of the kerneldoc comments affects the output formatting.
+Leading tabs in particular don't work, sections need to be indented
+under the section header, and several code blocks are reformatted.
+
+Cc: Frank Rowand <frowand.list@gmail.com>
+Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Link: https://lore.kernel.org/r/20210326192606.3702739-1-robh@kernel.org
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/base.c | 275 +++++++++++++++++++++++-----------------------
+ drivers/of/fdt.c  |   9 +-
+ 2 files changed, 141 insertions(+), 143 deletions(-)
+
+diff --git a/drivers/of/base.c b/drivers/of/base.c
+index 4032814133fe6..c4c64ef5fb7a8 100644
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -713,11 +713,11 @@ bool of_device_is_big_endian(const struct device_node *device)
+ EXPORT_SYMBOL(of_device_is_big_endian);
+ /**
+- *    of_get_parent - Get a node's parent if any
+- *    @node:  Node to get parent
++ * of_get_parent - Get a node's parent if any
++ * @node:     Node to get parent
+  *
+- *    Returns a node pointer with refcount incremented, use
+- *    of_node_put() on it when done.
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.
+  */
+ struct device_node *of_get_parent(const struct device_node *node)
+ {
+@@ -735,15 +735,15 @@ struct device_node *of_get_parent(const struct device_node *node)
+ EXPORT_SYMBOL(of_get_parent);
+ /**
+- *    of_get_next_parent - Iterate to a node's parent
+- *    @node:  Node to get parent of
++ * of_get_next_parent - Iterate to a node's parent
++ * @node:     Node to get parent of
+  *
+- *    This is like of_get_parent() except that it drops the
+- *    refcount on the passed node, making it suitable for iterating
+- *    through a node's parents.
++ * This is like of_get_parent() except that it drops the
++ * refcount on the passed node, making it suitable for iterating
++ * through a node's parents.
+  *
+- *    Returns a node pointer with refcount incremented, use
+- *    of_node_put() on it when done.
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.
+  */
+ struct device_node *of_get_next_parent(struct device_node *node)
+ {
+@@ -781,13 +781,13 @@ static struct device_node *__of_get_next_child(const struct device_node *node,
+            child = __of_get_next_child(parent, child))
+ /**
+- *    of_get_next_child - Iterate a node childs
+- *    @node:  parent node
+- *    @prev:  previous child of the parent node, or NULL to get first
++ * of_get_next_child - Iterate a node childs
++ * @node:     parent node
++ * @prev:     previous child of the parent node, or NULL to get first
+  *
+- *    Returns a node pointer with refcount incremented, use of_node_put() on
+- *    it when done. Returns NULL when prev is the last child. Decrements the
+- *    refcount of prev.
++ * Return: A node pointer with refcount incremented, use of_node_put() on
++ * it when done. Returns NULL when prev is the last child. Decrements the
++ * refcount of prev.
+  */
+ struct device_node *of_get_next_child(const struct device_node *node,
+       struct device_node *prev)
+@@ -803,12 +803,12 @@ struct device_node *of_get_next_child(const struct device_node *node,
+ EXPORT_SYMBOL(of_get_next_child);
+ /**
+- *    of_get_next_available_child - Find the next available child node
+- *    @node:  parent node
+- *    @prev:  previous child of the parent node, or NULL to get first
++ * of_get_next_available_child - Find the next available child node
++ * @node:     parent node
++ * @prev:     previous child of the parent node, or NULL to get first
+  *
+- *      This function is like of_get_next_child(), except that it
+- *      automatically skips any disabled nodes (i.e. status = "disabled").
++ * This function is like of_get_next_child(), except that it
++ * automatically skips any disabled nodes (i.e. status = "disabled").
+  */
+ struct device_node *of_get_next_available_child(const struct device_node *node,
+       struct device_node *prev)
+@@ -834,12 +834,12 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
+ EXPORT_SYMBOL(of_get_next_available_child);
+ /**
+- *    of_get_next_cpu_node - Iterate on cpu nodes
+- *    @prev:  previous child of the /cpus node, or NULL to get first
++ * of_get_next_cpu_node - Iterate on cpu nodes
++ * @prev:     previous child of the /cpus node, or NULL to get first
+  *
+- *    Returns a cpu node pointer with refcount incremented, use of_node_put()
+- *    on it when done. Returns NULL when prev is the last child. Decrements
+- *    the refcount of prev.
++ * Return: A cpu node pointer with refcount incremented, use of_node_put()
++ * on it when done. Returns NULL when prev is the last child. Decrements
++ * the refcount of prev.
+  */
+ struct device_node *of_get_next_cpu_node(struct device_node *prev)
+ {
+@@ -896,15 +896,15 @@ struct device_node *of_get_compatible_child(const struct device_node *parent,
+ EXPORT_SYMBOL(of_get_compatible_child);
+ /**
+- *    of_get_child_by_name - Find the child node by name for a given parent
+- *    @node:  parent node
+- *    @name:  child name to look for.
++ * of_get_child_by_name - Find the child node by name for a given parent
++ * @node:     parent node
++ * @name:     child name to look for.
+  *
+- *      This function looks for child node for given matching name
++ * This function looks for child node for given matching name
+  *
+- *    Returns a node pointer if found, with refcount incremented, use
+- *    of_node_put() on it when done.
+- *    Returns NULL if node is not found.
++ * Return: A node pointer if found, with refcount incremented, use
++ * of_node_put() on it when done.
++ * Returns NULL if node is not found.
+  */
+ struct device_node *of_get_child_by_name(const struct device_node *node,
+                               const char *name)
+@@ -955,22 +955,22 @@ struct device_node *__of_find_node_by_full_path(struct device_node *node,
+ }
+ /**
+- *    of_find_node_opts_by_path - Find a node matching a full OF path
+- *    @path: Either the full path to match, or if the path does not
+- *           start with '/', the name of a property of the /aliases
+- *           node (an alias).  In the case of an alias, the node
+- *           matching the alias' value will be returned.
+- *    @opts: Address of a pointer into which to store the start of
+- *           an options string appended to the end of the path with
+- *           a ':' separator.
+- *
+- *    Valid paths:
+- *            /foo/bar        Full path
+- *            foo             Valid alias
+- *            foo/bar         Valid alias + relative path
+- *
+- *    Returns a node pointer with refcount incremented, use
+- *    of_node_put() on it when done.
++ * of_find_node_opts_by_path - Find a node matching a full OF path
++ * @path: Either the full path to match, or if the path does not
++ *       start with '/', the name of a property of the /aliases
++ *       node (an alias).  In the case of an alias, the node
++ *       matching the alias' value will be returned.
++ * @opts: Address of a pointer into which to store the start of
++ *       an options string appended to the end of the path with
++ *       a ':' separator.
++ *
++ * Valid paths:
++ *  * /foo/bar        Full path
++ *  * foo     Valid alias
++ *  * foo/bar Valid alias + relative path
++ *
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.
+  */
+ struct device_node *of_find_node_opts_by_path(const char *path, const char **opts)
+ {
+@@ -1020,15 +1020,15 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt
+ EXPORT_SYMBOL(of_find_node_opts_by_path);
+ /**
+- *    of_find_node_by_name - Find a node by its "name" property
+- *    @from:  The node to start searching from or NULL; the node
++ * of_find_node_by_name - Find a node by its "name" property
++ * @from:     The node to start searching from or NULL; the node
+  *            you pass will not be searched, only the next one
+  *            will. Typically, you pass what the previous call
+  *            returned. of_node_put() will be called on @from.
+- *    @name:  The name string to match against
++ * @name:     The name string to match against
+  *
+- *    Returns a node pointer with refcount incremented, use
+- *    of_node_put() on it when done.
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.
+  */
+ struct device_node *of_find_node_by_name(struct device_node *from,
+       const char *name)
+@@ -1047,16 +1047,16 @@ struct device_node *of_find_node_by_name(struct device_node *from,
+ EXPORT_SYMBOL(of_find_node_by_name);
+ /**
+- *    of_find_node_by_type - Find a node by its "device_type" property
+- *    @from:  The node to start searching from, or NULL to start searching
++ * of_find_node_by_type - Find a node by its "device_type" property
++ * @from:     The node to start searching from, or NULL to start searching
+  *            the entire device tree. The node you pass will not be
+  *            searched, only the next one will; typically, you pass
+  *            what the previous call returned. of_node_put() will be
+  *            called on from for you.
+- *    @type:  The type string to match against
++ * @type:     The type string to match against
+  *
+- *    Returns a node pointer with refcount incremented, use
+- *    of_node_put() on it when done.
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.
+  */
+ struct device_node *of_find_node_by_type(struct device_node *from,
+       const char *type)
+@@ -1075,18 +1075,18 @@ struct device_node *of_find_node_by_type(struct device_node *from,
+ EXPORT_SYMBOL(of_find_node_by_type);
+ /**
+- *    of_find_compatible_node - Find a node based on type and one of the
++ * of_find_compatible_node - Find a node based on type and one of the
+  *                                tokens in its "compatible" property
+- *    @from:          The node to start searching from or NULL, the node
+- *                    you pass will not be searched, only the next one
+- *                    will; typically, you pass what the previous call
+- *                    returned. of_node_put() will be called on it
+- *    @type:          The type string to match "device_type" or NULL to ignore
+- *    @compatible:    The string to match to one of the tokens in the device
+- *                    "compatible" list.
+- *
+- *    Returns a node pointer with refcount incremented, use
+- *    of_node_put() on it when done.
++ * @from:     The node to start searching from or NULL, the node
++ *            you pass will not be searched, only the next one
++ *            will; typically, you pass what the previous call
++ *            returned. of_node_put() will be called on it
++ * @type:     The type string to match "device_type" or NULL to ignore
++ * @compatible:       The string to match to one of the tokens in the device
++ *            "compatible" list.
++ *
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.
+  */
+ struct device_node *of_find_compatible_node(struct device_node *from,
+       const char *type, const char *compatible)
+@@ -1106,16 +1106,16 @@ struct device_node *of_find_compatible_node(struct device_node *from,
+ EXPORT_SYMBOL(of_find_compatible_node);
+ /**
+- *    of_find_node_with_property - Find a node which has a property with
+- *                                   the given name.
+- *    @from:          The node to start searching from or NULL, the node
+- *                    you pass will not be searched, only the next one
+- *                    will; typically, you pass what the previous call
+- *                    returned. of_node_put() will be called on it
+- *    @prop_name:     The name of the property to look for.
+- *
+- *    Returns a node pointer with refcount incremented, use
+- *    of_node_put() on it when done.
++ * of_find_node_with_property - Find a node which has a property with
++ *                              the given name.
++ * @from:     The node to start searching from or NULL, the node
++ *            you pass will not be searched, only the next one
++ *            will; typically, you pass what the previous call
++ *            returned. of_node_put() will be called on it
++ * @prop_name:        The name of the property to look for.
++ *
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.
+  */
+ struct device_node *of_find_node_with_property(struct device_node *from,
+       const char *prop_name)
+@@ -1164,10 +1164,10 @@ const struct of_device_id *__of_match_node(const struct of_device_id *matches,
+ /**
+  * of_match_node - Tell if a device_node has a matching of_match structure
+- *    @matches:       array of of device match structures to search in
+- *    @node:          the of device structure to match against
++ * @matches:  array of of device match structures to search in
++ * @node:     the of device structure to match against
+  *
+- *    Low level utility function used by device matching.
++ * Low level utility function used by device matching.
+  */
+ const struct of_device_id *of_match_node(const struct of_device_id *matches,
+                                        const struct device_node *node)
+@@ -1183,17 +1183,17 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches,
+ EXPORT_SYMBOL(of_match_node);
+ /**
+- *    of_find_matching_node_and_match - Find a node based on an of_device_id
+- *                                      match table.
+- *    @from:          The node to start searching from or NULL, the node
+- *                    you pass will not be searched, only the next one
+- *                    will; typically, you pass what the previous call
+- *                    returned. of_node_put() will be called on it
+- *    @matches:       array of of device match structures to search in
+- *    @match:         Updated to point at the matches entry which matched
+- *
+- *    Returns a node pointer with refcount incremented, use
+- *    of_node_put() on it when done.
++ * of_find_matching_node_and_match - Find a node based on an of_device_id
++ *                                 match table.
++ * @from:     The node to start searching from or NULL, the node
++ *            you pass will not be searched, only the next one
++ *            will; typically, you pass what the previous call
++ *            returned. of_node_put() will be called on it
++ * @matches:  array of of device match structures to search in
++ * @match:    Updated to point at the matches entry which matched
++ *
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.
+  */
+ struct device_node *of_find_matching_node_and_match(struct device_node *from,
+                                       const struct of_device_id *matches,
+@@ -1539,21 +1539,21 @@ EXPORT_SYMBOL(of_parse_phandle);
+  * Caller is responsible to call of_node_put() on the returned out_args->np
+  * pointer.
+  *
+- * Example:
++ * Example::
+  *
+- * phandle1: node1 {
++ *  phandle1: node1 {
+  *    #list-cells = <2>;
+- * }
++ *  };
+  *
+- * phandle2: node2 {
++ *  phandle2: node2 {
+  *    #list-cells = <1>;
+- * }
++ *  };
+  *
+- * node3 {
++ *  node3 {
+  *    list = <&phandle1 1 2 &phandle2 3>;
+- * }
++ *  };
+  *
+- * To get a device_node of the `node2' node you may call this:
++ * To get a device_node of the ``node2`` node you may call this:
+  * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
+  */
+ int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
+@@ -1591,29 +1591,29 @@ EXPORT_SYMBOL(of_parse_phandle_with_args);
+  * Caller is responsible to call of_node_put() on the returned out_args->np
+  * pointer.
+  *
+- * Example:
++ * Example::
+  *
+- * phandle1: node1 {
+- *    #list-cells = <2>;
+- * }
++ *  phandle1: node1 {
++ *    #list-cells = <2>;
++ *  };
+  *
+- * phandle2: node2 {
+- *    #list-cells = <1>;
+- * }
++ *  phandle2: node2 {
++ *    #list-cells = <1>;
++ *  };
+  *
+- * phandle3: node3 {
+- *    #list-cells = <1>;
+- *    list-map = <0 &phandle2 3>,
+- *               <1 &phandle2 2>,
+- *               <2 &phandle1 5 1>;
+- *    list-map-mask = <0x3>;
+- * };
++ *  phandle3: node3 {
++ *    #list-cells = <1>;
++ *    list-map = <0 &phandle2 3>,
++ *               <1 &phandle2 2>,
++ *               <2 &phandle1 5 1>;
++ *    list-map-mask = <0x3>;
++ *  };
+  *
+- * node4 {
+- *    list = <&phandle1 1 2 &phandle3 0>;
+- * }
++ *  node4 {
++ *    list = <&phandle1 1 2 &phandle3 0>;
++ *  };
+  *
+- * To get a device_node of the `node2' node you may call this:
++ * To get a device_node of the ``node2`` node you may call this:
+  * of_parse_phandle_with_args(node4, "list", "list", 1, &args);
+  */
+ int of_parse_phandle_with_args_map(const struct device_node *np,
+@@ -1773,19 +1773,19 @@ EXPORT_SYMBOL(of_parse_phandle_with_args_map);
+  * Caller is responsible to call of_node_put() on the returned out_args->np
+  * pointer.
+  *
+- * Example:
++ * Example::
+  *
+- * phandle1: node1 {
+- * }
++ *  phandle1: node1 {
++ *  };
+  *
+- * phandle2: node2 {
+- * }
++ *  phandle2: node2 {
++ *  };
+  *
+- * node3 {
+- *    list = <&phandle1 0 2 &phandle2 2 3>;
+- * }
++ *  node3 {
++ *    list = <&phandle1 0 2 &phandle2 2 3>;
++ *  };
+  *
+- * To get a device_node of the `node2' node you may call this:
++ * To get a device_node of the ``node2`` node you may call this:
+  * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args);
+  */
+ int of_parse_phandle_with_fixed_args(const struct device_node *np,
+@@ -2030,13 +2030,12 @@ static void of_alias_add(struct alias_prop *ap, struct device_node *np,
+ /**
+  * of_alias_scan - Scan all properties of the 'aliases' node
++ * @dt_alloc: An allocator that provides a virtual address to memory
++ *            for storing the resulting tree
+  *
+  * The function scans all the properties of the 'aliases' node and populates
+  * the global lookup table with the properties.  It returns the
+  * number of alias properties found, or an error code in case of failure.
+- *
+- * @dt_alloc: An allocator that provides a virtual address to memory
+- *            for storing the resulting tree
+  */
+ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
+ {
+@@ -2231,12 +2230,12 @@ bool of_console_check(struct device_node *dn, char *name, int index)
+ EXPORT_SYMBOL_GPL(of_console_check);
+ /**
+- *    of_find_next_cache_node - Find a node's subsidiary cache
+- *    @np:    node of type "cpu" or "cache"
++ * of_find_next_cache_node - Find a node's subsidiary cache
++ * @np:       node of type "cpu" or "cache"
+  *
+- *    Returns a node pointer with refcount incremented, use
+- *    of_node_put() on it when done.  Caller should hold a reference
+- *    to np.
++ * Return: A node pointer with refcount incremented, use
++ * of_node_put() on it when done.  Caller should hold a reference
++ * to np.
+  */
+ struct device_node *of_find_next_cache_node(const struct device_node *np)
+ {
+diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
+index 6d519ef3c5da4..09a98668e7db0 100644
+--- a/drivers/of/fdt.c
++++ b/drivers/of/fdt.c
+@@ -349,11 +349,6 @@ static int unflatten_dt_nodes(const void *blob,
+ /**
+  * __unflatten_device_tree - create tree of device_nodes from flat blob
+- *
+- * unflattens a device-tree, creating the
+- * tree of struct device_node. It also fills the "name" and "type"
+- * pointers of the nodes so the normal device-tree walking functions
+- * can be used.
+  * @blob: The blob to expand
+  * @dad: Parent device node
+  * @mynodes: The device_node tree created by the call
+@@ -361,6 +356,10 @@ static int unflatten_dt_nodes(const void *blob,
+  * for the resulting tree
+  * @detached: if true set OF_DETACHED on @mynodes
+  *
++ * unflattens a device-tree, creating the tree of struct device_node. It also
++ * fills the "name" and "type" pointers of the nodes so the normal device-tree
++ * walking functions can be used.
++ *
+  * Returns NULL on failure or the memory chunk containing the unflattened
+  * device tree on success.
+  */
+-- 
+2.42.0
+
diff --git a/queue-5.4/of-iommu-make-of_map_rid-pci-agnostic.patch b/queue-5.4/of-iommu-make-of_map_rid-pci-agnostic.patch
new file mode 100644 (file)
index 0000000..8e799fc
--- /dev/null
@@ -0,0 +1,200 @@
+From 2b931bcceb369affc55fb9f9c80d13f8be41ed1c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2020 09:20:07 +0100
+Subject: of/iommu: Make of_map_rid() PCI agnostic
+
+From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+
+[ Upstream commit 746a71d02b5d15817fcb13c956ba999a87773952 ]
+
+There is nothing PCI specific (other than the RID - requester ID)
+in the of_map_rid() implementation, so the same function can be
+reused for input/output IDs mapping for other busses just as well.
+
+Rename the RID instances/names to a generic "id" tag.
+
+No functionality change intended.
+
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Acked-by: Joerg Roedel <jroedel@suse.de>
+Cc: Rob Herring <robh+dt@kernel.org>
+Cc: Joerg Roedel <joro@8bytes.org>
+Cc: Robin Murphy <robin.murphy@arm.com>
+Cc: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20200619082013.13661-7-lorenzo.pieralisi@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/of_iommu.c |  4 ++--
+ drivers/of/base.c        | 42 ++++++++++++++++++++--------------------
+ drivers/of/irq.c         |  2 +-
+ include/linux/of.h       |  4 ++--
+ 4 files changed, 26 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
+index 614a93aa5305a..656939ed842e7 100644
+--- a/drivers/iommu/of_iommu.c
++++ b/drivers/iommu/of_iommu.c
+@@ -121,7 +121,7 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
+       struct of_phandle_args iommu_spec = { .args_count = 1 };
+       int err;
+-      err = of_map_rid(info->np, alias, "iommu-map", "iommu-map-mask",
++      err = of_map_id(info->np, alias, "iommu-map", "iommu-map-mask",
+                        &iommu_spec.np, iommu_spec.args);
+       if (err)
+               return err == -ENODEV ? NO_IOMMU : err;
+@@ -137,7 +137,7 @@ static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev,
+       struct of_phandle_args iommu_spec = { .args_count = 1 };
+       int err;
+-      err = of_map_rid(master_np, mc_dev->icid, "iommu-map",
++      err = of_map_id(master_np, mc_dev->icid, "iommu-map",
+                        "iommu-map-mask", &iommu_spec.np,
+                        iommu_spec.args);
+       if (err)
+diff --git a/drivers/of/base.c b/drivers/of/base.c
+index 3f13b982e8b53..5c97366628b13 100644
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -2280,15 +2280,15 @@ int of_find_last_cache_level(unsigned int cpu)
+ }
+ /**
+- * of_map_rid - Translate a requester ID through a downstream mapping.
++ * of_map_id - Translate an ID through a downstream mapping.
+  * @np: root complex device node.
+- * @rid: device requester ID to map.
++ * @id: device ID to map.
+  * @map_name: property name of the map to use.
+  * @map_mask_name: optional property name of the mask to use.
+  * @target: optional pointer to a target device node.
+  * @id_out: optional pointer to receive the translated ID.
+  *
+- * Given a device requester ID, look up the appropriate implementation-defined
++ * Given a device ID, look up the appropriate implementation-defined
+  * platform ID and/or the target device which receives transactions on that
+  * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or
+  * @id_out may be NULL if only the other is required. If @target points to
+@@ -2298,11 +2298,11 @@ int of_find_last_cache_level(unsigned int cpu)
+  *
+  * Return: 0 on success or a standard error code on failure.
+  */
+-int of_map_rid(struct device_node *np, u32 rid,
++int of_map_id(struct device_node *np, u32 id,
+              const char *map_name, const char *map_mask_name,
+              struct device_node **target, u32 *id_out)
+ {
+-      u32 map_mask, masked_rid;
++      u32 map_mask, masked_id;
+       int map_len;
+       const __be32 *map = NULL;
+@@ -2314,7 +2314,7 @@ int of_map_rid(struct device_node *np, u32 rid,
+               if (target)
+                       return -ENODEV;
+               /* Otherwise, no map implies no translation */
+-              *id_out = rid;
++              *id_out = id;
+               return 0;
+       }
+@@ -2334,22 +2334,22 @@ int of_map_rid(struct device_node *np, u32 rid,
+       if (map_mask_name)
+               of_property_read_u32(np, map_mask_name, &map_mask);
+-      masked_rid = map_mask & rid;
++      masked_id = map_mask & id;
+       for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) {
+               struct device_node *phandle_node;
+-              u32 rid_base = be32_to_cpup(map + 0);
++              u32 id_base = be32_to_cpup(map + 0);
+               u32 phandle = be32_to_cpup(map + 1);
+               u32 out_base = be32_to_cpup(map + 2);
+-              u32 rid_len = be32_to_cpup(map + 3);
++              u32 id_len = be32_to_cpup(map + 3);
+-              if (rid_base & ~map_mask) {
+-                      pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n",
++              if (id_base & ~map_mask) {
++                      pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores id-base (0x%x)\n",
+                               np, map_name, map_name,
+-                              map_mask, rid_base);
++                              map_mask, id_base);
+                       return -EFAULT;
+               }
+-              if (masked_rid < rid_base || masked_rid >= rid_base + rid_len)
++              if (masked_id < id_base || masked_id >= id_base + id_len)
+                       continue;
+               phandle_node = of_find_node_by_phandle(phandle);
+@@ -2367,20 +2367,20 @@ int of_map_rid(struct device_node *np, u32 rid,
+               }
+               if (id_out)
+-                      *id_out = masked_rid - rid_base + out_base;
++                      *id_out = masked_id - id_base + out_base;
+-              pr_debug("%pOF: %s, using mask %08x, rid-base: %08x, out-base: %08x, length: %08x, rid: %08x -> %08x\n",
+-                      np, map_name, map_mask, rid_base, out_base,
+-                      rid_len, rid, masked_rid - rid_base + out_base);
++              pr_debug("%pOF: %s, using mask %08x, id-base: %08x, out-base: %08x, length: %08x, id: %08x -> %08x\n",
++                      np, map_name, map_mask, id_base, out_base,
++                      id_len, id, masked_id - id_base + out_base);
+               return 0;
+       }
+-      pr_info("%pOF: no %s translation for rid 0x%x on %pOF\n", np, map_name,
+-              rid, target && *target ? *target : NULL);
++      pr_info("%pOF: no %s translation for id 0x%x on %pOF\n", np, map_name,
++              id, target && *target ? *target : NULL);
+       /* Bypasses translation */
+       if (id_out)
+-              *id_out = rid;
++              *id_out = id;
+       return 0;
+ }
+-EXPORT_SYMBOL_GPL(of_map_rid);
++EXPORT_SYMBOL_GPL(of_map_id);
+diff --git a/drivers/of/irq.c b/drivers/of/irq.c
+index a296eaf52a5b2..d632bc5b3a2de 100644
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -587,7 +587,7 @@ static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
+        * "msi-map" property.
+        */
+       for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent)
+-              if (!of_map_rid(parent_dev->of_node, rid_in, "msi-map",
++              if (!of_map_id(parent_dev->of_node, rid_in, "msi-map",
+                               "msi-map-mask", np, &rid_out))
+                       break;
+       return rid_out;
+diff --git a/include/linux/of.h b/include/linux/of.h
+index e29b341598e99..e070c5ed62a09 100644
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -554,7 +554,7 @@ bool of_console_check(struct device_node *dn, char *name, int index);
+ extern int of_cpu_node_to_id(struct device_node *np);
+-int of_map_rid(struct device_node *np, u32 rid,
++int of_map_id(struct device_node *np, u32 id,
+              const char *map_name, const char *map_mask_name,
+              struct device_node **target, u32 *id_out);
+@@ -978,7 +978,7 @@ static inline int of_cpu_node_to_id(struct device_node *np)
+       return -ENODEV;
+ }
+-static inline int of_map_rid(struct device_node *np, u32 rid,
++static inline int of_map_id(struct device_node *np, u32 id,
+                            const char *map_name, const char *map_mask_name,
+                            struct device_node **target, u32 *id_out)
+ {
+-- 
+2.42.0
+
diff --git a/queue-5.4/of-irq-make-of_msi_map_get_device_domain-bus-agnosti.patch b/queue-5.4/of-irq-make-of_msi_map_get_device_domain-bus-agnosti.patch
new file mode 100644 (file)
index 0000000..218ea1a
--- /dev/null
@@ -0,0 +1,97 @@
+From de174d191aecc6a69cf5c44bec20c17a5dc931f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2020 09:20:10 +0100
+Subject: of/irq: make of_msi_map_get_device_domain() bus agnostic
+
+From: Diana Craciun <diana.craciun@oss.nxp.com>
+
+[ Upstream commit 6f881aba01109a01a43e4f135673c19190f61133 ]
+
+of_msi_map_get_device_domain() is PCI specific but it need not be and
+can be easily changed to be bus agnostic in order to be used by other
+busses by adding an IRQ domain bus token as an input parameter.
+
+Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>   # pci/msi.c
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Rob Herring <robh+dt@kernel.org>
+Cc: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20200619082013.13661-10-lorenzo.pieralisi@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/irq.c       | 8 +++++---
+ drivers/pci/msi.c      | 2 +-
+ include/linux/of_irq.h | 5 +++--
+ 3 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/of/irq.c b/drivers/of/irq.c
+index d632bc5b3a2de..1005e4f349ef6 100644
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -613,18 +613,20 @@ u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
+  * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain
+  * @dev: device for which the mapping is to be done.
+  * @rid: Requester ID for the device.
++ * @bus_token: Bus token
+  *
+  * Walk up the device hierarchy looking for devices with a "msi-map"
+  * property.
+  *
+  * Returns: the MSI domain for this device (or NULL on failure)
+  */
+-struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 rid)
++struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 id,
++                                              u32 bus_token)
+ {
+       struct device_node *np = NULL;
+-      __of_msi_map_rid(dev, &np, rid);
+-      return irq_find_matching_host(np, DOMAIN_BUS_PCI_MSI);
++      __of_msi_map_rid(dev, &np, id);
++      return irq_find_matching_host(np, bus_token);
+ }
+ /**
+diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
+index cc863cdd5cc74..392d2ecf7dc89 100644
+--- a/drivers/pci/msi.c
++++ b/drivers/pci/msi.c
+@@ -1624,7 +1624,7 @@ struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)
+       u32 rid = pci_dev_id(pdev);
+       pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
+-      dom = of_msi_map_get_device_domain(&pdev->dev, rid);
++      dom = of_msi_map_get_device_domain(&pdev->dev, rid, DOMAIN_BUS_PCI_MSI);
+       if (!dom)
+               dom = iort_get_device_domain(&pdev->dev, rid,
+                                            DOMAIN_BUS_PCI_MSI);
+diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
+index 1214cabb22479..7142a37227584 100644
+--- a/include/linux/of_irq.h
++++ b/include/linux/of_irq.h
+@@ -52,7 +52,8 @@ extern struct irq_domain *of_msi_get_domain(struct device *dev,
+                                           struct device_node *np,
+                                           enum irq_domain_bus_token token);
+ extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
+-                                                     u32 rid);
++                                                      u32 id,
++                                                      u32 bus_token);
+ extern void of_msi_configure(struct device *dev, struct device_node *np);
+ u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in);
+ #else
+@@ -85,7 +86,7 @@ static inline struct irq_domain *of_msi_get_domain(struct device *dev,
+       return NULL;
+ }
+ static inline struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
+-                                                            u32 rid)
++                                              u32 id, u32 bus_token)
+ {
+       return NULL;
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.4/of-irq-make-of_msi_map_rid-pci-bus-agnostic.patch b/queue-5.4/of-irq-make-of_msi_map_rid-pci-bus-agnostic.patch
new file mode 100644 (file)
index 0000000..e5a7b15
--- /dev/null
@@ -0,0 +1,145 @@
+From 43feea6bf296097366432b53034ab33b6901773a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2020 09:20:11 +0100
+Subject: of/irq: Make of_msi_map_rid() PCI bus agnostic
+
+From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+
+[ Upstream commit 2bcdd8f2c07f1aa1bfd34fa0dab8e06949e34846 ]
+
+There is nothing PCI bus specific in the of_msi_map_rid()
+implementation other than the requester ID tag for the input
+ID space. Rename requester ID to a more generic ID so that
+the translation code can be used by all busses that require
+input/output ID translations.
+
+No functional change intended.
+
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Rob Herring <robh+dt@kernel.org>
+Cc: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20200619082013.13661-11-lorenzo.pieralisi@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Stable-dep-of: d79972789d17 ("of: dynamic: Fix of_reconfig_get_state_change() return value documentation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/irq.c       | 28 ++++++++++++++--------------
+ drivers/pci/msi.c      |  2 +-
+ include/linux/of_irq.h |  8 ++++----
+ 3 files changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/of/irq.c b/drivers/of/irq.c
+index 1005e4f349ef6..25d17b8a1a1aa 100644
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -576,43 +576,43 @@ void __init of_irq_init(const struct of_device_id *matches)
+       }
+ }
+-static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
+-                          u32 rid_in)
++static u32 __of_msi_map_id(struct device *dev, struct device_node **np,
++                          u32 id_in)
+ {
+       struct device *parent_dev;
+-      u32 rid_out = rid_in;
++      u32 id_out = id_in;
+       /*
+        * Walk up the device parent links looking for one with a
+        * "msi-map" property.
+        */
+       for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent)
+-              if (!of_map_id(parent_dev->of_node, rid_in, "msi-map",
+-                              "msi-map-mask", np, &rid_out))
++              if (!of_map_id(parent_dev->of_node, id_in, "msi-map",
++                              "msi-map-mask", np, &id_out))
+                       break;
+-      return rid_out;
++      return id_out;
+ }
+ /**
+- * of_msi_map_rid - Map a MSI requester ID for a device.
++ * of_msi_map_id - Map a MSI ID for a device.
+  * @dev: device for which the mapping is to be done.
+  * @msi_np: device node of the expected msi controller.
+- * @rid_in: unmapped MSI requester ID for the device.
++ * @id_in: unmapped MSI ID for the device.
+  *
+  * Walk up the device hierarchy looking for devices with a "msi-map"
+- * property.  If found, apply the mapping to @rid_in.
++ * property.  If found, apply the mapping to @id_in.
+  *
+- * Returns the mapped MSI requester ID.
++ * Returns the mapped MSI ID.
+  */
+-u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
++u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in)
+ {
+-      return __of_msi_map_rid(dev, &msi_np, rid_in);
++      return __of_msi_map_id(dev, &msi_np, id_in);
+ }
+ /**
+  * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain
+  * @dev: device for which the mapping is to be done.
+- * @rid: Requester ID for the device.
++ * @id: Device ID.
+  * @bus_token: Bus token
+  *
+  * Walk up the device hierarchy looking for devices with a "msi-map"
+@@ -625,7 +625,7 @@ struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 id,
+ {
+       struct device_node *np = NULL;
+-      __of_msi_map_rid(dev, &np, id);
++      __of_msi_map_id(dev, &np, id);
+       return irq_find_matching_host(np, bus_token);
+ }
+diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
+index 392d2ecf7dc89..c4f4a8a3bf8fa 100644
+--- a/drivers/pci/msi.c
++++ b/drivers/pci/msi.c
+@@ -1603,7 +1603,7 @@ u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev)
+       pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
+       of_node = irq_domain_get_of_node(domain);
+-      rid = of_node ? of_msi_map_rid(&pdev->dev, of_node, rid) :
++      rid = of_node ? of_msi_map_id(&pdev->dev, of_node, rid) :
+                       iort_msi_map_id(&pdev->dev, rid);
+       return rid;
+diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
+index 7142a37227584..e8b78139f78c5 100644
+--- a/include/linux/of_irq.h
++++ b/include/linux/of_irq.h
+@@ -55,7 +55,7 @@ extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
+                                                       u32 id,
+                                                       u32 bus_token);
+ extern void of_msi_configure(struct device *dev, struct device_node *np);
+-u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in);
++u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in);
+ #else
+ static inline int of_irq_count(struct device_node *dev)
+ {
+@@ -93,10 +93,10 @@ static inline struct irq_domain *of_msi_map_get_device_domain(struct device *dev
+ static inline void of_msi_configure(struct device *dev, struct device_node *np)
+ {
+ }
+-static inline u32 of_msi_map_rid(struct device *dev,
+-                               struct device_node *msi_np, u32 rid_in)
++static inline u32 of_msi_map_id(struct device *dev,
++                               struct device_node *msi_np, u32 id_in)
+ {
+-      return rid_in;
++      return id_in;
+ }
+ #endif
+-- 
+2.42.0
+
index 4e41304178e23334fb2b19caf6dd23e177b7cb0d..3b048e56bc611664108e403c0eec80e5c734fbf2 100644 (file)
@@ -4,3 +4,23 @@ tg3-move-the-rt-x_dropped-counters-to-tg3_napi.patch
 tg3-increment-tx_dropped-in-tg3_tso_bug.patch
 kconfig-fix-memory-leak-from-range-properties.patch
 drm-amdgpu-correct-chunk_ptr-to-a-pointer-to-chunk.patch
+of-base-add-of_get_cpu_state_node-to-get-idle-states.patch
+acpi-iort-make-iort_get_device_domain-irq-domain-agn.patch
+acpi-iort-make-iort_msi_map_rid-pci-agnostic.patch
+of-iommu-make-of_map_rid-pci-agnostic.patch
+of-irq-make-of_msi_map_get_device_domain-bus-agnosti.patch
+of-irq-make-of_msi_map_rid-pci-bus-agnostic.patch
+of-base-fix-some-formatting-issues-and-provide-missi.patch
+of-fix-kerneldoc-output-formatting.patch
+of-add-missing-return-section-in-kerneldoc-comments.patch
+of-dynamic-fix-of_reconfig_get_state_change-return-v.patch
+ipv6-fix-potential-null-deref-in-fib6_add.patch
+hv_netvsc-rndis_filter-needs-to-select-nls.patch
+net-arcnet-fix-reset-flag-handling.patch
+net-arcnet-com20020-fix-error-handling.patch
+arcnet-restoring-support-for-multiple-sohard-arcnet-.patch
+ipv4-ip_gre-avoid-skb_pull-failure-in-ipgre_xmit.patch
+net-hns-fix-fake-link-up-on-xge-port.patch
+netfilter-xt_owner-fix-for-unsafe-access-of-sk-sk_so.patch
+tcp-do-not-accept-ack-of-bytes-we-never-sent.patch
+bpf-sockmap-updating-the-sg-structure-should-also-up.patch
diff --git a/queue-5.4/tcp-do-not-accept-ack-of-bytes-we-never-sent.patch b/queue-5.4/tcp-do-not-accept-ack-of-bytes-we-never-sent.patch
new file mode 100644 (file)
index 0000000..d90550e
--- /dev/null
@@ -0,0 +1,106 @@
+From 6ed64c74adf1266ed9d54c2d0ec702181db3072d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 16:18:41 +0000
+Subject: tcp: do not accept ACK of bytes we never sent
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 3d501dd326fb1c73f1b8206d4c6e1d7b15c07e27 ]
+
+This patch is based on a detailed report and ideas from Yepeng Pan
+and Christian Rossow.
+
+ACK seq validation is currently following RFC 5961 5.2 guidelines:
+
+   The ACK value is considered acceptable only if
+   it is in the range of ((SND.UNA - MAX.SND.WND) <= SEG.ACK <=
+   SND.NXT).  All incoming segments whose ACK value doesn't satisfy the
+   above condition MUST be discarded and an ACK sent back.  It needs to
+   be noted that RFC 793 on page 72 (fifth check) says: "If the ACK is a
+   duplicate (SEG.ACK < SND.UNA), it can be ignored.  If the ACK
+   acknowledges something not yet sent (SEG.ACK > SND.NXT) then send an
+   ACK, drop the segment, and return".  The "ignored" above implies that
+   the processing of the incoming data segment continues, which means
+   the ACK value is treated as acceptable.  This mitigation makes the
+   ACK check more stringent since any ACK < SND.UNA wouldn't be
+   accepted, instead only ACKs that are in the range ((SND.UNA -
+   MAX.SND.WND) <= SEG.ACK <= SND.NXT) get through.
+
+This can be refined for new (and possibly spoofed) flows,
+by not accepting ACK for bytes that were never sent.
+
+This greatly improves TCP security at a little cost.
+
+I added a Fixes: tag to make sure this patch will reach stable trees,
+even if the 'blamed' patch was adhering to the RFC.
+
+tp->bytes_acked was added in linux-4.2
+
+Following packetdrill test (courtesy of Yepeng Pan) shows
+the issue at hand:
+
+0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
++0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
++0 bind(3, ..., ...) = 0
++0 listen(3, 1024) = 0
+
+// ---------------- Handshake ------------------- //
+
+// when window scale is set to 14 the window size can be extended to
+// 65535 * (2^14) = 1073725440. Linux would accept an ACK packet
+// with ack number in (Server_ISN+1-1073725440. Server_ISN+1)
+// ,though this ack number acknowledges some data never
+// sent by the server.
+
++0 < S 0:0(0) win 65535 <mss 1400,nop,wscale 14>
++0 > S. 0:0(0) ack 1 <...>
++0 < . 1:1(0) ack 1 win 65535
++0 accept(3, ..., ...) = 4
+
+// For the established connection, we send an ACK packet,
+// the ack packet uses ack number 1 - 1073725300 + 2^32,
+// where 2^32 is used to wrap around.
+// Note: we used 1073725300 instead of 1073725440 to avoid possible
+// edge cases.
+// 1 - 1073725300 + 2^32 = 3221241997
+
+// Oops, old kernels happily accept this packet.
++0 < . 1:1001(1000) ack 3221241997 win 65535
+
+// After the kernel fix the following will be replaced by a challenge ACK,
+// and prior malicious frame would be dropped.
++0 > . 1:1(0) ack 1001
+
+Fixes: 354e4aa391ed ("tcp: RFC 5961 5.2 Blind Data Injection Attack Mitigation")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Yepeng Pan <yepeng.pan@cispa.de>
+Reported-by: Christian Rossow <rossow@cispa.de>
+Acked-by: Neal Cardwell <ncardwell@google.com>
+Link: https://lore.kernel.org/r/20231205161841.2702925-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_input.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index fe5ef114beba5..982fe464156a4 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -3657,8 +3657,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
+        * then we can probably ignore it.
+        */
+       if (before(ack, prior_snd_una)) {
++              u32 max_window;
++
++              /* do not accept ACK for bytes we never sent. */
++              max_window = min_t(u64, tp->max_window, tp->bytes_acked);
+               /* RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] */
+-              if (before(ack, prior_snd_una - tp->max_window)) {
++              if (before(ack, prior_snd_una - max_window)) {
+                       if (!(flag & FLAG_NO_CHALLENGE_ACK))
+                               tcp_send_challenge_ack(sk, skb);
+                       return -1;
+-- 
+2.42.0
+