|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] linux-2.6.18/privcmd: sprinkle around cond_resched() calls in mmap ioctl handling
Many of these operations can be arbitrarily long, which can become a
problem irrespective of them being exposed to privileged users only.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
--- sle11sp3.orig/drivers/xen/privcmd/privcmd.c 2012-12-12 12:05:51.000000000
+0100
+++ sle11sp3/drivers/xen/privcmd/privcmd.c 2014-01-16 10:01:23.000000000
+0100
@@ -126,6 +126,9 @@ static long privcmd_ioctl(struct file *f
p = mmapcmd.entry;
for (i = 0; i < mmapcmd.num;) {
+ if (i)
+ cond_resched();
+
nr = min(mmapcmd.num - i, MMAP_NR_PER_PAGE);
ret = -ENOMEM;
@@ -158,6 +161,9 @@ static long privcmd_ioctl(struct file *f
i = 0;
list_for_each(l, &pagelist) {
+ if (i)
+ cond_resched();
+
nr = i + min(mmapcmd.num - i, MMAP_NR_PER_PAGE);
msg = (privcmd_mmap_entry_t*)(l + 1);
@@ -186,6 +192,9 @@ static long privcmd_ioctl(struct file *f
addr = vma->vm_start;
i = 0;
list_for_each(l, &pagelist) {
+ if (i)
+ cond_resched();
+
nr = i + min(mmapcmd.num - i, MMAP_NR_PER_PAGE);
msg = (privcmd_mmap_entry_t*)(l + 1);
@@ -209,8 +218,12 @@ static long privcmd_ioctl(struct file *f
mmap_out:
up_write(&mm->mmap_sem);
- list_for_each_safe(l,l2,&pagelist)
+ i = 0;
+ list_for_each_safe(l, l2, &pagelist) {
+ if (!(++i & 7))
+ cond_resched();
free_page((unsigned long)l);
+ }
}
#undef MMAP_NR_PER_PAGE
break;
@@ -236,6 +249,9 @@ static long privcmd_ioctl(struct file *f
p = m.arr;
for (i=0; i<nr_pages; ) {
+ if (i)
+ cond_resched();
+
nr = min(nr_pages - i, MMAPBATCH_NR_PER_PAGE);
ret = -ENOMEM;
@@ -270,6 +286,9 @@ static long privcmd_ioctl(struct file *f
ret = 0;
paged_out = 0;
list_for_each(l, &pagelist) {
+ if (i)
+ cond_resched();
+
nr = i + min(nr_pages - i, MMAPBATCH_NR_PER_PAGE);
mfn = (unsigned long *)(l + 1);
@@ -302,6 +321,9 @@ static long privcmd_ioctl(struct file *f
else
ret = 0;
list_for_each(l, &pagelist) {
+ if (i)
+ cond_resched();
+
nr = min(nr_pages - i, MMAPBATCH_NR_PER_PAGE);
mfn = (unsigned long *)(l + 1);
if (copy_to_user(p, mfn, nr*sizeof(*mfn)))
@@ -310,8 +332,12 @@ static long privcmd_ioctl(struct file *f
}
}
mmapbatch_out:
- list_for_each_safe(l,l2,&pagelist)
+ i = 0;
+ list_for_each_safe(l, l2, &pagelist) {
+ if (!(++i & 7))
+ cond_resched();
free_page((unsigned long)l);
+ }
}
break;
@@ -335,6 +361,9 @@ static long privcmd_ioctl(struct file *f
p = m.arr;
for (i = 0; i < nr_pages; i += nr, p += nr) {
+ if (i)
+ cond_resched();
+
nr = min(nr_pages - i, MMAPBATCH_NR_PER_PAGE);
ret = -ENOMEM;
@@ -367,6 +396,9 @@ static long privcmd_ioctl(struct file *f
ret = 0;
paged_out = 0;
list_for_each(l, &pagelist) {
+ if (i)
+ cond_resched();
+
nr = i + min(nr_pages - i, MMAPBATCH_NR_PER_PAGE);
mfn = (void *)(l + 1);
err = (void *)(l + 1);
@@ -397,6 +429,9 @@ static long privcmd_ioctl(struct file *f
ret = paged_out ? -ENOENT : 0;
i = 0;
list_for_each(l, &pagelist) {
+ if (i)
+ cond_resched();
+
nr = min(nr_pages - i, MMAPBATCH_NR_PER_PAGE);
err = (void *)(l + 1);
if (copy_to_user(p, err, nr * sizeof(*err)))
@@ -407,8 +442,12 @@ static long privcmd_ioctl(struct file *f
ret = -EFAULT;
mmapbatch_v2_out:
- list_for_each_safe(l, l2, &pagelist)
+ i = 0;
+ list_for_each_safe(l, l2, &pagelist) {
+ if (!(++i & 7))
+ cond_resched();
free_page((unsigned long)l);
+ }
#undef MMAPBATCH_NR_PER_PAGE
}
break;
Attachment:
xen-privcmd-mmap-cond-resched.patch _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |