ANDROID: gunyah: Fix the issue with gunyah_cma_release

Currently, gunyah_cma_release() unconditionally releases the entire
CMA memory region of the VM, regardless of how much was actually mapped.
This can lead to issues if AVF clients lauches VM wherein the memory
mapped is less than the size of the VM's CMA region(max size).

To address this:
- A new mapped_size field is added to struct gunyah_cma to track the
actual size mapped.
- gunyah_cma_alloc() sets this field and logs a debug message if the
mapped size is less than the max size.
- gunyah_cma_release() now uses mapped_size to determine how much memory
to release.

Bug: 440480668
Change-Id: I6408c91eedb4cfe911a52c8a8a8734892e49e209
Signed-off-by: Nikhil V <nikhil.v@oss.qualcomm.com>
This commit is contained in:
Nikhil V
2025-08-20 18:30:23 +05:30
committed by Treehugger Robot
parent 65994b7471
commit c9198633ac
+11 -5
View File
@@ -19,7 +19,8 @@ struct gunyah_cma {
struct page *page;
struct miscdevice miscdev;
struct list_head list;
unsigned long size;
unsigned long max_size;
unsigned long mapped_size;
};
struct gunyah_cma_parent {
@@ -55,14 +56,19 @@ static int gunyah_cma_alloc(struct gunyah_cma *cma, loff_t len)
if (!cma->page)
return -ENOMEM;
if (len < max_size)
dev_dbg(&cma->dev, "client mapped %lld bytes, less than max %lld bytes\n",
len, max_size);
cma->mapped_size = len;
return 0;
}
static int gunyah_cma_release(struct inode *inode, struct file *file)
{
struct gunyah_cma *cma = file->private_data;
loff_t max_size = i_size_read(file_inode(cma->file));
unsigned int count = PAGE_ALIGN(max_size) >> PAGE_SHIFT;
unsigned int count = PAGE_ALIGN(cma->mapped_size) >> PAGE_SHIFT;
if (!cma->page)
return 0;
@@ -278,7 +284,7 @@ static long gunyah_cma_create_mem_fd(struct gunyah_cma *cma)
inode = file->f_inode;
inode->i_mode |= S_IFREG;
/* Platform specific size of CMA per VM */
i_size_write(inode, cma->size);
i_size_write(inode, cma->max_size);
file->f_flags |= O_LARGEFILE;
file->f_mapping = inode->i_mapping;
@@ -393,7 +399,7 @@ static int gunyah_cma_probe(struct platform_device *pdev)
dev_err(dev, "Failed to find reserved memory for %s\n", mem_name[i]);
goto err_device;
}
cma->size = rmem->size;
cma->max_size = rmem->size;
cma->page = NULL;
list_add(&cma->list, &pcma->gunyah_cma_children);
dev_dbg(dev, "Created a reserved cma pool for %s\n", mem_name[i]);