diff --git a/mm/usercopy.c b/mm/usercopy.c
index 968ff67..cb8ccc8 100644
--- a/mm/usercopy.c
+++ b/mm/usercopy.c
@@ -83,6 +83,40 @@ static inline void unpin_page(struct page *page)
 }
 
 /*
+ * map user space page to kernel space
+ * return NULL in case of failure
+ */
+void* __kmap_atomic_user_page(unsigned long addr,
+		struct page** page, spinlock_t **ptlp, int write)
+{
+	struct mm_struct *mm = current->mm ? : &init_mm;
+	pte_t pte;
+	void* maddr;
+
+	*page = pin_page(addr, write, &pte);
+	*ptlp = &mm->page_table_lock;
+	if ((*page == (struct page *)-1UL) || (!(*page) && !pte_present(pte)))
+		return NULL;
+
+	if (*page)
+		maddr = kmap_atomic(*page, KM_USER_COPY);
+	else
+		/* we will map with user pte */
+		maddr = kmap_atomic_pte(&pte, KM_USER_COPY);
+
+	return maddr;
+}
+
+void __kunmap_atomic_user_page(void* maddr, struct page* page,
+		spinlock_t *ptlp)
+{
+	kunmap_atomic(maddr, KM_USER_COPY);
+	spin_unlock(ptlp);
+	if (page)
+		unpin_page(page);
+}
+
+/*
  * Access another process' address space.
  * Source/target buffer must be kernel space,
  * Do not walk the page table directly, use get_user_pages
