--- /dev/null
+From d0522e0253daaea4693ad7064e2860f02c93bc92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Jul 2021 07:50:33 -0700
+Subject: ARC: Fix CONFIG_STACKDEPOT
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit bf79167fd86f3b97390fe2e70231d383526bd9cc ]
+
+Enabling CONFIG_STACKDEPOT results in the following build error.
+
+arc-elf-ld: lib/stackdepot.o: in function `filter_irq_stacks':
+stackdepot.c:(.text+0x456): undefined reference to `__irqentry_text_start'
+arc-elf-ld: stackdepot.c:(.text+0x456): undefined reference to `__irqentry_text_start'
+arc-elf-ld: stackdepot.c:(.text+0x476): undefined reference to `__irqentry_text_end'
+arc-elf-ld: stackdepot.c:(.text+0x476): undefined reference to `__irqentry_text_end'
+arc-elf-ld: stackdepot.c:(.text+0x484): undefined reference to `__softirqentry_text_start'
+arc-elf-ld: stackdepot.c:(.text+0x484): undefined reference to `__softirqentry_text_start'
+arc-elf-ld: stackdepot.c:(.text+0x48c): undefined reference to `__softirqentry_text_end'
+arc-elf-ld: stackdepot.c:(.text+0x48c): undefined reference to `__softirqentry_text_end'
+
+Other architectures address this problem by adding IRQENTRY_TEXT and
+SOFTIRQENTRY_TEXT to the text segment, so do the same here.
+
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arc/kernel/vmlinux.lds.S | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S
+index e2146a8da195..529ae50f9fe2 100644
+--- a/arch/arc/kernel/vmlinux.lds.S
++++ b/arch/arc/kernel/vmlinux.lds.S
+@@ -88,6 +88,8 @@ SECTIONS
+ CPUIDLE_TEXT
+ LOCK_TEXT
+ KPROBES_TEXT
++ IRQENTRY_TEXT
++ SOFTIRQENTRY_TEXT
+ *(.fixup)
+ *(.gnu.warning)
+ }
+--
+2.30.2
+
--- /dev/null
+From 928985c8025c1cca44b3c6c9d709785d37fd20a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jul 2021 20:41:23 +0100
+Subject: ASoC: component: Remove misplaced prefix handling in pin control
+ functions
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit 31428c78748cafdd9352e1f622eb89bf453d9700 ]
+
+When the component level pin control functions were added they for some
+no longer obvious reason handled adding prefixing of widget names. This
+meant that when the lack of prefix handling in the DAPM level pin
+operations was fixed by ae4fc532244b3bb4d (ASoC: dapm: use component
+prefix when checking widget names) the one device using the component
+level API ended up with the prefix being applied twice, causing all
+lookups to fail.
+
+Fix this by removing the redundant prefixing from the component code,
+which has the nice side effect of also making that code much simpler.
+
+Reported-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Tested-by: Lucas Tanure <tanureal@opensource.cirrus.com>
+Link: https://lore.kernel.org/r/20210726194123.54585-1-broonie@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/soc-component.c | 63 +++++++++++++++++----------------------
+ 1 file changed, 27 insertions(+), 36 deletions(-)
+
+diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c
+index 3a5e84e16a87..c8dfd0de30e4 100644
+--- a/sound/soc/soc-component.c
++++ b/sound/soc/soc-component.c
+@@ -148,86 +148,75 @@ int snd_soc_component_set_bias_level(struct snd_soc_component *component,
+ return soc_component_ret(component, ret);
+ }
+
+-static int soc_component_pin(struct snd_soc_component *component,
+- const char *pin,
+- int (*pin_func)(struct snd_soc_dapm_context *dapm,
+- const char *pin))
+-{
+- struct snd_soc_dapm_context *dapm =
+- snd_soc_component_get_dapm(component);
+- char *full_name;
+- int ret;
+-
+- if (!component->name_prefix) {
+- ret = pin_func(dapm, pin);
+- goto end;
+- }
+-
+- full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
+- if (!full_name) {
+- ret = -ENOMEM;
+- goto end;
+- }
+-
+- ret = pin_func(dapm, full_name);
+- kfree(full_name);
+-end:
+- return soc_component_ret(component, ret);
+-}
+-
+ int snd_soc_component_enable_pin(struct snd_soc_component *component,
+ const char *pin)
+ {
+- return soc_component_pin(component, pin, snd_soc_dapm_enable_pin);
++ struct snd_soc_dapm_context *dapm =
++ snd_soc_component_get_dapm(component);
++ return snd_soc_dapm_enable_pin(dapm, pin);
+ }
+ EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin);
+
+ int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
+ const char *pin)
+ {
+- return soc_component_pin(component, pin, snd_soc_dapm_enable_pin_unlocked);
++ struct snd_soc_dapm_context *dapm =
++ snd_soc_component_get_dapm(component);
++ return snd_soc_dapm_enable_pin_unlocked(dapm, pin);
+ }
+ EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);
+
+ int snd_soc_component_disable_pin(struct snd_soc_component *component,
+ const char *pin)
+ {
+- return soc_component_pin(component, pin, snd_soc_dapm_disable_pin);
++ struct snd_soc_dapm_context *dapm =
++ snd_soc_component_get_dapm(component);
++ return snd_soc_dapm_disable_pin(dapm, pin);
+ }
+ EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);
+
+ int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
+ const char *pin)
+ {
+- return soc_component_pin(component, pin, snd_soc_dapm_disable_pin_unlocked);
++ struct snd_soc_dapm_context *dapm =
++ snd_soc_component_get_dapm(component);
++ return snd_soc_dapm_disable_pin_unlocked(dapm, pin);
+ }
+ EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);
+
+ int snd_soc_component_nc_pin(struct snd_soc_component *component,
+ const char *pin)
+ {
+- return soc_component_pin(component, pin, snd_soc_dapm_nc_pin);
++ struct snd_soc_dapm_context *dapm =
++ snd_soc_component_get_dapm(component);
++ return snd_soc_dapm_nc_pin(dapm, pin);
+ }
+ EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);
+
+ int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
+ const char *pin)
+ {
+- return soc_component_pin(component, pin, snd_soc_dapm_nc_pin_unlocked);
++ struct snd_soc_dapm_context *dapm =
++ snd_soc_component_get_dapm(component);
++ return snd_soc_dapm_nc_pin_unlocked(dapm, pin);
+ }
+ EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);
+
+ int snd_soc_component_get_pin_status(struct snd_soc_component *component,
+ const char *pin)
+ {
+- return soc_component_pin(component, pin, snd_soc_dapm_get_pin_status);
++ struct snd_soc_dapm_context *dapm =
++ snd_soc_component_get_dapm(component);
++ return snd_soc_dapm_get_pin_status(dapm, pin);
+ }
+ EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);
+
+ int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
+ const char *pin)
+ {
+- return soc_component_pin(component, pin, snd_soc_dapm_force_enable_pin);
++ struct snd_soc_dapm_context *dapm =
++ snd_soc_component_get_dapm(component);
++ return snd_soc_dapm_force_enable_pin(dapm, pin);
+ }
+ EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);
+
+@@ -235,7 +224,9 @@ int snd_soc_component_force_enable_pin_unlocked(
+ struct snd_soc_component *component,
+ const char *pin)
+ {
+- return soc_component_pin(component, pin, snd_soc_dapm_force_enable_pin_unlocked);
++ struct snd_soc_dapm_context *dapm =
++ snd_soc_component_get_dapm(component);
++ return snd_soc_dapm_force_enable_pin_unlocked(dapm, pin);
+ }
+ EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked);
+
+--
+2.30.2
+
--- /dev/null
+From 00bf7b91b024694edf30111b33dc1837b11c4c6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jul 2021 21:31:21 +0800
+Subject: ASoC: rt5682: Adjust headset volume button threshold
+
+From: Derek Fang <derek.fang@realtek.com>
+
+[ Upstream commit 6d20bf7c020f417fdef1810a22da17c126603472 ]
+
+Adjust the threshold of headset button volume+ to fix
+the wrong button detection issue with some brand headsets.
+
+Signed-off-by: Derek Fang <derek.fang@realtek.com>
+Link: https://lore.kernel.org/r/20210721133121.12333-1-derek.fang@realtek.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt5682.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c
+index abcd6f483788..51ecaa2abcd1 100644
+--- a/sound/soc/codecs/rt5682.c
++++ b/sound/soc/codecs/rt5682.c
+@@ -44,6 +44,7 @@ static const struct reg_sequence patch_list[] = {
+ {RT5682_I2C_CTRL, 0x000f},
+ {RT5682_PLL2_INTERNAL, 0x8266},
+ {RT5682_SAR_IL_CMD_3, 0x8365},
++ {RT5682_SAR_IL_CMD_6, 0x0180},
+ };
+
+ void rt5682_apply_patch_list(struct rt5682_priv *rt5682, struct device *dev)
+--
+2.30.2
+
--- /dev/null
+From 2c32efa8bb61f12afdf63a58716bb975a7cd8f0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Aug 2021 15:06:08 +0800
+Subject: blk-iocost: fix lockdep warning on blkcg->lock
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 11431e26c9c43fa26f6b33ee1a90989f57b86024 ]
+
+blkcg->lock depends on q->queue_lock which may depend on another driver
+lock required in irq context, one example is dm-thin:
+
+ Chain exists of:
+ &pool->lock#3 --> &q->queue_lock --> &blkcg->lock
+
+ Possible interrupt unsafe locking scenario:
+
+ CPU0 CPU1
+ ---- ----
+ lock(&blkcg->lock);
+ local_irq_disable();
+ lock(&pool->lock#3);
+ lock(&q->queue_lock);
+ <Interrupt>
+ lock(&pool->lock#3);
+
+Fix the issue by using spin_lock_irq(&blkcg->lock) in ioc_weight_write().
+
+Cc: Tejun Heo <tj@kernel.org>
+Reported-by: Bruno Goncalves <bgoncalv@redhat.com>
+Link: https://lore.kernel.org/linux-block/CA+QYu4rzz6079ighEanS3Qq_Dmnczcf45ZoJoHKVLVATTo1e4Q@mail.gmail.com/T/#u
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Acked-by: Tejun Heo <tj@kernel.org>
+Link: https://lore.kernel.org/r/20210803070608.1766400-1-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-iocost.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/block/blk-iocost.c b/block/blk-iocost.c
+index 5fac3757e6e0..0e56557cacf2 100644
+--- a/block/blk-iocost.c
++++ b/block/blk-iocost.c
+@@ -3061,19 +3061,19 @@ static ssize_t ioc_weight_write(struct kernfs_open_file *of, char *buf,
+ if (v < CGROUP_WEIGHT_MIN || v > CGROUP_WEIGHT_MAX)
+ return -EINVAL;
+
+- spin_lock(&blkcg->lock);
++ spin_lock_irq(&blkcg->lock);
+ iocc->dfl_weight = v * WEIGHT_ONE;
+ hlist_for_each_entry(blkg, &blkcg->blkg_list, blkcg_node) {
+ struct ioc_gq *iocg = blkg_to_iocg(blkg);
+
+ if (iocg) {
+- spin_lock_irq(&iocg->ioc->lock);
++ spin_lock(&iocg->ioc->lock);
+ ioc_now(iocg->ioc, &now);
+ weight_updated(iocg, &now);
+- spin_unlock_irq(&iocg->ioc->lock);
++ spin_unlock(&iocg->ioc->lock);
+ }
+ }
+- spin_unlock(&blkcg->lock);
++ spin_unlock_irq(&blkcg->lock);
+
+ return nbytes;
+ }
+--
+2.30.2
+
--- /dev/null
+From 5f1b2e77914e352bd58a3d6bbabdef37c1121d19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Aug 2021 07:49:41 -0600
+Subject: io_uring: rsrc ref lock needs to be IRQ safe
+
+From: Jens Axboe <axboe@kernel.dk>
+
+[ Upstream commit 4956b9eaad456a88b0d56947bef036e086250beb ]
+
+Nadav reports running into the below splat on re-enabling softirqs:
+
+WARNING: CPU: 2 PID: 1777 at kernel/softirq.c:364 __local_bh_enable_ip+0xaa/0xe0
+Modules linked in:
+CPU: 2 PID: 1777 Comm: umem Not tainted 5.13.1+ #161
+Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/22/2020
+RIP: 0010:__local_bh_enable_ip+0xaa/0xe0
+Code: a9 00 ff ff 00 74 38 65 ff 0d a2 21 8c 7a e8 ed 1a 20 00 fb 66 0f 1f 44 00 00 5b 41 5c 5d c3 65 8b 05 e6 2d 8c 7a 85 c0 75 9a <0f> 0b eb 96 e8 2d 1f 20 00 eb a5 4c 89 e7 e8 73 4f 0c 00 eb ae 65
+RSP: 0018:ffff88812e58fcc8 EFLAGS: 00010046
+RAX: 0000000000000000 RBX: 0000000000000201 RCX: dffffc0000000000
+RDX: 0000000000000007 RSI: 0000000000000201 RDI: ffffffff8898c5ac
+RBP: ffff88812e58fcd8 R08: ffffffff8575dbbf R09: ffffed1028ef14f9
+R10: ffff88814778a7c3 R11: ffffed1028ef14f8 R12: ffffffff85c9e9ae
+R13: ffff88814778a000 R14: ffff88814778a7b0 R15: ffff8881086db890
+FS: 00007fbcfee17700(0000) GS:ffff8881e0300000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000c0402a5008 CR3: 000000011c1ac003 CR4: 00000000003706e0
+Call Trace:
+ _raw_spin_unlock_bh+0x31/0x40
+ io_rsrc_node_ref_zero+0x13e/0x190
+ io_dismantle_req+0x215/0x220
+ io_req_complete_post+0x1b8/0x720
+ __io_complete_rw.isra.0+0x16b/0x1f0
+ io_complete_rw+0x10/0x20
+
+where it's clear we end up calling the percpu count release directly
+from the completion path, as it's in atomic mode and we drop the last
+ref. For file/block IO, this can be from IRQ context already, and the
+softirq locking for rsrc isn't enough.
+
+Just make the lock fully IRQ safe, and ensure we correctly safe state
+from the release path as we don't know the full context there.
+
+Reported-by: Nadav Amit <nadav.amit@gmail.com>
+Tested-by: Nadav Amit <nadav.amit@gmail.com>
+Link: https://lore.kernel.org/io-uring/C187C836-E78B-4A31-B24C-D16919ACA093@gmail.com/
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/io_uring.c | 19 +++++--------------
+ 1 file changed, 5 insertions(+), 14 deletions(-)
+
+diff --git a/fs/io_uring.c b/fs/io_uring.c
+index 9df82eee440a..f6ddc7182943 100644
+--- a/fs/io_uring.c
++++ b/fs/io_uring.c
+@@ -7105,16 +7105,6 @@ static void io_free_file_tables(struct io_file_table *table, unsigned nr_files)
+ table->files = NULL;
+ }
+
+-static inline void io_rsrc_ref_lock(struct io_ring_ctx *ctx)
+-{
+- spin_lock_bh(&ctx->rsrc_ref_lock);
+-}
+-
+-static inline void io_rsrc_ref_unlock(struct io_ring_ctx *ctx)
+-{
+- spin_unlock_bh(&ctx->rsrc_ref_lock);
+-}
+-
+ static void io_rsrc_node_destroy(struct io_rsrc_node *ref_node)
+ {
+ percpu_ref_exit(&ref_node->refs);
+@@ -7131,9 +7121,9 @@ static void io_rsrc_node_switch(struct io_ring_ctx *ctx,
+ struct io_rsrc_node *rsrc_node = ctx->rsrc_node;
+
+ rsrc_node->rsrc_data = data_to_kill;
+- io_rsrc_ref_lock(ctx);
++ spin_lock_irq(&ctx->rsrc_ref_lock);
+ list_add_tail(&rsrc_node->node, &ctx->rsrc_ref_list);
+- io_rsrc_ref_unlock(ctx);
++ spin_unlock_irq(&ctx->rsrc_ref_lock);
+
+ atomic_inc(&data_to_kill->refs);
+ percpu_ref_kill(&rsrc_node->refs);
+@@ -7625,9 +7615,10 @@ static void io_rsrc_node_ref_zero(struct percpu_ref *ref)
+ {
+ struct io_rsrc_node *node = container_of(ref, struct io_rsrc_node, refs);
+ struct io_ring_ctx *ctx = node->rsrc_data->ctx;
++ unsigned long flags;
+ bool first_add = false;
+
+- io_rsrc_ref_lock(ctx);
++ spin_lock_irqsave(&ctx->rsrc_ref_lock, flags);
+ node->done = true;
+
+ while (!list_empty(&ctx->rsrc_ref_list)) {
+@@ -7639,7 +7630,7 @@ static void io_rsrc_node_ref_zero(struct percpu_ref *ref)
+ list_del(&node->node);
+ first_add |= llist_add(&node->llist, &ctx->rsrc_put_llist);
+ }
+- io_rsrc_ref_unlock(ctx);
++ spin_unlock_irqrestore(&ctx->rsrc_ref_lock, flags);
+
+ if (first_add)
+ mod_delayed_work(system_wq, &ctx->rsrc_put_work, HZ);
+--
+2.30.2
+
--- /dev/null
+From 438d464b33af45dec0fb787954f5e2d1b03bb60d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Aug 2021 13:37:48 +0100
+Subject: net: mscc: Fix non-GPL export of regmap APIs
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit 48c812e0327744b4965296f65c23fe2405692afc ]
+
+The ocelot driver makes use of regmap, wrapping it with driver specific
+operations that are thin wrappers around the core regmap APIs. These are
+exported with EXPORT_SYMBOL, dropping the _GPL from the core regmap
+exports which is frowned upon. Add _GPL suffixes to at least the APIs that
+are doing register I/O.
+
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot_io.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot_io.c b/drivers/net/ethernet/mscc/ocelot_io.c
+index ea4e83410fe4..7390fa3980ec 100644
+--- a/drivers/net/ethernet/mscc/ocelot_io.c
++++ b/drivers/net/ethernet/mscc/ocelot_io.c
+@@ -21,7 +21,7 @@ u32 __ocelot_read_ix(struct ocelot *ocelot, u32 reg, u32 offset)
+ ocelot->map[target][reg & REG_MASK] + offset, &val);
+ return val;
+ }
+-EXPORT_SYMBOL(__ocelot_read_ix);
++EXPORT_SYMBOL_GPL(__ocelot_read_ix);
+
+ void __ocelot_write_ix(struct ocelot *ocelot, u32 val, u32 reg, u32 offset)
+ {
+@@ -32,7 +32,7 @@ void __ocelot_write_ix(struct ocelot *ocelot, u32 val, u32 reg, u32 offset)
+ regmap_write(ocelot->targets[target],
+ ocelot->map[target][reg & REG_MASK] + offset, val);
+ }
+-EXPORT_SYMBOL(__ocelot_write_ix);
++EXPORT_SYMBOL_GPL(__ocelot_write_ix);
+
+ void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, u32 reg,
+ u32 offset)
+@@ -45,7 +45,7 @@ void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, u32 reg,
+ ocelot->map[target][reg & REG_MASK] + offset,
+ mask, val);
+ }
+-EXPORT_SYMBOL(__ocelot_rmw_ix);
++EXPORT_SYMBOL_GPL(__ocelot_rmw_ix);
+
+ u32 ocelot_port_readl(struct ocelot_port *port, u32 reg)
+ {
+@@ -58,7 +58,7 @@ u32 ocelot_port_readl(struct ocelot_port *port, u32 reg)
+ regmap_read(port->target, ocelot->map[target][reg & REG_MASK], &val);
+ return val;
+ }
+-EXPORT_SYMBOL(ocelot_port_readl);
++EXPORT_SYMBOL_GPL(ocelot_port_readl);
+
+ void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg)
+ {
+@@ -69,7 +69,7 @@ void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg)
+
+ regmap_write(port->target, ocelot->map[target][reg & REG_MASK], val);
+ }
+-EXPORT_SYMBOL(ocelot_port_writel);
++EXPORT_SYMBOL_GPL(ocelot_port_writel);
+
+ void ocelot_port_rmwl(struct ocelot_port *port, u32 val, u32 mask, u32 reg)
+ {
+@@ -77,7 +77,7 @@ void ocelot_port_rmwl(struct ocelot_port *port, u32 val, u32 mask, u32 reg)
+
+ ocelot_port_writel(port, (cur & (~mask)) | val, reg);
+ }
+-EXPORT_SYMBOL(ocelot_port_rmwl);
++EXPORT_SYMBOL_GPL(ocelot_port_rmwl);
+
+ u32 __ocelot_target_read_ix(struct ocelot *ocelot, enum ocelot_target target,
+ u32 reg, u32 offset)
+@@ -128,7 +128,7 @@ int ocelot_regfields_init(struct ocelot *ocelot,
+
+ return 0;
+ }
+-EXPORT_SYMBOL(ocelot_regfields_init);
++EXPORT_SYMBOL_GPL(ocelot_regfields_init);
+
+ static struct regmap_config ocelot_regmap_config = {
+ .reg_bits = 32,
+@@ -148,4 +148,4 @@ struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res)
+
+ return devm_regmap_init_mmio(ocelot->dev, regs, &ocelot_regmap_config);
+ }
+-EXPORT_SYMBOL(ocelot_regmap_init);
++EXPORT_SYMBOL_GPL(ocelot_regmap_init);
+--
+2.30.2
+
--- /dev/null
+From f3f16ba7d84eeffdea733bef9a446c4e4101af2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Jul 2021 00:29:19 +0200
+Subject: netfilter: conntrack: collect all entries in one cycle
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 4608fdfc07e116f9fc0895beb40abad7cdb5ee3d ]
+
+Michal Kubecek reports that conntrack gc is responsible for frequent
+wakeups (every 125ms) on idle systems.
+
+On busy systems, timed out entries are evicted during lookup.
+The gc worker is only needed to remove entries after system becomes idle
+after a busy period.
+
+To resolve this, always scan the entire table.
+If the scan is taking too long, reschedule so other work_structs can run
+and resume from next bucket.
+
+After a completed scan, wait for 2 minutes before the next cycle.
+Heuristics for faster re-schedule are removed.
+
+GC_SCAN_INTERVAL could be exposed as a sysctl in the future to allow
+tuning this as-needed or even turn the gc worker off.
+
+Reported-by: Michal Kubecek <mkubecek@suse.cz>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_core.c | 71 ++++++++++---------------------
+ 1 file changed, 22 insertions(+), 49 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index 69079a382d3a..6ba9f4b8d145 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -68,22 +68,17 @@ EXPORT_SYMBOL_GPL(nf_conntrack_hash);
+
+ struct conntrack_gc_work {
+ struct delayed_work dwork;
+- u32 last_bucket;
++ u32 next_bucket;
+ bool exiting;
+ bool early_drop;
+- long next_gc_run;
+ };
+
+ static __read_mostly struct kmem_cache *nf_conntrack_cachep;
+ static DEFINE_SPINLOCK(nf_conntrack_locks_all_lock);
+ static __read_mostly bool nf_conntrack_locks_all;
+
+-/* every gc cycle scans at most 1/GC_MAX_BUCKETS_DIV part of table */
+-#define GC_MAX_BUCKETS_DIV 128u
+-/* upper bound of full table scan */
+-#define GC_MAX_SCAN_JIFFIES (16u * HZ)
+-/* desired ratio of entries found to be expired */
+-#define GC_EVICT_RATIO 50u
++#define GC_SCAN_INTERVAL (120u * HZ)
++#define GC_SCAN_MAX_DURATION msecs_to_jiffies(10)
+
+ static struct conntrack_gc_work conntrack_gc_work;
+
+@@ -1359,17 +1354,13 @@ static bool gc_worker_can_early_drop(const struct nf_conn *ct)
+
+ static void gc_worker(struct work_struct *work)
+ {
+- unsigned int min_interval = max(HZ / GC_MAX_BUCKETS_DIV, 1u);
+- unsigned int i, goal, buckets = 0, expired_count = 0;
+- unsigned int nf_conntrack_max95 = 0;
++ unsigned long end_time = jiffies + GC_SCAN_MAX_DURATION;
++ unsigned int i, hashsz, nf_conntrack_max95 = 0;
++ unsigned long next_run = GC_SCAN_INTERVAL;
+ struct conntrack_gc_work *gc_work;
+- unsigned int ratio, scanned = 0;
+- unsigned long next_run;
+-
+ gc_work = container_of(work, struct conntrack_gc_work, dwork.work);
+
+- goal = nf_conntrack_htable_size / GC_MAX_BUCKETS_DIV;
+- i = gc_work->last_bucket;
++ i = gc_work->next_bucket;
+ if (gc_work->early_drop)
+ nf_conntrack_max95 = nf_conntrack_max / 100u * 95u;
+
+@@ -1377,15 +1368,15 @@ static void gc_worker(struct work_struct *work)
+ struct nf_conntrack_tuple_hash *h;
+ struct hlist_nulls_head *ct_hash;
+ struct hlist_nulls_node *n;
+- unsigned int hashsz;
+ struct nf_conn *tmp;
+
+- i++;
+ rcu_read_lock();
+
+ nf_conntrack_get_ht(&ct_hash, &hashsz);
+- if (i >= hashsz)
+- i = 0;
++ if (i >= hashsz) {
++ rcu_read_unlock();
++ break;
++ }
+
+ hlist_nulls_for_each_entry_rcu(h, n, &ct_hash[i], hnnode) {
+ struct nf_conntrack_net *cnet;
+@@ -1393,7 +1384,6 @@ static void gc_worker(struct work_struct *work)
+
+ tmp = nf_ct_tuplehash_to_ctrack(h);
+
+- scanned++;
+ if (test_bit(IPS_OFFLOAD_BIT, &tmp->status)) {
+ nf_ct_offload_timeout(tmp);
+ continue;
+@@ -1401,7 +1391,6 @@ static void gc_worker(struct work_struct *work)
+
+ if (nf_ct_is_expired(tmp)) {
+ nf_ct_gc_expired(tmp);
+- expired_count++;
+ continue;
+ }
+
+@@ -1434,7 +1423,14 @@ static void gc_worker(struct work_struct *work)
+ */
+ rcu_read_unlock();
+ cond_resched();
+- } while (++buckets < goal);
++ i++;
++
++ if (time_after(jiffies, end_time) && i < hashsz) {
++ gc_work->next_bucket = i;
++ next_run = 0;
++ break;
++ }
++ } while (i < hashsz);
+
+ if (gc_work->exiting)
+ return;
+@@ -1445,40 +1441,17 @@ static void gc_worker(struct work_struct *work)
+ *
+ * This worker is only here to reap expired entries when system went
+ * idle after a busy period.
+- *
+- * The heuristics below are supposed to balance conflicting goals:
+- *
+- * 1. Minimize time until we notice a stale entry
+- * 2. Maximize scan intervals to not waste cycles
+- *
+- * Normally, expire ratio will be close to 0.
+- *
+- * As soon as a sizeable fraction of the entries have expired
+- * increase scan frequency.
+ */
+- ratio = scanned ? expired_count * 100 / scanned : 0;
+- if (ratio > GC_EVICT_RATIO) {
+- gc_work->next_gc_run = min_interval;
+- } else {
+- unsigned int max = GC_MAX_SCAN_JIFFIES / GC_MAX_BUCKETS_DIV;
+-
+- BUILD_BUG_ON((GC_MAX_SCAN_JIFFIES / GC_MAX_BUCKETS_DIV) == 0);
+-
+- gc_work->next_gc_run += min_interval;
+- if (gc_work->next_gc_run > max)
+- gc_work->next_gc_run = max;
++ if (next_run) {
++ gc_work->early_drop = false;
++ gc_work->next_bucket = 0;
+ }
+-
+- next_run = gc_work->next_gc_run;
+- gc_work->last_bucket = i;
+- gc_work->early_drop = false;
+ queue_delayed_work(system_power_efficient_wq, &gc_work->dwork, next_run);
+ }
+
+ static void conntrack_gc_work_init(struct conntrack_gc_work *gc_work)
+ {
+ INIT_DEFERRABLE_WORK(&gc_work->dwork, gc_worker);
+- gc_work->next_gc_run = HZ;
+ gc_work->exiting = false;
+ }
+
+--
+2.30.2
+
--- /dev/null
+From 1639358eae074ec3a4411bdd0978f99dd25f2bfd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Jul 2021 17:01:15 +0200
+Subject: netfilter: ipset: Limit the maximal range of consecutive elements to
+ add/delete
+
+From: Jozsef Kadlecsik <kadlec@netfilter.org>
+
+[ Upstream commit 5f7b51bf09baca8e4f80cbe879536842bafb5f31 ]
+
+The range size of consecutive elements were not limited. Thus one could
+define a huge range which may result soft lockup errors due to the long
+execution time. Now the range size is limited to 2^20 entries.
+
+Reported-by: Brad Spengler <spender@grsecurity.net>
+Signed-off-by: Jozsef Kadlecsik <kadlec@netfilter.org>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/netfilter/ipset/ip_set.h | 3 +++
+ net/netfilter/ipset/ip_set_hash_ip.c | 9 ++++++++-
+ net/netfilter/ipset/ip_set_hash_ipmark.c | 10 +++++++++-
+ net/netfilter/ipset/ip_set_hash_ipport.c | 3 +++
+ net/netfilter/ipset/ip_set_hash_ipportip.c | 3 +++
+ net/netfilter/ipset/ip_set_hash_ipportnet.c | 3 +++
+ net/netfilter/ipset/ip_set_hash_net.c | 11 ++++++++++-
+ net/netfilter/ipset/ip_set_hash_netiface.c | 10 +++++++++-
+ net/netfilter/ipset/ip_set_hash_netnet.c | 16 +++++++++++++++-
+ net/netfilter/ipset/ip_set_hash_netport.c | 11 ++++++++++-
+ net/netfilter/ipset/ip_set_hash_netportnet.c | 16 +++++++++++++++-
+ 11 files changed, 88 insertions(+), 7 deletions(-)
+
+diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
+index 10279c4830ac..ada1296c87d5 100644
+--- a/include/linux/netfilter/ipset/ip_set.h
++++ b/include/linux/netfilter/ipset/ip_set.h
+@@ -196,6 +196,9 @@ struct ip_set_region {
+ u32 elements; /* Number of elements vs timeout */
+ };
+
++/* Max range where every element is added/deleted in one step */
++#define IPSET_MAX_RANGE (1<<20)
++
+ /* The max revision number supported by any set type + 1 */
+ #define IPSET_REVISION_MAX 9
+
+diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
+index d1bef23fd4f5..dd30c03d5a23 100644
+--- a/net/netfilter/ipset/ip_set_hash_ip.c
++++ b/net/netfilter/ipset/ip_set_hash_ip.c
+@@ -132,8 +132,11 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
+ if (ret)
+ return ret;
+- if (ip > ip_to)
++ if (ip > ip_to) {
++ if (ip_to == 0)
++ return -IPSET_ERR_HASH_ELEM;
+ swap(ip, ip_to);
++ }
+ } else if (tb[IPSET_ATTR_CIDR]) {
+ u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
+
+@@ -144,6 +147,10 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
+
+ hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1);
+
++ /* 64bit division is not allowed on 32bit */
++ if (((u64)ip_to - ip + 1) >> (32 - h->netmask) > IPSET_MAX_RANGE)
++ return -ERANGE;
++
+ if (retried) {
+ ip = ntohl(h->next.ip);
+ e.ip = htonl(ip);
+diff --git a/net/netfilter/ipset/ip_set_hash_ipmark.c b/net/netfilter/ipset/ip_set_hash_ipmark.c
+index 18346d18aa16..153de3457423 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipmark.c
++++ b/net/netfilter/ipset/ip_set_hash_ipmark.c
+@@ -121,6 +121,8 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
+
+ e.mark = ntohl(nla_get_be32(tb[IPSET_ATTR_MARK]));
+ e.mark &= h->markmask;
++ if (e.mark == 0 && e.ip == 0)
++ return -IPSET_ERR_HASH_ELEM;
+
+ if (adt == IPSET_TEST ||
+ !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR])) {
+@@ -133,8 +135,11 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
+ if (ret)
+ return ret;
+- if (ip > ip_to)
++ if (ip > ip_to) {
++ if (e.mark == 0 && ip_to == 0)
++ return -IPSET_ERR_HASH_ELEM;
+ swap(ip, ip_to);
++ }
+ } else if (tb[IPSET_ATTR_CIDR]) {
+ u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
+
+@@ -143,6 +148,9 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
+ ip_set_mask_from_to(ip, ip_to, cidr);
+ }
+
++ if (((u64)ip_to - ip + 1) > IPSET_MAX_RANGE)
++ return -ERANGE;
++
+ if (retried)
+ ip = ntohl(h->next.ip);
+ for (; ip <= ip_to; ip++) {
+diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c
+index e1ca11196515..7303138e46be 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipport.c
++++ b/net/netfilter/ipset/ip_set_hash_ipport.c
+@@ -173,6 +173,9 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ swap(port, port_to);
+ }
+
++ if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
++ return -ERANGE;
++
+ if (retried)
+ ip = ntohl(h->next.ip);
+ for (; ip <= ip_to; ip++) {
+diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c
+index ab179e064597..334fb1ad0e86 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipportip.c
++++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
+@@ -180,6 +180,9 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
+ swap(port, port_to);
+ }
+
++ if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
++ return -ERANGE;
++
+ if (retried)
+ ip = ntohl(h->next.ip);
+ for (; ip <= ip_to; ip++) {
+diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c
+index 8f075b44cf64..7df94f437f60 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipportnet.c
++++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
+@@ -253,6 +253,9 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ swap(port, port_to);
+ }
+
++ if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
++ return -ERANGE;
++
+ ip2_to = ip2_from;
+ if (tb[IPSET_ATTR_IP2_TO]) {
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to);
+diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c
+index c1a11f041ac6..1422739d9aa2 100644
+--- a/net/netfilter/ipset/ip_set_hash_net.c
++++ b/net/netfilter/ipset/ip_set_hash_net.c
+@@ -140,7 +140,7 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_net4_elem e = { .cidr = HOST_MASK };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 ip = 0, ip_to = 0;
++ u32 ip = 0, ip_to = 0, ipn, n = 0;
+ int ret;
+
+ if (tb[IPSET_ATTR_LINENO])
+@@ -188,6 +188,15 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
+ if (ip + UINT_MAX == ip_to)
+ return -IPSET_ERR_HASH_RANGE;
+ }
++ ipn = ip;
++ do {
++ ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr);
++ n++;
++ } while (ipn++ < ip_to);
++
++ if (n > IPSET_MAX_RANGE)
++ return -ERANGE;
++
+ if (retried)
+ ip = ntohl(h->next.ip);
+ do {
+diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
+index ddd51c2e1cb3..9810f5bf63f5 100644
+--- a/net/netfilter/ipset/ip_set_hash_netiface.c
++++ b/net/netfilter/ipset/ip_set_hash_netiface.c
+@@ -202,7 +202,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_netiface4_elem e = { .cidr = HOST_MASK, .elem = 1 };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 ip = 0, ip_to = 0;
++ u32 ip = 0, ip_to = 0, ipn, n = 0;
+ int ret;
+
+ if (tb[IPSET_ATTR_LINENO])
+@@ -256,6 +256,14 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
+ } else {
+ ip_set_mask_from_to(ip, ip_to, e.cidr);
+ }
++ ipn = ip;
++ do {
++ ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr);
++ n++;
++ } while (ipn++ < ip_to);
++
++ if (n > IPSET_MAX_RANGE)
++ return -ERANGE;
+
+ if (retried)
+ ip = ntohl(h->next.ip);
+diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c
+index 6532f0505e66..3d09eefe998a 100644
+--- a/net/netfilter/ipset/ip_set_hash_netnet.c
++++ b/net/netfilter/ipset/ip_set_hash_netnet.c
+@@ -168,7 +168,8 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ struct hash_netnet4_elem e = { };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+ u32 ip = 0, ip_to = 0;
+- u32 ip2 = 0, ip2_from = 0, ip2_to = 0;
++ u32 ip2 = 0, ip2_from = 0, ip2_to = 0, ipn;
++ u64 n = 0, m = 0;
+ int ret;
+
+ if (tb[IPSET_ATTR_LINENO])
+@@ -244,6 +245,19 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ } else {
+ ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]);
+ }
++ ipn = ip;
++ do {
++ ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr[0]);
++ n++;
++ } while (ipn++ < ip_to);
++ ipn = ip2_from;
++ do {
++ ipn = ip_set_range_to_cidr(ipn, ip2_to, &e.cidr[1]);
++ m++;
++ } while (ipn++ < ip2_to);
++
++ if (n*m > IPSET_MAX_RANGE)
++ return -ERANGE;
+
+ if (retried) {
+ ip = ntohl(h->next.ip[0]);
+diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c
+index ec1564a1cb5a..09cf72eb37f8 100644
+--- a/net/netfilter/ipset/ip_set_hash_netport.c
++++ b/net/netfilter/ipset/ip_set_hash_netport.c
+@@ -158,7 +158,8 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_netport4_elem e = { .cidr = HOST_MASK - 1 };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+- u32 port, port_to, p = 0, ip = 0, ip_to = 0;
++ u32 port, port_to, p = 0, ip = 0, ip_to = 0, ipn;
++ u64 n = 0;
+ bool with_ports = false;
+ u8 cidr;
+ int ret;
+@@ -235,6 +236,14 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ } else {
+ ip_set_mask_from_to(ip, ip_to, e.cidr + 1);
+ }
++ ipn = ip;
++ do {
++ ipn = ip_set_range_to_cidr(ipn, ip_to, &cidr);
++ n++;
++ } while (ipn++ < ip_to);
++
++ if (n*(port_to - port + 1) > IPSET_MAX_RANGE)
++ return -ERANGE;
+
+ if (retried) {
+ ip = ntohl(h->next.ip);
+diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c
+index 0e91d1e82f1c..19bcdb3141f6 100644
+--- a/net/netfilter/ipset/ip_set_hash_netportnet.c
++++ b/net/netfilter/ipset/ip_set_hash_netportnet.c
+@@ -182,7 +182,8 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ struct hash_netportnet4_elem e = { };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+ u32 ip = 0, ip_to = 0, p = 0, port, port_to;
+- u32 ip2_from = 0, ip2_to = 0, ip2;
++ u32 ip2_from = 0, ip2_to = 0, ip2, ipn;
++ u64 n = 0, m = 0;
+ bool with_ports = false;
+ int ret;
+
+@@ -284,6 +285,19 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ } else {
+ ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]);
+ }
++ ipn = ip;
++ do {
++ ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr[0]);
++ n++;
++ } while (ipn++ < ip_to);
++ ipn = ip2_from;
++ do {
++ ipn = ip_set_range_to_cidr(ipn, ip2_to, &e.cidr[1]);
++ m++;
++ } while (ipn++ < ip2_to);
++
++ if (n*m*(port_to - port + 1) > IPSET_MAX_RANGE)
++ return -ERANGE;
+
+ if (retried) {
+ ip = ntohl(h->next.ip[0]);
+--
+2.30.2
+
--- /dev/null
+From c598186b5c6dd9fd636b075702aac8e7c76f974d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Aug 2021 16:21:24 +0800
+Subject: once: Fix panic when module unload
+
+From: Kefeng Wang <wangkefeng.wang@huawei.com>
+
+[ Upstream commit 1027b96ec9d34f9abab69bc1a4dc5b1ad8ab1349 ]
+
+DO_ONCE
+DEFINE_STATIC_KEY_TRUE(___once_key);
+__do_once_done
+ once_disable_jump(once_key);
+ INIT_WORK(&w->work, once_deferred);
+ struct once_work *w;
+ w->key = key;
+ schedule_work(&w->work); module unload
+ //*the key is
+destroy*
+process_one_work
+ once_deferred
+ BUG_ON(!static_key_enabled(work->key));
+ static_key_count((struct static_key *)x) //*access key, crash*
+
+When module uses DO_ONCE mechanism, it could crash due to the above
+concurrency problem, we could reproduce it with link[1].
+
+Fix it by add/put module refcount in the once work process.
+
+[1] https://lore.kernel.org/netdev/eaa6c371-465e-57eb-6be9-f4b16b9d7cbf@huawei.com/
+
+Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Eric Dumazet <edumazet@google.com>
+Reported-by: Minmin chen <chenmingmin@huawei.com>
+Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
+Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/once.h | 4 ++--
+ lib/once.c | 11 ++++++++---
+ 2 files changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/include/linux/once.h b/include/linux/once.h
+index 9225ee6d96c7..ae6f4eb41cbe 100644
+--- a/include/linux/once.h
++++ b/include/linux/once.h
+@@ -7,7 +7,7 @@
+
+ bool __do_once_start(bool *done, unsigned long *flags);
+ void __do_once_done(bool *done, struct static_key_true *once_key,
+- unsigned long *flags);
++ unsigned long *flags, struct module *mod);
+
+ /* Call a function exactly once. The idea of DO_ONCE() is to perform
+ * a function call such as initialization of random seeds, etc, only
+@@ -46,7 +46,7 @@ void __do_once_done(bool *done, struct static_key_true *once_key,
+ if (unlikely(___ret)) { \
+ func(__VA_ARGS__); \
+ __do_once_done(&___done, &___once_key, \
+- &___flags); \
++ &___flags, THIS_MODULE); \
+ } \
+ } \
+ ___ret; \
+diff --git a/lib/once.c b/lib/once.c
+index 8b7d6235217e..59149bf3bfb4 100644
+--- a/lib/once.c
++++ b/lib/once.c
+@@ -3,10 +3,12 @@
+ #include <linux/spinlock.h>
+ #include <linux/once.h>
+ #include <linux/random.h>
++#include <linux/module.h>
+
+ struct once_work {
+ struct work_struct work;
+ struct static_key_true *key;
++ struct module *module;
+ };
+
+ static void once_deferred(struct work_struct *w)
+@@ -16,10 +18,11 @@ static void once_deferred(struct work_struct *w)
+ work = container_of(w, struct once_work, work);
+ BUG_ON(!static_key_enabled(work->key));
+ static_branch_disable(work->key);
++ module_put(work->module);
+ kfree(work);
+ }
+
+-static void once_disable_jump(struct static_key_true *key)
++static void once_disable_jump(struct static_key_true *key, struct module *mod)
+ {
+ struct once_work *w;
+
+@@ -29,6 +32,8 @@ static void once_disable_jump(struct static_key_true *key)
+
+ INIT_WORK(&w->work, once_deferred);
+ w->key = key;
++ w->module = mod;
++ __module_get(mod);
+ schedule_work(&w->work);
+ }
+
+@@ -53,11 +58,11 @@ bool __do_once_start(bool *done, unsigned long *flags)
+ EXPORT_SYMBOL(__do_once_start);
+
+ void __do_once_done(bool *done, struct static_key_true *once_key,
+- unsigned long *flags)
++ unsigned long *flags, struct module *mod)
+ __releases(once_lock)
+ {
+ *done = true;
+ spin_unlock_irqrestore(&once_lock, *flags);
+- once_disable_jump(once_key);
++ once_disable_jump(once_key, mod);
+ }
+ EXPORT_SYMBOL(__do_once_done);
+--
+2.30.2
+
--- /dev/null
+From ed6e984301624369e354c64ec27e7ae10e96db1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Aug 2021 10:03:12 +0200
+Subject: ovl: fix uninitialized pointer read in ovl_lookup_real_one()
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+[ Upstream commit 580c610429b3994e8db24418927747cf28443cde ]
+
+One error path can result in release_dentry_name_snapshot() being called
+before "name" was initialized by take_dentry_name_snapshot().
+
+Fix by moving the release_dentry_name_snapshot() to immediately after the
+only use.
+
+Reported-by: Colin Ian King <colin.king@canonical.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/overlayfs/export.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c
+index 41ebf52f1bbc..ebde05c9cf62 100644
+--- a/fs/overlayfs/export.c
++++ b/fs/overlayfs/export.c
+@@ -392,6 +392,7 @@ static struct dentry *ovl_lookup_real_one(struct dentry *connected,
+ */
+ take_dentry_name_snapshot(&name, real);
+ this = lookup_one_len(name.name.name, connected, name.name.len);
++ release_dentry_name_snapshot(&name);
+ err = PTR_ERR(this);
+ if (IS_ERR(this)) {
+ goto fail;
+@@ -406,7 +407,6 @@ static struct dentry *ovl_lookup_real_one(struct dentry *connected,
+ }
+
+ out:
+- release_dentry_name_snapshot(&name);
+ dput(parent);
+ inode_unlock(dir);
+ return this;
+--
+2.30.2
+
--- /dev/null
+From f9ae07a49946fddb20595d58222f12a4e7ef9ac8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jul 2021 10:21:34 +0200
+Subject: platform/x86: Add and use a dual_accel_detect() helper
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 153cca9caa81ca8912a70528daca4b9a523c6898 ]
+
+Various 360 degree hinges (yoga) style 2-in-1 devices use 2 accelerometers
+to allow the OS to determine the angle between the display and the base of
+the device.
+
+On Windows these are read by a special HingeAngleService process which
+calls undocumented ACPI methods, to let the firmware know if the 2-in-1 is
+in tablet- or laptop-mode. The firmware may use this to disable the kbd and
+touchpad to avoid spurious input in tablet-mode as well as to report
+SW_TABLET_MODE info to the OS.
+
+Since Linux does not call these undocumented methods, the SW_TABLET_MODE
+info reported by various pdx86 drivers is incorrect on these devices.
+
+Before this commit the intel-hid and thinkpad_acpi code already had 2
+hardcoded checks for ACPI hardware-ids of dual-accel sensors to avoid
+reporting broken info.
+
+And now we also have a bug-report about the same problem in the intel-vbtn
+code. Since there are at least 3 different ACPI hardware-ids in play, add
+a new dual_accel_detect() helper which checks for all 3, rather then
+adding different hardware-ids to the drivers as bug-reports trickle in.
+Having shared code which checks all known hardware-ids is esp. important
+for the intel-hid and intel-vbtn drivers as these are generic drivers
+which are used on a lot of devices.
+
+The BOSC0200 hardware-id requires special handling, because often it is
+used for a single-accelerometer setup. Only in a few cases it refers to
+a dual-accel setup, in which case there will be 2 I2cSerialBus resources
+in the device's resource-list, so the helper checks for this.
+
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=209011
+Reported-and-tested-by: Julius Lehmann <julius@devpi.de>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20210729082134.6683-1-hdegoede@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/Kconfig | 3 +
+ drivers/platform/x86/dual_accel_detect.h | 75 ++++++++++++++++++++++++
+ drivers/platform/x86/intel-hid.c | 21 ++-----
+ drivers/platform/x86/intel-vbtn.c | 18 +++++-
+ drivers/platform/x86/thinkpad_acpi.c | 3 +-
+ 5 files changed, 101 insertions(+), 19 deletions(-)
+ create mode 100644 drivers/platform/x86/dual_accel_detect.h
+
+diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
+index 60592fb88e7a..e878ac192758 100644
+--- a/drivers/platform/x86/Kconfig
++++ b/drivers/platform/x86/Kconfig
+@@ -507,6 +507,7 @@ config THINKPAD_ACPI
+ depends on RFKILL || RFKILL = n
+ depends on ACPI_VIDEO || ACPI_VIDEO = n
+ depends on BACKLIGHT_CLASS_DEVICE
++ depends on I2C
+ select ACPI_PLATFORM_PROFILE
+ select HWMON
+ select NVRAM
+@@ -701,6 +702,7 @@ config INTEL_HID_EVENT
+ tristate "INTEL HID Event"
+ depends on ACPI
+ depends on INPUT
++ depends on I2C
+ select INPUT_SPARSEKMAP
+ help
+ This driver provides support for the Intel HID Event hotkey interface.
+@@ -752,6 +754,7 @@ config INTEL_VBTN
+ tristate "INTEL VIRTUAL BUTTON"
+ depends on ACPI
+ depends on INPUT
++ depends on I2C
+ select INPUT_SPARSEKMAP
+ help
+ This driver provides support for the Intel Virtual Button interface.
+diff --git a/drivers/platform/x86/dual_accel_detect.h b/drivers/platform/x86/dual_accel_detect.h
+new file mode 100644
+index 000000000000..1a069159da91
+--- /dev/null
++++ b/drivers/platform/x86/dual_accel_detect.h
+@@ -0,0 +1,75 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Helper code to detect 360 degree hinges (yoga) style 2-in-1 devices using 2 accelerometers
++ * to allow the OS to determine the angle between the display and the base of the device.
++ *
++ * On Windows these are read by a special HingeAngleService process which calls undocumented
++ * ACPI methods, to let the firmware know if the 2-in-1 is in tablet- or laptop-mode.
++ * The firmware may use this to disable the kbd and touchpad to avoid spurious input in
++ * tablet-mode as well as to report SW_TABLET_MODE info to the OS.
++ *
++ * Since Linux does not call these undocumented methods, the SW_TABLET_MODE info reported
++ * by various drivers/platform/x86 drivers is incorrect. These drivers use the detection
++ * code in this file to disable SW_TABLET_MODE reporting to avoid reporting broken info
++ * (instead userspace can derive the status itself by directly reading the 2 accels).
++ */
++
++#include <linux/acpi.h>
++#include <linux/i2c.h>
++
++static int dual_accel_i2c_resource_count(struct acpi_resource *ares, void *data)
++{
++ struct acpi_resource_i2c_serialbus *sb;
++ int *count = data;
++
++ if (i2c_acpi_get_i2c_resource(ares, &sb))
++ *count = *count + 1;
++
++ return 1;
++}
++
++static int dual_accel_i2c_client_count(struct acpi_device *adev)
++{
++ int ret, count = 0;
++ LIST_HEAD(r);
++
++ ret = acpi_dev_get_resources(adev, &r, dual_accel_i2c_resource_count, &count);
++ if (ret < 0)
++ return ret;
++
++ acpi_dev_free_resource_list(&r);
++ return count;
++}
++
++static bool dual_accel_detect_bosc0200(void)
++{
++ struct acpi_device *adev;
++ int count;
++
++ adev = acpi_dev_get_first_match_dev("BOSC0200", NULL, -1);
++ if (!adev)
++ return false;
++
++ count = dual_accel_i2c_client_count(adev);
++
++ acpi_dev_put(adev);
++
++ return count == 2;
++}
++
++static bool dual_accel_detect(void)
++{
++ /* Systems which use a pair of accels with KIOX010A / KIOX020A ACPI ids */
++ if (acpi_dev_present("KIOX010A", NULL, -1))
++ return true;
++
++ /* Systems which use a single DUAL250E ACPI device to model 2 accels */
++ if (acpi_dev_present("DUAL250E", NULL, -1))
++ return true;
++
++ /* Systems which use a single BOSC0200 ACPI device to model 2 accels */
++ if (dual_accel_detect_bosc0200())
++ return true;
++
++ return false;
++}
+diff --git a/drivers/platform/x86/intel-hid.c b/drivers/platform/x86/intel-hid.c
+index 078648a9201b..7135d720af60 100644
+--- a/drivers/platform/x86/intel-hid.c
++++ b/drivers/platform/x86/intel-hid.c
+@@ -14,6 +14,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/suspend.h>
++#include "dual_accel_detect.h"
+
+ /* When NOT in tablet mode, VGBS returns with the flag 0x40 */
+ #define TABLET_MODE_FLAG BIT(6)
+@@ -121,6 +122,7 @@ struct intel_hid_priv {
+ struct input_dev *array;
+ struct input_dev *switches;
+ bool wakeup_mode;
++ bool dual_accel;
+ };
+
+ #define HID_EVENT_FILTER_UUID "eeec56b3-4442-408f-a792-4edd4d758054"
+@@ -450,22 +452,9 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
+ * SW_TABLET_MODE report, in these cases we enable support when receiving
+ * the first event instead of during driver setup.
+ *
+- * Some 360 degree hinges (yoga) style 2-in-1 devices use 2 accelerometers
+- * to allow the OS to determine the angle between the display and the base
+- * of the device. On Windows these are read by a special HingeAngleService
+- * process which calls an ACPI DSM (Device Specific Method) on the
+- * ACPI KIOX010A device node for the sensor in the display, to let the
+- * firmware know if the 2-in-1 is in tablet- or laptop-mode so that it can
+- * disable the kbd and touchpad to avoid spurious input in tablet-mode.
+- *
+- * The linux kxcjk1013 driver calls the DSM for this once at probe time
+- * to ensure that the builtin kbd and touchpad work. On some devices this
+- * causes a "spurious" 0xcd event on the intel-hid ACPI dev. In this case
+- * there is not a functional tablet-mode switch, so we should not register
+- * the tablet-mode switch device.
++ * See dual_accel_detect.h for more info on the dual_accel check.
+ */
+- if (!priv->switches && (event == 0xcc || event == 0xcd) &&
+- !acpi_dev_present("KIOX010A", NULL, -1)) {
++ if (!priv->switches && !priv->dual_accel && (event == 0xcc || event == 0xcd)) {
+ dev_info(&device->dev, "switch event received, enable switches supports\n");
+ err = intel_hid_switches_setup(device);
+ if (err)
+@@ -606,6 +595,8 @@ static int intel_hid_probe(struct platform_device *device)
+ return -ENOMEM;
+ dev_set_drvdata(&device->dev, priv);
+
++ priv->dual_accel = dual_accel_detect();
++
+ err = intel_hid_input_setup(device);
+ if (err) {
+ pr_err("Failed to setup Intel HID hotkeys\n");
+diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c
+index 888a764efad1..309166431063 100644
+--- a/drivers/platform/x86/intel-vbtn.c
++++ b/drivers/platform/x86/intel-vbtn.c
+@@ -14,6 +14,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/suspend.h>
++#include "dual_accel_detect.h"
+
+ /* Returned when NOT in tablet mode on some HP Stream x360 11 models */
+ #define VGBS_TABLET_MODE_FLAG_ALT 0x10
+@@ -66,6 +67,7 @@ static const struct key_entry intel_vbtn_switchmap[] = {
+ struct intel_vbtn_priv {
+ struct input_dev *buttons_dev;
+ struct input_dev *switches_dev;
++ bool dual_accel;
+ bool has_buttons;
+ bool has_switches;
+ bool wakeup_mode;
+@@ -160,6 +162,10 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
+ input_dev = priv->buttons_dev;
+ } else if ((ke = sparse_keymap_entry_from_scancode(priv->switches_dev, event))) {
+ if (!priv->has_switches) {
++ /* See dual_accel_detect.h for more info */
++ if (priv->dual_accel)
++ return;
++
+ dev_info(&device->dev, "Registering Intel Virtual Switches input-dev after receiving a switch event\n");
+ ret = input_register_device(priv->switches_dev);
+ if (ret)
+@@ -248,11 +254,15 @@ static const struct dmi_system_id dmi_switches_allow_list[] = {
+ {} /* Array terminator */
+ };
+
+-static bool intel_vbtn_has_switches(acpi_handle handle)
++static bool intel_vbtn_has_switches(acpi_handle handle, bool dual_accel)
+ {
+ unsigned long long vgbs;
+ acpi_status status;
+
++ /* See dual_accel_detect.h for more info */
++ if (dual_accel)
++ return false;
++
+ if (!dmi_check_system(dmi_switches_allow_list))
+ return false;
+
+@@ -263,13 +273,14 @@ static bool intel_vbtn_has_switches(acpi_handle handle)
+ static int intel_vbtn_probe(struct platform_device *device)
+ {
+ acpi_handle handle = ACPI_HANDLE(&device->dev);
+- bool has_buttons, has_switches;
++ bool dual_accel, has_buttons, has_switches;
+ struct intel_vbtn_priv *priv;
+ acpi_status status;
+ int err;
+
++ dual_accel = dual_accel_detect();
+ has_buttons = acpi_has_method(handle, "VBDL");
+- has_switches = intel_vbtn_has_switches(handle);
++ has_switches = intel_vbtn_has_switches(handle, dual_accel);
+
+ if (!has_buttons && !has_switches) {
+ dev_warn(&device->dev, "failed to read Intel Virtual Button driver\n");
+@@ -281,6 +292,7 @@ static int intel_vbtn_probe(struct platform_device *device)
+ return -ENOMEM;
+ dev_set_drvdata(&device->dev, priv);
+
++ priv->dual_accel = dual_accel;
+ priv->has_buttons = has_buttons;
+ priv->has_switches = has_switches;
+
+diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
+index edd71e744d27..f8cfb529d1a2 100644
+--- a/drivers/platform/x86/thinkpad_acpi.c
++++ b/drivers/platform/x86/thinkpad_acpi.c
+@@ -73,6 +73,7 @@
+ #include <linux/uaccess.h>
+ #include <acpi/battery.h>
+ #include <acpi/video.h>
++#include "dual_accel_detect.h"
+
+ /* ThinkPad CMOS commands */
+ #define TP_CMOS_VOLUME_DOWN 0
+@@ -3232,7 +3233,7 @@ static int hotkey_init_tablet_mode(void)
+ * the laptop/tent/tablet mode to the EC. The bmc150 iio driver
+ * does not support this, so skip the hotkey on these models.
+ */
+- if (has_tablet_mode && !acpi_dev_present("BOSC0200", "1", -1))
++ if (has_tablet_mode && !dual_accel_detect())
+ tp_features.hotkey_tablet = TP_HOTKEY_TABLET_USES_GMMS;
+ type = "GMMS";
+ } else if (acpi_evalf(hkey_handle, &res, "MHKG", "qd")) {
+--
+2.30.2
+
net-qrtr-fix-another-oob-read-in-qrtr_endpoint_post.patch
bpf-fix-ringbuf-helper-function-compatibility.patch
+asoc-rt5682-adjust-headset-volume-button-threshold.patch
+asoc-component-remove-misplaced-prefix-handling-in-p.patch
+platform-x86-add-and-use-a-dual_accel_detect-helper.patch
+arc-fix-config_stackdepot.patch
+netfilter-ipset-limit-the-maximal-range-of-consecuti.patch
+netfilter-conntrack-collect-all-entries-in-one-cycle.patch
+once-fix-panic-when-module-unload.patch
+io_uring-rsrc-ref-lock-needs-to-be-irq-safe.patch
+blk-iocost-fix-lockdep-warning-on-blkcg-lock.patch
+ovl-fix-uninitialized-pointer-read-in-ovl_lookup_rea.patch
+net-mscc-fix-non-gpl-export-of-regmap-apis.patch