git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge to Fedora kernel-2.6.18-1.2255_FC5-vs2.0.2.2-rc9 patched with stable patch...
[linux-2.6.git]
/
drivers
/
xen
/
privcmd
/
privcmd.c
diff --git
a/drivers/xen/privcmd/privcmd.c
b/drivers/xen/privcmd/privcmd.c
index
501aa5f
..
af9e13c
100644
(file)
--- a/
drivers/xen/privcmd/privcmd.c
+++ b/
drivers/xen/privcmd/privcmd.c
@@
-34,6
+34,10
@@
static struct proc_dir_entry *privcmd_intf;
static struct proc_dir_entry *capabilities_intf;
static struct proc_dir_entry *privcmd_intf;
static struct proc_dir_entry *capabilities_intf;
+#ifndef HAVE_ARCH_PRIVCMD_MMAP
+static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma);
+#endif
+
static int privcmd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long data)
{
static int privcmd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long data)
{
@@
-121,12
+125,10
@@
static int privcmd_ioctl(struct inode *inode, struct file *file,
vma = find_vma(mm, msg.va);
rc = -EINVAL;
vma = find_vma(mm, msg.va);
rc = -EINVAL;
- if (!vma || (msg.va != vma->vm_start) || vma->vm_private_data)
+ if (!vma || (msg.va != vma->vm_start) ||
+ !privcmd_enforce_singleshot_mapping(vma))
goto mmap_out;
goto mmap_out;
- /* Mapping is a one-shot operation per vma. */
- vma->vm_private_data = (void *)1;
-
va = vma->vm_start;
for (i = 0; i < mmapcmd.num; i++) {
va = vma->vm_start;
for (i = 0; i < mmapcmd.num; i++) {
@@
-136,7
+138,7
@@
static int privcmd_ioctl(struct inode *inode, struct file *file,
/* Do not allow range to wrap the address space. */
rc = -EINVAL;
/* Do not allow range to wrap the address space. */
rc = -EINVAL;
- if ((msg.npages > (
INT
_MAX >> PAGE_SHIFT)) ||
+ if ((msg.npages > (
LONG
_MAX >> PAGE_SHIFT)) ||
((unsigned long)(msg.npages << PAGE_SHIFT) >= -va))
goto mmap_out;
((unsigned long)(msg.npages << PAGE_SHIFT) >= -va))
goto mmap_out;
@@
-180,7
+182,7
@@
static int privcmd_ioctl(struct inode *inode, struct file *file,
if (copy_from_user(&m, udata, sizeof(m)))
return -EFAULT;
if (copy_from_user(&m, udata, sizeof(m)))
return -EFAULT;
- if ((m.num <= 0) || (m.num > (
INT
_MAX >> PAGE_SHIFT)))
+ if ((m.num <= 0) || (m.num > (
LONG
_MAX >> PAGE_SHIFT)))
return -EINVAL;
down_read(&mm->mmap_sem);
return -EINVAL;
down_read(&mm->mmap_sem);
@@
-188,15
+190,13
@@
static int privcmd_ioctl(struct inode *inode, struct file *file,
vma = find_vma(mm, m.addr);
if (!vma ||
(m.addr != vma->vm_start) ||
vma = find_vma(mm, m.addr);
if (!vma ||
(m.addr != vma->vm_start) ||
- ((m.addr + (m.num<<PAGE_SHIFT)) != vma->vm_end) ||
- vma->vm_private_data) {
+ ((m.addr + ((unsigned long)m.num<<PAGE_SHIFT)) !=
+ vma->vm_end) ||
+ !privcmd_enforce_singleshot_mapping(vma)) {
up_read(&mm->mmap_sem);
return -EINVAL;
}
up_read(&mm->mmap_sem);
return -EINVAL;
}
- /* Mapping is a one-shot operation per vma. */
- vma->vm_private_data = (void *)1;
-
p = m.arr;
addr = m.addr;
for (i = 0; i < m.num; i++, addr += PAGE_SIZE, p++) {
p = m.arr;
addr = m.addr;
for (i = 0; i < m.num; i++, addr += PAGE_SIZE, p++) {
@@
-250,6
+250,11
@@
static int privcmd_mmap(struct file * file, struct vm_area_struct * vma)
return 0;
}
return 0;
}
+
+static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma)
+{
+ return (xchg(&vma->vm_private_data, (void *)1) == NULL);
+}
#endif
static struct file_operations privcmd_file_ops = {
#endif
static struct file_operations privcmd_file_ops = {