commit:     b6b17bcba0ccba7341c05c6f3c1572b20e2abdd0
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Oct  5 11:59:21 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Oct  5 11:59:21 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=b6b17bcb

Linux patch 4.19.261

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README               |   4 +
 1260_linux-4.19.261.patch | 615 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 619 insertions(+)

diff --git a/0000_README b/0000_README
index 6bbe74fa..05c6a58c 100644
--- a/0000_README
+++ b/0000_README
@@ -1083,6 +1083,10 @@ Patch:  1259_linux-4.19.260.patch
 From:   https://www.kernel.org
 Desc:   Linux 4.19.260
 
+Patch:  1260_linux-4.19.261.patch
+From:   https://www.kernel.org
+Desc:   Linux 4.19.261
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1260_linux-4.19.261.patch b/1260_linux-4.19.261.patch
new file mode 100644
index 00000000..c3f6bb94
--- /dev/null
+++ b/1260_linux-4.19.261.patch
@@ -0,0 +1,615 @@
+diff --git a/Makefile b/Makefile
+index 61971754a74e8..165812d2f786b 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 4
+ PATCHLEVEL = 19
+-SUBLEVEL = 260
++SUBLEVEL = 261
+ EXTRAVERSION =
+ NAME = "People's Front"
+ 
+diff --git a/arch/arm/boot/dts/integratorap.dts 
b/arch/arm/boot/dts/integratorap.dts
+index 94d2ff9836d00..e6c5a99e07416 100644
+--- a/arch/arm/boot/dts/integratorap.dts
++++ b/arch/arm/boot/dts/integratorap.dts
+@@ -155,6 +155,7 @@
+ 
+       pci: pciv3@62000000 {
+               compatible = "arm,integrator-ap-pci", "v3,v360epc-pci";
++              device_type = "pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index b0dea0702c748..6d110a1c090dd 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -4560,6 +4560,10 @@ static const struct ata_blacklist_entry 
ata_device_blacklist [] = {
+       { "PIONEER DVD-RW  DVR-212D",   NULL,   ATA_HORKAGE_NOSETXFER },
+       { "PIONEER DVD-RW  DVR-216D",   NULL,   ATA_HORKAGE_NOSETXFER },
+ 
++      /* These specific Pioneer models have LPM issues */
++      { "PIONEER BD-RW   BDR-207M",   NULL,   ATA_HORKAGE_NOLPM },
++      { "PIONEER BD-RW   BDR-205",    NULL,   ATA_HORKAGE_NOLPM },
++
+       /* Crucial BX100 SSD 500GB has broken LPM support */
+       { "CT500BX100SSD1",             NULL,   ATA_HORKAGE_NOLPM },
+ 
+diff --git a/drivers/clk/bcm/clk-iproc-pll.c b/drivers/clk/bcm/clk-iproc-pll.c
+index 274441e2ddb28..8f0619f362e3b 100644
+--- a/drivers/clk/bcm/clk-iproc-pll.c
++++ b/drivers/clk/bcm/clk-iproc-pll.c
+@@ -736,6 +736,7 @@ void iproc_pll_clk_setup(struct device_node *node,
+       const char *parent_name;
+       struct iproc_clk *iclk_array;
+       struct clk_hw_onecell_data *clk_data;
++      const char *clk_name;
+ 
+       if (WARN_ON(!pll_ctrl) || WARN_ON(!clk_ctrl))
+               return;
+@@ -783,7 +784,12 @@ void iproc_pll_clk_setup(struct device_node *node,
+       iclk = &iclk_array[0];
+       iclk->pll = pll;
+ 
+-      init.name = node->name;
++      ret = of_property_read_string_index(node, "clock-output-names",
++                                          0, &clk_name);
++      if (WARN_ON(ret))
++              goto err_pll_register;
++
++      init.name = clk_name;
+       init.ops = &iproc_pll_ops;
+       init.flags = 0;
+       parent_name = of_clk_get_parent_name(node, 0);
+@@ -803,13 +809,11 @@ void iproc_pll_clk_setup(struct device_node *node,
+               goto err_pll_register;
+ 
+       clk_data->hws[0] = &iclk->hw;
++      parent_name = clk_name;
+ 
+       /* now initialize and register all leaf clocks */
+       for (i = 1; i < num_clks; i++) {
+-              const char *clk_name;
+-
+               memset(&init, 0, sizeof(init));
+-              parent_name = node->name;
+ 
+               ret = of_property_read_string_index(node, "clock-output-names",
+                                                   i, &clk_name);
+diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+index e21c7673cd5b8..57781833cae1b 100644
+--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
++++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+@@ -1690,12 +1690,6 @@ EXPORT_SYMBOL_GPL(analogix_dp_unbind);
+ int analogix_dp_suspend(struct analogix_dp_device *dp)
+ {
+       clk_disable_unprepare(dp->clock);
+-
+-      if (dp->plat_data->panel) {
+-              if (drm_panel_unprepare(dp->plat_data->panel))
+-                      DRM_ERROR("failed to turnoff the panel\n");
+-      }
+-
+       return 0;
+ }
+ EXPORT_SYMBOL_GPL(analogix_dp_suspend);
+@@ -1710,13 +1704,6 @@ int analogix_dp_resume(struct analogix_dp_device *dp)
+               return ret;
+       }
+ 
+-      if (dp->plat_data->panel) {
+-              if (drm_panel_prepare(dp->plat_data->panel)) {
+-                      DRM_ERROR("failed to setup the panel\n");
+-                      return -EBUSY;
+-              }
+-      }
+-
+       return 0;
+ }
+ EXPORT_SYMBOL_GPL(analogix_dp_resume);
+diff --git a/drivers/input/touchscreen/melfas_mip4.c 
b/drivers/input/touchscreen/melfas_mip4.c
+index 430a2bc5f7caf..5d947e721fa5d 100644
+--- a/drivers/input/touchscreen/melfas_mip4.c
++++ b/drivers/input/touchscreen/melfas_mip4.c
+@@ -1462,7 +1462,7 @@ static int mip4_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
+                                             "ce", GPIOD_OUT_LOW);
+       if (IS_ERR(ts->gpio_ce)) {
+               error = PTR_ERR(ts->gpio_ce);
+-              if (error != EPROBE_DEFER)
++              if (error != -EPROBE_DEFER)
+                       dev_err(&client->dev,
+                               "Failed to get gpio: %d\n", error);
+               return error;
+diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c
+index 5c81dc7371db7..1552d1f09c5c4 100644
+--- a/drivers/mmc/host/moxart-mmc.c
++++ b/drivers/mmc/host/moxart-mmc.c
+@@ -111,8 +111,8 @@
+ #define CLK_DIV_MASK          0x7f
+ 
+ /* REG_BUS_WIDTH */
+-#define BUS_WIDTH_8           BIT(2)
+-#define BUS_WIDTH_4           BIT(1)
++#define BUS_WIDTH_4_SUPPORT   BIT(3)
++#define BUS_WIDTH_4           BIT(2)
+ #define BUS_WIDTH_1           BIT(0)
+ 
+ #define MMC_VDD_360           23
+@@ -527,9 +527,6 @@ static void moxart_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
+       case MMC_BUS_WIDTH_4:
+               writel(BUS_WIDTH_4, host->base + REG_BUS_WIDTH);
+               break;
+-      case MMC_BUS_WIDTH_8:
+-              writel(BUS_WIDTH_8, host->base + REG_BUS_WIDTH);
+-              break;
+       default:
+               writel(BUS_WIDTH_1, host->base + REG_BUS_WIDTH);
+               break;
+@@ -646,16 +643,8 @@ static int moxart_probe(struct platform_device *pdev)
+               dmaengine_slave_config(host->dma_chan_rx, &cfg);
+       }
+ 
+-      switch ((readl(host->base + REG_BUS_WIDTH) >> 3) & 3) {
+-      case 1:
++      if (readl(host->base + REG_BUS_WIDTH) & BUS_WIDTH_4_SUPPORT)
+               mmc->caps |= MMC_CAP_4_BIT_DATA;
+-              break;
+-      case 2:
+-              mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
+-              break;
+-      default:
+-              break;
+-      }
+ 
+       writel(0, host->base + REG_INTERRUPT_MASK);
+ 
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index 8d10c29ba1763..56115792bea16 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -1357,6 +1357,7 @@ static const struct usb_device_id products[] = {
+       {QMI_FIXED_INTF(0x413c, 0x81b3, 8)},    /* Dell Wireless 5809e Gobi(TM) 
4G LTE Mobile Broadband Card (rev3) */
+       {QMI_FIXED_INTF(0x413c, 0x81b6, 8)},    /* Dell Wireless 5811e */
+       {QMI_FIXED_INTF(0x413c, 0x81b6, 10)},   /* Dell Wireless 5811e */
++      {QMI_FIXED_INTF(0x413c, 0x81c2, 8)},    /* Dell Wireless 5811e */
+       {QMI_FIXED_INTF(0x413c, 0x81cc, 8)},    /* Dell Wireless 5816e */
+       {QMI_FIXED_INTF(0x413c, 0x81d7, 0)},    /* Dell Wireless 5821e */
+       {QMI_FIXED_INTF(0x413c, 0x81d7, 1)},    /* Dell Wireless 5821e 
preproduction config */
+diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
+index 1316f5b0c0d7e..2263a66f6314e 100644
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -1596,6 +1596,7 @@ void usbnet_disconnect (struct usb_interface *intf)
+       struct usbnet           *dev;
+       struct usb_device       *xdev;
+       struct net_device       *net;
++      struct urb              *urb;
+ 
+       dev = usb_get_intfdata(intf);
+       usb_set_intfdata(intf, NULL);
+@@ -1612,7 +1613,11 @@ void usbnet_disconnect (struct usb_interface *intf)
+       net = dev->net;
+       unregister_netdev (net);
+ 
+-      usb_scuttle_anchored_urbs(&dev->deferred);
++      while ((urb = usb_get_from_anchor(&dev->deferred))) {
++              dev_kfree_skb(urb->context);
++              kfree(urb->sg);
++              usb_free_urb(urb);
++      }
+ 
+       if (dev->driver_info->unbind)
+               dev->driver_info->unbind (dev, intf);
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index a0a805a5ab6b2..582c3b1904180 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -1716,18 +1716,21 @@ static int nvme_pr_preempt(struct block_device *bdev, 
u64 old, u64 new,
+               enum pr_type type, bool abort)
+ {
+       u32 cdw10 = nvme_pr_type(type) << 8 | (abort ? 2 : 1);
++
+       return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_acquire);
+ }
+ 
+ static int nvme_pr_clear(struct block_device *bdev, u64 key)
+ {
+-      u32 cdw10 = 1 | (key ? 1 << 3 : 0);
+-      return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_register);
++      u32 cdw10 = 1 | (key ? 0 : 1 << 3);
++
++      return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release);
+ }
+ 
+ static int nvme_pr_release(struct block_device *bdev, u64 key, enum pr_type 
type)
+ {
+-      u32 cdw10 = nvme_pr_type(type) << 8 | (key ? 1 << 3 : 0);
++      u32 cdw10 = nvme_pr_type(type) << 8 | (key ? 0 : 1 << 3);
++
+       return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release);
+ }
+ 
+diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
+index b4b0f3480bd36..2c1672f9aac9b 100644
+--- a/drivers/soc/sunxi/sunxi_sram.c
++++ b/drivers/soc/sunxi/sunxi_sram.c
+@@ -78,8 +78,8 @@ static struct sunxi_sram_desc sun4i_a10_sram_d = {
+ 
+ static struct sunxi_sram_desc sun50i_a64_sram_c = {
+       .data   = SUNXI_SRAM_DATA("C", 0x4, 24, 1,
+-                                SUNXI_SRAM_MAP(0, 1, "cpu"),
+-                                SUNXI_SRAM_MAP(1, 0, "de2")),
++                                SUNXI_SRAM_MAP(1, 0, "cpu"),
++                                SUNXI_SRAM_MAP(0, 1, "de2")),
+ };
+ 
+ static const struct of_device_id sunxi_sram_dt_ids[] = {
+@@ -264,6 +264,7 @@ int sunxi_sram_claim(struct device *dev)
+       writel(val | ((device << sram_data->offset) & mask),
+              base + sram_data->reg);
+ 
++      sram_desc->claimed = true;
+       spin_unlock(&sram_lock);
+ 
+       return 0;
+@@ -324,12 +325,12 @@ static struct regmap_config sunxi_sram_emac_clock_regmap 
= {
+       .writeable_reg  = sunxi_sram_regmap_accessible_reg,
+ };
+ 
+-static int sunxi_sram_probe(struct platform_device *pdev)
++static int __init sunxi_sram_probe(struct platform_device *pdev)
+ {
+       struct resource *res;
+-      struct dentry *d;
+       struct regmap *emac_clock;
+       const struct sunxi_sramc_variant *variant;
++      struct device *dev = &pdev->dev;
+ 
+       sram_dev = &pdev->dev;
+ 
+@@ -342,13 +343,6 @@ static int sunxi_sram_probe(struct platform_device *pdev)
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+ 
+-      of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+-
+-      d = debugfs_create_file("sram", S_IRUGO, NULL, NULL,
+-                              &sunxi_sram_fops);
+-      if (!d)
+-              return -ENOMEM;
+-
+       if (variant->has_emac_clock) {
+               emac_clock = devm_regmap_init_mmio(&pdev->dev, base,
+                                                  
&sunxi_sram_emac_clock_regmap);
+@@ -357,6 +351,10 @@ static int sunxi_sram_probe(struct platform_device *pdev)
+                       return PTR_ERR(emac_clock);
+       }
+ 
++      of_platform_populate(dev->of_node, NULL, NULL, dev);
++
++      debugfs_create_file("sram", 0444, NULL, NULL, &sunxi_sram_fops);
++
+       return 0;
+ }
+ 
+@@ -398,9 +396,8 @@ static struct platform_driver sunxi_sram_driver = {
+               .name           = "sunxi-sram",
+               .of_match_table = sunxi_sram_dt_match,
+       },
+-      .probe  = sunxi_sram_probe,
+ };
+-module_platform_driver(sunxi_sram_driver);
++builtin_platform_driver_probe(sunxi_sram_driver, sunxi_sram_probe);
+ 
+ MODULE_AUTHOR("Maxime Ripard <[email protected]>");
+ MODULE_DESCRIPTION("Allwinner sunXi SRAM Controller Driver");
+diff --git a/drivers/usb/storage/unusual_uas.h 
b/drivers/usb/storage/unusual_uas.h
+index 0b37c8e550e7d..92e9bd006622d 100644
+--- a/drivers/usb/storage/unusual_uas.h
++++ b/drivers/usb/storage/unusual_uas.h
+@@ -52,6 +52,13 @@ UNUSUAL_DEV(0x059f, 0x1061, 0x0000, 0x9999,
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_NO_REPORT_OPCODES | US_FL_NO_SAME),
+ 
++/* Reported-by: Hongling Zeng <[email protected]> */
++UNUSUAL_DEV(0x090c, 0x2000, 0x0000, 0x9999,
++              "Hiksemi",
++              "External HDD",
++              USB_SC_DEVICE, USB_PR_DEVICE, NULL,
++              US_FL_IGNORE_UAS),
++
+ /*
+  * Apricorn USB3 dongle sometimes returns "USBSUSBSUSBS" in response to SCSI
+  * commands in UAS mode.  Observed with the 1.28 firmware; are there others?
+@@ -76,6 +83,13 @@ UNUSUAL_DEV(0x0bc2, 0x331a, 0x0000, 0x9999,
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_NO_REPORT_LUNS),
+ 
++/* Reported-by: Hongling Zeng <[email protected]> */
++UNUSUAL_DEV(0x0bda, 0x9210, 0x0000, 0x9999,
++              "Hiksemi",
++              "External HDD",
++              USB_SC_DEVICE, USB_PR_DEVICE, NULL,
++              US_FL_IGNORE_UAS),
++
+ /* Reported-by: Benjamin Tissoires <[email protected]> */
+ UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999,
+               "Initio Corporation",
+@@ -118,6 +132,13 @@ UNUSUAL_DEV(0x154b, 0xf00d, 0x0000, 0x9999,
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_NO_ATA_1X),
+ 
++/* Reported-by: Hongling Zeng <[email protected]> */
++UNUSUAL_DEV(0x17ef, 0x3899, 0x0000, 0x9999,
++              "Thinkplus",
++              "External HDD",
++              USB_SC_DEVICE, USB_PR_DEVICE, NULL,
++              US_FL_IGNORE_UAS),
++
+ /* Reported-by: Hans de Goede <[email protected]> */
+ UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999,
+               "VIA",
+diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
+index bb7159f697f2f..f47a3390118fe 100644
+--- a/fs/ntfs/super.c
++++ b/fs/ntfs/super.c
+@@ -2106,7 +2106,8 @@ get_ctx_vol_failed:
+       // TODO: Initialize security.
+       /* Get the extended system files' directory inode. */
+       vol->extend_ino = ntfs_iget(sb, FILE_Extend);
+-      if (IS_ERR(vol->extend_ino) || is_bad_inode(vol->extend_ino)) {
++      if (IS_ERR(vol->extend_ino) || is_bad_inode(vol->extend_ino) ||
++          !S_ISDIR(vol->extend_ino->i_mode)) {
+               if (!IS_ERR(vol->extend_ino))
+                       iput(vol->extend_ino);
+               ntfs_error(sb, "Failed to load $Extend.");
+diff --git a/mm/migrate.c b/mm/migrate.c
+index 76f8dedc0e02b..171573613c397 100644
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -2359,13 +2359,14 @@ next:
+               migrate->dst[migrate->npages] = 0;
+               migrate->src[migrate->npages++] = mpfn;
+       }
+-      arch_leave_lazy_mmu_mode();
+-      pte_unmap_unlock(ptep - 1, ptl);
+ 
+       /* Only flush the TLB if we actually modified any entries */
+       if (unmapped)
+               flush_tlb_range(walk->vma, start, end);
+ 
++      arch_leave_lazy_mmu_mode();
++      pte_unmap_unlock(ptep - 1, ptl);
++
+       return 0;
+ }
+ 
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 9c35403d96461..1cffd4e1fd8fb 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -3779,6 +3779,30 @@ void fs_reclaim_release(gfp_t gfp_mask)
+ EXPORT_SYMBOL_GPL(fs_reclaim_release);
+ #endif
+ 
++/*
++ * Zonelists may change due to hotplug during allocation. Detect when 
zonelists
++ * have been rebuilt so allocation retries. Reader side does not lock and
++ * retries the allocation if zonelist changes. Writer side is protected by the
++ * embedded spin_lock.
++ */
++static DEFINE_SEQLOCK(zonelist_update_seq);
++
++static unsigned int zonelist_iter_begin(void)
++{
++      if (IS_ENABLED(CONFIG_MEMORY_HOTREMOVE))
++              return read_seqbegin(&zonelist_update_seq);
++
++      return 0;
++}
++
++static unsigned int check_retry_zonelist(unsigned int seq)
++{
++      if (IS_ENABLED(CONFIG_MEMORY_HOTREMOVE))
++              return read_seqretry(&zonelist_update_seq, seq);
++
++      return seq;
++}
++
+ /* Perform direct synchronous page reclaim */
+ static int
+ __perform_reclaim(gfp_t gfp_mask, unsigned int order,
+@@ -4084,6 +4108,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int 
order,
+       int compaction_retries;
+       int no_progress_loops;
+       unsigned int cpuset_mems_cookie;
++      unsigned int zonelist_iter_cookie;
+       int reserve_flags;
+ 
+       /*
+@@ -4094,11 +4119,12 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int 
order,
+                               (__GFP_ATOMIC|__GFP_DIRECT_RECLAIM)))
+               gfp_mask &= ~__GFP_ATOMIC;
+ 
+-retry_cpuset:
++restart:
+       compaction_retries = 0;
+       no_progress_loops = 0;
+       compact_priority = DEF_COMPACT_PRIORITY;
+       cpuset_mems_cookie = read_mems_allowed_begin();
++      zonelist_iter_cookie = zonelist_iter_begin();
+ 
+       /*
+        * The fast path uses conservative alloc_flags to succeed only until
+@@ -4247,9 +4273,13 @@ retry:
+               goto retry;
+ 
+ 
+-      /* Deal with possible cpuset update races before we start OOM killing */
+-      if (check_retry_cpuset(cpuset_mems_cookie, ac))
+-              goto retry_cpuset;
++      /*
++       * Deal with possible cpuset update races or zonelist updates to avoid
++       * a unnecessary OOM kill.
++       */
++      if (check_retry_cpuset(cpuset_mems_cookie, ac) ||
++          check_retry_zonelist(zonelist_iter_cookie))
++              goto restart;
+ 
+       /* Reclaim has failed us, start killing things */
+       page = __alloc_pages_may_oom(gfp_mask, order, ac, &did_some_progress);
+@@ -4269,9 +4299,13 @@ retry:
+       }
+ 
+ nopage:
+-      /* Deal with possible cpuset update races before we fail */
+-      if (check_retry_cpuset(cpuset_mems_cookie, ac))
+-              goto retry_cpuset;
++      /*
++       * Deal with possible cpuset update races or zonelist updates to avoid
++       * a unnecessary OOM kill.
++       */
++      if (check_retry_cpuset(cpuset_mems_cookie, ac) ||
++          check_retry_zonelist(zonelist_iter_cookie))
++              goto restart;
+ 
+       /*
+        * Make sure that __GFP_NOFAIL request doesn't leak out and make sure
+@@ -4569,6 +4603,18 @@ refill:
+               /* reset page count bias and offset to start of new frag */
+               nc->pagecnt_bias = PAGE_FRAG_CACHE_MAX_SIZE + 1;
+               offset = size - fragsz;
++              if (unlikely(offset < 0)) {
++                      /*
++                       * The caller is trying to allocate a fragment
++                       * with fragsz > PAGE_SIZE but the cache isn't big
++                       * enough to satisfy the request, this may
++                       * happen in low memory conditions.
++                       * We don't release the cache page because
++                       * it could make memory pressure worse
++                       * so we simply return NULL here.
++                       */
++                      return NULL;
++              }
+       }
+ 
+       nc->pagecnt_bias--;
+@@ -5379,9 +5425,8 @@ static void __build_all_zonelists(void *data)
+       int nid;
+       int __maybe_unused cpu;
+       pg_data_t *self = data;
+-      static DEFINE_SPINLOCK(lock);
+ 
+-      spin_lock(&lock);
++      write_seqlock(&zonelist_update_seq);
+ 
+ #ifdef CONFIG_NUMA
+       memset(node_load, 0, sizeof(node_load));
+@@ -5414,7 +5459,7 @@ static void __build_all_zonelists(void *data)
+ #endif
+       }
+ 
+-      spin_unlock(&lock);
++      write_sequnlock(&zonelist_update_seq);
+ }
+ 
+ static noinline void __init
+diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
+index d12b07eb3a585..e2916b115b930 100644
+--- a/security/integrity/ima/ima.h
++++ b/security/integrity/ima/ima.h
+@@ -298,6 +298,7 @@ static inline int ima_read_xattr(struct dentry *dentry,
+ #ifdef CONFIG_IMA_LSM_RULES
+ 
+ #define security_filter_rule_init security_audit_rule_init
++#define security_filter_rule_free security_audit_rule_free
+ #define security_filter_rule_match security_audit_rule_match
+ 
+ #else
+@@ -308,6 +309,10 @@ static inline int security_filter_rule_init(u32 field, 
u32 op, char *rulestr,
+       return -EINVAL;
+ }
+ 
++static inline void security_filter_rule_free(void *lsmrule)
++{
++}
++
+ static inline int security_filter_rule_match(u32 secid, u32 field, u32 op,
+                                            void *lsmrule,
+                                            struct audit_context *actx)
+diff --git a/security/integrity/ima/ima_policy.c 
b/security/integrity/ima/ima_policy.c
+index 2d5a3daa02f92..b2dadff3626b9 100644
+--- a/security/integrity/ima/ima_policy.c
++++ b/security/integrity/ima/ima_policy.c
+@@ -241,6 +241,21 @@ static int __init default_appraise_policy_setup(char *str)
+ }
+ __setup("ima_appraise_tcb", default_appraise_policy_setup);
+ 
++static void ima_free_rule(struct ima_rule_entry *entry)
++{
++      int i;
++
++      if (!entry)
++              return;
++
++      kfree(entry->fsname);
++      for (i = 0; i < MAX_LSM_RULES; i++) {
++              security_filter_rule_free(entry->lsm[i].rule);
++              kfree(entry->lsm[i].args_p);
++      }
++      kfree(entry);
++}
++
+ /*
+  * The LSM policy can be reloaded, leaving the IMA LSM based rules referring
+  * to the old, stale LSM policy.  Update the IMA LSM based rules to reflect
+@@ -647,6 +662,7 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry,
+                                          &entry->lsm[lsm_rule].rule);
+       if (!entry->lsm[lsm_rule].rule) {
+               kfree(entry->lsm[lsm_rule].args_p);
++              entry->lsm[lsm_rule].args_p = NULL;
+               return -EINVAL;
+       }
+ 
+@@ -1019,7 +1035,7 @@ ssize_t ima_parse_add_rule(char *rule)
+ 
+       result = ima_parse_rule(p, entry);
+       if (result) {
+-              kfree(entry);
++              ima_free_rule(entry);
+               integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL,
+                                   NULL, op, "invalid-policy", result,
+                                   audit_info);
+@@ -1040,15 +1056,11 @@ ssize_t ima_parse_add_rule(char *rule)
+ void ima_delete_rules(void)
+ {
+       struct ima_rule_entry *entry, *tmp;
+-      int i;
+ 
+       temp_ima_appraise = 0;
+       list_for_each_entry_safe(entry, tmp, &ima_temp_rules, list) {
+-              for (i = 0; i < MAX_LSM_RULES; i++)
+-                      kfree(entry->lsm[i].args_p);
+-
+               list_del(&entry->list);
+-              kfree(entry);
++              ima_free_rule(entry);
+       }
+ }
+ 
+diff --git a/tools/testing/selftests/net/reuseport_bpf.c 
b/tools/testing/selftests/net/reuseport_bpf.c
+index b5277106df1fd..b0cc082fbb84f 100644
+--- a/tools/testing/selftests/net/reuseport_bpf.c
++++ b/tools/testing/selftests/net/reuseport_bpf.c
+@@ -330,7 +330,7 @@ static void test_extra_filter(const struct test_params p)
+       if (bind(fd1, addr, sockaddr_size()))
+               error(1, errno, "failed to bind recv socket 1");
+ 
+-      if (!bind(fd2, addr, sockaddr_size()) && errno != EADDRINUSE)
++      if (!bind(fd2, addr, sockaddr_size()) || errno != EADDRINUSE)
+               error(1, errno, "bind socket 2 should fail with EADDRINUSE");
+ 
+       free(addr);

Reply via email to