Skip to content

Commit 456f17c

Browse files
Ingo MolnarLinus Torvalds
authored andcommitted
[PATCH] user-vm-unlock-2.5.31-A2
This implements CLONE_VM_RELEASE, which lets the child release the 'user VM' at mm_release() time.
1 parent aeb44e1 commit 456f17c

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed

arch/i386/kernel/process.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
566566
struct_cpy(childregs, regs);
567567
childregs->eax = 0;
568568
childregs->esp = esp;
569+
p->user_vm_lock = NULL;
569570

570571
p->thread.esp = (unsigned long) childregs;
571572
p->thread.esp0 = (unsigned long) (childregs+1);
@@ -579,6 +580,19 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
579580
unlazy_fpu(tsk);
580581
struct_cpy(&p->thread.i387, &tsk->thread.i387);
581582

583+
if (unlikely(NULL != tsk->thread.ts_io_bitmap)) {
584+
p->thread.ts_io_bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
585+
if (!p->thread.ts_io_bitmap)
586+
return -ENOMEM;
587+
memcpy(p->thread.ts_io_bitmap, tsk->thread.ts_io_bitmap,
588+
IO_BITMAP_BYTES);
589+
}
590+
591+
/*
592+
* The common fastpath:
593+
*/
594+
if (!(clone_flags & (CLONE_SETTLS | CLONE_SETTID | CLONE_RELEASE_VM)))
595+
return 0;
582596
/*
583597
* Set a new TLS for the child thread?
584598
*/
@@ -608,14 +622,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
608622
if (put_user(p->pid, (pid_t *)childregs->edx))
609623
return -EFAULT;
610624

611-
if (unlikely(NULL != tsk->thread.ts_io_bitmap)) {
612-
p->thread.ts_io_bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
613-
if (!p->thread.ts_io_bitmap)
614-
return -ENOMEM;
615-
memcpy(p->thread.ts_io_bitmap, tsk->thread.ts_io_bitmap,
616-
IO_BITMAP_BYTES);
625+
/*
626+
* Does the userspace VM want any unlock on mm_release()?
627+
*/
628+
if (clone_flags & CLONE_RELEASE_VM) {
629+
childregs->esp -= sizeof(0UL);
630+
p->user_vm_lock = (long *) esp;
617631
}
618-
619632
return 0;
620633
}
621634

include/linux/sched.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ struct exec_domain;
4848
#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
4949
#define CLONE_SETTID 0x00100000 /* write the TID back to userspace */
5050
#define CLONE_DETACHED 0x00200000 /* parent wants no child-exit signal */
51+
#define CLONE_RELEASE_VM 0x00400000 /* release the userspace VM */
5152

5253
#define CLONE_SIGNAL (CLONE_SIGHAND | CLONE_THREAD)
5354

@@ -306,6 +307,7 @@ struct task_struct {
306307

307308
wait_queue_head_t wait_chldexit; /* for wait4() */
308309
struct completion *vfork_done; /* for vfork() */
310+
long *user_vm_lock; /* for CLONE_RELEASE_VM */
309311

310312
unsigned long rt_priority;
311313
unsigned long it_real_value, it_prof_value, it_virt_value;

kernel/fork.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,12 @@ void mm_release(void)
367367
tsk->vfork_done = NULL;
368368
complete(vfork_done);
369369
}
370+
if (tsk->user_vm_lock)
371+
/*
372+
* We dont check the error code - if userspace has
373+
* not set up a proper pointer then tough luck.
374+
*/
375+
put_user(0UL, tsk->user_vm_lock);
370376
}
371377

372378
static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)

0 commit comments

Comments
 (0)