summaryrefslogtreecommitdiff
path: root/drivers/misc/uacce/uacce.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/uacce/uacce.c')
-rw-r--r--drivers/misc/uacce/uacce.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c
index ffced4da3c2c..d39307f060bd 100644
--- a/drivers/misc/uacce/uacce.c
+++ b/drivers/misc/uacce/uacce.c
@@ -224,6 +224,7 @@ static int uacce_fops_open(struct inode *inode, struct file *filep)
init_waitqueue_head(&q->wait);
filep->private_data = q;
+ uacce->inode = inode;
q->state = UACCE_Q_INIT;
return 0;
@@ -253,6 +254,14 @@ static int uacce_fops_release(struct inode *inode, struct file *filep)
return 0;
}
+static vm_fault_t uacce_vma_fault(struct vm_fault *vmf)
+{
+ if (vmf->flags & (FAULT_FLAG_MKWRITE | FAULT_FLAG_WRITE))
+ return VM_FAULT_SIGBUS;
+
+ return 0;
+}
+
static void uacce_vma_close(struct vm_area_struct *vma)
{
struct uacce_queue *q = vma->vm_private_data;
@@ -265,6 +274,7 @@ static void uacce_vma_close(struct vm_area_struct *vma)
}
static const struct vm_operations_struct uacce_vm_ops = {
+ .fault = uacce_vma_fault,
.close = uacce_vma_close,
};
@@ -556,6 +566,12 @@ void uacce_remove(struct uacce_device *uacce)
if (!uacce)
return;
+ /*
+ * unmap remaining mapping from user space, preventing user still
+ * access the mmaped area while parent device is already removed
+ */
+ if (uacce->inode)
+ unmap_mapping_range(uacce->inode->i_mapping, 0, 0, 1);
/* ensure no open queue remains */
mutex_lock(&uacce->mm_lock);