[PATCH 08/19] nitro_enclaves: Let the region tracking arrays fall back to vmalloc

From: Alexander Graf

Date: Wed Nov 11 2026 - 22:08:51 EST


NE_SET_USER_MEMORY_REGION allocates two tracking arrays that grow with
the region, and for a large region kzalloc_objs() fails with a WARN.
Neither needs physically contiguous memory, so allocate both with
kvzalloc_objs(), with __GFP_NOWARN since a region can push even
kvmalloc() past its limit.

Fixes: 7dc9d4309fdb ("nitro_enclaves: Add logic for setting an enclave memory region")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Alexander Graf <graf@xxxxxxxxxx>
---
drivers/virt/nitro_enclaves/ne_misc_dev.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/virt/nitro_enclaves/ne_misc_dev.c b/drivers/virt/nitro_enclaves/ne_misc_dev.c
index 821624c93795b..ac33fbcd41f35 100644
--- a/drivers/virt/nitro_enclaves/ne_misc_dev.c
+++ b/drivers/virt/nitro_enclaves/ne_misc_dev.c
@@ -938,15 +938,17 @@ static int ne_set_user_memory_region_ioctl(struct ne_enclave *ne_enclave,

max_nr_pages = mem_region.memory_size / NE_MIN_MEM_REGION_SIZE;

- ne_mem_region->pages = kzalloc_objs(*ne_mem_region->pages, max_nr_pages);
+ ne_mem_region->pages = kvzalloc_objs(*ne_mem_region->pages, max_nr_pages,
+ GFP_KERNEL | __GFP_NOWARN);
if (!ne_mem_region->pages) {
rc = -ENOMEM;

goto free_mem_region;
}

- phys_contig_mem_regions.regions = kzalloc_objs(*phys_contig_mem_regions.regions,
- max_nr_pages);
+ phys_contig_mem_regions.regions = kvzalloc_objs(*phys_contig_mem_regions.regions,
+ max_nr_pages,
+ GFP_KERNEL | __GFP_NOWARN);
if (!phys_contig_mem_regions.regions) {
rc = -ENOMEM;

@@ -1036,7 +1038,7 @@ static int ne_set_user_memory_region_ioctl(struct ne_enclave *ne_enclave,
dev_err_ratelimited(ne_misc_dev.this_device,
"Error in slot add mem [rc=%d]\n", rc);

- kfree(phys_contig_mem_regions.regions);
+ kvfree(phys_contig_mem_regions.regions);

/*
* Exit here without put pages as memory regions may
@@ -1049,7 +1051,7 @@ static int ne_set_user_memory_region_ioctl(struct ne_enclave *ne_enclave,
ne_enclave->nr_mem_regions++;
}

- kfree(phys_contig_mem_regions.regions);
+ kvfree(phys_contig_mem_regions.regions);

return 0;

@@ -1057,8 +1059,8 @@ static int ne_set_user_memory_region_ioctl(struct ne_enclave *ne_enclave,
for (i = 0; i < ne_mem_region->nr_pages; i++)
put_page(ne_mem_region->pages[i]);
free_mem_region:
- kfree(phys_contig_mem_regions.regions);
- kfree(ne_mem_region->pages);
+ kvfree(phys_contig_mem_regions.regions);
+ kvfree(ne_mem_region->pages);
kfree(ne_mem_region);

return rc;
@@ -1448,7 +1450,7 @@ static void ne_enclave_remove_all_mem_region_entries(struct ne_enclave *ne_encla
for (i = 0; i < ne_mem_region->nr_pages; i++)
put_page(ne_mem_region->pages[i]);

- kfree(ne_mem_region->pages);
+ kvfree(ne_mem_region->pages);

kfree(ne_mem_region);
}
--
2.47.1