--- olpc-2.6-master.00/arch/ia64/ia32/binfmt_elf32.c	2007-02-28 20:05:25.000000000 -0500
+++ olpc-2.6-master-vs22x.02/arch/ia64/ia32/binfmt_elf32.c	2007-03-01 11:52:20.000000000 -0500
@@ -233,7 +233,8 @@ ia32_setup_arg_pages (struct linux_binpr
 			kmem_cache_free(vm_area_cachep, mpnt);
 			return ret;
 		}
-		current->mm->stack_vm = current->mm->total_vm = vma_pages(mpnt);
+		vx_vmpages_sub(current->mm, current->mm->total_vm - vma_pages(mpnt));
+		current->mm->stack_vm = current->mm->total_vm;
 	}
 
 	for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
--- olpc-2.6-master.00/arch/ia64/kernel/perfmon.c	2007-02-28 20:05:25.000000000 -0500
+++ olpc-2.6-master-vs22x.02/arch/ia64/kernel/perfmon.c	2007-03-01 11:52:20.000000000 -0500
@@ -2393,7 +2394,7 @@ pfm_smpl_buffer_alloc(struct task_struct
 	 */
 	insert_vm_struct(mm, vma);
 
-	mm->total_vm  += size >> PAGE_SHIFT;
+	vx_vmpages_add(mm, size >> PAGE_SHIFT);
 	vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
 							vma_pages(vma));
 	up_write(&task->mm->mmap_sem);
--- olpc-2.6-master.00/arch/x86_64/ia32/ia32_binfmt.c	2007-02-28 20:05:26.000000000 -0500
+++ olpc-2.6-master-vs22x.02/arch/x86_64/ia32/ia32_binfmt.c	2007-03-01 11:52:20.000000000 -0500
@@ -322,7 +322,8 @@ int ia32_setup_arg_pages(struct linux_bi
 			kmem_cache_free(vm_area_cachep, mpnt);
 			return ret;
 		}
-		mm->stack_vm = mm->total_vm = vma_pages(mpnt);
+		vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
+		mm->stack_vm = mm->total_vm;
 	} 
 
 	for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
--- olpc-2.6-master.00/drivers/infiniband/core/uverbs_mem.c	2007-02-28 20:05:26.000000000 -0500
+++ olpc-2.6-master-vs22x.02/drivers/infiniband/core/uverbs_mem.c	2007-03-01 11:52:20.000000000 -0500
@@ -161,7 +162,7 @@ out:
 	if (ret < 0)
 		__ib_umem_release(dev, mem, 0);
 	else
-		current->mm->locked_vm = locked;
+		vx_vmlocked_sub(current->mm, current->mm->locked_vm - locked);
 
 	up_write(&current->mm->mmap_sem);
 	free_page((unsigned long) page_list);
--- olpc-2.6-master.00/drivers/infiniband/core/uverbs_mem.c	2007-02-28 20:05:26.000000000 -0500
+++ olpc-2.6-master-vs22x.02/drivers/infiniband/core/uverbs_mem.c	2007-03-01 11:52:20.000000000 -0500
@@ -174,8 +175,8 @@ void ib_umem_release(struct ib_device *d
 	__ib_umem_release(dev, umem, 1);
 
 	down_write(&current->mm->mmap_sem);
-	current->mm->locked_vm -=
-		PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT;
+	vx_vmlocked_sub(current->mm,
+		PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT);
 	up_write(&current->mm->mmap_sem);
 }
 
--- olpc-2.6-master.00/drivers/infiniband/core/uverbs_mem.c	2007-02-28 20:05:26.000000000 -0500
+++ olpc-2.6-master-vs22x.02/drivers/infiniband/core/uverbs_mem.c	2007-03-01 11:52:20.000000000 -0500
@@ -185,7 +186,7 @@ static void ib_umem_account(struct work_
 		container_of(_work, struct ib_umem_account_work, work);
 
 	down_write(&work->mm->mmap_sem);
-	work->mm->locked_vm -= work->diff;
+	vx_vmlocked_sub(work->mm, work->diff);
 	up_write(&work->mm->mmap_sem);
 	mmput(work->mm);
 	kfree(work);
--- olpc-2.6-master.00/drivers/infiniband/hw/ipath/ipath_user_pages.c	2007-02-28 20:05:26.000000000 -0500
+++ olpc-2.6-master-vs22x.02/drivers/infiniband/hw/ipath/ipath_user_pages.c	2007-03-01 11:52:20.000000000 -0500
@@ -61,7 +62,8 @@ static int __get_user_pages(unsigned lon
 	lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >>
 		PAGE_SHIFT;
 
-	if (num_pages > lock_limit) {
+	if (num_pages > lock_limit ||
+		!vx_vmlocked_avail(current->mm, num_pages)) {
 		ret = -ENOMEM;
 		goto bail;
 	}
--- olpc-2.6-master.00/drivers/infiniband/hw/ipath/ipath_user_pages.c	2007-02-28 20:05:26.000000000 -0500
+++ olpc-2.6-master-vs22x.02/drivers/infiniband/hw/ipath/ipath_user_pages.c	2007-03-01 11:52:20.000000000 -0500
@@ -78,7 +80,7 @@ static int __get_user_pages(unsigned lon
 			goto bail_release;
 	}
 
-	current->mm->locked_vm += num_pages;
+	vx_vmlocked_add(current->mm, num_pages);
 
 	ret = 0;
 	goto bail;
--- olpc-2.6-master.00/drivers/infiniband/hw/ipath/ipath_user_pages.c	2007-02-28 20:05:26.000000000 -0500
+++ olpc-2.6-master-vs22x.02/drivers/infiniband/hw/ipath/ipath_user_pages.c	2007-03-01 11:52:20.000000000 -0500
@@ -203,7 +205,7 @@ void ipath_release_user_pages(struct pag
 
 	__ipath_release_user_pages(p, num_pages, 1);
 
-	current->mm->locked_vm -= num_pages;
+	vx_vmlocked_sub(current->mm, num_pages);
 
 	up_write(&current->mm->mmap_sem);
 }
--- olpc-2.6-master.00/drivers/infiniband/hw/ipath/ipath_user_pages.c	2007-02-28 20:05:26.000000000 -0500
+++ olpc-2.6-master-vs22x.02/drivers/infiniband/hw/ipath/ipath_user_pages.c	2007-03-01 11:52:20.000000000 -0500
@@ -220,7 +222,7 @@ static void user_pages_account(struct wo
 		container_of(_work, struct ipath_user_pages_work, work);
 
 	down_write(&work->mm->mmap_sem);
-	work->mm->locked_vm -= work->num_pages;
+	vx_vmlocked_sub(work->mm, work->num_pages);
 	up_write(&work->mm->mmap_sem);
 	mmput(work->mm);
 	kfree(work);
--- olpc-2.6-master.00/fs/exec.c	2007-02-28 20:05:28.000000000 -0500
+++ olpc-2.6-master-vs22x.02/fs/exec.c	2007-03-01 11:52:20.000000000 -0500
@@ -435,7 +436,8 @@ int setup_arg_pages(struct linux_binprm 
 			kmem_cache_free(vm_area_cachep, mpnt);
 			return ret;
 		}
-		mm->stack_vm = mm->total_vm = vma_pages(mpnt);
+		vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
+		mm->stack_vm = mm->total_vm;
 	}
 
 	for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
--- olpc-2.6-master.00/include/linux/sched.h	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/include/linux/sched.h	2007-03-01 11:52:20.000000000 -0500
@@ -274,12 +277,11 @@ extern void arch_unmap_area_topdown(stru
  * The mm counters are not protected by its page_table_lock,
  * so must be incremented atomically.
  */
-#define set_mm_counter(mm, member, value) atomic_long_set(&(mm)->_##member, value)
-#define get_mm_counter(mm, member) ((unsigned long)atomic_long_read(&(mm)->_##member))
-#define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member)
-#define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member)
-#define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member)
 typedef atomic_long_t mm_counter_t;
+#define __set_mm_counter(mm, member, value) \
+	atomic_long_set(&(mm)->_##member, value)
+#define get_mm_counter(mm, member) \
+	((unsigned long)atomic_long_read(&(mm)->_##member))
 
 #else  /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
 /*
--- olpc-2.6-master.00/include/linux/sched.h	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/include/linux/sched.h	2007-03-01 11:52:20.000000000 -0500
@@ -286,12 +288,9 @@ *****
  * The mm counters are protected by its page_table_lock,
  * so can be incremented directly.
  */
-#define set_mm_counter(mm, member, value) (mm)->_##member = (value)
-#define get_mm_counter(mm, member) ((mm)->_##member)
-#define add_mm_counter(mm, member, value) (mm)->_##member += (value)
-#define inc_mm_counter(mm, member) (mm)->_##member++
-#define dec_mm_counter(mm, member) (mm)->_##member--
 typedef unsigned long mm_counter_t;
+#define __set_mm_counter(mm, member, value) (mm)->_##member = (value)
+#define get_mm_counter(mm, member) ((mm)->_##member)
 
 #endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
 
--- olpc-2.6-master.00/include/linux/sched.h	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/include/linux/sched.h	2007-03-01 11:52:20.000000000 -0500
@@ -295,6 +294,13 @@ *****
 
 #endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
 
+#define set_mm_counter(mm, member, value) \
+	vx_ ## member ## pages_sub((mm), (get_mm_counter(mm, member) - value))
+#define add_mm_counter(mm, member, value) \
+	vx_ ## member ## pages_add((mm), (value))
+#define inc_mm_counter(mm, member) vx_ ## member ## pages_inc((mm))
+#define dec_mm_counter(mm, member) vx_ ## member ## pages_dec((mm))
+
 #define get_mm_rss(mm)					\
 	(get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss))
 #define update_hiwater_rss(mm)	do {			\
--- olpc-2.6-master.00/include/linux/sched.h	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/include/linux/sched.h	2007-03-01 11:52:20.000000000 -0500
@@ -352,6 +358,7 @@ struct mm_struct {
 
 	/* Architecture-specific MM context */
 	mm_context_t context;
+	struct vx_info *mm_vx_info;
 
 	/* Swap token stuff */
 	/*
--- olpc-2.6-master.00/kernel/fork.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/kernel/fork.c	2007-03-01 11:52:20.000000000 -0500
@@ -215,6 +222,8 @@ static inline int dup_mmap(struct mm_str
 	mm->free_area_cache = oldmm->mmap_base;
 	mm->cached_hole_size = ~0UL;
 	mm->map_count = 0;
+	__set_mm_counter(mm, file_rss, 0);
+	__set_mm_counter(mm, anon_rss, 0);
 	cpus_clear(mm->cpu_vm_mask);
 	mm->mm_rb = RB_ROOT;
 	rb_link = &mm->mm_rb.rb_node;
--- olpc-2.6-master.00/kernel/fork.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/kernel/fork.c	2007-03-01 11:52:20.000000000 -0500
@@ -226,7 +235,7 @@ static inline int dup_mmap(struct mm_str
 
 		if (mpnt->vm_flags & VM_DONTCOPY) {
 			long pages = vma_pages(mpnt);
-			mm->total_vm -= pages;
+			vx_vmpages_sub(mm, pages);
 			vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
 								-pages);
 			continue;
--- olpc-2.6-master.00/kernel/fork.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/kernel/fork.c	2007-03-01 11:52:20.000000000 -0500
@@ -343,6 +350,7 @@ static struct mm_struct * mm_init(struct
 
 	if (likely(!mm_alloc_pgd(mm))) {
 		mm->def_flags = 0;
+		set_vx_info(&mm->mm_vx_info, current->vx_info);
 		return mm;
 	}
 	free_mm(mm);
--- olpc-2.6-master.00/kernel/fork.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/kernel/fork.c	2007-03-01 11:52:20.000000000 -0500
@@ -374,6 +382,7 @@ void fastcall __mmdrop(struct mm_struct 
 	BUG_ON(mm == &init_mm);
 	mm_free_pgd(mm);
 	destroy_context(mm);
+	clr_vx_info(&mm->mm_vx_info);
 	free_mm(mm);
 }
 
--- olpc-2.6-master.00/kernel/fork.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/kernel/fork.c	2007-03-01 11:52:20.000000000 -0500
@@ -488,6 +497,7 @@ static struct mm_struct *dup_mm(struct t
 		goto fail_nomem;
 
 	memcpy(mm, oldmm, sizeof(*mm));
+	mm->mm_vx_info = NULL;
 
 	/* Initializing for Swap token stuff */
 	mm->token_priority = 0;
--- olpc-2.6-master.00/kernel/fork.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/kernel/fork.c	2007-03-01 11:52:20.000000000 -0500
@@ -519,6 +529,7 @@ fail_nocontext:
 	 * If init_new_context() failed, we cannot use mmput() to free the mm
 	 * because it calls destroy_context()
 	 */
+	clr_vx_info(&mm->mm_vx_info);
 	mm_free_pgd(mm);
 	free_mm(mm);
 	return NULL;
--- olpc-2.6-master.00/kernel/fork.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/kernel/fork.c	2007-03-01 11:52:20.000000000 -0500
@@ -589,6 +600,7 @@ static inline struct fs_struct *__copy_f
 			fs->altroot = NULL;
 		}
 		read_unlock(&old->lock);
+		atomic_inc(&vs_global_fs);
 	}
 	return fs;
 }
--- olpc-2.6-master.00/kernel/fork.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/kernel/fork.c	2007-03-01 11:52:20.000000000 -0500
@@ -992,7 +1008,25 @@ static struct task_struct *copy_process(
 	DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
 	DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
 #endif
+	init_vx_info(&p->vx_info, current->vx_info);
+	init_nx_info(&p->nx_info, current->nx_info);
+
+	/* check vserver memory */
+	if (p->mm && !(clone_flags & CLONE_VM)) {
+		if (vx_vmpages_avail(p->mm, p->mm->total_vm))
+			vx_pages_add(p->vx_info, RLIMIT_AS, p->mm->total_vm);
+		else
+			goto bad_fork_free;
+	}
+	if (p->mm && vx_flags(VXF_FORK_RSS, 0)) {
+		if (!vx_rss_avail(p->mm, get_mm_counter(p->mm, file_rss)))
+			goto bad_fork_cleanup_vm;
+	}
+
 	retval = -EAGAIN;
+	if (!vx_nproc_avail(1))
+		goto bad_fork_cleanup_vm;
+
 	if (atomic_read(&p->user->processes) >=
 			p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
 		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
--- olpc-2.6-master.00/kernel/fork.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/kernel/fork.c	2007-03-01 11:52:20.000000000 -0500
@@ -997,7 +1031,7 @@ *****
 			p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
 		if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
 				p->user != &root_user)
-			goto bad_fork_free;
+			goto bad_fork_cleanup_vm;
 	}
 
 	atomic_inc(&p->user->__count);
--- olpc-2.6-master.00/kernel/fork.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/kernel/fork.c	2007-03-01 11:52:20.000000000 -0500
@@ -1303,6 +1349,9 @@ bad_fork_cleanup_count:
 	put_group_info(p->group_info);
 	atomic_dec(&p->user->processes);
 	free_uid(p->user);
+bad_fork_cleanup_vm:
+	if (p->mm && !(clone_flags & CLONE_VM))
+		vx_pages_sub(p->vx_info, RLIMIT_AS, p->mm->total_vm);
 bad_fork_free:
 	free_task(p);
 fork_out:
--- olpc-2.6-master.00/kernel/nsproxy.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/kernel/nsproxy.c	2007-03-01 11:52:20.000000000 -0500
@@ -145,5 +141,6 @@ void free_nsproxy(struct nsproxy *ns)
 		put_ipc_ns(ns->ipc_ns);
 	if (ns->pid_ns)
 		put_pid_ns(ns->pid_ns);
+	atomic_dec(&vs_global_nsproxy);
 	kfree(ns);
 }
--- olpc-2.6-master.00/mm/fremap.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/fremap.c	2007-03-01 11:52:20.000000000 -0500
@@ -74,6 +75,8 @@ int install_page(struct mm_struct *mm, s
 	err = -ENOMEM;
 	if (page_mapcount(page) > INT_MAX/2)
 		goto unlock;
+	if (!vx_rss_avail(mm, 1))
+		goto unlock;
 
 	if (pte_none(*pte) || !zap_pte(mm, vma, addr, pte))
 		inc_mm_counter(mm, file_rss);
--- olpc-2.6-master.00/mm/memory.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/memory.c	2007-03-01 11:52:20.000000000 -0500
@@ -498,6 +498,9 @@ static int copy_pte_range(struct mm_stru
 	int progress = 0;
 	int rss[2];
 
+	if (!vx_rss_avail(dst_mm, ((end - addr)/PAGE_SIZE + 1)))
+		return -ENOMEM;
+
 again:
 	rss[1] = rss[0] = 0;
 	dst_pte = pte_alloc_map_lock(dst_mm, dst_pmd, addr, &dst_ptl);
--- olpc-2.6-master.00/mm/memory.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/memory.c	2007-03-01 11:52:20.000000000 -0500
@@ -2062,6 +2065,11 @@ static int do_swap_page(struct mm_struct
 		count_vm_event(PGMAJFAULT);
 	}
 
+	if (!vx_rss_avail(mm, 1)) {
+		ret = VM_FAULT_OOM;
+		goto out;
+	}
+
 	delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
 	mark_page_accessed(page);
 	lock_page(page);
--- olpc-2.6-master.00/mm/memory.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/memory.c	2007-03-01 11:52:20.000000000 -0500
@@ -2134,6 +2142,8 @@ static int do_anonymous_page(struct mm_s
 		/* Allocate our own private page. */
 		pte_unmap(page_table);
 
+		if (!vx_rss_avail(mm, 1))
+			goto oom;
 		if (unlikely(anon_vma_prepare(vma)))
 			goto oom;
 		page = alloc_zeroed_user_highpage(vma, address);
--- olpc-2.6-master.00/mm/memory.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/memory.c	2007-03-01 11:52:20.000000000 -0500
@@ -2207,6 +2217,9 @@ static int do_no_page(struct mm_struct *
 	pte_unmap(page_table);
 	BUG_ON(vma->vm_flags & VM_PFNMAP);
 
+	if (!vx_rss_avail(mm, 1))
+		return VM_FAULT_OOM;
+
 	if (vma->vm_file) {
 		mapping = vma->vm_file->f_mapping;
 		sequence = mapping->truncate_count;
--- olpc-2.6-master.00/mm/mlock.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mlock.c	2007-03-01 11:52:20.000000000 -0500
@@ -65,7 +66,7 @@ success:
 			ret = make_pages_present(start, end);
 	}
 
-	mm->locked_vm -= pages;
+	vx_vmlocked_sub(mm, pages);
 out:
 	if (ret == -ENOMEM)
 		ret = -EAGAIN;
--- olpc-2.6-master.00/mm/mlock.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mlock.c	2007-03-01 11:52:20.000000000 -0500
@@ -123,7 +124,7 @@ static int do_mlock(unsigned long start,
 
 asmlinkage long sys_mlock(unsigned long start, size_t len)
 {
-	unsigned long locked;
+	unsigned long locked, grow;
 	unsigned long lock_limit;
 	int error = -ENOMEM;
 
--- olpc-2.6-master.00/mm/mlock.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mlock.c	2007-03-01 11:52:20.000000000 -0500
@@ -134,8 +135,10 @@ asmlinkage long sys_mlock(unsigned long 
 	len = PAGE_ALIGN(len + (start & ~PAGE_MASK));
 	start &= PAGE_MASK;
 
-	locked = len >> PAGE_SHIFT;
-	locked += current->mm->locked_vm;
+	grow = len >> PAGE_SHIFT;
+	if (!vx_vmlocked_avail(current->mm, grow))
+		goto out;
+	locked = current->mm->locked_vm + grow;
 
 	lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
 	lock_limit >>= PAGE_SHIFT;
--- olpc-2.6-master.00/mm/mlock.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mlock.c	2007-03-01 11:52:20.000000000 -0500
@@ -143,6 +146,7 @@ asmlinkage long sys_mlock(unsigned long 
 	/* check against resource limits */
 	if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
 		error = do_mlock(start, len, 1);
+out:
 	up_write(&current->mm->mmap_sem);
 	return error;
 }
--- olpc-2.6-master.00/mm/mlock.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mlock.c	2007-03-01 11:52:20.000000000 -0500
@@ -202,6 +206,8 @@ asmlinkage long sys_mlockall(int flags)
 	lock_limit >>= PAGE_SHIFT;
 
 	ret = -ENOMEM;
+	if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
+		goto out;
 	if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
 	    capable(CAP_IPC_LOCK))
 		ret = do_mlockall(flags);
--- olpc-2.6-master.00/mm/mmap.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mmap.c	2007-03-01 11:52:20.000000000 -0500
@@ -1141,10 +1141,10 @@ munmap_back:
 		kmem_cache_free(vm_area_cachep, vma);
 	}
 out:	
-	mm->total_vm += len >> PAGE_SHIFT;
+	vx_vmpages_add(mm, len >> PAGE_SHIFT);
 	vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
 	if (vm_flags & VM_LOCKED) {
-		mm->locked_vm += len >> PAGE_SHIFT;
+		vx_vmlocked_add(mm, len >> PAGE_SHIFT);
 		make_pages_present(addr, addr + len);
 	}
 	if (flags & MAP_POPULATE) {
--- olpc-2.6-master.00/mm/mmap.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mmap.c	2007-03-01 11:52:20.000000000 -0500
@@ -1511,9 +1511,9 @@ static int acct_stack_growth(struct vm_a
 		return -ENOMEM;
 
 	/* Ok, everything looks good - let it rip */
-	mm->total_vm += grow;
+	vx_vmpages_add(mm, grow);
 	if (vma->vm_flags & VM_LOCKED)
-		mm->locked_vm += grow;
+		vx_vmlocked_add(mm, grow);
 	vm_stat_account(mm, vma->vm_flags, vma->vm_file, grow);
 	return 0;
 }
--- olpc-2.6-master.00/mm/mmap.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mmap.c	2007-03-01 11:52:20.000000000 -0500
@@ -1666,9 +1666,9 @@ static void remove_vma_list(struct mm_st
 	do {
 		long nrpages = vma_pages(vma);
 
-		mm->total_vm -= nrpages;
+		vx_vmpages_sub(mm, nrpages);
 		if (vma->vm_flags & VM_LOCKED)
-			mm->locked_vm -= nrpages;
+			vx_vmlocked_sub(mm, nrpages);
 		vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
 		vma = remove_vma(vma);
 	} while (vma);
--- olpc-2.6-master.00/mm/mmap.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mmap.c	2007-03-01 11:52:20.000000000 -0500
@@ -1907,6 +1907,8 @@ unsigned long do_brk(unsigned long addr,
 		lock_limit >>= PAGE_SHIFT;
 		if (locked > lock_limit && !capable(CAP_IPC_LOCK))
 			return -EAGAIN;
+		if (!vx_vmlocked_avail(mm, len >> PAGE_SHIFT))
+			return -ENOMEM;
 	}
 
 	/*
--- olpc-2.6-master.00/mm/mmap.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mmap.c	2007-03-01 11:52:20.000000000 -0500
@@ -1933,7 +1935,8 @@ unsigned long do_brk(unsigned long addr,
 	if (mm->map_count > sysctl_max_map_count)
 		return -ENOMEM;
 
-	if (security_vm_enough_memory(len >> PAGE_SHIFT))
+	if (security_vm_enough_memory(len >> PAGE_SHIFT) ||
+		!vx_vmpages_avail(mm, len >> PAGE_SHIFT))
 		return -ENOMEM;
 
 	/* Can we just expand an old private anonymous mapping? */
--- olpc-2.6-master.00/mm/mmap.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mmap.c	2007-03-01 11:52:20.000000000 -0500
@@ -1959,9 +1962,9 @@ unsigned long do_brk(unsigned long addr,
 				(VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
 	vma_link(mm, vma, prev, rb_link, rb_parent);
 out:
-	mm->total_vm += len >> PAGE_SHIFT;
+	vx_vmpages_add(mm, len >> PAGE_SHIFT);
 	if (flags & VM_LOCKED) {
-		mm->locked_vm += len >> PAGE_SHIFT;
+		vx_vmlocked_add(mm, len >> PAGE_SHIFT);
 		make_pages_present(addr, addr + len);
 	}
 	return addr;
--- olpc-2.6-master.00/mm/mmap.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mmap.c	2007-03-01 11:52:20.000000000 -0500
@@ -2026,7 +2034,8 @@ int insert_vm_struct(struct mm_struct * 
 	if (__vma && __vma->vm_start < vma->vm_end)
 		return -ENOMEM;
 	if ((vma->vm_flags & VM_ACCOUNT) &&
-	     security_vm_enough_memory(vma_pages(vma)))
+		(security_vm_enough_memory(vma_pages(vma)) ||
+		!vx_vmpages_avail(mm, vma_pages(vma))))
 		return -ENOMEM;
 	vma_link(mm, vma, prev, rb_link, rb_parent);
 	return 0;
--- olpc-2.6-master.00/mm/mmap.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mmap.c	2007-03-01 11:52:20.000000000 -0500
@@ -2099,6 +2108,8 @@ int may_expand_vm(struct mm_struct *mm, 
 
 	if (cur + npages > lim)
 		return 0;
+	if (!vx_vmpages_avail(mm, npages))
+		return 0;
 	return 1;
 }
 
--- olpc-2.6-master.00/mm/mmap.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mmap.c	2007-03-01 11:52:20.000000000 -0500
@@ -2169,7 +2180,6 @@ int install_special_mapping(struct mm_st
 		return -ENOMEM;
 	}
 
-	mm->total_vm += len >> PAGE_SHIFT;
-
+	vx_vmpages_add(mm, len >> PAGE_SHIFT);
 	return 0;
 }
--- olpc-2.6-master.00/mm/mremap.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mremap.c	2007-03-01 11:52:20.000000000 -0500
@@ -212,7 +213,7 @@ static unsigned long move_vma(struct vm_
 	 * If this were a serious issue, we'd add a flag to do_munmap().
 	 */
 	hiwater_vm = mm->hiwater_vm;
-	mm->total_vm += new_len >> PAGE_SHIFT;
+	vx_vmpages_add(mm, new_len >> PAGE_SHIFT);
 	vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
 
 	if (do_munmap(mm, old_addr, old_len) < 0) {
--- olpc-2.6-master.00/mm/mremap.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mremap.c	2007-03-01 11:52:20.000000000 -0500
@@ -230,7 +231,7 @@ static unsigned long move_vma(struct vm_
 	}
 
 	if (vm_flags & VM_LOCKED) {
-		mm->locked_vm += new_len >> PAGE_SHIFT;
+		vx_vmlocked_add(mm, new_len >> PAGE_SHIFT);
 		if (new_len > old_len)
 			make_pages_present(new_addr + old_len,
 					   new_addr + new_len);
--- olpc-2.6-master.00/mm/mremap.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mremap.c	2007-03-01 11:52:20.000000000 -0500
@@ -337,6 +338,9 @@ unsigned long do_mremap(unsigned long ad
 		ret = -EAGAIN;
 		if (locked > lock_limit && !capable(CAP_IPC_LOCK))
 			goto out;
+		if (!vx_vmlocked_avail(current->mm,
+			(new_len - old_len) >> PAGE_SHIFT))
+			goto out;
 	}
 	if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) {
 		ret = -ENOMEM;
--- olpc-2.6-master.00/mm/mremap.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/mremap.c	2007-03-01 11:52:20.000000000 -0500
@@ -365,10 +369,10 @@ unsigned long do_mremap(unsigned long ad
 			vma_adjust(vma, vma->vm_start,
 				addr + new_len, vma->vm_pgoff, NULL);
 
-			mm->total_vm += pages;
+			vx_vmpages_add(mm, pages);
 			vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages);
 			if (vma->vm_flags & VM_LOCKED) {
-				mm->locked_vm += pages;
+				vx_vmlocked_add(mm, pages);
 				make_pages_present(addr + old_len,
 						   addr + new_len);
 			}
--- olpc-2.6-master.00/mm/nommu.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/nommu.c	2007-03-01 11:52:20.000000000 -0500
@@ -921,7 +921,7 @@ unsigned long do_mmap_pgoff(struct file 
 	realalloc += kobjsize(vma);
 	askedalloc += sizeof(*vma);
 
-	current->mm->total_vm += len >> PAGE_SHIFT;
+	vx_vmpages_add(current->mm, len >> PAGE_SHIFT);
 
 	add_nommu_vma(vma);
 
--- olpc-2.6-master.00/mm/nommu.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/nommu.c	2007-03-01 11:52:20.000000000 -0500
@@ -1046,7 +1046,7 @@ int do_munmap(struct mm_struct *mm, unsi
 	kfree(vml);
 
 	update_hiwater_vm(mm);
-	mm->total_vm -= len >> PAGE_SHIFT;
+	vx_vmpages_sub(mm, len >> PAGE_SHIFT);
 
 #ifdef DEBUG
 	show_process_blocks();
--- olpc-2.6-master.00/mm/nommu.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/nommu.c	2007-03-01 11:52:20.000000000 -0500
@@ -1078,7 +1078,7 @@ void exit_mmap(struct mm_struct * mm)
 		printk("Exit_mmap:\n");
 #endif
 
-		mm->total_vm = 0;
+		vx_vmpages_sub(mm, mm->total_vm);
 
 		while ((tmp = mm->context.vmlist)) {
 			mm->context.vmlist = tmp->next;
--- olpc-2.6-master.00/mm/oom_kill.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/oom_kill.c	2007-03-01 11:52:20.000000000 -0500
@@ -24,6 +24,7 @@
 #include <linux/cpuset.h>
 #include <linux/module.h>
 #include <linux/notifier.h>
+#include <linux/vs_memory.h>
 
 int sysctl_panic_on_oom;
 /* #define DEBUG */
--- olpc-2.6-master.00/mm/oom_kill.c	2007-02-28 20:05:29.000000000 -0500
+++ olpc-2.6-master-vs22x.02/mm/oom_kill.c	2007-03-01 11:52:20.000000000 -0500
@@ -66,6 +67,12 @@ unsigned long badness(struct task_struct
 	points = mm->total_vm;
 
 	/*
+	 * add points for context badness
+	 */
+
+	points += vx_badness(p, mm);
+
+	/*
 	 * After this unlock we can no longer dereference local variable `mm'
 	 */
 	task_unlock(p);
