From 3cd2da27a6f189aa3161ce3facc20711524b27bc Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Fri, 27 Aug 2021 13:35:48 -0400 Subject: [PATCH] Fixes for 5.13 Signed-off-by: Sasha Levin --- queue-5.13/arc-fix-config_stackdepot.patch | 47 +++ ...emove-misplaced-prefix-handling-in-p.patch | 160 +++++++++ ...just-headset-volume-button-threshold.patch | 35 ++ ...st-fix-lockdep-warning-on-blkcg-lock.patch | 71 ++++ ...g-rsrc-ref-lock-needs-to-be-irq-safe.patch | 108 ++++++ ...cc-fix-non-gpl-export-of-regmap-apis.patch | 99 ++++++ ...ack-collect-all-entries-in-one-cycle.patch | 185 +++++++++++ ...limit-the-maximal-range-of-consecuti.patch | 309 +++++++++++++++++ .../once-fix-panic-when-module-unload.patch | 123 +++++++ ...lized-pointer-read-in-ovl_lookup_rea.patch | 45 +++ ...d-and-use-a-dual_accel_detect-helper.patch | 314 ++++++++++++++++++ queue-5.13/series | 11 + 12 files changed, 1507 insertions(+) create mode 100644 queue-5.13/arc-fix-config_stackdepot.patch create mode 100644 queue-5.13/asoc-component-remove-misplaced-prefix-handling-in-p.patch create mode 100644 queue-5.13/asoc-rt5682-adjust-headset-volume-button-threshold.patch create mode 100644 queue-5.13/blk-iocost-fix-lockdep-warning-on-blkcg-lock.patch create mode 100644 queue-5.13/io_uring-rsrc-ref-lock-needs-to-be-irq-safe.patch create mode 100644 queue-5.13/net-mscc-fix-non-gpl-export-of-regmap-apis.patch create mode 100644 queue-5.13/netfilter-conntrack-collect-all-entries-in-one-cycle.patch create mode 100644 queue-5.13/netfilter-ipset-limit-the-maximal-range-of-consecuti.patch create mode 100644 queue-5.13/once-fix-panic-when-module-unload.patch create mode 100644 queue-5.13/ovl-fix-uninitialized-pointer-read-in-ovl_lookup_rea.patch create mode 100644 queue-5.13/platform-x86-add-and-use-a-dual_accel_detect-helper.patch diff --git a/queue-5.13/arc-fix-config_stackdepot.patch b/queue-5.13/arc-fix-config_stackdepot.patch new file mode 100644 index 00000000000..fd8b0111564 --- /dev/null +++ b/queue-5.13/arc-fix-config_stackdepot.patch @@ -0,0 +1,47 @@ +From d0522e0253daaea4693ad7064e2860f02c93bc92 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 10 Jul 2021 07:50:33 -0700 +Subject: ARC: Fix CONFIG_STACKDEPOT + +From: Guenter Roeck + +[ 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 +Signed-off-by: Vineet Gupta +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..e351fc7778f --- /dev/null +++ b/queue-5.13/asoc-component-remove-misplaced-prefix-handling-in-p.patch @@ -0,0 +1,160 @@ +From 928985c8025c1cca44b3c6c9d709785d37fd20a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Jul 2021 20:41:23 +0100 +Subject: ASoC: component: Remove misplaced prefix handling in pin control + functions + +From: Mark Brown + +[ 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 +Signed-off-by: Mark Brown +Tested-by: Lucas Tanure +Link: https://lore.kernel.org/r/20210726194123.54585-1-broonie@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..68f8dd43c20 --- /dev/null +++ b/queue-5.13/asoc-rt5682-adjust-headset-volume-button-threshold.patch @@ -0,0 +1,35 @@ +From 00bf7b91b024694edf30111b33dc1837b11c4c6e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Jul 2021 21:31:21 +0800 +Subject: ASoC: rt5682: Adjust headset volume button threshold + +From: Derek Fang + +[ 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 +Link: https://lore.kernel.org/r/20210721133121.12333-1-derek.fang@realtek.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..42a346428c2 --- /dev/null +++ b/queue-5.13/blk-iocost-fix-lockdep-warning-on-blkcg-lock.patch @@ -0,0 +1,71 @@ +From 2c32efa8bb61f12afdf63a58716bb975a7cd8f0f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Aug 2021 15:06:08 +0800 +Subject: blk-iocost: fix lockdep warning on blkcg->lock + +From: Ming Lei + +[ 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); + + lock(&pool->lock#3); + +Fix the issue by using spin_lock_irq(&blkcg->lock) in ioc_weight_write(). + +Cc: Tejun Heo +Reported-by: Bruno Goncalves +Link: https://lore.kernel.org/linux-block/CA+QYu4rzz6079ighEanS3Qq_Dmnczcf45ZoJoHKVLVATTo1e4Q@mail.gmail.com/T/#u +Signed-off-by: Ming Lei +Acked-by: Tejun Heo +Link: https://lore.kernel.org/r/20210803070608.1766400-1-ming.lei@redhat.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..cd3d8ed6327 --- /dev/null +++ b/queue-5.13/io_uring-rsrc-ref-lock-needs-to-be-irq-safe.patch @@ -0,0 +1,108 @@ +From 5f1b2e77914e352bd58a3d6bbabdef37c1121d19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Aug 2021 07:49:41 -0600 +Subject: io_uring: rsrc ref lock needs to be IRQ safe + +From: Jens Axboe + +[ 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 +Tested-by: Nadav Amit +Link: https://lore.kernel.org/io-uring/C187C836-E78B-4A31-B24C-D16919ACA093@gmail.com/ +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..419c0c26a9e --- /dev/null +++ b/queue-5.13/net-mscc-fix-non-gpl-export-of-regmap-apis.patch @@ -0,0 +1,99 @@ +From 438d464b33af45dec0fb787954f5e2d1b03bb60d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Aug 2021 13:37:48 +0100 +Subject: net: mscc: Fix non-GPL export of regmap APIs + +From: Mark Brown + +[ 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 +Acked-by: Alexandre Belloni +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..73910f4a16a --- /dev/null +++ b/queue-5.13/netfilter-conntrack-collect-all-entries-in-one-cycle.patch @@ -0,0 +1,185 @@ +From f3f16ba7d84eeffdea733bef9a446c4e4101af2e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Jul 2021 00:29:19 +0200 +Subject: netfilter: conntrack: collect all entries in one cycle + +From: Florian Westphal + +[ 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 +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..4fec5163a06 --- /dev/null +++ b/queue-5.13/netfilter-ipset-limit-the-maximal-range-of-consecuti.patch @@ -0,0 +1,309 @@ +From 1639358eae074ec3a4411bdd0978f99dd25f2bfd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Jozsef Kadlecsik +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..830246047c0 --- /dev/null +++ b/queue-5.13/once-fix-panic-when-module-unload.patch @@ -0,0 +1,123 @@ +From c598186b5c6dd9fd636b075702aac8e7c76f974d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Aug 2021 16:21:24 +0800 +Subject: once: Fix panic when module unload + +From: Kefeng Wang + +[ 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 +Cc: Daniel Borkmann +Cc: David S. Miller +Cc: Eric Dumazet +Reported-by: Minmin chen +Signed-off-by: Kefeng Wang +Acked-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include + + 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 index 00000000000..007d8d8eeb8 --- /dev/null +++ b/queue-5.13/ovl-fix-uninitialized-pointer-read-in-ovl_lookup_rea.patch @@ -0,0 +1,45 @@ +From ed6e984301624369e354c64ec27e7ae10e96db1d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Aug 2021 10:03:12 +0200 +Subject: ovl: fix uninitialized pointer read in ovl_lookup_real_one() + +From: Miklos Szeredi + +[ 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 +Signed-off-by: Miklos Szeredi +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..3db0630a3b3 --- /dev/null +++ b/queue-5.13/platform-x86-add-and-use-a-dual_accel_detect-helper.patch @@ -0,0 +1,314 @@ +From f9ae07a49946fddb20595d58222f12a4e7ef9ac8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Jul 2021 10:21:34 +0200 +Subject: platform/x86: Add and use a dual_accel_detect() helper + +From: Hans de Goede + +[ 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 +Signed-off-by: Hans de Goede +Reviewed-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20210729082134.6683-1-hdegoede@redhat.com +Signed-off-by: Sasha Levin +--- + 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 ++#include ++ ++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 + #include + #include ++#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 + #include + #include ++#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 + #include + #include ++#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 + diff --git a/queue-5.13/series b/queue-5.13/series index 737806f2afb..f63422d2783 100644 --- a/queue-5.13/series +++ b/queue-5.13/series @@ -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 -- 2.47.3