The XOL slot bitmap has the same lifetime as struct xol_area, but it
is currently allocated separately.  That adds another allocation
failure path and a matching cleanup branch without buying any extra
flexibility.

Store the bitmap as a flexible array member and allocate it together
with the xol_area using kzalloc_flex().  The bitmap remains
zero-initialized, while the allocation and error handling become
simpler.

Assisted-by: Codex:GPT-5.5
Signed-off-by: Rosen Penev <[email protected]>
---
 kernel/events/uprobes.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 4084e926e284..9ef74c2ad390 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -108,7 +108,6 @@ static LIST_HEAD(delayed_uprobe_list);
  */
 struct xol_area {
        wait_queue_head_t               wq;             /* if all slots are 
busy */
-       unsigned long                   *bitmap;        /* 0 = free slot */
 
        struct page                     *page;
        /*
@@ -117,6 +116,7 @@ struct xol_area {
         * the vma go away, and we must handle that reasonably gracefully.
         */
        unsigned long                   vaddr;          /* Page(s) of 
instruction slots */
+       unsigned long                   bitmap[];       /* 0 = free slot */
 };
 
 static void uprobe_warn(struct task_struct *t, const char *msg)
@@ -1755,18 +1755,13 @@ static struct xol_area *__create_xol_area(unsigned long 
vaddr)
        struct xol_area *area;
        void *insns;
 
-       area = kzalloc_obj(*area);
+       area = kzalloc_flex(*area, bitmap, BITS_TO_LONGS(UINSNS_PER_PAGE));
        if (unlikely(!area))
                goto out;
 
-       area->bitmap = kcalloc(BITS_TO_LONGS(UINSNS_PER_PAGE), sizeof(long),
-                              GFP_KERNEL);
-       if (!area->bitmap)
-               goto free_area;
-
        area->page = alloc_page(GFP_HIGHUSER | __GFP_ZERO);
        if (!area->page)
-               goto free_bitmap;
+               goto free_area;
 
        area->vaddr = vaddr;
        init_waitqueue_head(&area->wq);
@@ -1779,8 +1774,6 @@ static struct xol_area *__create_xol_area(unsigned long 
vaddr)
                return area;
 
        __free_page(area->page);
- free_bitmap:
-       kfree(area->bitmap);
  free_area:
        kfree(area);
  out:
-- 
2.54.0


Reply via email to