Add an ioctl for unmapping objects in an mshare region. Signed-off-by: Anthony Yznaga <anthony.yznaga@xxxxxxxxxx> --- include/uapi/linux/msharefs.h | 7 ++++++ mm/mshare.c | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/include/uapi/linux/msharefs.h b/include/uapi/linux/msharefs.h index fea0afdf000d..f7af1f2b5ee7 100644 --- a/include/uapi/linux/msharefs.h +++ b/include/uapi/linux/msharefs.h @@ -21,6 +21,7 @@ #define MSHAREFS_GET_SIZE _IOR('x', 0, struct mshare_info) #define MSHAREFS_SET_SIZE _IOW('x', 1, struct mshare_info) #define MSHAREFS_CREATE_MAPPING _IOW('x', 2, struct mshare_create) +#define MSHAREFS_UNMAP _IOW('x', 3, struct mshare_unmap) struct mshare_info { __u64 start; @@ -35,4 +36,10 @@ struct mshare_create { __u32 flags; __u32 fd; }; + +struct mshare_unmap { + __u64 addr; + __u64 size; +}; + #endif diff --git a/mm/mshare.c b/mm/mshare.c index d70f10210b46..8f53b8132895 100644 --- a/mm/mshare.c +++ b/mm/mshare.c @@ -241,6 +241,32 @@ msharefs_create_mapping(struct mm_struct *host_mm, struct mshare_data *m_data, return err; } +static long +msharefs_unmap(struct mm_struct *host_mm, struct mshare_data *m_data, + struct mshare_unmap *m_unmap) +{ + unsigned long mshare_start, mshare_end; + unsigned long addr = m_unmap->addr; + unsigned long size = m_unmap->size; + int err; + + mshare_start = m_data->minfo.start; + mshare_end = mshare_start + m_data->minfo.size; + + if ((addr < mshare_start) || (addr >= mshare_end) || + (addr + size > mshare_end)) + return -EINVAL; + + if (mmap_write_lock_killable(host_mm)) + return -EINTR; + + err = do_munmap(host_mm, addr, size, NULL); + + mmap_write_unlock(host_mm); + + return err; +} + static long msharefs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -248,6 +274,7 @@ msharefs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct mm_struct *host_mm = m_data->mm; struct mshare_info minfo; struct mshare_create mcreate; + struct mshare_unmap m_unmap; switch (cmd) { case MSHAREFS_GET_SIZE: @@ -293,6 +320,23 @@ msharefs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return msharefs_create_mapping(host_mm, m_data, &mcreate); + case MSHAREFS_UNMAP: + if (copy_from_user(&m_unmap, (struct mshare_unmap __user *)arg, + sizeof(m_unmap))) + return -EFAULT; + + /* + * validate mshare region + */ + spin_lock(&m_data->m_lock); + if (m_data->minfo.size == 0) { + spin_unlock(&m_data->m_lock); + return -EINVAL; + } + spin_unlock(&m_data->m_lock); + + return msharefs_unmap(host_mm, m_data, &m_unmap); + default: return -ENOTTY; } -- 2.43.5