[PATCH v2 17/20] mm/mshare: Add an ioctl for unmapping objects in an mshare region

From: Anthony Yznaga
Date: Thu Apr 03 2025 - 22:23:53 EST


The arguments are the same as munmap() except that the start of the
mapping is specified as an offset into the mshare region instead of
as an address.

Signed-off-by: Anthony Yznaga <anthony.yznaga@xxxxxxxxxx>
---
include/uapi/linux/msharefs.h | 7 ++++++
mm/mshare.c | 40 +++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+)

diff --git a/include/uapi/linux/msharefs.h b/include/uapi/linux/msharefs.h
index ad129beeef62..fb0235d1e384 100644
--- a/include/uapi/linux/msharefs.h
+++ b/include/uapi/linux/msharefs.h
@@ -19,6 +19,7 @@
* msharefs specific ioctl commands
*/
#define MSHAREFS_CREATE_MAPPING _IOW('x', 0, struct mshare_create)
+#define MSHAREFS_UNMAP _IOW('x', 1, struct mshare_unmap)

struct mshare_create {
__u64 region_offset;
@@ -28,4 +29,10 @@ struct mshare_create {
__u32 flags;
__u32 fd;
};
+
+struct mshare_unmap {
+ __u64 region_offset;
+ __u64 size;
+};
+
#endif
diff --git a/mm/mshare.c b/mm/mshare.c
index be0aaa894963..a6106f6264cb 100644
--- a/mm/mshare.c
+++ b/mm/mshare.c
@@ -281,11 +281,41 @@ msharefs_create_mapping(struct mshare_data *m_data, struct mshare_create *mcreat
return error;
}

+static long
+msharefs_unmap(struct mshare_data *m_data, struct mshare_unmap *munmap)
+{
+ struct mm_struct *host_mm = m_data->mm;
+ unsigned long mshare_start, mshare_end, mshare_size;
+ unsigned long region_offset = munmap->region_offset;
+ unsigned long size = munmap->size;
+ unsigned long addr;
+ int error;
+
+ mshare_start = m_data->start;
+ mshare_size = m_data->size;
+ mshare_end = mshare_start + mshare_size;
+ addr = mshare_start + region_offset;
+
+ if ((size > mshare_size) || (region_offset >= mshare_size) ||
+ (addr + size > mshare_end))
+ return -EINVAL;
+
+ if (mmap_write_lock_killable(host_mm))
+ return -EINTR;
+
+ error = do_munmap(host_mm, addr, size, NULL);
+
+ mmap_write_unlock(host_mm);
+
+ return error;
+}
+
static long
msharefs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct mshare_data *m_data = filp->private_data;
struct mshare_create mcreate;
+ struct mshare_unmap munmap;

switch (cmd) {
case MSHAREFS_CREATE_MAPPING:
@@ -298,6 +328,16 @@ msharefs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)

return msharefs_create_mapping(m_data, &mcreate);

+ case MSHAREFS_UNMAP:
+ if (copy_from_user(&munmap, (struct mshare_unmap __user *)arg,
+ sizeof(munmap)))
+ return -EFAULT;
+
+ if (!test_bit(MSHARE_INITIALIZED, &m_data->flags))
+ return -EINVAL;
+
+ return msharefs_unmap(m_data, &munmap);
+
default:
return -ENOTTY;
}
--
2.43.5