/* Do DAT for user address by page table walk, return kernel address. This function needs to be called with current->mm->page_table_lock held.  */
static __always_inline unsigned long __dat_user_addr(unsigned long uaddr)
/* Do DAT for user address by page table walk, return kernel address. This function needs to be called with current->mm->page_table_lock held.  */
static __always_inline unsigned long __dat_user_addr(unsigned long uaddr)
{
	struct mm_struct *mm = current->mm;
	unsigned long pfn;
	pte_t *pte;
	int rc;
retry:
	pte = follow_table(mm, uaddr);
	if ((unsigned long) pte < 0x1000)
		goto fault;
	if (!pte_present(*pte)) {
		pte = (pte_t *) 0x11;
		goto fault;
	}
	pfn = pte_pfn(*pte);
	return (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1));
fault:
	spin_unlock(&mm->page_table_lock);
	rc = __handle_fault(uaddr, (unsigned long) pte, 0);
	spin_lock(&mm->page_table_lock);
	if (!rc)
		goto retry;
	return 0;
}