+++ /dev/null
-From 709d4e26841afc15a57b3416696a472a0266983c Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 31 Jul 2023 16:30:03 +0530
-Subject: dt-bindings: display: rockchip-vop: Document rv1126 vop
-
-From: Jagan Teki <jagan@edgeble.ai>
-
-[ 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 <jagan@edgeble.ai>
-Acked-by: Conor Dooley <conor.dooley@microchip.com>
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
-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 <sashal@kernel.org>
----
- .../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
-
+++ /dev/null
-From 1def1216b3d3bdcb1a38742910191d4dd015dd31 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 7 Sep 2023 10:52:03 +0200
-Subject: fbdev/core: Unexport logo helpers
-
-From: Thomas Zimmermann <tzimmermann@suse.de>
-
-[ 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 <tzimmermann@suse.de>
-Acked-by: Javier Martinez Canillas <javierm@redhat.com>
-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 <sashal@kernel.org>
----
- 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
-
+++ /dev/null
-From ba1f857547f7d8dfd9b50a9be168cd344dcb484b Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sat, 1 Mar 2025 08:16:31 -0800
-Subject: fbdev: hyperv_fb: Allow graceful removal of framebuffer
-
-From: Saurabh Sengar <ssengar@linux.microsoft.com>
-
-[ 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] <TASK>
-[ 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 <ssengar@linux.microsoft.com>
-Reviewed-by: Michael Kelley <mhklinux@outlook.com>
-Tested-by: Michael Kelley <mhklinux@outlook.com>
-Link: https://lore.kernel.org/r/1740845791-19977-3-git-send-email-ssengar@linux.microsoft.com
-Signed-off-by: Wei Liu <wei.liu@kernel.org>
-Message-ID: <1740845791-19977-3-git-send-email-ssengar@linux.microsoft.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- 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
-
+++ /dev/null
-From 1dde7485e6894a25fef58ee96a6d9ab029a362c5 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sat, 1 Mar 2025 08:16:30 -0800
-Subject: fbdev: hyperv_fb: Simplify hvfb_putmem
-
-From: Saurabh Sengar <ssengar@linux.microsoft.com>
-
-[ 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 <ssengar@linux.microsoft.com>
-Reviewed-by: Michael Kelley <mhklinux@outlook.com>
-Tested-by: Michael Kelley <mhklinux@outlook.com>
-Link: https://lore.kernel.org/r/1740845791-19977-2-git-send-email-ssengar@linux.microsoft.com
-Signed-off-by: Wei Liu <wei.liu@kernel.org>
-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 <sashal@kernel.org>
----
- 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
-
--- /dev/null
+From pablo@netfilter.org Tue Mar 18 15:15:29 2025
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+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 <fw@strlen.de>
+
+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 <sven.auhagen@voleatech.de>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
+
--- /dev/null
+From pablo@netfilter.org Tue Mar 18 15:15:29 2025
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+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 <pablo@netfilter.org>
+
+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 <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+
--- /dev/null
+From 7395dfacfff65e9938ac0889dafa1ab01e987d15 Mon Sep 17 00:00:00 2001
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+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 <pablo@netfilter.org>
+
+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 <pablo@netfilter.org>
+Signed-off-by: Jianqi Ren <jianqi.ren.cn@windriver.com>
+Signed-off-by: He Zhe <zhe.he@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
--- /dev/null
+From 966944f3711665db13e214fef6d02982c49bb972 Mon Sep 17 00:00:00 2001
+From: Mitchell Levy <levymitchell0@gmail.com>
+Date: Fri, 7 Mar 2025 15:27:00 -0800
+Subject: rust: lockdep: Remove support for dynamically allocated LockClassKeys
+
+From: Mitchell Levy <levymitchell0@gmail.com>
+
+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 <aliceryhl@google.com>
+Signed-off-by: Mitchell Levy <levymitchell0@gmail.com>
+Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20250307232717.1759087-11-boqun.feng@gmail.com
+Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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<bindings:
+ unsafe impl Sync for LockClassKey {}
+
+ impl LockClassKey {
+- /// Creates a new lock class key.
+- pub const fn new() -> 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
+ }};
+ }
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
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