kernel: Add hooks for user-accessible timers in the kernel.

Hooks for user-accessible timers allow implementation of a
more efficient gettimeofday in user-space.

Change-Id: If2f63d010c1cf142eb84f3745617e756913e46f7
Signed-off-by: Brent DeGraaf <bdegraaf@codeaurora.org>
diff --git a/mm/Kconfig b/mm/Kconfig
index 4cde97f..bbab5a6 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -390,3 +390,14 @@
           the memory corresponding to the hole to be removed using memblock-
           remove.
 
+config USE_USER_ACCESSIBLE_TIMERS
+	bool "Enables timers accessible from userspace"
+	depends on MMU
+	help
+	  User-accessible timers allow the kernel to map kernel timer
+	  registers to a userspace accessible page, to allow faster
+	  access to time information.  This flag will enable the
+	  interface code in the main kernel.  However, there are
+	  architecture-specific code that will need to be enabled
+	  separately.
+
diff --git a/mm/memory.c b/mm/memory.c
index 6105f47..174fcaa 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1726,6 +1726,19 @@
 			goto next_page;
 		}
 
+		if (use_user_accessible_timers()) {
+			if (!vma && in_user_timers_area(mm, start)) {
+				int goto_next_page = 0;
+				int user_timer_ret = get_user_timer_page(vma,
+					mm, start, gup_flags, pages, i,
+					&goto_next_page);
+				if (goto_next_page)
+					goto next_page;
+				else
+					return user_timer_ret;
+			}
+		}
+
 		if (!vma ||
 		    (vma->vm_flags & (VM_IO | VM_PFNMAP)) ||
 		    !(vm_flags & vma->vm_flags))
diff --git a/mm/mlock.c b/mm/mlock.c
index ef726e8..38c77ab 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -229,7 +229,9 @@
 
 	if (!((vma->vm_flags & (VM_DONTEXPAND | VM_RESERVED)) ||
 			is_vm_hugetlb_page(vma) ||
-			vma == get_gate_vma(current->mm))) {
+			vma == get_gate_vma(current->mm) ||
+			((use_user_accessible_timers() &&
+				(vma == get_user_timers_vma(current->mm)))))) {
 
 		__mlock_vma_pages_range(vma, start, end, NULL);
 
@@ -324,7 +326,9 @@
 	int lock = !!(newflags & VM_LOCKED);
 
 	if (newflags == vma->vm_flags || (vma->vm_flags & VM_SPECIAL) ||
-	    is_vm_hugetlb_page(vma) || vma == get_gate_vma(current->mm))
+	    is_vm_hugetlb_page(vma) || vma == get_gate_vma(current->mm) ||
+	    ((use_user_accessible_timers()) &&
+		(vma == get_user_timers_vma(current->mm))))
 		goto out;	/* don't set VM_LOCKED,  don't count */
 
 	pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);