From: Greg Kroah-Hartman Date: Wed, 19 Mar 2025 14:09:22 +0000 (-0700) Subject: commit.msg-stable patches X-Git-Tag: v6.6.84~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7a18a216b9d2f0ad6a0e45490e72346dc2bb9f08;p=thirdparty%2Fkernel%2Fstable-queue.git commit.msg-stable patches added patches: --- diff --git a/queue-6.6/dt-bindings-display-rockchip-vop-document-rv1126-vop.patch b/queue-6.6/dt-bindings-display-rockchip-vop-document-rv1126-vop.patch deleted file mode 100644 index 7eb9e37917..0000000000 --- a/queue-6.6/dt-bindings-display-rockchip-vop-document-rv1126-vop.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 709d4e26841afc15a57b3416696a472a0266983c Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 31 Jul 2023 16:30:03 +0530 -Subject: dt-bindings: display: rockchip-vop: Document rv1126 vop - -From: Jagan Teki - -[ Upstream commit aadbaac84fc95efa800e4c73ae86fefb8c86288b ] - -The VOP on Rockchip's RV1126 SoC is different from other SoC's -VOP implementations, so add a separate compatible for it. - -Signed-off-by: Jagan Teki -Acked-by: Conor Dooley -Signed-off-by: Heiko Stuebner -Link: https://patchwork.freedesktop.org/patch/msgid/20230731110012.2913742-6-jagan@edgeble.ai -Stable-dep-of: ea2f45ab0e53 ("fbdev: hyperv_fb: Allow graceful removal of framebuffer") -Signed-off-by: Sasha Levin ---- - .../devicetree/bindings/display/rockchip/rockchip-vop.yaml | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml -index df61cb5f5c54b..b339b7e708c65 100644 ---- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml -+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml -@@ -31,6 +31,7 @@ properties: - - rockchip,rk3368-vop - - rockchip,rk3399-vop-big - - rockchip,rk3399-vop-lit -+ - rockchip,rv1126-vop - - reg: - minItems: 1 --- -2.39.5 - diff --git a/queue-6.6/fbdev-core-unexport-logo-helpers.patch b/queue-6.6/fbdev-core-unexport-logo-helpers.patch deleted file mode 100644 index a2553ccbe3..0000000000 --- a/queue-6.6/fbdev-core-unexport-logo-helpers.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 1def1216b3d3bdcb1a38742910191d4dd015dd31 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 7 Sep 2023 10:52:03 +0200 -Subject: fbdev/core: Unexport logo helpers - -From: Thomas Zimmermann - -[ Upstream commit fa671e4f1556e2c18e5443f777a75ae041290068 ] - -The interfaces for the fbdev logo are not used outside of the fbdev -module. Hence declare the fbdev logo functions in the internal header -file and remove their symbol exports. Only build the functions if -CONFIG_LOGO has been selected. - -Signed-off-by: Thomas Zimmermann -Acked-by: Javier Martinez Canillas -Link: https://patchwork.freedesktop.org/patch/msgid/20230907085408.9354-5-tzimmermann@suse.de -Stable-dep-of: ea2f45ab0e53 ("fbdev: hyperv_fb: Allow graceful removal of framebuffer") -Signed-off-by: Sasha Levin ---- - drivers/video/fbdev/core/fb_internal.h | 16 ++++++++++++++++ - drivers/video/fbdev/core/fbmem.c | 5 ----- - include/linux/fb.h | 5 ----- - 3 files changed, 16 insertions(+), 10 deletions(-) - -diff --git a/drivers/video/fbdev/core/fb_internal.h b/drivers/video/fbdev/core/fb_internal.h -index 4c8d509a00265..1116faefa0347 100644 ---- a/drivers/video/fbdev/core/fb_internal.h -+++ b/drivers/video/fbdev/core/fb_internal.h -@@ -21,6 +21,22 @@ static inline void fb_unregister_chrdev(void) - #endif - - /* fbmem.c */ -+#if defined(CONFIG_LOGO) -+extern bool fb_center_logo; -+extern int fb_logo_count; -+int fb_prepare_logo(struct fb_info *fb_info, int rotate); -+int fb_show_logo(struct fb_info *fb_info, int rotate); -+#else -+static inline int fb_prepare_logo(struct fb_info *info, int rotate) -+{ -+ return 0; -+} -+static inline int fb_show_logo(struct fb_info *info, int rotate) -+{ -+ return 0; -+} -+#endif /* CONFIG_LOGO */ -+ - extern struct class *fb_class; - extern struct mutex registration_lock; - extern struct fb_info *registered_fb[FB_MAX]; -diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c -index ee44a46a66be1..0d0003bcdd933 100644 ---- a/drivers/video/fbdev/core/fbmem.c -+++ b/drivers/video/fbdev/core/fbmem.c -@@ -695,12 +695,7 @@ int fb_show_logo(struct fb_info *info, int rotate) - - return y; - } --#else --int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; } --int fb_show_logo(struct fb_info *info, int rotate) { return 0; } - #endif /* CONFIG_LOGO */ --EXPORT_SYMBOL(fb_prepare_logo); --EXPORT_SYMBOL(fb_show_logo); - - int - fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var) -diff --git a/include/linux/fb.h b/include/linux/fb.h -index 322b4d20afa55..16a9a0a0894d9 100644 ---- a/include/linux/fb.h -+++ b/include/linux/fb.h -@@ -591,8 +591,6 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, - /* fbmem.c */ - extern int register_framebuffer(struct fb_info *fb_info); - extern void unregister_framebuffer(struct fb_info *fb_info); --extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); --extern int fb_show_logo(struct fb_info *fb_info, int rotate); - extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size); - extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx, - u32 height, u32 shift_high, u32 shift_low, u32 mod); -@@ -603,9 +601,6 @@ extern int fb_get_color_depth(struct fb_var_screeninfo *var, - extern int fb_get_options(const char *name, char **option); - extern int fb_new_modelist(struct fb_info *info); - --extern bool fb_center_logo; --extern int fb_logo_count; -- - static inline void lock_fb_info(struct fb_info *info) - { - mutex_lock(&info->lock); --- -2.39.5 - diff --git a/queue-6.6/fbdev-hyperv_fb-allow-graceful-removal-of-framebuffe.patch b/queue-6.6/fbdev-hyperv_fb-allow-graceful-removal-of-framebuffe.patch deleted file mode 100644 index 8dbf8051d5..0000000000 --- a/queue-6.6/fbdev-hyperv_fb-allow-graceful-removal-of-framebuffe.patch +++ /dev/null @@ -1,117 +0,0 @@ -From ba1f857547f7d8dfd9b50a9be168cd344dcb484b Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sat, 1 Mar 2025 08:16:31 -0800 -Subject: fbdev: hyperv_fb: Allow graceful removal of framebuffer - -From: Saurabh Sengar - -[ Upstream commit ea2f45ab0e53b255f72c85ccd99e2b394fc5fceb ] - -When a Hyper-V framebuffer device is unbind, hyperv_fb driver tries to -release the framebuffer forcefully. If this framebuffer is in use it -produce the following WARN and hence this framebuffer is never released. - -[ 44.111220] WARNING: CPU: 35 PID: 1882 at drivers/video/fbdev/core/fb_info.c:70 framebuffer_release+0x2c/0x40 -< snip > -[ 44.111289] Call Trace: -[ 44.111290] -[ 44.111291] ? show_regs+0x6c/0x80 -[ 44.111295] ? __warn+0x8d/0x150 -[ 44.111298] ? framebuffer_release+0x2c/0x40 -[ 44.111300] ? report_bug+0x182/0x1b0 -[ 44.111303] ? handle_bug+0x6e/0xb0 -[ 44.111306] ? exc_invalid_op+0x18/0x80 -[ 44.111308] ? asm_exc_invalid_op+0x1b/0x20 -[ 44.111311] ? framebuffer_release+0x2c/0x40 -[ 44.111313] ? hvfb_remove+0x86/0xa0 [hyperv_fb] -[ 44.111315] vmbus_remove+0x24/0x40 [hv_vmbus] -[ 44.111323] device_remove+0x40/0x80 -[ 44.111325] device_release_driver_internal+0x20b/0x270 -[ 44.111327] ? bus_find_device+0xb3/0xf0 - -Fix this by moving the release of framebuffer and assosiated memory -to fb_ops.fb_destroy function, so that framebuffer framework handles -it gracefully. - -While we fix this, also replace manual registrations/unregistration of -framebuffer with devm_register_framebuffer. - -Fixes: 68a2d20b79b1 ("drivers/video: add Hyper-V Synthetic Video Frame Buffer Driver") - -Signed-off-by: Saurabh Sengar -Reviewed-by: Michael Kelley -Tested-by: Michael Kelley -Link: https://lore.kernel.org/r/1740845791-19977-3-git-send-email-ssengar@linux.microsoft.com -Signed-off-by: Wei Liu -Message-ID: <1740845791-19977-3-git-send-email-ssengar@linux.microsoft.com> -Signed-off-by: Sasha Levin ---- - drivers/video/fbdev/hyperv_fb.c | 20 +++++++++++++++----- - 1 file changed, 15 insertions(+), 5 deletions(-) - -diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c -index 5e0dc5033b988..eb5b4eb948352 100644 ---- a/drivers/video/fbdev/hyperv_fb.c -+++ b/drivers/video/fbdev/hyperv_fb.c -@@ -283,6 +283,8 @@ static uint screen_depth; - static uint screen_fb_size; - static uint dio_fb_size; /* FB size for deferred IO */ - -+static void hvfb_putmem(struct fb_info *info); -+ - /* Send message to Hyper-V host */ - static inline int synthvid_send(struct hv_device *hdev, - struct synthvid_msg *msg) -@@ -863,6 +865,17 @@ static void hvfb_ops_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, - hvfb_ondemand_refresh_throttle(par, x, y, width, height); - } - -+/* -+ * fb_ops.fb_destroy is called by the last put_fb_info() call at the end -+ * of unregister_framebuffer() or fb_release(). Do any cleanup related to -+ * framebuffer here. -+ */ -+static void hvfb_destroy(struct fb_info *info) -+{ -+ hvfb_putmem(info); -+ framebuffer_release(info); -+} -+ - /* - * TODO: GEN1 codepaths allocate from system or DMA-able memory. Fix the - * driver to use the _SYSMEM_ or _DMAMEM_ helpers in these cases. -@@ -878,6 +891,7 @@ static const struct fb_ops hvfb_ops = { - .fb_set_par = hvfb_set_par, - .fb_setcolreg = hvfb_setcolreg, - .fb_blank = hvfb_blank, -+ .fb_destroy = hvfb_destroy, - }; - - /* Get options from kernel paramenter "video=" */ -@@ -1178,7 +1192,7 @@ static int hvfb_probe(struct hv_device *hdev, - if (ret) - goto error; - -- ret = register_framebuffer(info); -+ ret = devm_register_framebuffer(&hdev->device, info); - if (ret) { - pr_err("Unable to register framebuffer\n"); - goto error; -@@ -1226,14 +1240,10 @@ static void hvfb_remove(struct hv_device *hdev) - - fb_deferred_io_cleanup(info); - -- unregister_framebuffer(info); - cancel_delayed_work_sync(&par->dwork); - - vmbus_close(hdev->channel); - hv_set_drvdata(hdev, NULL); -- -- hvfb_putmem(info); -- framebuffer_release(info); - } - - static int hvfb_suspend(struct hv_device *hdev) --- -2.39.5 - diff --git a/queue-6.6/fbdev-hyperv_fb-simplify-hvfb_putmem.patch b/queue-6.6/fbdev-hyperv_fb-simplify-hvfb_putmem.patch deleted file mode 100644 index 230f860365..0000000000 --- a/queue-6.6/fbdev-hyperv_fb-simplify-hvfb_putmem.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 1dde7485e6894a25fef58ee96a6d9ab029a362c5 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sat, 1 Mar 2025 08:16:30 -0800 -Subject: fbdev: hyperv_fb: Simplify hvfb_putmem - -From: Saurabh Sengar - -[ Upstream commit f5e728a50bb17336a20803dde488515b833ecd1d ] - -The device object required in 'hvfb_release_phymem' function -for 'dma_free_coherent' can also be obtained from the 'info' -pointer, making 'hdev' parameter in 'hvfb_putmem' redundant. -Remove the unnecessary 'hdev' argument from 'hvfb_putmem'. - -Signed-off-by: Saurabh Sengar -Reviewed-by: Michael Kelley -Tested-by: Michael Kelley -Link: https://lore.kernel.org/r/1740845791-19977-2-git-send-email-ssengar@linux.microsoft.com -Signed-off-by: Wei Liu -Message-ID: <1740845791-19977-2-git-send-email-ssengar@linux.microsoft.com> -Stable-dep-of: ea2f45ab0e53 ("fbdev: hyperv_fb: Allow graceful removal of framebuffer") -Signed-off-by: Sasha Levin ---- - drivers/video/fbdev/hyperv_fb.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c -index 99e12abdeea1e..5e0dc5033b988 100644 ---- a/drivers/video/fbdev/hyperv_fb.c -+++ b/drivers/video/fbdev/hyperv_fb.c -@@ -953,7 +953,7 @@ static phys_addr_t hvfb_get_phymem(struct hv_device *hdev, - } - - /* Release contiguous physical memory */ --static void hvfb_release_phymem(struct hv_device *hdev, -+static void hvfb_release_phymem(struct device *device, - phys_addr_t paddr, unsigned int size) - { - unsigned int order = get_order(size); -@@ -961,7 +961,7 @@ static void hvfb_release_phymem(struct hv_device *hdev, - if (order <= MAX_ORDER) - __free_pages(pfn_to_page(paddr >> PAGE_SHIFT), order); - else -- dma_free_coherent(&hdev->device, -+ dma_free_coherent(device, - round_up(size, PAGE_SIZE), - phys_to_virt(paddr), - paddr); -@@ -1080,7 +1080,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) - } - - /* Release the framebuffer */ --static void hvfb_putmem(struct hv_device *hdev, struct fb_info *info) -+static void hvfb_putmem(struct fb_info *info) - { - struct hvfb_par *par = info->par; - -@@ -1089,7 +1089,7 @@ static void hvfb_putmem(struct hv_device *hdev, struct fb_info *info) - iounmap(par->mmio_vp); - vmbus_free_mmio(par->mem->start, screen_fb_size); - } else { -- hvfb_release_phymem(hdev, info->fix.smem_start, -+ hvfb_release_phymem(info->device, info->fix.smem_start, - screen_fb_size); - } - -@@ -1203,7 +1203,7 @@ static int hvfb_probe(struct hv_device *hdev, - - error: - fb_deferred_io_cleanup(info); -- hvfb_putmem(hdev, info); -+ hvfb_putmem(info); - error2: - vmbus_close(hdev->channel); - error1: -@@ -1232,7 +1232,7 @@ static void hvfb_remove(struct hv_device *hdev) - vmbus_close(hdev->channel); - hv_set_drvdata(hdev, NULL); - -- hvfb_putmem(hdev, info); -+ hvfb_putmem(info); - framebuffer_release(info); - } - --- -2.39.5 - diff --git a/queue-6.6/netfilter-nf_tables-allow-clone-callbacks-to-sleep.patch b/queue-6.6/netfilter-nf_tables-allow-clone-callbacks-to-sleep.patch new file mode 100644 index 0000000000..1d46fb7d8d --- /dev/null +++ b/queue-6.6/netfilter-nf_tables-allow-clone-callbacks-to-sleep.patch @@ -0,0 +1,244 @@ +From pablo@netfilter.org Tue Mar 18 15:15:29 2025 +From: Pablo Neira Ayuso +Date: Tue, 18 Mar 2025 23:15:22 +0100 +Subject: netfilter: nf_tables: allow clone callbacks to sleep +To: netfilter-devel@vger.kernel.org +Cc: gregkh@linuxfoundation.org, sashal@kernel.org, stable@vger.kernel.org +Message-ID: <20250318221522.225942-3-pablo@netfilter.org> + +From: Florian Westphal + +commit fa23e0d4b756d25829e124d6b670a4c6bbd4bf7e upstream. + +Sven Auhagen reports transaction failures with following error: + ./main.nft:13:1-26: Error: Could not process rule: Cannot allocate memory + percpu: allocation failed, size=16 align=8 atomic=1, atomic alloc failed, no space left + +This points to failing pcpu allocation with GFP_ATOMIC flag. +However, transactions happen from user context and are allowed to sleep. + +One case where we can call into percpu allocator with GFP_ATOMIC is +nft_counter expression. + +Normally this happens from control plane, so this could use GFP_KERNEL +instead. But one use case, element insertion from packet path, +needs to use GFP_ATOMIC allocations (nft_dynset expression). + +At this time, .clone callbacks always use GFP_ATOMIC for this reason. + +Add gfp_t argument to the .clone function and pass GFP_KERNEL or +GFP_ATOMIC flag depending on context, this allows all clone memory +allocations to sleep for the normal (transaction) case. + +Cc: Sven Auhagen +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman +--- + include/net/netfilter/nf_tables.h | 4 ++-- + net/netfilter/nf_tables_api.c | 8 ++++---- + net/netfilter/nft_connlimit.c | 4 ++-- + net/netfilter/nft_counter.c | 4 ++-- + net/netfilter/nft_dynset.c | 2 +- + net/netfilter/nft_last.c | 4 ++-- + net/netfilter/nft_limit.c | 14 ++++++++------ + net/netfilter/nft_quota.c | 4 ++-- + 8 files changed, 23 insertions(+), 21 deletions(-) + +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -407,7 +407,7 @@ struct nft_expr_info; + + int nft_expr_inner_parse(const struct nft_ctx *ctx, const struct nlattr *nla, + struct nft_expr_info *info); +-int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src); ++int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src, gfp_t gfp); + void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr); + int nft_expr_dump(struct sk_buff *skb, unsigned int attr, + const struct nft_expr *expr, bool reset); +@@ -936,7 +936,7 @@ struct nft_expr_ops { + struct nft_regs *regs, + const struct nft_pktinfo *pkt); + int (*clone)(struct nft_expr *dst, +- const struct nft_expr *src); ++ const struct nft_expr *src, gfp_t gfp); + unsigned int size; + + int (*init)(const struct nft_ctx *ctx, +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -3332,7 +3332,7 @@ err_expr_parse: + return ERR_PTR(err); + } + +-int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src) ++int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src, gfp_t gfp) + { + int err; + +@@ -3340,7 +3340,7 @@ int nft_expr_clone(struct nft_expr *dst, + return -EINVAL; + + dst->ops = src->ops; +- err = src->ops->clone(dst, src); ++ err = src->ops->clone(dst, src, gfp); + if (err < 0) + return err; + +@@ -6457,7 +6457,7 @@ int nft_set_elem_expr_clone(const struct + if (!expr) + goto err_expr; + +- err = nft_expr_clone(expr, set->exprs[i]); ++ err = nft_expr_clone(expr, set->exprs[i], GFP_KERNEL_ACCOUNT); + if (err < 0) { + kfree(expr); + goto err_expr; +@@ -6496,7 +6496,7 @@ static int nft_set_elem_expr_setup(struc + + for (i = 0; i < num_exprs; i++) { + expr = nft_setelem_expr_at(elem_expr, elem_expr->size); +- err = nft_expr_clone(expr, expr_array[i]); ++ err = nft_expr_clone(expr, expr_array[i], GFP_KERNEL_ACCOUNT); + if (err < 0) + goto err_elem_expr_setup; + +--- a/net/netfilter/nft_connlimit.c ++++ b/net/netfilter/nft_connlimit.c +@@ -210,12 +210,12 @@ static void nft_connlimit_destroy(const + nft_connlimit_do_destroy(ctx, priv); + } + +-static int nft_connlimit_clone(struct nft_expr *dst, const struct nft_expr *src) ++static int nft_connlimit_clone(struct nft_expr *dst, const struct nft_expr *src, gfp_t gfp) + { + struct nft_connlimit *priv_dst = nft_expr_priv(dst); + struct nft_connlimit *priv_src = nft_expr_priv(src); + +- priv_dst->list = kmalloc(sizeof(*priv_dst->list), GFP_ATOMIC); ++ priv_dst->list = kmalloc(sizeof(*priv_dst->list), gfp); + if (!priv_dst->list) + return -ENOMEM; + +--- a/net/netfilter/nft_counter.c ++++ b/net/netfilter/nft_counter.c +@@ -231,7 +231,7 @@ static void nft_counter_destroy(const st + nft_counter_do_destroy(priv); + } + +-static int nft_counter_clone(struct nft_expr *dst, const struct nft_expr *src) ++static int nft_counter_clone(struct nft_expr *dst, const struct nft_expr *src, gfp_t gfp) + { + struct nft_counter_percpu_priv *priv = nft_expr_priv(src); + struct nft_counter_percpu_priv *priv_clone = nft_expr_priv(dst); +@@ -241,7 +241,7 @@ static int nft_counter_clone(struct nft_ + + nft_counter_fetch(priv, &total); + +- cpu_stats = alloc_percpu_gfp(struct nft_counter, GFP_ATOMIC); ++ cpu_stats = alloc_percpu_gfp(struct nft_counter, gfp); + if (cpu_stats == NULL) + return -ENOMEM; + +--- a/net/netfilter/nft_dynset.c ++++ b/net/netfilter/nft_dynset.c +@@ -35,7 +35,7 @@ static int nft_dynset_expr_setup(const s + + for (i = 0; i < priv->num_exprs; i++) { + expr = nft_setelem_expr_at(elem_expr, elem_expr->size); +- if (nft_expr_clone(expr, priv->expr_array[i]) < 0) ++ if (nft_expr_clone(expr, priv->expr_array[i], GFP_ATOMIC) < 0) + return -1; + + elem_expr->size += priv->expr_array[i]->ops->size; +--- a/net/netfilter/nft_last.c ++++ b/net/netfilter/nft_last.c +@@ -102,12 +102,12 @@ static void nft_last_destroy(const struc + kfree(priv->last); + } + +-static int nft_last_clone(struct nft_expr *dst, const struct nft_expr *src) ++static int nft_last_clone(struct nft_expr *dst, const struct nft_expr *src, gfp_t gfp) + { + struct nft_last_priv *priv_dst = nft_expr_priv(dst); + struct nft_last_priv *priv_src = nft_expr_priv(src); + +- priv_dst->last = kzalloc(sizeof(*priv_dst->last), GFP_ATOMIC); ++ priv_dst->last = kzalloc(sizeof(*priv_dst->last), gfp); + if (!priv_dst->last) + return -ENOMEM; + +--- a/net/netfilter/nft_limit.c ++++ b/net/netfilter/nft_limit.c +@@ -150,7 +150,7 @@ static void nft_limit_destroy(const stru + } + + static int nft_limit_clone(struct nft_limit_priv *priv_dst, +- const struct nft_limit_priv *priv_src) ++ const struct nft_limit_priv *priv_src, gfp_t gfp) + { + priv_dst->tokens_max = priv_src->tokens_max; + priv_dst->rate = priv_src->rate; +@@ -158,7 +158,7 @@ static int nft_limit_clone(struct nft_li + priv_dst->burst = priv_src->burst; + priv_dst->invert = priv_src->invert; + +- priv_dst->limit = kmalloc(sizeof(*priv_dst->limit), GFP_ATOMIC); ++ priv_dst->limit = kmalloc(sizeof(*priv_dst->limit), gfp); + if (!priv_dst->limit) + return -ENOMEM; + +@@ -223,14 +223,15 @@ static void nft_limit_pkts_destroy(const + nft_limit_destroy(ctx, &priv->limit); + } + +-static int nft_limit_pkts_clone(struct nft_expr *dst, const struct nft_expr *src) ++static int nft_limit_pkts_clone(struct nft_expr *dst, const struct nft_expr *src, ++ gfp_t gfp) + { + struct nft_limit_priv_pkts *priv_dst = nft_expr_priv(dst); + struct nft_limit_priv_pkts *priv_src = nft_expr_priv(src); + + priv_dst->cost = priv_src->cost; + +- return nft_limit_clone(&priv_dst->limit, &priv_src->limit); ++ return nft_limit_clone(&priv_dst->limit, &priv_src->limit, gfp); + } + + static struct nft_expr_type nft_limit_type; +@@ -281,12 +282,13 @@ static void nft_limit_bytes_destroy(cons + nft_limit_destroy(ctx, priv); + } + +-static int nft_limit_bytes_clone(struct nft_expr *dst, const struct nft_expr *src) ++static int nft_limit_bytes_clone(struct nft_expr *dst, const struct nft_expr *src, ++ gfp_t gfp) + { + struct nft_limit_priv *priv_dst = nft_expr_priv(dst); + struct nft_limit_priv *priv_src = nft_expr_priv(src); + +- return nft_limit_clone(priv_dst, priv_src); ++ return nft_limit_clone(priv_dst, priv_src, gfp); + } + + static const struct nft_expr_ops nft_limit_bytes_ops = { +--- a/net/netfilter/nft_quota.c ++++ b/net/netfilter/nft_quota.c +@@ -233,7 +233,7 @@ static void nft_quota_destroy(const stru + return nft_quota_do_destroy(ctx, priv); + } + +-static int nft_quota_clone(struct nft_expr *dst, const struct nft_expr *src) ++static int nft_quota_clone(struct nft_expr *dst, const struct nft_expr *src, gfp_t gfp) + { + struct nft_quota *priv_dst = nft_expr_priv(dst); + struct nft_quota *priv_src = nft_expr_priv(src); +@@ -241,7 +241,7 @@ static int nft_quota_clone(struct nft_ex + priv_dst->quota = priv_src->quota; + priv_dst->flags = priv_src->flags; + +- priv_dst->consumed = kmalloc(sizeof(*priv_dst->consumed), GFP_ATOMIC); ++ priv_dst->consumed = kmalloc(sizeof(*priv_dst->consumed), gfp); + if (!priv_dst->consumed) + return -ENOMEM; + diff --git a/queue-6.6/netfilter-nf_tables-bail-out-if-stateful-expression-provides-no-.clone.patch b/queue-6.6/netfilter-nf_tables-bail-out-if-stateful-expression-provides-no-.clone.patch new file mode 100644 index 0000000000..5ceddc2e05 --- /dev/null +++ b/queue-6.6/netfilter-nf_tables-bail-out-if-stateful-expression-provides-no-.clone.patch @@ -0,0 +1,47 @@ +From pablo@netfilter.org Tue Mar 18 15:15:29 2025 +From: Pablo Neira Ayuso +Date: Tue, 18 Mar 2025 23:15:21 +0100 +Subject: netfilter: nf_tables: bail out if stateful expression provides no .clone +To: netfilter-devel@vger.kernel.org +Cc: gregkh@linuxfoundation.org, sashal@kernel.org, stable@vger.kernel.org +Message-ID: <20250318221522.225942-2-pablo@netfilter.org> + +From: Pablo Neira Ayuso + +commit 3c13725f43dcf43ad8a9bcd6a9f12add19a8f93e upstream. + +All existing NFT_EXPR_STATEFUL provide a .clone interface, remove +fallback to copy content of stateful expression since this is never +exercised and bail out if .clone interface is not defined. + +Stable-dep-of: fa23e0d4b756 ("netfilter: nf_tables: allow clone callbacks to sleep") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman +--- + net/netfilter/nf_tables_api.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -3336,14 +3336,13 @@ int nft_expr_clone(struct nft_expr *dst, + { + int err; + +- if (src->ops->clone) { +- dst->ops = src->ops; +- err = src->ops->clone(dst, src); +- if (err < 0) +- return err; +- } else { +- memcpy(dst, src, src->ops->size); +- } ++ if (WARN_ON_ONCE(!src->ops->clone)) ++ return -EINVAL; ++ ++ dst->ops = src->ops; ++ err = src->ops->clone(dst, src); ++ if (err < 0) ++ return err; + + __module_get(src->ops->type->owner); + diff --git a/queue-6.6/netfilter-nf_tables-use-timestamp-to-check-for-set-element-timeout.patch b/queue-6.6/netfilter-nf_tables-use-timestamp-to-check-for-set-element-timeout.patch new file mode 100644 index 0000000000..bfcfa78694 --- /dev/null +++ b/queue-6.6/netfilter-nf_tables-use-timestamp-to-check-for-set-element-timeout.patch @@ -0,0 +1,309 @@ +From 7395dfacfff65e9938ac0889dafa1ab01e987d15 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Tue, 6 Feb 2024 00:11:40 +0100 +Subject: netfilter: nf_tables: use timestamp to check for set element timeout + +From: Pablo Neira Ayuso + +commit 7395dfacfff65e9938ac0889dafa1ab01e987d15 upstream. + +Add a timestamp field at the beginning of the transaction, store it +in the nftables per-netns area. + +Update set backend .insert, .deactivate and sync gc path to use the +timestamp, this avoids that an element expires while control plane +transaction is still unfinished. + +.lookup and .update, which are used from packet path, still use the +current time to check if the element has expired. And .get path and dump +also since this runs lockless under rcu read size lock. Then, there is +async gc which also needs to check the current time since it runs +asynchronously from a workqueue. + +Fixes: c3e1b005ed1c ("netfilter: nf_tables: add set element timeout support") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Jianqi Ren +Signed-off-by: He Zhe +Signed-off-by: Greg Kroah-Hartman +--- + include/net/netfilter/nf_tables.h | 16 ++++++++++++++-- + net/netfilter/nf_tables_api.c | 4 +++- + net/netfilter/nft_set_hash.c | 8 +++++++- + net/netfilter/nft_set_pipapo.c | 18 +++++++++++------- + net/netfilter/nft_set_rbtree.c | 11 +++++++---- + 5 files changed, 42 insertions(+), 15 deletions(-) + +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -826,10 +826,16 @@ static inline struct nft_set_elem_expr * + return nft_set_ext(ext, NFT_SET_EXT_EXPRESSIONS); + } + +-static inline bool nft_set_elem_expired(const struct nft_set_ext *ext) ++static inline bool __nft_set_elem_expired(const struct nft_set_ext *ext, ++ u64 tstamp) + { + return nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION) && +- time_is_before_eq_jiffies64(*nft_set_ext_expiration(ext)); ++ time_after_eq64(tstamp, *nft_set_ext_expiration(ext)); ++} ++ ++static inline bool nft_set_elem_expired(const struct nft_set_ext *ext) ++{ ++ return __nft_set_elem_expired(ext, get_jiffies_64()); + } + + static inline struct nft_set_ext *nft_set_elem_ext(const struct nft_set *set, +@@ -1791,6 +1797,7 @@ struct nftables_pernet { + struct list_head notify_list; + struct mutex commit_mutex; + u64 table_handle; ++ u64 tstamp; + unsigned int base_seq; + unsigned int gc_seq; + u8 validate_state; +@@ -1803,6 +1810,11 @@ static inline struct nftables_pernet *nf + return net_generic(net, nf_tables_net_id); + } + ++static inline u64 nft_net_tstamp(const struct net *net) ++{ ++ return nft_pernet(net)->tstamp; ++} ++ + #define __NFT_REDUCE_READONLY 1UL + #define NFT_REDUCE_READONLY (void *)__NFT_REDUCE_READONLY + +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -9963,6 +9963,7 @@ dead_elem: + struct nft_trans_gc *nft_trans_gc_catchall_sync(struct nft_trans_gc *gc) + { + struct nft_set_elem_catchall *catchall, *next; ++ u64 tstamp = nft_net_tstamp(gc->net); + const struct nft_set *set = gc->set; + struct nft_set_elem elem; + struct nft_set_ext *ext; +@@ -9972,7 +9973,7 @@ struct nft_trans_gc *nft_trans_gc_catcha + list_for_each_entry_safe(catchall, next, &set->catchall_list, list) { + ext = nft_set_elem_ext(set, catchall->elem); + +- if (!nft_set_elem_expired(ext)) ++ if (!__nft_set_elem_expired(ext, tstamp)) + continue; + + gc = nft_trans_gc_queue_sync(gc, GFP_KERNEL); +@@ -10777,6 +10778,7 @@ static bool nf_tables_valid_genid(struct + bool genid_ok; + + mutex_lock(&nft_net->commit_mutex); ++ nft_net->tstamp = get_jiffies_64(); + + genid_ok = genid == 0 || nft_net->base_seq == genid; + if (!genid_ok) +--- a/net/netfilter/nft_set_hash.c ++++ b/net/netfilter/nft_set_hash.c +@@ -37,6 +37,7 @@ struct nft_rhash_cmp_arg { + const struct nft_set *set; + const u32 *key; + u8 genmask; ++ u64 tstamp; + }; + + static inline u32 nft_rhash_key(const void *data, u32 len, u32 seed) +@@ -63,7 +64,7 @@ static inline int nft_rhash_cmp(struct r + return 1; + if (nft_set_elem_is_dead(&he->ext)) + return 1; +- if (nft_set_elem_expired(&he->ext)) ++ if (__nft_set_elem_expired(&he->ext, x->tstamp)) + return 1; + if (!nft_set_elem_active(&he->ext, x->genmask)) + return 1; +@@ -88,6 +89,7 @@ bool nft_rhash_lookup(const struct net * + .genmask = nft_genmask_cur(net), + .set = set, + .key = key, ++ .tstamp = get_jiffies_64(), + }; + + he = rhashtable_lookup(&priv->ht, &arg, nft_rhash_params); +@@ -106,6 +108,7 @@ static void *nft_rhash_get(const struct + .genmask = nft_genmask_cur(net), + .set = set, + .key = elem->key.val.data, ++ .tstamp = get_jiffies_64(), + }; + + he = rhashtable_lookup(&priv->ht, &arg, nft_rhash_params); +@@ -129,6 +132,7 @@ static bool nft_rhash_update(struct nft_ + .genmask = NFT_GENMASK_ANY, + .set = set, + .key = key, ++ .tstamp = get_jiffies_64(), + }; + + he = rhashtable_lookup(&priv->ht, &arg, nft_rhash_params); +@@ -172,6 +176,7 @@ static int nft_rhash_insert(const struct + .genmask = nft_genmask_next(net), + .set = set, + .key = elem->key.val.data, ++ .tstamp = nft_net_tstamp(net), + }; + struct nft_rhash_elem *prev; + +@@ -214,6 +219,7 @@ static void *nft_rhash_deactivate(const + .genmask = nft_genmask_next(net), + .set = set, + .key = elem->key.val.data, ++ .tstamp = nft_net_tstamp(net), + }; + + rcu_read_lock(); +--- a/net/netfilter/nft_set_pipapo.c ++++ b/net/netfilter/nft_set_pipapo.c +@@ -504,6 +504,7 @@ out: + * @set: nftables API set representation + * @data: Key data to be matched against existing elements + * @genmask: If set, check that element is active in given genmask ++ * @tstamp: timestamp to check for expired elements + * + * This is essentially the same as the lookup function, except that it matches + * key data against the uncommitted copy and doesn't use preallocated maps for +@@ -513,7 +514,8 @@ out: + */ + static struct nft_pipapo_elem *pipapo_get(const struct net *net, + const struct nft_set *set, +- const u8 *data, u8 genmask) ++ const u8 *data, u8 genmask, ++ u64 tstamp) + { + struct nft_pipapo_elem *ret = ERR_PTR(-ENOENT); + struct nft_pipapo *priv = nft_set_priv(set); +@@ -568,7 +570,7 @@ next_match: + goto out; + + if (last) { +- if (nft_set_elem_expired(&f->mt[b].e->ext)) ++ if (__nft_set_elem_expired(&f->mt[b].e->ext, tstamp)) + goto next_match; + if ((genmask && + !nft_set_elem_active(&f->mt[b].e->ext, genmask))) +@@ -605,7 +607,7 @@ static void *nft_pipapo_get(const struct + const struct nft_set_elem *elem, unsigned int flags) + { + return pipapo_get(net, set, (const u8 *)elem->key.val.data, +- nft_genmask_cur(net)); ++ nft_genmask_cur(net), get_jiffies_64()); + } + + /** +@@ -1199,6 +1201,7 @@ static int nft_pipapo_insert(const struc + struct nft_pipapo *priv = nft_set_priv(set); + struct nft_pipapo_match *m = priv->clone; + u8 genmask = nft_genmask_next(net); ++ u64 tstamp = nft_net_tstamp(net); + struct nft_pipapo_field *f; + const u8 *start_p, *end_p; + int i, bsize_max, err = 0; +@@ -1208,7 +1211,7 @@ static int nft_pipapo_insert(const struc + else + end = start; + +- dup = pipapo_get(net, set, start, genmask); ++ dup = pipapo_get(net, set, start, genmask, tstamp); + if (!IS_ERR(dup)) { + /* Check if we already have the same exact entry */ + const struct nft_data *dup_key, *dup_end; +@@ -1230,7 +1233,7 @@ static int nft_pipapo_insert(const struc + + if (PTR_ERR(dup) == -ENOENT) { + /* Look for partially overlapping entries */ +- dup = pipapo_get(net, set, end, nft_genmask_next(net)); ++ dup = pipapo_get(net, set, end, nft_genmask_next(net), tstamp); + } + + if (PTR_ERR(dup) != -ENOENT) { +@@ -1581,6 +1584,7 @@ static void pipapo_gc(struct nft_set *se + { + struct nft_pipapo *priv = nft_set_priv(set); + struct net *net = read_pnet(&set->net); ++ u64 tstamp = nft_net_tstamp(net); + int rules_f0, first_rule = 0; + struct nft_pipapo_elem *e; + struct nft_trans_gc *gc; +@@ -1615,7 +1619,7 @@ static void pipapo_gc(struct nft_set *se + /* synchronous gc never fails, there is no need to set on + * NFT_SET_ELEM_DEAD_BIT. + */ +- if (nft_set_elem_expired(&e->ext)) { ++ if (__nft_set_elem_expired(&e->ext, tstamp)) { + priv->dirty = true; + + gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); +@@ -1786,7 +1790,7 @@ static void *pipapo_deactivate(const str + { + struct nft_pipapo_elem *e; + +- e = pipapo_get(net, set, data, nft_genmask_next(net)); ++ e = pipapo_get(net, set, data, nft_genmask_next(net), nft_net_tstamp(net)); + if (IS_ERR(e)) + return NULL; + +--- a/net/netfilter/nft_set_rbtree.c ++++ b/net/netfilter/nft_set_rbtree.c +@@ -314,6 +314,7 @@ static int __nft_rbtree_insert(const str + struct nft_rbtree *priv = nft_set_priv(set); + u8 cur_genmask = nft_genmask_cur(net); + u8 genmask = nft_genmask_next(net); ++ u64 tstamp = nft_net_tstamp(net); + int d; + + /* Descend the tree to search for an existing element greater than the +@@ -361,7 +362,7 @@ static int __nft_rbtree_insert(const str + /* perform garbage collection to avoid bogus overlap reports + * but skip new elements in this transaction. + */ +- if (nft_set_elem_expired(&rbe->ext) && ++ if (__nft_set_elem_expired(&rbe->ext, tstamp) && + nft_set_elem_active(&rbe->ext, cur_genmask)) { + const struct nft_rbtree_elem *removed_end; + +@@ -553,6 +554,7 @@ static void *nft_rbtree_deactivate(const + const struct rb_node *parent = priv->root.rb_node; + struct nft_rbtree_elem *rbe, *this = elem->priv; + u8 genmask = nft_genmask_next(net); ++ u64 tstamp = nft_net_tstamp(net); + int d; + + while (parent != NULL) { +@@ -573,7 +575,7 @@ static void *nft_rbtree_deactivate(const + nft_rbtree_interval_end(this)) { + parent = parent->rb_right; + continue; +- } else if (nft_set_elem_expired(&rbe->ext)) { ++ } else if (__nft_set_elem_expired(&rbe->ext, tstamp)) { + break; + } else if (!nft_set_elem_active(&rbe->ext, genmask)) { + parent = parent->rb_left; +@@ -632,9 +634,10 @@ static void nft_rbtree_gc(struct nft_set + struct nft_rbtree *priv = nft_set_priv(set); + struct nft_rbtree_elem *rbe, *rbe_end = NULL; + struct nftables_pernet *nft_net; ++ struct net *net = read_pnet(&set->net); ++ u64 tstamp = nft_net_tstamp(net); + struct rb_node *node, *next; + struct nft_trans_gc *gc; +- struct net *net; + + set = nft_set_container_of(priv); + net = read_pnet(&set->net); +@@ -657,7 +660,7 @@ static void nft_rbtree_gc(struct nft_set + rbe_end = rbe; + continue; + } +- if (!nft_set_elem_expired(&rbe->ext)) ++ if (!__nft_set_elem_expired(&rbe->ext, tstamp)) + continue; + + gc = nft_trans_gc_queue_sync(gc, GFP_KERNEL); diff --git a/queue-6.6/rust-lockdep-remove-support-for-dynamically-allocated-lockclasskeys.patch b/queue-6.6/rust-lockdep-remove-support-for-dynamically-allocated-lockclasskeys.patch new file mode 100644 index 0000000000..cf30d44a47 --- /dev/null +++ b/queue-6.6/rust-lockdep-remove-support-for-dynamically-allocated-lockclasskeys.patch @@ -0,0 +1,53 @@ +From 966944f3711665db13e214fef6d02982c49bb972 Mon Sep 17 00:00:00 2001 +From: Mitchell Levy +Date: Fri, 7 Mar 2025 15:27:00 -0800 +Subject: rust: lockdep: Remove support for dynamically allocated LockClassKeys + +From: Mitchell Levy + +commit 966944f3711665db13e214fef6d02982c49bb972 upstream. + +Currently, dynamically allocated LockCLassKeys can be used from the Rust +side without having them registered. This is a soundness issue, so +remove them. + +Fixes: 6ea5aa08857a ("rust: sync: introduce `LockClassKey`") +Suggested-by: Alice Ryhl +Signed-off-by: Mitchell Levy +Signed-off-by: Boqun Feng +Signed-off-by: Ingo Molnar +Reviewed-by: Benno Lossin +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20250307232717.1759087-11-boqun.feng@gmail.com +Signed-off-by: Boqun Feng +Signed-off-by: Greg Kroah-Hartman +--- + rust/kernel/sync.rs | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +--- a/rust/kernel/sync.rs ++++ b/rust/kernel/sync.rs +@@ -26,11 +26,6 @@ pub struct LockClassKey(Opaque Self { +- Self(Opaque::uninit()) +- } +- + pub(crate) fn as_ptr(&self) -> *mut bindings::lock_class_key { + self.0.get() + } +@@ -41,7 +36,10 @@ impl LockClassKey { + #[macro_export] + macro_rules! static_lock_class { + () => {{ +- static CLASS: $crate::sync::LockClassKey = $crate::sync::LockClassKey::new(); ++ static CLASS: $crate::sync::LockClassKey = ++ // SAFETY: lockdep expects uninitialized memory when it's handed a statically allocated ++ // lock_class_key ++ unsafe { ::core::mem::MaybeUninit::uninit().assume_init() }; + &CLASS + }}; + } diff --git a/queue-6.6/series b/queue-6.6/series index 089a7ae009..61e663e96b 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -19,13 +19,9 @@ net-dsa-mv88e6xxx-verify-after-atu-load-ops.patch net-mctp-i2c-copy-headers-if-cloned.patch netpoll-hold-rcu-read-lock-in-__netpoll_send_skb.patch drm-hyperv-fix-address-space-leak-when-hyper-v-drm-d.patch -dt-bindings-display-rockchip-vop-document-rv1126-vop.patch fbdev-hyperv_fb-use-fb_ops-helpers-for-deferred-i-o.patch fbdev-mmp-mmpfb-do-not-display-boot-up-logo.patch -fbdev-core-unexport-logo-helpers.patch fbdev-introduce-devm_register_framebuffer.patch -fbdev-hyperv_fb-simplify-hvfb_putmem.patch -fbdev-hyperv_fb-allow-graceful-removal-of-framebuffe.patch drivers-hv-vmbus-don-t-release-fb_mmio-resource-in-v.patch net-mlx5-handle-errors-in-mlx5_chains_create_table.patch eth-bnxt-do-not-update-checksum-in-bnxt_xdp_build_sk.patch @@ -167,3 +163,7 @@ bluetooth-l2cap-fix-corrupted-list-in-hci_chan_del.patch nvme-fc-rely-on-state-transitions-to-handle-connectivity-loss.patch hid-apple-disable-fn-key-handling-on-the-omoton-kb066.patch nvme-tcp-fix-a-c2htermreq-error-message.patch +rust-lockdep-remove-support-for-dynamically-allocated-lockclasskeys.patch +netfilter-nf_tables-use-timestamp-to-check-for-set-element-timeout.patch +netfilter-nf_tables-bail-out-if-stateful-expression-provides-no-.clone.patch +netfilter-nf_tables-allow-clone-callbacks-to-sleep.patch