]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.13
authorSasha Levin <sashal@kernel.org>
Fri, 27 Aug 2021 17:35:48 +0000 (13:35 -0400)
committerSasha Levin <sashal@kernel.org>
Fri, 27 Aug 2021 17:35:48 +0000 (13:35 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
12 files changed:
queue-5.13/arc-fix-config_stackdepot.patch [new file with mode: 0644]
queue-5.13/asoc-component-remove-misplaced-prefix-handling-in-p.patch [new file with mode: 0644]
queue-5.13/asoc-rt5682-adjust-headset-volume-button-threshold.patch [new file with mode: 0644]
queue-5.13/blk-iocost-fix-lockdep-warning-on-blkcg-lock.patch [new file with mode: 0644]
queue-5.13/io_uring-rsrc-ref-lock-needs-to-be-irq-safe.patch [new file with mode: 0644]
queue-5.13/net-mscc-fix-non-gpl-export-of-regmap-apis.patch [new file with mode: 0644]
queue-5.13/netfilter-conntrack-collect-all-entries-in-one-cycle.patch [new file with mode: 0644]
queue-5.13/netfilter-ipset-limit-the-maximal-range-of-consecuti.patch [new file with mode: 0644]
queue-5.13/once-fix-panic-when-module-unload.patch [new file with mode: 0644]
queue-5.13/ovl-fix-uninitialized-pointer-read-in-ovl_lookup_rea.patch [new file with mode: 0644]
queue-5.13/platform-x86-add-and-use-a-dual_accel_detect-helper.patch [new file with mode: 0644]
queue-5.13/series

diff --git a/queue-5.13/arc-fix-config_stackdepot.patch b/queue-5.13/arc-fix-config_stackdepot.patch
new file mode 100644 (file)
index 0000000..fd8b011
--- /dev/null
@@ -0,0 +1,47 @@
+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
+
diff --git a/queue-5.13/asoc-component-remove-misplaced-prefix-handling-in-p.patch b/queue-5.13/asoc-component-remove-misplaced-prefix-handling-in-p.patch
new file mode 100644 (file)
index 0000000..e351fc7
--- /dev/null
@@ -0,0 +1,160 @@
+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
+
diff --git a/queue-5.13/asoc-rt5682-adjust-headset-volume-button-threshold.patch b/queue-5.13/asoc-rt5682-adjust-headset-volume-button-threshold.patch
new file mode 100644 (file)
index 0000000..68f8dd4
--- /dev/null
@@ -0,0 +1,35 @@
+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
+
diff --git a/queue-5.13/blk-iocost-fix-lockdep-warning-on-blkcg-lock.patch b/queue-5.13/blk-iocost-fix-lockdep-warning-on-blkcg-lock.patch
new file mode 100644 (file)
index 0000000..42a3464
--- /dev/null
@@ -0,0 +1,71 @@
+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
+
diff --git a/queue-5.13/io_uring-rsrc-ref-lock-needs-to-be-irq-safe.patch b/queue-5.13/io_uring-rsrc-ref-lock-needs-to-be-irq-safe.patch
new file mode 100644 (file)
index 0000000..cd3d8ed
--- /dev/null
@@ -0,0 +1,108 @@
+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
+
diff --git a/queue-5.13/net-mscc-fix-non-gpl-export-of-regmap-apis.patch b/queue-5.13/net-mscc-fix-non-gpl-export-of-regmap-apis.patch
new file mode 100644 (file)
index 0000000..419c0c2
--- /dev/null
@@ -0,0 +1,99 @@
+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
+
diff --git a/queue-5.13/netfilter-conntrack-collect-all-entries-in-one-cycle.patch b/queue-5.13/netfilter-conntrack-collect-all-entries-in-one-cycle.patch
new file mode 100644 (file)
index 0000000..73910f4
--- /dev/null
@@ -0,0 +1,185 @@
+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
+
diff --git a/queue-5.13/netfilter-ipset-limit-the-maximal-range-of-consecuti.patch b/queue-5.13/netfilter-ipset-limit-the-maximal-range-of-consecuti.patch
new file mode 100644 (file)
index 0000000..4fec516
--- /dev/null
@@ -0,0 +1,309 @@
+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
+
diff --git a/queue-5.13/once-fix-panic-when-module-unload.patch b/queue-5.13/once-fix-panic-when-module-unload.patch
new file mode 100644 (file)
index 0000000..8302460
--- /dev/null
@@ -0,0 +1,123 @@
+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
+
diff --git a/queue-5.13/ovl-fix-uninitialized-pointer-read-in-ovl_lookup_rea.patch b/queue-5.13/ovl-fix-uninitialized-pointer-read-in-ovl_lookup_rea.patch
new file mode 100644 (file)
index 0000000..007d8d8
--- /dev/null
@@ -0,0 +1,45 @@
+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
+
diff --git a/queue-5.13/platform-x86-add-and-use-a-dual_accel_detect-helper.patch b/queue-5.13/platform-x86-add-and-use-a-dual_accel_detect-helper.patch
new file mode 100644 (file)
index 0000000..3db0630
--- /dev/null
@@ -0,0 +1,314 @@
+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
+
index 737806f2afb2e8fff5d3719aae83494135df8232..f63422d27836780cb13922f93b7fa2bab50e5b74 100644 (file)
@@ -1,2 +1,13 @@
 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